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 | |
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')
-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 | ||||
-rw-r--r-- | dom/html/HTMLContentElement.cpp | 379 | ||||
-rw-r--r-- | dom/html/HTMLContentElement.h | 126 | ||||
-rw-r--r-- | dom/html/moz.build | 2 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/mochitest.ini | 4 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_dest_insertion_points.html | 73 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_dynamic_content_element_matching.html | 50 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_fallback_dest_insertion_points.html | 71 | ||||
-rw-r--r-- | dom/tests/mochitest/webcomponents/test_nested_content_element.html | 127 | ||||
-rw-r--r-- | dom/webidl/HTMLContentElement.webidl | 20 | ||||
-rw-r--r-- | dom/webidl/moz.build | 1 |
14 files changed, 12 insertions, 1178 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; } 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<mozilla::dom::NodeInfo>&& 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<NodeInfo>& for our callees. - RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); - if (!nsDocument::IsWebComponentsEnabled(nodeInfo)) { - already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget()); - return new mozilla::dom::HTMLUnknownElement(nodeInfoArg); - } - - already_AddRefed<mozilla::dom::NodeInfo> nodeInfoArg(nodeInfo.forget()); - return new mozilla::dom::HTMLContentElement(nodeInfoArg); -} - -using namespace mozilla::dom; - -HTMLContentElement::HTMLContentElement(already_AddRefed<mozilla::dom::NodeInfo>& 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<JSObject*> aGivenProto) -{ - return HTMLContentElementBinding::Wrap(aCx, this, aGivenProto); -} - -nsresult -HTMLContentElement::BindToTree(nsIDocument* aDocument, - nsIContent* aParent, - nsIContent* aBindingParent, - bool aCompileEventHandlers) -{ - RefPtr<ShadowRoot> 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<ShadowRoot> 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<nsIContent*>& 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<nsIContent*>& 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<nsIContent*>& 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<DistributedContentList> -HTMLContentElement::GetDistributedNodes() -{ - RefPtr<DistributedContentList> 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<JSObject*> 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<mozilla::dom::NodeInfo>& 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<nsIContent>& MatchedNodes() { return mMatchedNodes; } - void AppendMatchedNode(nsIContent* aContent); - void RemoveMatchedNode(nsIContent* aContent); - void InsertMatchedNode(uint32_t aIndex, nsIContent* aContent); - void ClearMatchedNodes(); - - // WebIDL methods. - already_AddRefed<DistributedContentList> 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<JSObject*> 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<nsIContent> mMatchedNodes; - - nsAutoPtr<nsCSSSelectorList> 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<JSObject*> aGivenProto) override; -protected: - virtual ~DistributedContentList(); - RefPtr<HTMLContentElement> mParent; - nsCOMArray<nsIContent> 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 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=999999 ---> -<head> - <meta charset="utf-8"> - <title>Test for Bug 999999</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=999999">Mozilla Bug 999999</a> -<p id="display"></p> -<div id="content"> -<div id="shadowhost"> -</div> -</div> -<pre id="test"> -</pre> -<script type="application/javascript"> - -/** Test for Bug 999999 **/ -var host = document.getElementById("shadowhost"); - -// Test destination insertion points of node distributed to content element. -var shadowRoot = host.createShadowRoot(); -shadowRoot.innerHTML = '<div id="innerhost"><content id="innercontent" select=".red"></content></div>'; -var innerContent = shadowRoot.getElementById("innercontent"); - -var span = document.createElement("span"); -span.setAttribute("class", "red blue"); -is(host.getDestinationInsertionPoints().length, 0, "Destination insertion points should be empty when not being distributed."); - -host.appendChild(span); - -is(span.getDestinationInsertionPoints().length, 1, "Destination insertion points should only contain a single content insertion point."); -is(span.getDestinationInsertionPoints()[0], innerContent, "Content element should contain destination insertion point."); - -// Test destination insertion points of redistributed node. -var innerHost = shadowRoot.getElementById("innerhost"); -var innerShadowRoot = innerHost.createShadowRoot(); -innerShadowRoot.innerHTML = '<content id="innerinnercontent" select=".blue"></content>'; - -var innerInnerContent = innerShadowRoot.getElementById("innerinnercontent"); - -is(span.getDestinationInsertionPoints().length, 2, "Redistributed node should have 2 destination insertion points."); -is(span.getDestinationInsertionPoints()[1], innerInnerContent, "Nested content insertion point should be in list of destination insertion points."); - -// Test destination insertion points after removing reprojection onto second content element. -span.setAttribute("class", "red"); -is(span.getDestinationInsertionPoints().length, 1, "Destination insertion points should only contain 1 insertion point after removing reprojection."); -is(span.getDestinationInsertionPoints()[0], innerContent, "First content element should be only insertion point after removing reprojection."); - -// Test destination insertion points after removing the projected content from the host. -host.removeChild(span); -is(span.getDestinationInsertionPoints().length, 0, "Destination insertion points should be empty after being removed from the shadow host."); - -// Test destination insertion points of distributed content after removing insertion point. -var div = document.createElement("div"); -div.setAttribute("class", "red blue"); -host.appendChild(div); - -is(div.getDestinationInsertionPoints().length, 2, "Div should be distributed into 2 insertion points."); - -innerShadowRoot.removeChild(innerInnerContent); - -is(div.getDestinationInsertionPoints().length, 1, "Div should be distributed into insertion point in one ShadowRoot."); -is(div.getDestinationInsertionPoints()[0], innerContent, "Destination insertion points should only contain content insertion point in first ShadowRoot."); - -</script> -</body> -</html> 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 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=806506 ---> -<head> - <title>Test for dynamic changes to content matching content elements</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<div class="tall" id="bodydiv"></div> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a> -<script> -// Create ShadowRoot. -var elem = document.createElement("div"); -var root = elem.createShadowRoot(); - -var redInsertionPoint = document.createElement("content"); -redInsertionPoint.select = "*[data-color=red]"; - -var blueInsertionPoint = document.createElement("content"); -blueInsertionPoint.select = "*[data-color=blue]"; - -root.appendChild(redInsertionPoint); -root.appendChild(blueInsertionPoint); - -is(blueInsertionPoint.getDistributedNodes().length, 0, "Blue insertion point should have no distributed nodes."); -is(redInsertionPoint.getDistributedNodes().length, 0, "Red insertion point should have no distrubted nodes."); - -var matchElement = document.createElement("div"); -matchElement.setAttribute("data-color", "red"); -elem.appendChild(matchElement); - -is(blueInsertionPoint.getDistributedNodes().length, 0, "Blue insertion point should have no distributed nodes."); -is(redInsertionPoint.getDistributedNodes().length, 1, "Red insertion point should match recently inserted div."); - -matchElement.setAttribute("data-color", "blue"); -is(blueInsertionPoint.getDistributedNodes().length, 1, "Blue insertion point should match element after changing attribute value."); -is(redInsertionPoint.getDistributedNodes().length, 0, "Red insertion point should not match element after changing attribute value."); - -matchElement.removeAttribute("data-color"); - -is(blueInsertionPoint.getDistributedNodes().length, 0, "Blue insertion point should have no distributed nodes after removing the matching attribute."); -is(redInsertionPoint.getDistributedNodes().length, 0, "Red insertion point should have no distrubted nodes after removing the matching attribute."); - -</script> -</body> -</html> - 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 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=999999 ---> -<head> - <meta charset="utf-8"> - <title>Test for Bug 999999</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=999999">Mozilla Bug 999999</a> -<p id="display"></p> -<div id="content"> -<div id="shadowhost"></div> -</div> -<pre id="test"> -</pre> -<script type="application/javascript"> - -/** Test for Bug 999999 **/ -var host = document.getElementById("shadowhost"); - -// Test destination insertion points of node distributed to content element. -var shadowRoot = host.createShadowRoot(); -shadowRoot.innerHTML = '<div id="innerhost"><content id="innercontent"></content></div>'; - -var fallback = document.createElement("span"); -var innerContent = shadowRoot.getElementById("innercontent"); - -innerContent.appendChild(fallback); - -is(fallback.getDestinationInsertionPoints().length, 1, "Active fallback content should be distributed to insertion point."); -is(fallback.getDestinationInsertionPoints()[0], innerContent, "Insertion point should be in list of destination insertion points."); - -// Test destination insertion points of reprojected fallback content. -var innerHost = shadowRoot.getElementById("innerhost"); -var innerShadowRoot = innerHost.createShadowRoot(); -innerShadowRoot.innerHTML = '<content id="innerinnercontent"></content>'; - -var innerInnerContent = innerShadowRoot.getElementById("innerinnercontent"); - -is(fallback.getDestinationInsertionPoints().length, 2, "Fallback content should have been distributed into parent and reprojected into another insertion point."); -is(fallback.getDestinationInsertionPoints()[1], innerInnerContent, "Destination insertion points should contain content element to which the node was reprojected."); - -// Test destination insertion points of fallback content that was dropped due to content element matching a node in the host. -var span = document.createElement("span"); -host.appendChild(span); - -is(fallback.getDestinationInsertionPoints().length, 0, "After dropping insertion points, fallback content should not have any nodes in destination insertion points list."); - -// Test destination insertion points of fallback content after reactivating by dropping matched content on host. -host.removeChild(span); -is(fallback.getDestinationInsertionPoints().length, 2, "Fallback content should have 2 destination insertion points after being reactivated."); -is(fallback.getDestinationInsertionPoints()[0], innerContent, "First destination insertion point should be the parent content"); -is(fallback.getDestinationInsertionPoints()[1], innerInnerContent, "Second destination insertion point should be the content to which the node is reprojected."); - -// Test destination insertion points of fallback content after removed from the tree. -innerContent.removeChild(fallback); -is(fallback.getDestinationInsertionPoints().length, 0, "Fallback content is no longer fallback content, destination insertion points should be empty."); - -// Test destination insertion points of child of non-insertion point content element. -var notInsertionPointContent = document.createElement("content"); -var notFallback = document.createElement("span"); -notInsertionPointContent.appendChild(notFallback); -is(notFallback.getDestinationInsertionPoints().length, 0, "Child of non-insertion point content should not be distributed to any nodes."); - -</script> -</body> -</html> 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 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=806506 ---> -<head> - <title>Test for HTMLContent element</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<div id="grabme"></div> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a> -<script> - -/** - * Constructs a node with a nested ShadowRoot with the following structure: - * <span> - - - - - - - - - - <ShadowRoot> - * <span> <span> - - - - - - - - - - <ShadowRoot> - * id=one id=four <span> - * data-color=red data-color=orange id=eleven - * <span> <span> <content> - * id=two id=five id=twelve - * data-color=blue data-color=purple select=secondSelect - * <span> <content> <span> - * id=three id=six id=thirteen - * data-color=green select=firstSelect - * <span> - * id=seven - * <content> - * id=eight - * <span> - * id=nine - * <span> - * id=ten - * data-color=grey - */ -function constructTree(firstSelect, secondSelect) { - var rootSpan = document.createElement("span"); - rootSpan.innerHTML = '<span id="one" data-color="red"></span><span id="two" data-color="blue"></span><span id="three" data-color="green"></span>'; - var firstShadow = rootSpan.createShadowRoot(); - firstShadow.innerHTML = '<span id="four" data-color="orange"><span id="five" data-color="purple"></span><content id="six" select="' + firstSelect + '"><span id="seven"></span><content id="eight"></content><span id="nine"></span></content><span id="ten"></span></span>'; - var secondShadow = firstShadow.firstChild.createShadowRoot(); - secondShadow.innerHTML = '<span id="eleven"></span><content id="twelve" select="' + secondSelect + '"></content><span id="thirteen"></span>'; - return rootSpan; -} - -// Create a tree with content that matches on everything and check node distribution. -var allSpan = constructTree("*", "*"); -var firstContent = allSpan.shadowRoot.getElementById("six"); -var firstDistNodes = firstContent.getDistributedNodes(); -is(firstDistNodes.length, 3, "Universal selector should match all nodes."); -// Check the order of the distributed nodes. -is(firstDistNodes.item(0).id, "one", "First distributed node should have id of 'one'"); -is(firstDistNodes.item(1).id, "two", "Second distributed node should have id of 'two'"); -is(firstDistNodes.item(2).id, "three", "Third distributed node should have id of 'three'"); -var secondContent = allSpan.shadowRoot.firstChild.shadowRoot.getElementById("twelve"); -var secondDistNodes = secondContent.getDistributedNodes(); -is(secondDistNodes.length, 5, "Universial selector should match all nodes including those distributed into content."); -// Check the order of the distribute nodes. -is(secondDistNodes.item(0).id, "five", "First distributed node should have id of 'five'"); -is(secondDistNodes.item(1).id, "one", "Second distributed (reprojected) node should have id of 'one'"); -is(secondDistNodes.item(2).id, "two", "Third distributed (reprojected) node should have id of 'two'"); -is(secondDistNodes.item(3).id, "three", "Fourth distributed (reprojected) node should have id of 'three'"); -is(secondDistNodes.item(4).id, "ten", "Fifth distributed node should have id of 'ten'"); - -// Append an element after id=two and make sure that it is inserted into the corrent -// position in the insertion points. -var additionalSpan = document.createElement("span"); -additionalSpan.id = "additional"; - -// Insert the additional span in the third position, before the span with id=three. -allSpan.insertBefore(additionalSpan, allSpan.childNodes.item(2)); -firstDistNodes = firstContent.getDistributedNodes(); -secondDistNodes = secondContent.getDistributedNodes(); -is(firstDistNodes.length, 4, "First insertion point should match one more node."); -is(firstDistNodes.item(2).id, "additional", "Additional span should have been inserted into the third position of the first insertion point."); - -is(secondDistNodes.length, 6, "Second insertion point should match one more node."); -is(secondDistNodes.item(3).id, "additional", "Additional span should have been inserted into the fourth position of the second insertion point."); - -function nodeListDoesNotContain(nodeList, element) { - for (var i = 0; i < nodeList.length; i++) { - if (nodeList[i] == element) { - return false; - } - } - return true; -} - -// Remove the span with id=one and check that it is removed from all insertion points. -allSpan = constructTree("*", "*"); -var spanOne = allSpan.firstChild; -allSpan.removeChild(spanOne); -firstContent = allSpan.shadowRoot.getElementById("six"); -ok(nodeListDoesNotContain(firstContent.getDistributedNodes(), spanOne), "Child removed from host should not appear in insertion point node list."); -secondContent = allSpan.shadowRoot.firstChild.shadowRoot.getElementById("twelve"); -ok(nodeListDoesNotContain(secondContent.getDistributedNodes(), spanOne), "Child removed from host should not appear in nested insertion point node list."); - -// Make sure <content> in fallback content is inactive. -// First insertion point will not match anything and will use fallback content. -allSpan = constructTree("#nomatch", "*"); -var fallbackInsertionPoint = allSpan.shadowRoot.getElementById("eight"); -is(fallbackInsertionPoint.getDistributedNodes().length, 0, "Insertion points in default content should be inactive."); - -// Insertion points with non-universal selectors. -allSpan = constructTree("span[data-color=blue]", "*"); -firstContent = allSpan.shadowRoot.getElementById("six"); -is(firstContent.getDistributedNodes().length, 1, "Insertion point selector should only match one node."); -is(firstContent.getDistributedNodes()[0].dataset.color, "blue", "Projected node should match selector."); -secondContent = allSpan.shadowRoot.firstChild.shadowRoot.getElementById("twelve"); -is(secondContent.getDistributedNodes().length, 3, "Second insertion point should match two children and one reprojected node."); -is(secondContent.getDistributedNodes()[1].dataset.color, "blue", "Projected node should match selector."); - -allSpan = constructTree("span[data-color=blue]", "span[data-color=blue]"); -firstContent = allSpan.shadowRoot.getElementById("six"); -is(firstContent.getDistributedNodes().length, 1, "Insertion point selector should only match one node."); -is(firstContent.getDistributedNodes()[0].dataset.color, "blue", "Projected node should match selector."); -secondContent = allSpan.shadowRoot.firstChild.shadowRoot.getElementById("twelve"); -is(secondContent.getDistributedNodes().length, 1, "Insertion point should only match reprojected node."); -is(secondContent.getDistributedNodes()[0].dataset.color, "blue", "Projected node should match selector."); - -// Make sure that dynamically appended default content will get distributed. -</script> -</body> -</html> - 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', |