| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |