Chromium Code Reviews| 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/frame/Frame.h" | 38 #include "core/frame/Frame.h" |
| 38 #include "core/frame/FrameSerializer.h" | 39 #include "core/frame/FrameSerializer.h" |
| 39 #include "core/frame/LocalFrame.h" | 40 #include "core/frame/LocalFrame.h" |
| 40 #include "core/frame/RemoteFrame.h" | 41 #include "core/frame/RemoteFrame.h" |
| 41 #include "core/frame/WebLocalFrameBase.h" | 42 #include "core/frame/WebLocalFrameBase.h" |
| 42 #include "core/html/HTMLAllCollection.h" | 43 #include "core/html/HTMLAllCollection.h" |
| 43 #include "core/html/HTMLFrameElementBase.h" | 44 #include "core/html/HTMLFrameElementBase.h" |
| 44 #include "core/html/HTMLFrameOwnerElement.h" | 45 #include "core/html/HTMLFrameOwnerElement.h" |
| 45 #include "core/html/HTMLImageElement.h" | 46 #include "core/html/HTMLImageElement.h" |
| 46 #include "core/html/HTMLInputElement.h" | 47 #include "core/html/HTMLInputElement.h" |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 73 #include "public/web/WebFrameSerializerCacheControlPolicy.h" | 74 #include "public/web/WebFrameSerializerCacheControlPolicy.h" |
| 74 #include "public/web/WebFrameSerializerClient.h" | 75 #include "public/web/WebFrameSerializerClient.h" |
| 75 #include "web/WebFrameSerializerImpl.h" | 76 #include "web/WebFrameSerializerImpl.h" |
| 76 #include "web/WebRemoteFrameImpl.h" | 77 #include "web/WebRemoteFrameImpl.h" |
| 77 | 78 |
| 78 namespace blink { | 79 namespace blink { |
| 79 | 80 |
| 80 namespace { | 81 namespace { |
| 81 | 82 |
| 82 const int kPopupOverlayZIndexThreshold = 50; | 83 const int kPopupOverlayZIndexThreshold = 50; |
| 84 const char kShadowModeAttributeName[] = "shadowmode"; | |
| 85 const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus"; | |
| 83 | 86 |
| 84 class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate { | 87 class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate { |
| 88 STACK_ALLOCATED() | |
| 85 WTF_MAKE_NONCOPYABLE(MHTMLFrameSerializerDelegate); | 89 WTF_MAKE_NONCOPYABLE(MHTMLFrameSerializerDelegate); |
| 86 | 90 |
| 87 public: | 91 public: |
| 88 explicit MHTMLFrameSerializerDelegate( | 92 MHTMLFrameSerializerDelegate( |
| 89 WebFrameSerializer::MHTMLPartsGenerationDelegate&); | 93 WebFrameSerializer::MHTMLPartsGenerationDelegate&, |
| 94 HeapHashSet<WeakMember<const Element>>&); | |
| 90 ~MHTMLFrameSerializerDelegate() override; | 95 ~MHTMLFrameSerializerDelegate() override; |
| 91 bool ShouldIgnoreElement(const Element&) override; | 96 bool ShouldIgnoreElement(const Element&) override; |
| 92 bool ShouldIgnoreAttribute(const Element&, const Attribute&) override; | 97 bool ShouldIgnoreAttribute(const Element&, const Attribute&) override; |
| 93 bool RewriteLink(const Element&, String& rewritten_link) override; | 98 bool RewriteLink(const Element&, String& rewritten_link) override; |
| 94 bool ShouldSkipResourceWithURL(const KURL&) override; | 99 bool ShouldSkipResourceWithURL(const KURL&) override; |
| 95 bool ShouldSkipResource( | 100 bool ShouldSkipResource( |
| 96 FrameSerializer::ResourceHasCacheControlNoStoreHeader) override; | 101 FrameSerializer::ResourceHasCacheControlNoStoreHeader) override; |
| 97 Vector<Attribute> GetCustomAttributes(const Element&) override; | 102 Vector<Attribute> GetCustomAttributes(const Element&) override; |
| 103 std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override; | |
| 98 | 104 |
| 99 private: | 105 private: |
| 100 bool ShouldIgnoreHiddenElement(const Element&); | 106 bool ShouldIgnoreHiddenElement(const Element&); |
| 101 bool ShouldIgnoreMetaElement(const Element&); | 107 bool ShouldIgnoreMetaElement(const Element&); |
| 102 bool ShouldIgnorePopupOverlayElement(const Element&); | 108 bool ShouldIgnorePopupOverlayElement(const Element&); |
| 103 void GetCustomAttributesForImageElement(const HTMLImageElement&, | 109 void GetCustomAttributesForImageElement(const HTMLImageElement&, |
| 104 Vector<Attribute>*); | 110 Vector<Attribute>*); |
| 105 void GetCustomAttributesForFormControlElement(const Element&, | 111 void GetCustomAttributesForFormControlElement(const Element&, |
| 106 Vector<Attribute>*); | 112 Vector<Attribute>*); |
| 107 | 113 |
| 108 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_; | 114 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_; |
| 115 HeapHashSet<WeakMember<const Element>>& shadow_template_elements_; | |
| 109 bool popup_overlays_skipped_; | 116 bool popup_overlays_skipped_; |
| 110 }; | 117 }; |
| 111 | 118 |
| 112 MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate( | 119 MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate( |
| 113 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate) | 120 WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate, |
| 114 : web_delegate_(web_delegate), popup_overlays_skipped_(false) {} | 121 HeapHashSet<WeakMember<const Element>>& shadow_template_elements) |
| 122 : web_delegate_(web_delegate), | |
| 123 shadow_template_elements_(shadow_template_elements), | |
| 124 popup_overlays_skipped_(false) {} | |
| 115 | 125 |
| 116 MHTMLFrameSerializerDelegate::~MHTMLFrameSerializerDelegate() { | 126 MHTMLFrameSerializerDelegate::~MHTMLFrameSerializerDelegate() { |
| 117 if (web_delegate_.RemovePopupOverlay()) { | 127 if (web_delegate_.RemovePopupOverlay()) { |
| 118 UMA_HISTOGRAM_BOOLEAN( | 128 UMA_HISTOGRAM_BOOLEAN( |
| 119 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", | 129 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", |
| 120 popup_overlays_skipped_); | 130 popup_overlays_skipped_); |
| 121 } | 131 } |
| 122 } | 132 } |
| 123 | 133 |
| 124 bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) { | 134 bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 if (attribute.LocalName() == HTMLNames::srcsetAttr) | 205 if (attribute.LocalName() == HTMLNames::srcsetAttr) |
| 196 return true; | 206 return true; |
| 197 | 207 |
| 198 // Do not save ping attribute since anyway the ping will be blocked from | 208 // Do not save ping attribute since anyway the ping will be blocked from |
| 199 // MHTML. | 209 // MHTML. |
| 200 if (isHTMLAnchorElement(element) && | 210 if (isHTMLAnchorElement(element) && |
| 201 attribute.LocalName() == HTMLNames::pingAttr) { | 211 attribute.LocalName() == HTMLNames::pingAttr) { |
| 202 return true; | 212 return true; |
| 203 } | 213 } |
| 204 | 214 |
| 215 // The special attribute in a template element to denote the shadow DOM | |
| 216 // should only be generated from MHTML serialization. If it is found in the | |
| 217 // original page, it should be ignored. | |
| 218 if (isHTMLTemplateElement(element) && | |
| 219 attribute.LocalName() == kShadowModeAttributeName && | |
|
Mike West
2017/06/14 07:03:59
Should we be stripping `kShadowDelegatesFocusAttri
jianli
2017/06/14 19:06:08
kShadowDelegatesFocusAttributeName can't take any
Dmitry Titov
2017/06/14 19:33:10
Hm, stripping all attributes that feature adds mig
jianli
2017/06/14 21:48:06
Sounds reasonable. I am going to remove this attri
| |
| 220 !shadow_template_elements_.Contains(&element)) { | |
| 221 return true; | |
| 222 } | |
| 223 | |
| 205 // If srcdoc attribute for frame elements will be rewritten as src attribute | 224 // If srcdoc attribute for frame elements will be rewritten as src attribute |
| 206 // containing link instead of html contents, don't ignore the attribute. | 225 // containing link instead of html contents, don't ignore the attribute. |
| 207 // Bail out now to avoid the check in Element::isScriptingAttribute. | 226 // Bail out now to avoid the check in Element::isScriptingAttribute. |
| 208 bool is_src_doc_attribute = IsHTMLFrameElementBase(element) && | 227 bool is_src_doc_attribute = IsHTMLFrameElementBase(element) && |
| 209 attribute.GetName() == HTMLNames::srcdocAttr; | 228 attribute.GetName() == HTMLNames::srcdocAttr; |
| 210 String new_link_for_the_element; | 229 String new_link_for_the_element; |
| 211 if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element)) | 230 if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element)) |
| 212 return false; | 231 return false; |
| 213 | 232 |
| 214 // Do not include attributes that contain javascript. This is because the | 233 // Do not include attributes that contain javascript. This is because the |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 Vector<Attribute>* attributes) { | 341 Vector<Attribute>* attributes) { |
| 323 // Disable all form elements in MTHML to tell the user that the form cannot be | 342 // Disable all form elements in MTHML to tell the user that the form cannot be |
| 324 // worked on. MHTML is loaded in full sandboxing mode which disable the form | 343 // worked on. MHTML is loaded in full sandboxing mode which disable the form |
| 325 // submission and script execution. | 344 // submission and script execution. |
| 326 if (element.FastHasAttribute(HTMLNames::disabledAttr)) | 345 if (element.FastHasAttribute(HTMLNames::disabledAttr)) |
| 327 return; | 346 return; |
| 328 Attribute disabled_attribute(HTMLNames::disabledAttr, ""); | 347 Attribute disabled_attribute(HTMLNames::disabledAttr, ""); |
| 329 attributes->push_back(disabled_attribute); | 348 attributes->push_back(disabled_attribute); |
| 330 } | 349 } |
| 331 | 350 |
| 351 std::pair<Node*, Element*> MHTMLFrameSerializerDelegate::GetAuxiliaryDOMTree( | |
| 352 const Element& element) const { | |
| 353 const ElementShadow* shadow = element.Shadow(); | |
| 354 if (!shadow) | |
| 355 return std::pair<Node*, Element*>(); | |
| 356 ShadowRoot& shadow_root = shadow->OldestShadowRoot(); | |
| 357 | |
| 358 String shadow_mode; | |
| 359 switch (shadow_root.GetType()) { | |
| 360 case ShadowRootType::kUserAgent: | |
| 361 // No need to serialize. | |
| 362 return std::pair<Node*, Element*>(); | |
| 363 case ShadowRootType::V0: | |
| 364 shadow_mode = "v0"; | |
| 365 break; | |
| 366 case ShadowRootType::kOpen: | |
| 367 shadow_mode = "open"; | |
| 368 break; | |
| 369 case ShadowRootType::kClosed: | |
| 370 shadow_mode = "closed"; | |
| 371 break; | |
| 372 } | |
| 373 | |
| 374 // Put the shadow DOM content inside a template element. A special attribute | |
| 375 // is set to tell the mode of the shadow DOM. | |
| 376 Element* template_element = | |
| 377 Element::Create(HTMLNames::templateTag, &(element.GetDocument())); | |
| 378 template_element->setAttribute( | |
| 379 QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom), | |
| 380 AtomicString(shadow_mode)); | |
| 381 if (shadow_root.GetType() != ShadowRootType::V0 && | |
| 382 shadow_root.delegatesFocus()) { | |
| 383 template_element->setAttribute( | |
| 384 QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName, | |
| 385 g_null_atom), | |
| 386 g_empty_atom); | |
| 387 } | |
| 388 shadow_template_elements_.insert(template_element); | |
| 389 | |
| 390 return std::pair<Node*, Element*>(&shadow_root, template_element); | |
| 391 } | |
| 392 | |
| 332 bool CacheControlNoStoreHeaderPresent( | 393 bool CacheControlNoStoreHeaderPresent( |
| 333 const WebLocalFrameBase& web_local_frame) { | 394 const WebLocalFrameBase& web_local_frame) { |
| 334 const ResourceResponse& response = | 395 const ResourceResponse& response = |
| 335 web_local_frame.DataSource()->GetResponse().ToResourceResponse(); | 396 web_local_frame.DataSource()->GetResponse().ToResourceResponse(); |
| 336 if (response.CacheControlContainsNoStore()) | 397 if (response.CacheControlContainsNoStore()) |
| 337 return true; | 398 return true; |
| 338 | 399 |
| 339 const ResourceRequest& request = | 400 const ResourceRequest& request = |
| 340 web_local_frame.DataSource()->GetRequest().ToResourceRequest(); | 401 web_local_frame.DataSource()->GetRequest().ToResourceRequest(); |
| 341 return request.CacheControlContainsNoStore(); | 402 return request.CacheControlContainsNoStore(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 ? MHTMLArchive::EncodingPolicy::kUseBinaryEncoding | 468 ? MHTMLArchive::EncodingPolicy::kUseBinaryEncoding |
| 408 : MHTMLArchive::EncodingPolicy::kUseDefaultEncoding; | 469 : MHTMLArchive::EncodingPolicy::kUseDefaultEncoding; |
| 409 | 470 |
| 410 // Serialize. | 471 // Serialize. |
| 411 TRACE_EVENT_BEGIN0("page-serialization", | 472 TRACE_EVENT_BEGIN0("page-serialization", |
| 412 "WebFrameSerializer::generateMHTMLParts serializing"); | 473 "WebFrameSerializer::generateMHTMLParts serializing"); |
| 413 Deque<SerializedResource> resources; | 474 Deque<SerializedResource> resources; |
| 414 { | 475 { |
| 415 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( | 476 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( |
| 416 "PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame"); | 477 "PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame"); |
| 417 MHTMLFrameSerializerDelegate core_delegate(*web_delegate); | 478 HeapHashSet<WeakMember<const Element>> shadow_template_elements; |
| 479 MHTMLFrameSerializerDelegate core_delegate(*web_delegate, | |
| 480 shadow_template_elements); | |
| 418 FrameSerializer serializer(resources, core_delegate); | 481 FrameSerializer serializer(resources, core_delegate); |
| 419 serializer.SerializeFrame(*frame); | 482 serializer.SerializeFrame(*frame); |
| 420 } | 483 } |
| 421 | 484 |
| 422 TRACE_EVENT_END1("page-serialization", | 485 TRACE_EVENT_END1("page-serialization", |
| 423 "WebFrameSerializer::generateMHTMLParts serializing", | 486 "WebFrameSerializer::generateMHTMLParts serializing", |
| 424 "resource count", | 487 "resource count", |
| 425 static_cast<unsigned long long>(resources.size())); | 488 static_cast<unsigned long long>(resources.size())); |
| 426 | 489 |
| 427 // There was an error serializing the frame (e.g. of an image resource). | 490 // 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... | |
| 479 const WebString& base_target) { | 542 const WebString& base_target) { |
| 480 // TODO(yosin) We should call |FrameSerializer::baseTagDeclarationOf()|. | 543 // TODO(yosin) We should call |FrameSerializer::baseTagDeclarationOf()|. |
| 481 if (base_target.IsEmpty()) | 544 if (base_target.IsEmpty()) |
| 482 return String("<base href=\".\">"); | 545 return String("<base href=\".\">"); |
| 483 String base_string = "<base href=\".\" target=\"" + | 546 String base_string = "<base href=\".\" target=\"" + |
| 484 static_cast<const String&>(base_target) + "\">"; | 547 static_cast<const String&>(base_target) + "\">"; |
| 485 return base_string; | 548 return base_string; |
| 486 } | 549 } |
| 487 | 550 |
| 488 } // namespace blink | 551 } // namespace blink |
| OLD | NEW |