From 8beb65dd501cbdcfd6a793027b5de2a1fdfc7149 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 17 Apr 2020 07:08:22 -0400 Subject: Bug 1418002 - Remove HTMLContentElement Tag #1375 --- dom/base/ChildIterator.cpp | 21 +- dom/base/ShadowRoot.cpp | 266 +-------------- dom/base/ShadowRoot.h | 36 -- dom/base/nsContentUtils.cpp | 14 +- dom/html/HTMLContentElement.cpp | 379 --------------------- dom/html/HTMLContentElement.h | 126 ------- dom/html/moz.build | 2 - dom/tests/mochitest/webcomponents/mochitest.ini | 4 - .../webcomponents/test_dest_insertion_points.html | 73 ---- .../test_dynamic_content_element_matching.html | 50 --- .../test_fallback_dest_insertion_points.html | 71 ---- .../webcomponents/test_nested_content_element.html | 127 ------- dom/webidl/HTMLContentElement.webidl | 20 -- dom/webidl/moz.build | 1 - 14 files changed, 12 insertions(+), 1178 deletions(-) delete mode 100644 dom/html/HTMLContentElement.cpp delete mode 100644 dom/html/HTMLContentElement.h delete mode 100644 dom/tests/mochitest/webcomponents/test_dest_insertion_points.html delete mode 100644 dom/tests/mochitest/webcomponents/test_dynamic_content_element_matching.html delete mode 100644 dom/tests/mochitest/webcomponents/test_fallback_dest_insertion_points.html delete mode 100644 dom/tests/mochitest/webcomponents/test_nested_content_element.html delete mode 100644 dom/webidl/HTMLContentElement.webidl (limited to 'dom') 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(aContent)); } + return MatchedNodes(); // Web components case - MOZ_ASSERT(aContent->IsHTMLElement(nsGkAtoms::content)); - return MatchedNodes(HTMLContentElement::FromContent(aContent)); + // XXX handle 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" @@ -223,35 +222,6 @@ ShadowRoot::GetElementsByClassName(const nsAString& aClasses) return nsContentUtils::GetElementsByClassName(this, 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& 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() { @@ -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& 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 nodePool; - ExplicitChildIterator childIterator(GetHost()); - for (nsIContent* content = childIterator.GetNextChild(); content; - content = childIterator.GetNextChild()) { - nodePool.AppendElement(content); - } - - nsTArray 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 . 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, @@ -73,28 +72,6 @@ public: void DistributeAllNodes(); 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& aDestInsertionPoints); - // WebIDL methods. Element* GetElementById(const nsAString& aElementId); already_AddRefed @@ -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 mInsertionPoints; - nsTHashtable 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 ? + 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; } diff --git a/dom/html/HTMLContentElement.cpp b/dom/html/HTMLContentElement.cpp deleted file mode 100644 index 15d79c761..000000000 --- a/dom/html/HTMLContentElement.cpp +++ /dev/null @@ -1,379 +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/HTMLContentElement.h" -#include "mozilla/dom/HTMLContentElementBinding.h" -#include "mozilla/dom/HTMLUnknownElement.h" -#include "mozilla/dom/NodeListBinding.h" -#include "mozilla/dom/ShadowRoot.h" -#include "mozilla/css/StyleRule.h" -#include "nsGkAtoms.h" -#include "nsStyleConsts.h" -#include "nsIAtom.h" -#include "nsCSSRuleProcessor.h" -#include "nsRuleData.h" -#include "nsRuleProcessorData.h" -#include "nsRuleWalker.h" -#include "nsCSSParser.h" -#include "nsDocument.h" - -// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Content) to add check for web components -// being enabled. -nsGenericHTMLElement* -NS_NewHTMLContentElement(already_AddRefed&& aNodeInfo, - mozilla::dom::FromParser aFromParser) -{ - // When this check is removed, remove the nsDocument.h and - // HTMLUnknownElement.h includes. Also remove nsINode::IsHTMLContentElement. - // - // 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::HTMLContentElement(nodeInfoArg); -} - -using namespace mozilla::dom; - -HTMLContentElement::HTMLContentElement(already_AddRefed& aNodeInfo) - : nsGenericHTMLElement(aNodeInfo), mValidSelector(true), mIsInsertionPoint(false) -{ -} - -HTMLContentElement::~HTMLContentElement() -{ -} - -NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLContentElement, - nsGenericHTMLElement, - mMatchedNodes) - -NS_IMPL_ADDREF_INHERITED(HTMLContentElement, Element) -NS_IMPL_RELEASE_INHERITED(HTMLContentElement, Element) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLContentElement) -NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement) - -NS_IMPL_ELEMENT_CLONE(HTMLContentElement) - -JSObject* -HTMLContentElement::WrapNode(JSContext *aCx, JS::Handle aGivenProto) -{ - return HTMLContentElementBinding::Wrap(aCx, this, aGivenProto); -} - -nsresult -HTMLContentElement::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) { - nsINode* parentNode = nsINode::GetParentNode(); - while (parentNode && parentNode != containingShadow) { - if (parentNode->IsHTMLContentElement()) { - // Content element in fallback content is not an insertion point. - return NS_OK; - } - parentNode = parentNode->GetParentNode(); - } - - // If the content element is being inserted into a ShadowRoot, - // add this element to the list of insertion points. - mIsInsertionPoint = true; - containingShadow->AddInsertionPoint(this); - containingShadow->SetInsertionPointChanged(); - } - - return NS_OK; -} - -void -HTMLContentElement::UnbindFromTree(bool aDeep, bool aNullParent) -{ - RefPtr oldContainingShadow = GetContainingShadow(); - - nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); - - if (oldContainingShadow && !GetContainingShadow() && mIsInsertionPoint) { - oldContainingShadow->RemoveInsertionPoint(this); - - // Remove all the matched nodes now that the - // insertion point is no longer an insertion point. - ClearMatchedNodes(); - oldContainingShadow->SetInsertionPointChanged(); - - mIsInsertionPoint = false; - } -} - -void -HTMLContentElement::AppendMatchedNode(nsIContent* aContent) -{ - mMatchedNodes.AppendElement(aContent); - nsTArray& destInsertionPoint = aContent->DestInsertionPoints(); - destInsertionPoint.AppendElement(this); - - if (mMatchedNodes.Length() == 1) { - // Fallback content gets dropped so we need to updated fallback - // content distribution. - UpdateFallbackDistribution(); - } -} - -void -HTMLContentElement::UpdateFallbackDistribution() -{ - for (nsIContent* child = nsINode::GetFirstChild(); - child; - child = child->GetNextSibling()) { - nsTArray& destInsertionPoint = child->DestInsertionPoints(); - destInsertionPoint.Clear(); - if (mMatchedNodes.IsEmpty()) { - destInsertionPoint.AppendElement(this); - } - } -} - -void -HTMLContentElement::RemoveMatchedNode(nsIContent* aContent) -{ - mMatchedNodes.RemoveElement(aContent); - ShadowRoot::RemoveDestInsertionPoint(this, aContent->DestInsertionPoints()); - - if (mMatchedNodes.IsEmpty()) { - // Fallback content is activated so we need to update fallback - // content distribution. - UpdateFallbackDistribution(); - } -} - -void -HTMLContentElement::InsertMatchedNode(uint32_t aIndex, nsIContent* aContent) -{ - mMatchedNodes.InsertElementAt(aIndex, aContent); - nsTArray& destInsertionPoint = aContent->DestInsertionPoints(); - destInsertionPoint.AppendElement(this); - - if (mMatchedNodes.Length() == 1) { - // Fallback content gets dropped so we need to updated fallback - // content distribution. - UpdateFallbackDistribution(); - } -} - -void -HTMLContentElement::ClearMatchedNodes() -{ - for (uint32_t i = 0; i < mMatchedNodes.Length(); i++) { - ShadowRoot::RemoveDestInsertionPoint(this, mMatchedNodes[i]->DestInsertionPoints()); - } - - mMatchedNodes.Clear(); - - UpdateFallbackDistribution(); -} - -static bool -IsValidContentSelectors(nsCSSSelector* aSelector) -{ - nsCSSSelector* currentSelector = aSelector; - while (currentSelector) { - // Blacklist invalid selector fragments. - if (currentSelector->IsPseudoElement() || - currentSelector->mPseudoClassList || - currentSelector->mNegations || - currentSelector->mOperator) { - return false; - } - - currentSelector = currentSelector->mNext; - } - - return true; -} - -nsresult -HTMLContentElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValue* aValue, - const nsAttrValue* aOldValue, bool aNotify) -{ - if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::select) { - if (aValue) { - // Select attribute was updated, the insertion point may match different - // elements. - nsIDocument* doc = OwnerDoc(); - nsCSSParser parser(doc->CSSLoader()); - - mValidSelector = true; - mSelectorList = nullptr; - - nsAutoString valueStr; - aValue->ToString(valueStr); - nsresult rv = parser.ParseSelectorString(valueStr, - doc->GetDocumentURI(), - // Bug 11240 - 0, // XXX get the line number! - getter_Transfers(mSelectorList)); - - // We don't want to return an exception if parsing failed because - // the spec does not define it as an exception case. - if (NS_SUCCEEDED(rv)) { - // Ensure that all the selectors are valid - nsCSSSelectorList* selectors = mSelectorList; - while (selectors) { - if (!IsValidContentSelectors(selectors->mSelectors)) { - // If we have an invalid selector, we can not match anything. - mValidSelector = false; - mSelectorList = nullptr; - break; - } - selectors = selectors->mNext; - } - } - - if (ShadowRoot* containingShadow = GetContainingShadow()) { - containingShadow->DistributeAllNodes(); - } - } else { - // The select attribute was removed. This insertion point becomes - // a universal selector. - mValidSelector = true; - mSelectorList = nullptr; - - if (ShadowRoot* containingShadow = GetContainingShadow()) { - containingShadow->DistributeAllNodes(); - } - } - } - - return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue, - aOldValue, aNotify); -} - -bool -HTMLContentElement::Match(nsIContent* aContent) -{ - if (!mValidSelector) { - return false; - } - - if (mSelectorList) { - nsIDocument* doc = OwnerDoc(); - ShadowRoot* containingShadow = GetContainingShadow(); - nsIContent* host = containingShadow->GetHost(); - - TreeMatchContext matchingContext(false, nsRuleWalker::eRelevantLinkUnvisited, - doc, TreeMatchContext::eNeverMatchVisited); - doc->FlushPendingLinkUpdates(); - matchingContext.SetHasSpecifiedScope(); - matchingContext.AddScopeElement(host->AsElement()); - - if (!aContent->IsElement()) { - return false; - } - - return nsCSSRuleProcessor::SelectorListMatches(aContent->AsElement(), - matchingContext, - mSelectorList); - } - - return true; -} - -already_AddRefed -HTMLContentElement::GetDistributedNodes() -{ - RefPtr list = new DistributedContentList(this); - return list.forget(); -} - -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DistributedContentList, mParent, - mDistributedNodes) - -NS_INTERFACE_TABLE_HEAD(DistributedContentList) - NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY - NS_INTERFACE_TABLE(DistributedContentList, nsINodeList, nsIDOMNodeList) - NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(DistributedContentList) -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(DistributedContentList) -NS_IMPL_CYCLE_COLLECTING_RELEASE(DistributedContentList) - -DistributedContentList::DistributedContentList(HTMLContentElement* aHostElement) - : mParent(aHostElement) -{ - MOZ_COUNT_CTOR(DistributedContentList); - - if (aHostElement->IsInsertionPoint()) { - if (aHostElement->MatchedNodes().IsEmpty()) { - // Fallback content. - nsINode* contentNode = aHostElement; - for (nsIContent* content = contentNode->GetFirstChild(); - content; - content = content->GetNextSibling()) { - mDistributedNodes.AppendElement(content); - } - } else { - mDistributedNodes.AppendElements(aHostElement->MatchedNodes()); - } - } -} - -DistributedContentList::~DistributedContentList() -{ - MOZ_COUNT_DTOR(DistributedContentList); -} - -nsIContent* -DistributedContentList::Item(uint32_t aIndex) -{ - return mDistributedNodes.SafeElementAt(aIndex); -} - -NS_IMETHODIMP -DistributedContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn) -{ - nsIContent* item = Item(aIndex); - if (!item) { - return NS_ERROR_FAILURE; - } - - return CallQueryInterface(item, aReturn); -} - -NS_IMETHODIMP -DistributedContentList::GetLength(uint32_t* aLength) -{ - *aLength = mDistributedNodes.Length(); - return NS_OK; -} - -int32_t -DistributedContentList::IndexOf(nsIContent* aContent) -{ - return mDistributedNodes.IndexOf(aContent); -} - -JSObject* -DistributedContentList::WrapObject(JSContext* aCx, JS::Handle aGivenProto) -{ - return NodeListBinding::Wrap(aCx, this, aGivenProto); -} - diff --git a/dom/html/HTMLContentElement.h b/dom/html/HTMLContentElement.h deleted file mode 100644 index 630e26d17..000000000 --- a/dom/html/HTMLContentElement.h +++ /dev/null @@ -1,126 +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_HTMLContentElement_h__ -#define mozilla_dom_HTMLContentElement_h__ - -#include "nsAutoPtr.h" -#include "nsINodeList.h" -#include "nsGenericHTMLElement.h" - -struct nsCSSSelectorList; - -namespace mozilla { -namespace dom { - -class DistributedContentList; - -class HTMLContentElement final : public nsGenericHTMLElement -{ -public: - explicit HTMLContentElement(already_AddRefed& aNodeInfo); - - // nsISupports - NS_DECL_ISUPPORTS_INHERITED - - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLContentElement, - nsGenericHTMLElement) - - NS_IMPL_FROMCONTENT_HELPER(HTMLContentElement, IsHTMLContentElement()) - - virtual bool IsHTMLContentElement() const override { return true; } - - virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override; - - virtual nsIDOMNode* AsDOMNode() override { return this; } - - virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, - nsIContent* aBindingParent, - bool aCompileEventHandlers) override; - - virtual void UnbindFromTree(bool aDeep = true, - bool aNullParent = true) override; - - /** - * Returns whether if the selector of this insertion point - * matches the provided content. - */ - bool Match(nsIContent* aContent); - bool IsInsertionPoint() const { return mIsInsertionPoint; } - nsCOMArray& MatchedNodes() { return mMatchedNodes; } - void AppendMatchedNode(nsIContent* aContent); - void RemoveMatchedNode(nsIContent* aContent); - void InsertMatchedNode(uint32_t aIndex, nsIContent* aContent); - void ClearMatchedNodes(); - - // WebIDL methods. - already_AddRefed GetDistributedNodes(); - void GetSelect(nsAString& aSelect) - { - Element::GetAttr(kNameSpaceID_None, nsGkAtoms::select, aSelect); - } - void SetSelect(const nsAString& aSelect) - { - Element::SetAttr(kNameSpaceID_None, nsGkAtoms::select, aSelect, true); - } - -protected: - virtual ~HTMLContentElement(); - - virtual JSObject* WrapNode(JSContext *aCx, JS::Handle aGivenProto) override; - - /** - * Updates the destination insertion points of the fallback - * content of this insertion point. If there are nodes matched - * to this insertion point, then destination insertion points - * of fallback are cleared, otherwise, this insertion point - * is a destination insertion point. - */ - void UpdateFallbackDistribution(); - - virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValue* aValue, - const nsAttrValue* aOldValue, - bool aNotify) override; - - /** - * An array of nodes from the ShadowRoot host that match the - * content insertion selector. - */ - nsCOMArray mMatchedNodes; - - nsAutoPtr mSelectorList; - bool mValidSelector; - bool mIsInsertionPoint; -}; - -class DistributedContentList : public nsINodeList -{ -public: - explicit DistributedContentList(HTMLContentElement* aHostElement); - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DistributedContentList) - - // nsIDOMNodeList - NS_DECL_NSIDOMNODELIST - - // nsINodeList - virtual nsIContent* Item(uint32_t aIndex) override; - virtual int32_t IndexOf(nsIContent* aContent) override; - virtual nsINode* GetParentObject() override { return mParent; } - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; -protected: - virtual ~DistributedContentList(); - RefPtr mParent; - nsCOMArray mDistributedNodes; -}; - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_HTMLContentElement_h__ - diff --git a/dom/html/moz.build b/dom/html/moz.build index 79554df21..342b027a5 100644 --- a/dom/html/moz.build +++ b/dom/html/moz.build @@ -52,7 +52,6 @@ EXPORTS.mozilla.dom += [ 'HTMLBRElement.h', 'HTMLButtonElement.h', 'HTMLCanvasElement.h', - 'HTMLContentElement.h', 'HTMLDataElement.h', 'HTMLDataListElement.h', 'HTMLDetailsElement.h', @@ -131,7 +130,6 @@ UNIFIED_SOURCES += [ 'HTMLBRElement.cpp', 'HTMLButtonElement.cpp', 'HTMLCanvasElement.cpp', - 'HTMLContentElement.cpp', 'HTMLDataElement.cpp', 'HTMLDataListElement.cpp', 'HTMLDetailsElement.cpp', diff --git a/dom/tests/mochitest/webcomponents/mochitest.ini b/dom/tests/mochitest/webcomponents/mochitest.ini index 2cfd747c4..d56196272 100644 --- a/dom/tests/mochitest/webcomponents/mochitest.ini +++ b/dom/tests/mochitest/webcomponents/mochitest.ini @@ -25,11 +25,7 @@ skip-if = !debug # TestFunctions only applied in debug builds [test_custom_element_define.html] [test_custom_element_define_parser.html] [test_custom_element_template.html] -[test_nested_content_element.html] -[test_dest_insertion_points.html] -[test_fallback_dest_insertion_points.html] [test_detached_style.html] -[test_dynamic_content_element_matching.html] [test_document_adoptnode.html] [test_document_importnode.html] [test_document_register.html] diff --git a/dom/tests/mochitest/webcomponents/test_dest_insertion_points.html b/dom/tests/mochitest/webcomponents/test_dest_insertion_points.html deleted file mode 100644 index 2d4a92ed2..000000000 --- a/dom/tests/mochitest/webcomponents/test_dest_insertion_points.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - Test for Bug 999999 - - - - -Mozilla Bug 999999 -

-
-
-
-
-
-
- - - diff --git a/dom/tests/mochitest/webcomponents/test_dynamic_content_element_matching.html b/dom/tests/mochitest/webcomponents/test_dynamic_content_element_matching.html deleted file mode 100644 index c9af76610..000000000 --- a/dom/tests/mochitest/webcomponents/test_dynamic_content_element_matching.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Test for dynamic changes to content matching content elements - - - - -
-Bug 806506 - - - - diff --git a/dom/tests/mochitest/webcomponents/test_fallback_dest_insertion_points.html b/dom/tests/mochitest/webcomponents/test_fallback_dest_insertion_points.html deleted file mode 100644 index 4eefa165f..000000000 --- a/dom/tests/mochitest/webcomponents/test_fallback_dest_insertion_points.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - Test for Bug 999999 - - - - -Mozilla Bug 999999 -

-
-
-
-
-
- - - diff --git a/dom/tests/mochitest/webcomponents/test_nested_content_element.html b/dom/tests/mochitest/webcomponents/test_nested_content_element.html deleted file mode 100644 index 1d98d2996..000000000 --- a/dom/tests/mochitest/webcomponents/test_nested_content_element.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - Test for HTMLContent element - - - - -
-Bug 806506 - - - - diff --git a/dom/webidl/HTMLContentElement.webidl b/dom/webidl/HTMLContentElement.webidl deleted file mode 100644 index ea809f120..000000000 --- a/dom/webidl/HTMLContentElement.webidl +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. - * - * The origin of this IDL file is - * https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html - * - * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and - * Opera Software ASA. You are granted a license to use, reproduce - * and create derivative works of this document. - */ - -[Func="nsDocument::IsWebComponentsEnabled"] -interface HTMLContentElement : HTMLElement -{ - attribute DOMString select; - NodeList getDistributedNodes(); -}; - diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index ae97bbb30..d76a58e1f 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -177,7 +177,6 @@ WEBIDL_FILES = [ 'HTMLButtonElement.webidl', 'HTMLCanvasElement.webidl', 'HTMLCollection.webidl', - 'HTMLContentElement.webidl', 'HTMLDataElement.webidl', 'HTMLDataListElement.webidl', 'HTMLDetailsElement.webidl', -- cgit v1.2.3