From 5f12940329ba496da5730863cae94cd8c0b145da Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 17 Apr 2020 06:34:38 -0400 Subject: Bug 1396584 - Remove support for multiple ShadowRoots Tag #1375 --- dom/html/HTMLShadowElement.cpp | 373 --------------------------------- dom/html/HTMLShadowElement.h | 96 --------- dom/html/moz.build | 2 - dom/html/nsGenericHTMLElement.h | 1 - dom/html/nsGenericHTMLFrameElement.cpp | 1 + dom/html/nsHTMLContentSink.cpp | 1 + 6 files changed, 2 insertions(+), 472 deletions(-) delete mode 100644 dom/html/HTMLShadowElement.cpp delete mode 100644 dom/html/HTMLShadowElement.h (limited to 'dom/html') diff --git a/dom/html/HTMLShadowElement.cpp b/dom/html/HTMLShadowElement.cpp deleted file mode 100644 index 8824c2875..000000000 --- a/dom/html/HTMLShadowElement.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozilla/dom/ShadowRoot.h" - -#include "ChildIterator.h" -#include "nsContentUtils.h" -#include "nsDocument.h" -#include "mozilla/dom/HTMLShadowElement.h" -#include "mozilla/dom/HTMLUnknownElement.h" -#include "mozilla/dom/HTMLShadowElementBinding.h" - -// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Shadow) to add check for web components -// being enabled. -nsGenericHTMLElement* -NS_NewHTMLShadowElement(already_AddRefed&& aNodeInfo, - mozilla::dom::FromParser aFromParser) -{ - // When this check is removed, remove the nsDocument.h and - // HTMLUnknownElement.h includes. Also remove nsINode::IsHTMLShadowElement. - // - // We have to jump through some hoops to be able to produce both NodeInfo* and - // already_AddRefed& for our callees. - RefPtr nodeInfo(aNodeInfo); - if (!nsDocument::IsWebComponentsEnabled(nodeInfo)) { - already_AddRefed nodeInfoArg(nodeInfo.forget()); - return new mozilla::dom::HTMLUnknownElement(nodeInfoArg); - } - - already_AddRefed nodeInfoArg(nodeInfo.forget()); - return new mozilla::dom::HTMLShadowElement(nodeInfoArg); -} - -using namespace mozilla::dom; - -HTMLShadowElement::HTMLShadowElement(already_AddRefed& aNodeInfo) - : nsGenericHTMLElement(aNodeInfo), mIsInsertionPoint(false) -{ -} - -HTMLShadowElement::~HTMLShadowElement() -{ - if (mProjectedShadow) { - mProjectedShadow->RemoveMutationObserver(this); - } -} - -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLShadowElement) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLShadowElement, - nsGenericHTMLElement) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mProjectedShadow) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLShadowElement, - nsGenericHTMLElement) - if (tmp->mProjectedShadow) { - tmp->mProjectedShadow->RemoveMutationObserver(tmp); - tmp->mProjectedShadow = nullptr; - } -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_ADDREF_INHERITED(HTMLShadowElement, Element) -NS_IMPL_RELEASE_INHERITED(HTMLShadowElement, Element) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLShadowElement) -NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement) - -NS_IMPL_ELEMENT_CLONE(HTMLShadowElement) - -JSObject* -HTMLShadowElement::WrapNode(JSContext *aCx, JS::Handle aGivenProto) -{ - return HTMLShadowElementBinding::Wrap(aCx, this, aGivenProto); -} - -void -HTMLShadowElement::SetProjectedShadow(ShadowRoot* aProjectedShadow) -{ - if (mProjectedShadow) { - mProjectedShadow->RemoveMutationObserver(this); - - // The currently projected ShadowRoot is going away, - // thus the destination insertion points need to be updated. - ExplicitChildIterator childIterator(mProjectedShadow); - for (nsIContent* content = childIterator.GetNextChild(); - content; - content = childIterator.GetNextChild()) { - ShadowRoot::RemoveDestInsertionPoint(this, content->DestInsertionPoints()); - } - } - - mProjectedShadow = aProjectedShadow; - if (mProjectedShadow) { - // A new ShadowRoot is being projected, thus its explcit - // children will be distributed to this shadow insertion point. - ExplicitChildIterator childIterator(mProjectedShadow); - for (nsIContent* content = childIterator.GetNextChild(); - content; - content = childIterator.GetNextChild()) { - content->DestInsertionPoints().AppendElement(this); - } - - // Watch for mutations on the projected shadow because - // it affects the nodes that are distributed to this shadow - // insertion point. - mProjectedShadow->AddMutationObserver(this); - } -} - -static bool -IsInFallbackContent(nsIContent* aContent) -{ - nsINode* parentNode = aContent->GetParentNode(); - while (parentNode) { - if (parentNode->IsHTMLElement(nsGkAtoms::content)) { - return true; - } - parentNode = parentNode->GetParentNode(); - } - - return false; -} - -nsresult -HTMLShadowElement::BindToTree(nsIDocument* aDocument, - nsIContent* aParent, - nsIContent* aBindingParent, - bool aCompileEventHandlers) -{ - RefPtr oldContainingShadow = GetContainingShadow(); - - nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent, - aBindingParent, - aCompileEventHandlers); - NS_ENSURE_SUCCESS(rv, rv); - - ShadowRoot* containingShadow = GetContainingShadow(); - if (containingShadow && !oldContainingShadow) { - // Keep track of all descendant elements in tree order so - // that when the current shadow insertion point is removed, the next - // one can be found quickly. - TreeOrderComparator comparator; - containingShadow->ShadowDescendants().InsertElementSorted(this, comparator); - - if (containingShadow->ShadowDescendants()[0] != this) { - // Only the first (in tree order) of a ShadowRoot can be an insertion point. - return NS_OK; - } - - if (IsInFallbackContent(this)) { - // If the first shadow element in tree order is invalid (in fallback content), - // the containing ShadowRoot will not have a shadow insertion point. - containingShadow->SetShadowElement(nullptr); - } else { - mIsInsertionPoint = true; - containingShadow->SetShadowElement(this); - } - - containingShadow->SetInsertionPointChanged(); - } - - if (mIsInsertionPoint && containingShadow) { - // Propagate BindToTree calls to projected shadow root children. - ShadowRoot* projectedShadow = containingShadow->GetOlderShadowRoot(); - if (projectedShadow) { - projectedShadow->SetIsComposedDocParticipant(IsInComposedDoc()); - - for (nsIContent* child = projectedShadow->GetFirstChild(); child; - child = child->GetNextSibling()) { - rv = child->BindToTree(nullptr, projectedShadow, - projectedShadow->GetBindingParent(), - aCompileEventHandlers); - NS_ENSURE_SUCCESS(rv, rv); - } - } - } - - return NS_OK; -} - -void -HTMLShadowElement::UnbindFromTree(bool aDeep, bool aNullParent) -{ - RefPtr oldContainingShadow = GetContainingShadow(); - - if (mIsInsertionPoint && oldContainingShadow) { - // Propagate UnbindFromTree call to previous projected shadow - // root children. - ShadowRoot* projectedShadow = oldContainingShadow->GetOlderShadowRoot(); - if (projectedShadow) { - for (nsIContent* child = projectedShadow->GetFirstChild(); child; - child = child->GetNextSibling()) { - child->UnbindFromTree(true, false); - } - - projectedShadow->SetIsComposedDocParticipant(false); - } - } - - nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); - - if (oldContainingShadow && !GetContainingShadow() && mIsInsertionPoint) { - nsTArray& shadowDescendants = - oldContainingShadow->ShadowDescendants(); - shadowDescendants.RemoveElement(this); - oldContainingShadow->SetShadowElement(nullptr); - - // Find the next shadow insertion point. - if (shadowDescendants.Length() > 0 && - !IsInFallbackContent(shadowDescendants[0])) { - oldContainingShadow->SetShadowElement(shadowDescendants[0]); - } - - oldContainingShadow->SetInsertionPointChanged(); - - mIsInsertionPoint = false; - } -} - -void -HTMLShadowElement::DistributeSingleNode(nsIContent* aContent) -{ - if (aContent->DestInsertionPoints().Contains(this)) { - // Node has already been distrbuted this this node, - // we are done. - return; - } - - aContent->DestInsertionPoints().AppendElement(this); - - // Handle the case where the shadow element is a child of - // a node with a ShadowRoot. The nodes that have been distributed to - // this shadow insertion point will need to be reprojected into the - // insertion points of the parent's ShadowRoot. - ShadowRoot* parentShadowRoot = GetParent()->GetShadowRoot(); - if (parentShadowRoot) { - parentShadowRoot->DistributeSingleNode(aContent); - return; - } - - // Handle the case where the parent of this shadow element is a ShadowRoot - // that is projected into a shadow insertion point in the younger ShadowRoot. - ShadowRoot* containingShadow = GetContainingShadow(); - ShadowRoot* youngerShadow = containingShadow->GetYoungerShadowRoot(); - if (youngerShadow && GetParent() == containingShadow) { - HTMLShadowElement* youngerShadowElement = youngerShadow->GetShadowElement(); - if (youngerShadowElement) { - youngerShadowElement->DistributeSingleNode(aContent); - } - } -} - -void -HTMLShadowElement::RemoveDistributedNode(nsIContent* aContent) -{ - ShadowRoot::RemoveDestInsertionPoint(this, aContent->DestInsertionPoints()); - - // Handle the case where the shadow element is a child of - // a node with a ShadowRoot. The nodes that have been distributed to - // this shadow insertion point will need to be removed from the - // insertion points of the parent's ShadowRoot. - ShadowRoot* parentShadowRoot = GetParent()->GetShadowRoot(); - if (parentShadowRoot) { - parentShadowRoot->RemoveDistributedNode(aContent); - return; - } - - // Handle the case where the parent of this shadow element is a ShadowRoot - // that is projected into a shadow insertion point in the younger ShadowRoot. - ShadowRoot* containingShadow = GetContainingShadow(); - ShadowRoot* youngerShadow = containingShadow->GetYoungerShadowRoot(); - if (youngerShadow && GetParent() == containingShadow) { - HTMLShadowElement* youngerShadowElement = youngerShadow->GetShadowElement(); - if (youngerShadowElement) { - youngerShadowElement->RemoveDistributedNode(aContent); - } - } -} - -void -HTMLShadowElement::DistributeAllNodes() -{ - // All the explicit children of the projected ShadowRoot are distributed - // into this shadow insertion point so update the destination insertion - // points. - ShadowRoot* containingShadow = GetContainingShadow(); - ShadowRoot* olderShadow = containingShadow->GetOlderShadowRoot(); - if (olderShadow) { - ExplicitChildIterator childIterator(olderShadow); - for (nsIContent* content = childIterator.GetNextChild(); - content; - content = childIterator.GetNextChild()) { - ShadowRoot::RemoveDestInsertionPoint(this, content->DestInsertionPoints()); - content->DestInsertionPoints().AppendElement(this); - } - } - - // Handle the case where the shadow element is a child of - // a node with a ShadowRoot. The nodes that have been distributed to - // this shadow insertion point will need to be reprojected into the - // insertion points of the parent's ShadowRoot. - ShadowRoot* parentShadowRoot = GetParent()->GetShadowRoot(); - if (parentShadowRoot) { - parentShadowRoot->DistributeAllNodes(); - return; - } - - // Handle the case where the parent of this shadow element is a ShadowRoot - // that is projected into a shadow insertion point in the younger ShadowRoot. - ShadowRoot* youngerShadow = containingShadow->GetYoungerShadowRoot(); - if (youngerShadow && GetParent() == containingShadow) { - HTMLShadowElement* youngerShadowElement = youngerShadow->GetShadowElement(); - if (youngerShadowElement) { - youngerShadowElement->DistributeAllNodes(); - } - } -} - -void -HTMLShadowElement::ContentAppended(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aFirstNewContent, - int32_t aNewIndexInContainer) -{ - // Watch for content appended to the projected shadow (the ShadowRoot that - // will be rendered in place of this shadow insertion point) because the - // nodes may need to be distributed into other insertion points. - nsIContent* currentChild = aFirstNewContent; - while (currentChild) { - if (ShadowRoot::IsPooledNode(currentChild, aContainer, mProjectedShadow)) { - DistributeSingleNode(currentChild); - } - currentChild = currentChild->GetNextSibling(); - } -} - -void -HTMLShadowElement::ContentInserted(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - int32_t aIndexInContainer) -{ - // Watch for content appended to the projected shadow (the ShadowRoot that - // will be rendered in place of this shadow insertion point) because the - // nodes may need to be distributed into other insertion points. - if (!ShadowRoot::IsPooledNode(aChild, aContainer, mProjectedShadow)) { - return; - } - - DistributeSingleNode(aChild); -} - -void -HTMLShadowElement::ContentRemoved(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - int32_t aIndexInContainer, - nsIContent* aPreviousSibling) -{ - // Watch for content removed from the projected shadow (the ShadowRoot that - // will be rendered in place of this shadow insertion point) because the - // nodes may need to be removed from other insertion points. - if (!ShadowRoot::IsPooledNode(aChild, aContainer, mProjectedShadow)) { - return; - } - - RemoveDistributedNode(aChild); -} - diff --git a/dom/html/HTMLShadowElement.h b/dom/html/HTMLShadowElement.h deleted file mode 100644 index 95083b802..000000000 --- a/dom/html/HTMLShadowElement.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_HTMLShadowElement_h__ -#define mozilla_dom_HTMLShadowElement_h__ - -#include "nsGenericHTMLElement.h" - -namespace mozilla { -namespace dom { - -class HTMLShadowElement final : public nsGenericHTMLElement, - public nsStubMutationObserver -{ -public: - explicit HTMLShadowElement(already_AddRefed& aNodeInfo); - - // nsISupports - NS_DECL_ISUPPORTS_INHERITED - - NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED - NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED - NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED - - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLShadowElement, - nsGenericHTMLElement) - - static HTMLShadowElement* FromContent(nsIContent* aContent) - { - if (aContent->IsHTMLShadowElement()) { - return static_cast(aContent); - } - - return nullptr; - } - - virtual bool IsHTMLShadowElement() const override { return true; } - - virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override; - - virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, - nsIContent* aBindingParent, - bool aCompileEventHandlers) override; - - virtual void UnbindFromTree(bool aDeep = true, - bool aNullParent = true) override; - - bool IsInsertionPoint() { return mIsInsertionPoint; } - - /** - * Sets the ShadowRoot that will be rendered in place of - * this shadow insertion point. - */ - void SetProjectedShadow(ShadowRoot* aProjectedShadow); - - /** - * Distributes a single explicit child of the projected ShadowRoot - * to relevant insertion points. - */ - void DistributeSingleNode(nsIContent* aContent); - - /** - * Removes a single explicit child of the projected ShadowRoot - * from relevant insertion points. - */ - void RemoveDistributedNode(nsIContent* aContent); - - /** - * Distributes all the explicit children of the projected ShadowRoot - * to the shadow insertion point in the younger ShadowRoot and - * the content insertion point of the parent node's ShadowRoot. - */ - void DistributeAllNodes(); - - // WebIDL methods. - ShadowRoot* GetOlderShadowRoot() { return mProjectedShadow; } - -protected: - virtual ~HTMLShadowElement(); - - virtual JSObject* WrapNode(JSContext *aCx, JS::Handle aGivenProto) override; - - // The ShadowRoot that will be rendered in place of this shadow insertion point. - RefPtr mProjectedShadow; - - bool mIsInsertionPoint; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_HTMLShadowElement_h__ - diff --git a/dom/html/moz.build b/dom/html/moz.build index c86c169b5..1ccc630fd 100644 --- a/dom/html/moz.build +++ b/dom/html/moz.build @@ -92,7 +92,6 @@ EXPORTS.mozilla.dom += [ 'HTMLProgressElement.h', 'HTMLScriptElement.h', 'HTMLSelectElement.h', - 'HTMLShadowElement.h', 'HTMLSharedElement.h', 'HTMLSharedListElement.h', 'HTMLSharedObjectElement.h', @@ -172,7 +171,6 @@ UNIFIED_SOURCES += [ 'HTMLProgressElement.cpp', 'HTMLScriptElement.cpp', 'HTMLSelectElement.cpp', - 'HTMLShadowElement.cpp', 'HTMLSharedElement.cpp', 'HTMLSharedListElement.cpp', 'HTMLSharedObjectElement.cpp', diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index 16f438acc..3b451b29c 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -1700,7 +1700,6 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Pre) NS_DECLARE_NS_NEW_HTML_ELEMENT(Progress) NS_DECLARE_NS_NEW_HTML_ELEMENT(Script) NS_DECLARE_NS_NEW_HTML_ELEMENT(Select) -NS_DECLARE_NS_NEW_HTML_ELEMENT(Shadow) NS_DECLARE_NS_NEW_HTML_ELEMENT(Source) NS_DECLARE_NS_NEW_HTML_ELEMENT(Span) NS_DECLARE_NS_NEW_HTML_ELEMENT(Style) diff --git a/dom/html/nsGenericHTMLFrameElement.cpp b/dom/html/nsGenericHTMLFrameElement.cpp index 03e6ffb42..8170179e2 100644 --- a/dom/html/nsGenericHTMLFrameElement.cpp +++ b/dom/html/nsGenericHTMLFrameElement.cpp @@ -27,6 +27,7 @@ #include "nsServiceManagerUtils.h" #include "nsSubDocumentFrame.h" #include "nsXULElement.h" +#include "nsAttrValueOrString.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/dom/html/nsHTMLContentSink.cpp b/dom/html/nsHTMLContentSink.cpp index 1c390a53e..eb22b772f 100644 --- a/dom/html/nsHTMLContentSink.cpp +++ b/dom/html/nsHTMLContentSink.cpp @@ -31,6 +31,7 @@ #include "mozilla/Logging.h" #include "nsNodeUtils.h" #include "nsIContent.h" +#include "mozilla/dom/CustomElementRegistry.h" #include "mozilla/dom/Element.h" #include "mozilla/Preferences.h" -- cgit v1.2.3