diff options
Diffstat (limited to 'dom/html/HTMLContentElement.cpp')
-rw-r--r-- | dom/html/HTMLContentElement.cpp | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/dom/html/HTMLContentElement.cpp b/dom/html/HTMLContentElement.cpp deleted file mode 100644 index 01c0158a0..000000000 --- a/dom/html/HTMLContentElement.cpp +++ /dev/null @@ -1,393 +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::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, - nsIAtom* aPrefix, const nsAString& aValue, - bool aNotify) -{ - nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, - aValue, aNotify); - NS_ENSURE_SUCCESS(rv, rv); - - if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::select) { - // Select attribute was updated, the insertion point may match different - // elements. - nsIDocument* doc = OwnerDoc(); - nsCSSParser parser(doc->CSSLoader()); - - mValidSelector = true; - mSelectorList = nullptr; - - nsresult rv = parser.ParseSelectorString(aValue, - 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; - } - } - - ShadowRoot* containingShadow = GetContainingShadow(); - if (containingShadow) { - containingShadow->DistributeAllNodes(); - } - } - - return NS_OK; -} - -nsresult -HTMLContentElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, - bool aNotify) -{ - nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, - aAttribute, aNotify); - NS_ENSURE_SUCCESS(rv, rv); - - if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::select) { - // The select attribute was removed. This insertion point becomes - // a universal selector. - mValidSelector = true; - mSelectorList = nullptr; - - ShadowRoot* containingShadow = GetContainingShadow(); - if (containingShadow) { - containingShadow->DistributeAllNodes(); - } - } - - return NS_OK; -} - -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); -} - |