diff options
author | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 07:08:22 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 07:08:22 -0400 |
commit | 8beb65dd501cbdcfd6a793027b5de2a1fdfc7149 (patch) | |
tree | 4b524fb1a1888b37bc347dc65c7c200979fe54aa /dom/base | |
parent | 5524318fe73a1123da10491a6a545b50af88ea60 (diff) | |
download | UXP-8beb65dd501cbdcfd6a793027b5de2a1fdfc7149.tar UXP-8beb65dd501cbdcfd6a793027b5de2a1fdfc7149.tar.gz UXP-8beb65dd501cbdcfd6a793027b5de2a1fdfc7149.tar.lz UXP-8beb65dd501cbdcfd6a793027b5de2a1fdfc7149.tar.xz UXP-8beb65dd501cbdcfd6a793027b5de2a1fdfc7149.zip |
Bug 1418002 - Remove HTMLContentElement
Tag #1375
Diffstat (limited to 'dom/base')
-rw-r--r-- | dom/base/ChildIterator.cpp | 21 | ||||
-rw-r--r-- | dom/base/ShadowRoot.cpp | 266 | ||||
-rw-r--r-- | dom/base/ShadowRoot.h | 36 | ||||
-rw-r--r-- | dom/base/nsContentUtils.cpp | 14 |
4 files changed, 12 insertions, 325 deletions
diff --git a/dom/base/ChildIterator.cpp b/dom/base/ChildIterator.cpp index 391b7c326..dc356fc01 100644 --- a/dom/base/ChildIterator.cpp +++ b/dom/base/ChildIterator.cpp @@ -7,7 +7,6 @@ #include "ChildIterator.h" #include "nsContentUtils.h" #include "mozilla/dom/XBLChildrenElement.h" -#include "mozilla/dom/HTMLContentElement.h" #include "mozilla/dom/ShadowRoot.h" #include "nsIAnonymousContentCreator.h" #include "nsIFrame.h" @@ -18,33 +17,29 @@ namespace dom { class MatchedNodes { public: - explicit MatchedNodes(HTMLContentElement* aInsertionPoint) - : mIsContentElement(true), mContentElement(aInsertionPoint) {} - + explicit MatchedNodes() + : mIsContentElement(false), mChildrenElement(nullptr) {} explicit MatchedNodes(XBLChildrenElement* aInsertionPoint) : mIsContentElement(false), mChildrenElement(aInsertionPoint) {} uint32_t Length() const { - return mIsContentElement ? mContentElement->MatchedNodes().Length() - : mChildrenElement->InsertedChildrenLength(); + return mChildrenElement ? mChildrenElement->InsertedChildrenLength() : 0; } nsIContent* operator[](int32_t aIndex) const { - return mIsContentElement ? mContentElement->MatchedNodes()[aIndex] - : mChildrenElement->InsertedChild(aIndex); + return mChildrenElement ? mChildrenElement->InsertedChild(aIndex) : nullptr; } bool IsEmpty() const { - return mIsContentElement ? mContentElement->MatchedNodes().IsEmpty() - : !mChildrenElement->HasInsertedChildren(); + return mChildrenElement && !mChildrenElement->HasInsertedChildren(); } protected: + // Leftover from Shadow DOM v0. bool mIsContentElement; union { - HTMLContentElement* mContentElement; XBLChildrenElement* mChildrenElement; }; }; @@ -57,9 +52,9 @@ GetMatchedNodesForPoint(nsIContent* aContent) return MatchedNodes(static_cast<XBLChildrenElement*>(aContent)); } + return MatchedNodes(); // Web components case - MOZ_ASSERT(aContent->IsHTMLElement(nsGkAtoms::content)); - return MatchedNodes(HTMLContentElement::FromContent(aContent)); + // XXX handle <slot> element? } nsIContent* diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp index e00bb69d8..97214e050 100644 --- a/dom/base/ShadowRoot.cpp +++ b/dom/base/ShadowRoot.cpp @@ -14,7 +14,6 @@ #include "nsIDOMHTMLElement.h" #include "nsIStyleSheetLinkingElement.h" #include "mozilla/dom/Element.h" -#include "mozilla/dom/HTMLContentElement.h" #include "nsXBLPrototypeBinding.h" #include "mozilla/StyleSheet.h" #include "mozilla/StyleSheetInlines.h" @@ -224,35 +223,6 @@ ShadowRoot::GetElementsByClassName(const nsAString& aClasses) } void -ShadowRoot::AddInsertionPoint(HTMLContentElement* aInsertionPoint) -{ - TreeOrderComparator comparator; - mInsertionPoints.InsertElementSorted(aInsertionPoint, comparator); -} - -void -ShadowRoot::RemoveInsertionPoint(HTMLContentElement* aInsertionPoint) -{ - mInsertionPoints.RemoveElement(aInsertionPoint); -} - -void -ShadowRoot::RemoveDestInsertionPoint(nsIContent* aInsertionPoint, - nsTArray<nsIContent*>& aDestInsertionPoints) -{ - // Remove the insertion point from the destination insertion points. - // Also remove all succeeding insertion points because it is no longer - // possible for the content to be distributed into deeper node trees. - int32_t index = aDestInsertionPoints.IndexOf(aInsertionPoint); - - // It's possible that we already removed the insertion point while processing - // other insertion point removals. - if (index >= 0) { - aDestInsertionPoints.SetLength(index); - } -} - -void ShadowRoot::DistributionChanged() { // FIXME(emilio): We could be more granular in a bunch of cases. @@ -269,133 +239,10 @@ ShadowRoot::DistributionChanged() shell->DestroyFramesForAndRestyle(host); } -const HTMLContentElement* -ShadowRoot::DistributeSingleNode(nsIContent* aContent) -{ - // Find the insertion point to which the content belongs. - HTMLContentElement* foundInsertionPoint = nullptr; - for (HTMLContentElement* insertionPoint : mInsertionPoints) { - if (insertionPoint->Match(aContent)) { - if (insertionPoint->MatchedNodes().Contains(aContent)) { - // Node is already matched into the insertion point. We are done. - return insertionPoint; - } - - // Matching may cause the insertion point to drop fallback content. - if (insertionPoint->MatchedNodes().IsEmpty() && - insertionPoint->HasChildren()) { - // This match will cause the insertion point to drop all fallback - // content and used matched nodes instead. Give up on the optimization - // and just distribute all nodes. - DistributeAllNodes(); - MOZ_ASSERT(insertionPoint->MatchedNodes().Contains(aContent)); - return insertionPoint; - } - foundInsertionPoint = insertionPoint; - break; - } - } - - if (!foundInsertionPoint) { - return nullptr; - } - - // Find the index into the insertion point. - nsCOMArray<nsIContent>& matchedNodes = foundInsertionPoint->MatchedNodes(); - // Find the appropriate position in the matched node list for the - // newly distributed content. - bool isIndexFound = false; - ExplicitChildIterator childIterator(GetHost()); - for (uint32_t i = 0; i < matchedNodes.Length(); i++) { - // Seek through the host's explicit children until the inserted content - // is found or when the current matched node is reached. - if (childIterator.Seek(aContent, matchedNodes[i])) { - // aContent was found before the current matched node. - foundInsertionPoint->InsertMatchedNode(i, aContent); - isIndexFound = true; - break; - } - } - - if (!isIndexFound) { - // We have still not found an index in the insertion point, - // thus it must be at the end. - MOZ_ASSERT(childIterator.Seek(aContent, nullptr), - "Trying to match a node that is not a candidate to be matched"); - foundInsertionPoint->AppendMatchedNode(aContent); - } - - return foundInsertionPoint; -} - -const HTMLContentElement* -ShadowRoot::RemoveDistributedNode(nsIContent* aContent) -{ - // Find insertion point containing the content and remove the node. - for (HTMLContentElement* insertionPoint : mInsertionPoints) { - if (!insertionPoint->MatchedNodes().Contains(aContent)) { - continue; - } - - // Removing the matched node may cause the insertion point to use - // fallback content. - if (insertionPoint->MatchedNodes().Length() == 1 && - insertionPoint->HasChildren()) { - // Removing the matched node will cause fallback content to be - // used instead. Give up optimization and distribute all nodes. - DistributeAllNodes(); - return insertionPoint; - } - - insertionPoint->RemoveMatchedNode(aContent); - return insertionPoint; - } - - return nullptr; -} - void ShadowRoot::DistributeAllNodes() { - // Create node pool. - nsTArray<nsIContent*> nodePool; - ExplicitChildIterator childIterator(GetHost()); - for (nsIContent* content = childIterator.GetNextChild(); content; - content = childIterator.GetNextChild()) { - nodePool.AppendElement(content); - } - - nsTArray<ShadowRoot*> shadowsToUpdate; - - for (HTMLContentElement* insertionPoint : mInsertionPoints) { - insertionPoint->ClearMatchedNodes(); - // Assign matching nodes from node pool. - for (uint32_t j = 0; j < nodePool.Length(); j++) { - if (insertionPoint->Match(nodePool[j])) { - insertionPoint->AppendMatchedNode(nodePool[j]); - nodePool.RemoveElementAt(j--); - } - } - - // Keep track of instances where the content insertion point is distributed - // (parent of insertion point has a ShadowRoot). - nsIContent* insertionParent = insertionPoint->GetParent(); - MOZ_ASSERT(insertionParent, "The only way for an insertion point to be in the" - "mInsertionPoints array is to be a descendant of a" - "ShadowRoot, in which case, it should have a parent"); - - // If the parent of the insertion point has a ShadowRoot, the nodes distributed - // to the insertion point must be reprojected to the insertion points of the - // parent's ShadowRoot. - ShadowRoot* parentShadow = insertionParent->GetShadowRoot(); - if (parentShadow && !shadowsToUpdate.Contains(parentShadow)) { - shadowsToUpdate.AppendElement(parentShadow); - } - } - - for (ShadowRoot* shadow : shadowsToUpdate) { - shadow->DistributeAllNodes(); - } + //XXX Handle <slot>. DistributionChanged(); } @@ -475,13 +322,6 @@ ShadowRoot::IsPooledNode(nsIContent* aContent) const return true; } - if (auto* content = HTMLContentElement::FromContentOrNull(container)) { - // Fallback content will end up in pool if its parent is a child of the host. - return content->IsInsertionPoint() && - content->MatchedNodes().IsEmpty() && - container->GetParentNode() == host; - } - return false; } @@ -497,13 +337,6 @@ ShadowRoot::AttributeChanged(nsIDocument* aDocument, return; } - // Attributes may change insertion point matching, find its new distribution. - // - // FIXME(emilio): What about state changes? - if (!RedistributeElement(aElement)) { - return; - } - if (!aElement->IsInComposedDoc()) { return; } @@ -513,52 +346,10 @@ ShadowRoot::AttributeChanged(nsIDocument* aDocument, return; } + //XXX optimize this! shell->DestroyFramesForAndRestyle(aElement); } -bool -ShadowRoot::RedistributeElement(Element* aElement) -{ - auto* oldInsertionPoint = RemoveDistributedNode(aElement); - auto* newInsertionPoint = DistributeSingleNode(aElement); - - if (oldInsertionPoint == newInsertionPoint) { - if (oldInsertionPoint) { - if (auto* shadow = oldInsertionPoint->GetParent()->GetShadowRoot()) { - return shadow->RedistributeElement(aElement); - } - } - - return false; - } - - while (oldInsertionPoint) { - // Handle the case where the parent of the insertion point has a ShadowRoot. - // The node distributed into the insertion point must be reprojected to the - // insertion points of the parent's ShadowRoot. - auto* shadow = oldInsertionPoint->GetParent()->GetShadowRoot(); - if (!shadow) { - break; - } - - oldInsertionPoint = shadow->RemoveDistributedNode(aElement); - } - - while (newInsertionPoint) { - // Handle the case where the parent of the insertion point has a ShadowRoot. - // The node distributed into the insertion point must be reprojected to the - // insertion points of the parent's ShadowRoot. - auto* shadow = newInsertionPoint->GetParent()->GetShadowRoot(); - if (!shadow) { - break; - } - - newInsertionPoint = shadow->DistributeSingleNode(aElement); - } - - return true; -} - void ShadowRoot::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer, @@ -583,31 +374,6 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument, mInsertionPointChanged = false; return; } - - // Add insertion point to destination insertion points of fallback content. - if (nsContentUtils::IsContentInsertionPoint(aContainer)) { - HTMLContentElement* content = HTMLContentElement::FromContent(aContainer); - if (content && content->MatchedNodes().IsEmpty()) { - aChild->DestInsertionPoints().AppendElement(aContainer); - } - } - - // Watch for new nodes added to the pool because the node - // may need to be added to an insertion point. - if (IsPooledNode(aChild)) { - auto* insertionPoint = DistributeSingleNode(aChild); - while (insertionPoint) { - // Handle the case where the parent of the insertion point has a ShadowRoot. - // The node distributed into the insertion point must be reprojected to the - // insertion points of the parent's ShadowRoot. - auto* parentShadow = insertionPoint->GetParent()->GetShadowRoot(); - if (!parentShadow) { - break; - } - - insertionPoint = parentShadow->DistributeSingleNode(aChild); - } - } } void @@ -622,34 +388,6 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument, mInsertionPointChanged = false; return; } - - // Clear destination insertion points for removed - // fallback content. - if (nsContentUtils::IsContentInsertionPoint(aContainer)) { - HTMLContentElement* content = HTMLContentElement::FromContent(aContainer); - if (content->MatchedNodes().IsEmpty()) { - aChild->DestInsertionPoints().Clear(); - } - } - - // Watch for node that is removed from the pool because - // it may need to be removed from an insertion point. - if (IsPooledNode(aChild)) { - auto* insertionPoint = RemoveDistributedNode(aChild); - while (insertionPoint) { - // Handle the case where the parent of the insertion point has a - // ShadowRoot. - // - // The removed node needs to be removed from the insertion points of the - // parent's ShadowRoot. - auto* parentShadow = insertionPoint->GetParent()->GetShadowRoot(); - if (!parentShadow) { - break; - } - - insertionPoint = parentShadow->RemoveDistributedNode(aChild); - } - } } nsresult diff --git a/dom/base/ShadowRoot.h b/dom/base/ShadowRoot.h index 4a5b54e85..5efff5be7 100644 --- a/dom/base/ShadowRoot.h +++ b/dom/base/ShadowRoot.h @@ -24,7 +24,6 @@ namespace mozilla { namespace dom { class Element; -class HTMLContentElement; class ShadowRootStyleSheetList; class ShadowRoot final : public DocumentFragment, @@ -74,28 +73,6 @@ public: private: /** - * Distributes a single explicit child of the pool host to the content - * insertion points in this ShadowRoot. - * - * Returns the insertion point the element is distributed to after this call. - * - * Note that this doesn't handle distributing the node in the insertion point - * parent's shadow root. - */ - const HTMLContentElement* DistributeSingleNode(nsIContent* aContent); - - /** - * Removes a single explicit child of the pool host from the content - * insertion points in this ShadowRoot. - * - * Returns the old insertion point, if any. - * - * Note that this doesn't handle removing the node in the returned insertion - * point parent's shadow root. - */ - const HTMLContentElement* RemoveDistributedNode(nsIContent* aContent); - - /** * Redistributes a node of the pool, and returns whether the distribution * changed. */ @@ -109,9 +86,6 @@ private: bool IsPooledNode(nsIContent* aChild) const; public: - void AddInsertionPoint(HTMLContentElement* aInsertionPoint); - void RemoveInsertionPoint(HTMLContentElement* aInsertionPoint); - void SetInsertionPointChanged() { mInsertionPointChanged = true; } void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; } @@ -120,9 +94,6 @@ public: static ShadowRoot* FromNode(nsINode* aNode); - static void RemoveDestInsertionPoint(nsIContent* aInsertionPoint, - nsTArray<nsIContent*>& aDestInsertionPoints); - // WebIDL methods. Element* GetElementById(const nsAString& aElementId); already_AddRefed<nsContentList> @@ -147,13 +118,6 @@ protected: ShadowRootMode mMode; - // An array of content insertion points that are a descendant of the ShadowRoot - // sorted in tree order. Insertion points are responsible for notifying - // the ShadowRoot when they are removed or added as a descendant. The insertion - // points are kept alive by the parent node, thus weak references are held - // by the array. - nsTArray<HTMLContentElement*> mInsertionPoints; - nsTHashtable<nsIdentifierMapEntry> mIdentifierMap; nsXBLPrototypeBinding* mProtoBinding; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 3d23bedea..038da24b4 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -45,7 +45,6 @@ #include "mozilla/dom/FileSystemSecurity.h" #include "mozilla/dom/HTMLMediaElement.h" #include "mozilla/dom/HTMLTemplateElement.h" -#include "mozilla/dom/HTMLContentElement.h" #include "mozilla/dom/ipc/BlobChild.h" #include "mozilla/dom/ipc/BlobParent.h" #include "mozilla/dom/Promise.h" @@ -7036,9 +7035,8 @@ nsContentUtils::IsContentInsertionPoint(nsIContent* aContent) } // Check if the content is a web components content insertion point. - HTMLContentElement* contentElement = - HTMLContentElement::FromContent(aContent); - return contentElement && contentElement->IsInsertionPoint(); + // XXX handle <slot>? + return false; } // static @@ -7055,14 +7053,6 @@ nsContentUtils::HasDistributedChildren(nsIContent* aContent) return true; } - HTMLContentElement* contentEl = HTMLContentElement::FromContent(aContent); - if (contentEl && contentEl->IsInsertionPoint()) { - // Children of a content insertion point are distributed to the - // content insertion point if the content insertion point does - // not match any nodes (fallback content). - return contentEl->MatchedNodes().IsEmpty(); - } - return false; } |