Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1534)

Side by Side Diff: third_party/WebKit/Source/web/WebFrameSerializer.cpp

Issue 2912213002: Support serializing shadow DOM to MHTML (Closed)
Patch Set: Strip anoter shadow attribute Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 16 matching lines...) Expand all
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "public/web/WebFrameSerializer.h" 31 #include "public/web/WebFrameSerializer.h"
32 32
33 #include "core/HTMLNames.h" 33 #include "core/HTMLNames.h"
34 #include "core/InputTypeNames.h" 34 #include "core/InputTypeNames.h"
35 #include "core/dom/Document.h" 35 #include "core/dom/Document.h"
36 #include "core/dom/Element.h" 36 #include "core/dom/Element.h"
37 #include "core/dom/shadow/ElementShadow.h"
37 #include "core/exported/WebRemoteFrameImpl.h" 38 #include "core/exported/WebRemoteFrameImpl.h"
38 #include "core/frame/Frame.h" 39 #include "core/frame/Frame.h"
39 #include "core/frame/FrameSerializer.h" 40 #include "core/frame/FrameSerializer.h"
40 #include "core/frame/LocalFrame.h" 41 #include "core/frame/LocalFrame.h"
41 #include "core/frame/RemoteFrame.h" 42 #include "core/frame/RemoteFrame.h"
42 #include "core/frame/WebLocalFrameBase.h" 43 #include "core/frame/WebLocalFrameBase.h"
43 #include "core/html/HTMLAllCollection.h" 44 #include "core/html/HTMLAllCollection.h"
44 #include "core/html/HTMLFrameElementBase.h" 45 #include "core/html/HTMLFrameElementBase.h"
45 #include "core/html/HTMLFrameOwnerElement.h" 46 #include "core/html/HTMLFrameOwnerElement.h"
46 #include "core/html/HTMLImageElement.h" 47 #include "core/html/HTMLImageElement.h"
(...skipping 27 matching lines...) Expand all
74 #include "public/web/WebFrame.h" 75 #include "public/web/WebFrame.h"
75 #include "public/web/WebFrameSerializerCacheControlPolicy.h" 76 #include "public/web/WebFrameSerializerCacheControlPolicy.h"
76 #include "public/web/WebFrameSerializerClient.h" 77 #include "public/web/WebFrameSerializerClient.h"
77 #include "web/WebFrameSerializerImpl.h" 78 #include "web/WebFrameSerializerImpl.h"
78 79
79 namespace blink { 80 namespace blink {
80 81
81 namespace { 82 namespace {
82 83
83 const int kPopupOverlayZIndexThreshold = 50; 84 const int kPopupOverlayZIndexThreshold = 50;
85 const char kShadowModeAttributeName[] = "shadowmode";
86 const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus";
84 87
85 class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate { 88 class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate {
89 STACK_ALLOCATED();
86 WTF_MAKE_NONCOPYABLE(MHTMLFrameSerializerDelegate); 90 WTF_MAKE_NONCOPYABLE(MHTMLFrameSerializerDelegate);
87 91
88 public: 92 public:
89 explicit MHTMLFrameSerializerDelegate( 93 MHTMLFrameSerializerDelegate(
90 WebFrameSerializer::MHTMLPartsGenerationDelegate&); 94 WebFrameSerializer::MHTMLPartsGenerationDelegate&,
95 HeapHashSet<WeakMember<const Element>>&);
91 ~MHTMLFrameSerializerDelegate() override; 96 ~MHTMLFrameSerializerDelegate() override;
92 bool ShouldIgnoreElement(const Element&) override; 97 bool ShouldIgnoreElement(const Element&) override;
93 bool ShouldIgnoreAttribute(const Element&, const Attribute&) override; 98 bool ShouldIgnoreAttribute(const Element&, const Attribute&) override;
94 bool RewriteLink(const Element&, String& rewritten_link) override; 99 bool RewriteLink(const Element&, String& rewritten_link) override;
95 bool ShouldSkipResourceWithURL(const KURL&) override; 100 bool ShouldSkipResourceWithURL(const KURL&) override;
96 bool ShouldSkipResource( 101 bool ShouldSkipResource(
97 FrameSerializer::ResourceHasCacheControlNoStoreHeader) override; 102 FrameSerializer::ResourceHasCacheControlNoStoreHeader) override;
98 Vector<Attribute> GetCustomAttributes(const Element&) override; 103 Vector<Attribute> GetCustomAttributes(const Element&) override;
104 std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override;
99 bool ShouldCollectProblemMetric() override; 105 bool ShouldCollectProblemMetric() override;
100 106
101 private: 107 private:
102 bool ShouldIgnoreHiddenElement(const Element&); 108 bool ShouldIgnoreHiddenElement(const Element&);
103 bool ShouldIgnoreMetaElement(const Element&); 109 bool ShouldIgnoreMetaElement(const Element&);
104 bool ShouldIgnorePopupOverlayElement(const Element&); 110 bool ShouldIgnorePopupOverlayElement(const Element&);
105 void GetCustomAttributesForImageElement(const HTMLImageElement&, 111 void GetCustomAttributesForImageElement(const HTMLImageElement&,
106 Vector<Attribute>*); 112 Vector<Attribute>*);
107 void GetCustomAttributesForFormControlElement(const Element&, 113 void GetCustomAttributesForFormControlElement(const Element&,
108 Vector<Attribute>*); 114 Vector<Attribute>*);
109 115
110 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_; 116 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_;
117 HeapHashSet<WeakMember<const Element>>& shadow_template_elements_;
111 bool popup_overlays_skipped_; 118 bool popup_overlays_skipped_;
112 }; 119 };
113 120
114 MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate( 121 MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate(
115 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate) 122 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate,
116 : web_delegate_(web_delegate), popup_overlays_skipped_(false) {} 123 HeapHashSet<WeakMember<const Element>>& shadow_template_elements)
124 : web_delegate_(web_delegate),
125 shadow_template_elements_(shadow_template_elements),
126 popup_overlays_skipped_(false) {}
117 127
118 MHTMLFrameSerializerDelegate::~MHTMLFrameSerializerDelegate() { 128 MHTMLFrameSerializerDelegate::~MHTMLFrameSerializerDelegate() {
119 if (web_delegate_.RemovePopupOverlay()) { 129 if (web_delegate_.RemovePopupOverlay()) {
120 UMA_HISTOGRAM_BOOLEAN( 130 UMA_HISTOGRAM_BOOLEAN(
121 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", 131 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped",
122 popup_overlays_skipped_); 132 popup_overlays_skipped_);
123 } 133 }
124 } 134 }
125 135
126 bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) { 136 bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 if (attribute.LocalName() == HTMLNames::srcsetAttr) 207 if (attribute.LocalName() == HTMLNames::srcsetAttr)
198 return true; 208 return true;
199 209
200 // Do not save ping attribute since anyway the ping will be blocked from 210 // Do not save ping attribute since anyway the ping will be blocked from
201 // MHTML. 211 // MHTML.
202 if (isHTMLAnchorElement(element) && 212 if (isHTMLAnchorElement(element) &&
203 attribute.LocalName() == HTMLNames::pingAttr) { 213 attribute.LocalName() == HTMLNames::pingAttr) {
204 return true; 214 return true;
205 } 215 }
206 216
217 // The special attribute in a template element to denote the shadow DOM
218 // should only be generated from MHTML serialization. If it is found in the
219 // original page, it should be ignored.
220 if (isHTMLTemplateElement(element) &&
221 (attribute.LocalName() == kShadowModeAttributeName ||
222 attribute.LocalName() == kShadowDelegatesFocusAttributeName) &&
223 !shadow_template_elements_.Contains(&element)) {
224 return true;
225 }
226
207 // If srcdoc attribute for frame elements will be rewritten as src attribute 227 // If srcdoc attribute for frame elements will be rewritten as src attribute
208 // containing link instead of html contents, don't ignore the attribute. 228 // containing link instead of html contents, don't ignore the attribute.
209 // Bail out now to avoid the check in Element::isScriptingAttribute. 229 // Bail out now to avoid the check in Element::isScriptingAttribute.
210 bool is_src_doc_attribute = IsHTMLFrameElementBase(element) && 230 bool is_src_doc_attribute = IsHTMLFrameElementBase(element) &&
211 attribute.GetName() == HTMLNames::srcdocAttr; 231 attribute.GetName() == HTMLNames::srcdocAttr;
212 String new_link_for_the_element; 232 String new_link_for_the_element;
213 if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element)) 233 if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element))
214 return false; 234 return false;
215 235
216 // Do not include attributes that contain javascript. This is because the 236 // Do not include attributes that contain javascript. This is because the
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 Vector<Attribute>* attributes) { 348 Vector<Attribute>* attributes) {
329 // Disable all form elements in MTHML to tell the user that the form cannot be 349 // Disable all form elements in MTHML to tell the user that the form cannot be
330 // worked on. MHTML is loaded in full sandboxing mode which disable the form 350 // worked on. MHTML is loaded in full sandboxing mode which disable the form
331 // submission and script execution. 351 // submission and script execution.
332 if (element.FastHasAttribute(HTMLNames::disabledAttr)) 352 if (element.FastHasAttribute(HTMLNames::disabledAttr))
333 return; 353 return;
334 Attribute disabled_attribute(HTMLNames::disabledAttr, ""); 354 Attribute disabled_attribute(HTMLNames::disabledAttr, "");
335 attributes->push_back(disabled_attribute); 355 attributes->push_back(disabled_attribute);
336 } 356 }
337 357
358 std::pair<Node*, Element*> MHTMLFrameSerializerDelegate::GetAuxiliaryDOMTree(
359 const Element& element) const {
360 const ElementShadow* shadow = element.Shadow();
361 if (!shadow)
362 return std::pair<Node*, Element*>();
363 ShadowRoot& shadow_root = shadow->OldestShadowRoot();
364
365 String shadow_mode;
366 switch (shadow_root.GetType()) {
367 case ShadowRootType::kUserAgent:
368 // No need to serialize.
369 return std::pair<Node*, Element*>();
370 case ShadowRootType::V0:
371 shadow_mode = "v0";
372 break;
373 case ShadowRootType::kOpen:
374 shadow_mode = "open";
375 break;
376 case ShadowRootType::kClosed:
377 shadow_mode = "closed";
378 break;
379 }
380
381 // Put the shadow DOM content inside a template element. A special attribute
382 // is set to tell the mode of the shadow DOM.
383 Element* template_element =
384 Element::Create(HTMLNames::templateTag, &(element.GetDocument()));
385 template_element->setAttribute(
386 QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom),
387 AtomicString(shadow_mode));
388 if (shadow_root.GetType() != ShadowRootType::V0 &&
389 shadow_root.delegatesFocus()) {
390 template_element->setAttribute(
391 QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName,
392 g_null_atom),
393 g_empty_atom);
394 }
395 shadow_template_elements_.insert(template_element);
396
397 return std::pair<Node*, Element*>(&shadow_root, template_element);
398 }
399
338 bool CacheControlNoStoreHeaderPresent( 400 bool CacheControlNoStoreHeaderPresent(
339 const WebLocalFrameBase& web_local_frame) { 401 const WebLocalFrameBase& web_local_frame) {
340 const ResourceResponse& response = 402 const ResourceResponse& response =
341 web_local_frame.DataSource()->GetResponse().ToResourceResponse(); 403 web_local_frame.DataSource()->GetResponse().ToResourceResponse();
342 if (response.CacheControlContainsNoStore()) 404 if (response.CacheControlContainsNoStore())
343 return true; 405 return true;
344 406
345 const ResourceRequest& request = 407 const ResourceRequest& request =
346 web_local_frame.DataSource()->GetRequest().ToResourceRequest(); 408 web_local_frame.DataSource()->GetRequest().ToResourceRequest();
347 return request.CacheControlContainsNoStore(); 409 return request.CacheControlContainsNoStore();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 ? MHTMLArchive::EncodingPolicy::kUseBinaryEncoding 475 ? MHTMLArchive::EncodingPolicy::kUseBinaryEncoding
414 : MHTMLArchive::EncodingPolicy::kUseDefaultEncoding; 476 : MHTMLArchive::EncodingPolicy::kUseDefaultEncoding;
415 477
416 // Serialize. 478 // Serialize.
417 TRACE_EVENT_BEGIN0("page-serialization", 479 TRACE_EVENT_BEGIN0("page-serialization",
418 "WebFrameSerializer::generateMHTMLParts serializing"); 480 "WebFrameSerializer::generateMHTMLParts serializing");
419 Deque<SerializedResource> resources; 481 Deque<SerializedResource> resources;
420 { 482 {
421 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( 483 SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
422 "PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame"); 484 "PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame");
423 MHTMLFrameSerializerDelegate core_delegate(*web_delegate); 485 HeapHashSet<WeakMember<const Element>> shadow_template_elements;
486 MHTMLFrameSerializerDelegate core_delegate(*web_delegate,
487 shadow_template_elements);
424 FrameSerializer serializer(resources, core_delegate); 488 FrameSerializer serializer(resources, core_delegate);
425 serializer.SerializeFrame(*frame); 489 serializer.SerializeFrame(*frame);
426 } 490 }
427 491
428 TRACE_EVENT_END1("page-serialization", 492 TRACE_EVENT_END1("page-serialization",
429 "WebFrameSerializer::generateMHTMLParts serializing", 493 "WebFrameSerializer::generateMHTMLParts serializing",
430 "resource count", 494 "resource count",
431 static_cast<unsigned long long>(resources.size())); 495 static_cast<unsigned long long>(resources.size()));
432 496
433 // There was an error serializing the frame (e.g. of an image resource). 497 // There was an error serializing the frame (e.g. of an image resource).
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 const WebString& base_target) { 549 const WebString& base_target) {
486 // TODO(yosin) We should call |FrameSerializer::baseTagDeclarationOf()|. 550 // TODO(yosin) We should call |FrameSerializer::baseTagDeclarationOf()|.
487 if (base_target.IsEmpty()) 551 if (base_target.IsEmpty())
488 return String("<base href=\".\">"); 552 return String("<base href=\".\">");
489 String base_string = "<base href=\".\" target=\"" + 553 String base_string = "<base href=\".\" target=\"" +
490 static_cast<const String&>(base_target) + "\">"; 554 static_cast<const String&>(base_target) + "\">";
491 return base_string; 555 return base_string;
492 } 556 }
493 557
494 } // namespace blink 558 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/LocalFrameClientImpl.cpp ('k') | third_party/WebKit/Source/web/tests/MHTMLTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698