forked from mirrors/gecko-dev
		
	 01583602a9
			
		
	
	
		01583602a9
		
	
	
	
	
		
			
			The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout.  The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
 # The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
    xargs perl -p -i -e '
 s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
 s/nsRefPtr ?</RefPtr</g;   # handle declarations and variables
'
 # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
 # Handle nsRefPtr.h itself, a couple places that define constructors
 # from nsRefPtr, and code generators specially.  We do this here, rather
 # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
 # things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
     mfbt/nsRefPtr.h \
     xpcom/glue/nsCOMPtr.h \
     xpcom/base/OwningNonNull.h \
     ipc/ipdl/ipdl/lower.py \
     ipc/ipdl/ipdl/builtin.py \
     dom/bindings/Codegen.py \
     python/lldbutils/lldbutils/utils.py
 # In our indiscriminate substitution above, we renamed
 # nsRefPtrGetterAddRefs, the class behind getter_AddRefs.  Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
    xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
    git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
    hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
--HG--
rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
		
	
			
		
			
				
	
	
		
			372 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			372 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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/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"
 | |
| 
 | |
| NS_IMPL_NS_NEW_HTML_ELEMENT(Content)
 | |
| 
 | |
| 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->IsHTMLElement(nsGkAtoms::content)) {
 | |
|         // 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);
 | |
| }
 | |
| 
 |