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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/web/WebFrameSerializer.cpp
diff --git a/third_party/WebKit/Source/web/WebFrameSerializer.cpp b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
index 19e50a9e5d00d285739ec83271cc6b0320e20d9f..60af38cc62b2d8e520a9b05844a73486b254b1a8 100644
--- a/third_party/WebKit/Source/web/WebFrameSerializer.cpp
+++ b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
@@ -34,6 +34,7 @@
#include "core/InputTypeNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/shadow/ElementShadow.h"
#include "core/exported/WebRemoteFrameImpl.h"
#include "core/frame/Frame.h"
#include "core/frame/FrameSerializer.h"
@@ -81,13 +82,17 @@ namespace blink {
namespace {
const int kPopupOverlayZIndexThreshold = 50;
+const char kShadowModeAttributeName[] = "shadowmode";
+const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus";
class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate {
+ STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(MHTMLFrameSerializerDelegate);
public:
- explicit MHTMLFrameSerializerDelegate(
- WebFrameSerializer::MHTMLPartsGenerationDelegate&);
+ MHTMLFrameSerializerDelegate(
+ WebFrameSerializer::MHTMLPartsGenerationDelegate&,
+ HeapHashSet<WeakMember<const Element>>&);
~MHTMLFrameSerializerDelegate() override;
bool ShouldIgnoreElement(const Element&) override;
bool ShouldIgnoreAttribute(const Element&, const Attribute&) override;
@@ -96,6 +101,7 @@ class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate {
bool ShouldSkipResource(
FrameSerializer::ResourceHasCacheControlNoStoreHeader) override;
Vector<Attribute> GetCustomAttributes(const Element&) override;
+ std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override;
bool ShouldCollectProblemMetric() override;
private:
@@ -108,12 +114,16 @@ class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate {
Vector<Attribute>*);
WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_;
+ HeapHashSet<WeakMember<const Element>>& shadow_template_elements_;
bool popup_overlays_skipped_;
};
MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate(
- WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate)
- : web_delegate_(web_delegate), popup_overlays_skipped_(false) {}
+ WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate,
+ HeapHashSet<WeakMember<const Element>>& shadow_template_elements)
+ : web_delegate_(web_delegate),
+ shadow_template_elements_(shadow_template_elements),
+ popup_overlays_skipped_(false) {}
MHTMLFrameSerializerDelegate::~MHTMLFrameSerializerDelegate() {
if (web_delegate_.RemovePopupOverlay()) {
@@ -204,6 +214,16 @@ bool MHTMLFrameSerializerDelegate::ShouldIgnoreAttribute(
return true;
}
+ // The special attribute in a template element to denote the shadow DOM
+ // should only be generated from MHTML serialization. If it is found in the
+ // original page, it should be ignored.
+ if (isHTMLTemplateElement(element) &&
+ (attribute.LocalName() == kShadowModeAttributeName ||
+ attribute.LocalName() == kShadowDelegatesFocusAttributeName) &&
+ !shadow_template_elements_.Contains(&element)) {
+ return true;
+ }
+
// If srcdoc attribute for frame elements will be rewritten as src attribute
// containing link instead of html contents, don't ignore the attribute.
// Bail out now to avoid the check in Element::isScriptingAttribute.
@@ -335,6 +355,48 @@ void MHTMLFrameSerializerDelegate::GetCustomAttributesForFormControlElement(
attributes->push_back(disabled_attribute);
}
+std::pair<Node*, Element*> MHTMLFrameSerializerDelegate::GetAuxiliaryDOMTree(
+ const Element& element) const {
+ const ElementShadow* shadow = element.Shadow();
+ if (!shadow)
+ return std::pair<Node*, Element*>();
+ ShadowRoot& shadow_root = shadow->OldestShadowRoot();
+
+ String shadow_mode;
+ switch (shadow_root.GetType()) {
+ case ShadowRootType::kUserAgent:
+ // No need to serialize.
+ return std::pair<Node*, Element*>();
+ case ShadowRootType::V0:
+ shadow_mode = "v0";
+ break;
+ case ShadowRootType::kOpen:
+ shadow_mode = "open";
+ break;
+ case ShadowRootType::kClosed:
+ shadow_mode = "closed";
+ break;
+ }
+
+ // Put the shadow DOM content inside a template element. A special attribute
+ // is set to tell the mode of the shadow DOM.
+ Element* template_element =
+ Element::Create(HTMLNames::templateTag, &(element.GetDocument()));
+ template_element->setAttribute(
+ QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom),
+ AtomicString(shadow_mode));
+ if (shadow_root.GetType() != ShadowRootType::V0 &&
+ shadow_root.delegatesFocus()) {
+ template_element->setAttribute(
+ QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName,
+ g_null_atom),
+ g_empty_atom);
+ }
+ shadow_template_elements_.insert(template_element);
+
+ return std::pair<Node*, Element*>(&shadow_root, template_element);
+}
+
bool CacheControlNoStoreHeaderPresent(
const WebLocalFrameBase& web_local_frame) {
const ResourceResponse& response =
@@ -420,7 +482,9 @@ WebThreadSafeData WebFrameSerializer::GenerateMHTMLParts(
{
SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
"PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame");
- MHTMLFrameSerializerDelegate core_delegate(*web_delegate);
+ HeapHashSet<WeakMember<const Element>> shadow_template_elements;
+ MHTMLFrameSerializerDelegate core_delegate(*web_delegate,
+ shadow_template_elements);
FrameSerializer serializer(resources, core_delegate);
serializer.SerializeFrame(*frame);
}
« 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