Loading content/xbl/public/nsIXBLInsertionPoint.h +3 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,9 @@ public: NS_IMETHOD SetDefaultContent(nsIContent* aDefaultContent)=0; NS_IMETHOD GetDefaultContent(nsIContent** aDefaultContent)=0; NS_IMETHOD SetDefaultContentTemplate(nsIContent* aDefaultContent)=0; NS_IMETHOD GetDefaultContentTemplate(nsIContent** aDefaultContent)=0; NS_IMETHOD AddChild(nsIContent* aChildElement)=0; NS_IMETHOD InsertChildAt(PRInt32 aIndex, nsIContent* aChildElement)=0; NS_IMETHOD RemoveChild(nsIContent* aChildElement)=0; Loading content/xbl/src/nsXBLBinding.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -600,7 +600,7 @@ PRBool PR_CALLBACK RealizeDefaultContent(nsHashKey* aKey, void* aData, void* aCl if (insCount == 0) { nsCOMPtr<nsIContent> defContent; currPoint->GetDefaultContent(getter_AddRefs(defContent)); currPoint->GetDefaultContentTemplate(getter_AddRefs(defContent)); if (defContent) { // We need to take this template and use it to realize the // actual default content (through cloning). Loading Loading @@ -743,8 +743,6 @@ nsXBLBinding::GenerateAnonymousContent() clonedContent = do_QueryInterface(clonedNode); SetAnonymousContent(clonedContent); mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent); if (hasInsertionPoints) { // Now check and see if we have a single insertion point // or multiple insertion points. Loading Loading @@ -847,6 +845,8 @@ nsXBLBinding::GenerateAnonymousContent() mInsertionPointTable->Enumerate(RealizeDefaultContent, &data); } } mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent); } // Always check the content element for potential attributes. Loading content/xbl/src/nsXBLInsertionPoint.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aI NS_INIT_REFCNT(); mParentElement = aParentElement; mIndex = aIndex; mDefaultContent = aDefaultContent; mDefaultContentTemplate = aDefaultContent; } nsXBLInsertionPoint::~nsXBLInsertionPoint() Loading Loading @@ -71,6 +71,22 @@ nsXBLInsertionPoint::GetDefaultContent(nsIContent** aDefaultContent) return NS_OK; } NS_IMETHODIMP nsXBLInsertionPoint::SetDefaultContentTemplate(nsIContent* aDefaultContent) { mDefaultContentTemplate = aDefaultContent; return NS_OK; } NS_IMETHODIMP nsXBLInsertionPoint::GetDefaultContentTemplate(nsIContent** aDefaultContent) { *aDefaultContent = mDefaultContentTemplate; NS_IF_ADDREF(*aDefaultContent); return NS_OK; } NS_IMETHODIMP nsXBLInsertionPoint::AddChild(nsIContent* aChildElement) { Loading content/xbl/src/nsXBLInsertionPoint.h +6 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ public: NS_IMETHOD SetDefaultContent(nsIContent* aDefaultContent); NS_IMETHOD GetDefaultContent(nsIContent** aDefaultContent); NS_IMETHOD SetDefaultContentTemplate(nsIContent* aDefaultContent); NS_IMETHOD GetDefaultContentTemplate(nsIContent** aDefaultContent); NS_IMETHOD AddChild(nsIContent* aChildElement); NS_IMETHOD InsertChildAt(PRInt32 aIndex, nsIContent* aChildElement); NS_IMETHOD RemoveChild(nsIContent* aChildElement); Loading @@ -57,7 +60,9 @@ protected: nsIContent* mParentElement; // This ref is weak. The parent of the <children> element. PRInt32 mIndex; // The index of this insertion point. -1 is a pseudo-point. nsCOMPtr<nsISupportsArray> mElements; // An array of elements present at the insertion point. nsCOMPtr<nsIContent> mDefaultContent; // The default content at this insertion point. nsCOMPtr<nsIContent> mDefaultContentTemplate ; // The template default content that will be cloned if // the insertion point is empty. nsCOMPtr<nsIContent> mDefaultContent; // The cloned default content obtained by cloning mDefaultContentTemplate. }; extern nsresult Loading content/xbl/src/nsXBLPrototypeBinding.cpp +86 −15 Original line number Diff line number Diff line Loading @@ -641,7 +641,7 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceI xblAttr->GetElement(getter_AddRefs(element)); nsCOMPtr<nsIContent> realElement; LocateInstance(content, aAnonymousContent, element, getter_AddRefs(realElement)); LocateInstance(aChangedElement, content, aAnonymousContent, element, getter_AddRefs(realElement)); xblAttr->GetDstAttribute(getter_AddRefs(dstAttr)); Loading Loading @@ -737,7 +737,7 @@ PRBool PR_CALLBACK InstantiateInsertionPoint(nsHashKey* aKey, void* aData, void* binding->GetAnonymousContent(getter_AddRefs(instanceRoot)); nsCOMPtr<nsIContent> templRoot; proto->GetImmediateChild(nsXBLPrototypeBinding::kContentAtom, getter_AddRefs(templRoot)); proto->LocateInstance(templRoot, instanceRoot, content, getter_AddRefs(realContent)); proto->LocateInstance(nsnull, templRoot, instanceRoot, content, getter_AddRefs(realContent)); if (!realContent) binding->GetBoundElement(getter_AddRefs(realContent)); Loading Loading @@ -806,7 +806,7 @@ nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent* entry->GetDefaultContent(aDefaultContent); // Addref happens here. nsCOMPtr<nsIContent> templContent; GetImmediateChild(kContentAtom, getter_AddRefs(templContent)); LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent)); LocateInstance(nsnull, templContent, aCopyRoot, content, getter_AddRefs(realContent)); } else { // We got nothin'. Bail. Loading Loading @@ -844,7 +844,7 @@ nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement, entry->GetDefaultContent(aDefaultContent); // Addref happens here. nsCOMPtr<nsIContent> templContent; GetImmediateChild(kContentAtom, getter_AddRefs(templContent)); LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent)); LocateInstance(nsnull, templContent, aCopyRoot, content, getter_AddRefs(realContent)); } else { // The only insertion point specified was actually a filtered insertion point. Loading Loading @@ -964,30 +964,94 @@ nsXBLPrototypeBinding::ConstructHandlers() } void nsXBLPrototypeBinding::LocateInstance(nsIContent* aTemplRoot, nsIContent* aCopyRoot, nsXBLPrototypeBinding::LocateInstance(nsIContent* aBoundElement, nsIContent* aTemplRoot, nsIContent* aCopyRoot, nsIContent* aTemplChild, nsIContent** aCopyResult) { // XXX We will get in trouble if the binding instantiation deviates from the template // in the prototype. if (aTemplChild == aTemplRoot) { if (aTemplChild == aTemplRoot || !aTemplChild) { *aCopyResult = nsnull; return; } nsCOMPtr<nsIContent> templParent; nsCOMPtr<nsIContent> copyParent; nsCOMPtr<nsIContent> childPoint; aTemplChild->GetParent(*getter_AddRefs(templParent)); if (aBoundElement) { nsCOMPtr<nsIAtom> tag; templParent->GetTag(*getter_AddRefs(tag)); if (tag == kChildrenAtom) { childPoint = templParent; childPoint->GetParent(*getter_AddRefs(templParent)); } } if (!templParent) return; if (templParent.get() == aTemplRoot) copyParent = aCopyRoot; else LocateInstance(aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent)); LocateInstance(aBoundElement, aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent)); if (childPoint && aBoundElement) { // First we have to locate this insertion point and use its index and its // count to detemine our precise position within the template. nsCOMPtr<nsIDocument> doc; aBoundElement->GetDocument(*getter_AddRefs(doc)); nsCOMPtr<nsIBindingManager> bm; doc->GetBindingManager(getter_AddRefs(bm)); nsCOMPtr<nsIXBLBinding> binding; bm->GetBinding(aBoundElement, getter_AddRefs(binding)); nsCOMPtr<nsIXBLBinding> currBinding = binding; while (currBinding) { nsCOMPtr<nsIContent> anonContent; currBinding->GetAnonymousContent(getter_AddRefs(anonContent)); if (anonContent) break; nsCOMPtr<nsIXBLBinding> tempBinding = currBinding; tempBinding->GetBaseBinding(getter_AddRefs(currBinding)); } nsCOMPtr<nsISupportsArray> points; currBinding->GetInsertionPointsFor(copyParent, getter_AddRefs(points)); nsCOMPtr<nsIXBLInsertionPoint> insertionPoint; PRUint32 count; points->Count(&count); for (PRUint32 i = 0; i < count; i++) { // Next we have to find the real insertion point for this proto insertion // point. If it does not contain any default content, then we should // return null, since the content is not in the clone. nsCOMPtr<nsIXBLInsertionPoint> currPoint = getter_AddRefs((nsIXBLInsertionPoint*)points->ElementAt(i)); nsCOMPtr<nsIContent> defContent; currPoint->GetDefaultContentTemplate(getter_AddRefs(defContent)); if (defContent == childPoint) { // Now check to see if we even built default content at this // insertion point. currPoint->GetDefaultContent(getter_AddRefs(defContent)); if (defContent) { // Find out the index of the template element within the <children> elt. PRInt32 index; childPoint->IndexOf(aTemplChild, index); // Now we just have to find the corresponding elt underneath the cloned // default content. defContent->ChildAt(index, *aCopyResult); } break; } } } else if (copyParent) { PRInt32 index; templParent->IndexOf(aTemplChild, index); copyParent->ChildAt(index, *aCopyResult); // Addref happens here. } } struct nsXBLAttrChangeData { Loading Loading @@ -1039,7 +1103,8 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure) curr->GetElement(getter_AddRefs(element)); nsCOMPtr<nsIContent> realElement; changeData->mProto->LocateInstance(content, changeData->mContent, element, getter_AddRefs(realElement)); changeData->mProto->LocateInstance(changeData->mBoundElement, content, changeData->mContent, element, getter_AddRefs(realElement)); if (realElement) { realElement->SetAttribute(kNameSpaceID_None, dst, value, PR_FALSE); nsCOMPtr<nsIAtom> tag; Loading Loading @@ -1240,7 +1305,7 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent) nsISupportsKey key(atom); mInsertionPointTable->Put(&key, xblIns); token = nsCRT::strtok( newStr, ", ", &newStr ); token = nsCRT::strtok( newStr, "| ", &newStr ); } nsMemory::Free(str); Loading @@ -1267,8 +1332,14 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent) // in situations where no content ends up being placed at the insertion point. PRInt32 defaultCount; child->ChildCount(defaultCount); if (defaultCount > 0) if (defaultCount > 0) { // Annotate the insertion point with our default content. xblIns->SetDefaultContent(child); // Reconnect back to our parent for access later. This makes "inherits" easier // to work with on default content. child->SetParent(parent); } } } } Loading Loading
content/xbl/public/nsIXBLInsertionPoint.h +3 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,9 @@ public: NS_IMETHOD SetDefaultContent(nsIContent* aDefaultContent)=0; NS_IMETHOD GetDefaultContent(nsIContent** aDefaultContent)=0; NS_IMETHOD SetDefaultContentTemplate(nsIContent* aDefaultContent)=0; NS_IMETHOD GetDefaultContentTemplate(nsIContent** aDefaultContent)=0; NS_IMETHOD AddChild(nsIContent* aChildElement)=0; NS_IMETHOD InsertChildAt(PRInt32 aIndex, nsIContent* aChildElement)=0; NS_IMETHOD RemoveChild(nsIContent* aChildElement)=0; Loading
content/xbl/src/nsXBLBinding.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -600,7 +600,7 @@ PRBool PR_CALLBACK RealizeDefaultContent(nsHashKey* aKey, void* aData, void* aCl if (insCount == 0) { nsCOMPtr<nsIContent> defContent; currPoint->GetDefaultContent(getter_AddRefs(defContent)); currPoint->GetDefaultContentTemplate(getter_AddRefs(defContent)); if (defContent) { // We need to take this template and use it to realize the // actual default content (through cloning). Loading Loading @@ -743,8 +743,6 @@ nsXBLBinding::GenerateAnonymousContent() clonedContent = do_QueryInterface(clonedNode); SetAnonymousContent(clonedContent); mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent); if (hasInsertionPoints) { // Now check and see if we have a single insertion point // or multiple insertion points. Loading Loading @@ -847,6 +845,8 @@ nsXBLBinding::GenerateAnonymousContent() mInsertionPointTable->Enumerate(RealizeDefaultContent, &data); } } mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent); } // Always check the content element for potential attributes. Loading
content/xbl/src/nsXBLInsertionPoint.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aI NS_INIT_REFCNT(); mParentElement = aParentElement; mIndex = aIndex; mDefaultContent = aDefaultContent; mDefaultContentTemplate = aDefaultContent; } nsXBLInsertionPoint::~nsXBLInsertionPoint() Loading Loading @@ -71,6 +71,22 @@ nsXBLInsertionPoint::GetDefaultContent(nsIContent** aDefaultContent) return NS_OK; } NS_IMETHODIMP nsXBLInsertionPoint::SetDefaultContentTemplate(nsIContent* aDefaultContent) { mDefaultContentTemplate = aDefaultContent; return NS_OK; } NS_IMETHODIMP nsXBLInsertionPoint::GetDefaultContentTemplate(nsIContent** aDefaultContent) { *aDefaultContent = mDefaultContentTemplate; NS_IF_ADDREF(*aDefaultContent); return NS_OK; } NS_IMETHODIMP nsXBLInsertionPoint::AddChild(nsIContent* aChildElement) { Loading
content/xbl/src/nsXBLInsertionPoint.h +6 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ public: NS_IMETHOD SetDefaultContent(nsIContent* aDefaultContent); NS_IMETHOD GetDefaultContent(nsIContent** aDefaultContent); NS_IMETHOD SetDefaultContentTemplate(nsIContent* aDefaultContent); NS_IMETHOD GetDefaultContentTemplate(nsIContent** aDefaultContent); NS_IMETHOD AddChild(nsIContent* aChildElement); NS_IMETHOD InsertChildAt(PRInt32 aIndex, nsIContent* aChildElement); NS_IMETHOD RemoveChild(nsIContent* aChildElement); Loading @@ -57,7 +60,9 @@ protected: nsIContent* mParentElement; // This ref is weak. The parent of the <children> element. PRInt32 mIndex; // The index of this insertion point. -1 is a pseudo-point. nsCOMPtr<nsISupportsArray> mElements; // An array of elements present at the insertion point. nsCOMPtr<nsIContent> mDefaultContent; // The default content at this insertion point. nsCOMPtr<nsIContent> mDefaultContentTemplate ; // The template default content that will be cloned if // the insertion point is empty. nsCOMPtr<nsIContent> mDefaultContent; // The cloned default content obtained by cloning mDefaultContentTemplate. }; extern nsresult Loading
content/xbl/src/nsXBLPrototypeBinding.cpp +86 −15 Original line number Diff line number Diff line Loading @@ -641,7 +641,7 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceI xblAttr->GetElement(getter_AddRefs(element)); nsCOMPtr<nsIContent> realElement; LocateInstance(content, aAnonymousContent, element, getter_AddRefs(realElement)); LocateInstance(aChangedElement, content, aAnonymousContent, element, getter_AddRefs(realElement)); xblAttr->GetDstAttribute(getter_AddRefs(dstAttr)); Loading Loading @@ -737,7 +737,7 @@ PRBool PR_CALLBACK InstantiateInsertionPoint(nsHashKey* aKey, void* aData, void* binding->GetAnonymousContent(getter_AddRefs(instanceRoot)); nsCOMPtr<nsIContent> templRoot; proto->GetImmediateChild(nsXBLPrototypeBinding::kContentAtom, getter_AddRefs(templRoot)); proto->LocateInstance(templRoot, instanceRoot, content, getter_AddRefs(realContent)); proto->LocateInstance(nsnull, templRoot, instanceRoot, content, getter_AddRefs(realContent)); if (!realContent) binding->GetBoundElement(getter_AddRefs(realContent)); Loading Loading @@ -806,7 +806,7 @@ nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent* entry->GetDefaultContent(aDefaultContent); // Addref happens here. nsCOMPtr<nsIContent> templContent; GetImmediateChild(kContentAtom, getter_AddRefs(templContent)); LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent)); LocateInstance(nsnull, templContent, aCopyRoot, content, getter_AddRefs(realContent)); } else { // We got nothin'. Bail. Loading Loading @@ -844,7 +844,7 @@ nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement, entry->GetDefaultContent(aDefaultContent); // Addref happens here. nsCOMPtr<nsIContent> templContent; GetImmediateChild(kContentAtom, getter_AddRefs(templContent)); LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent)); LocateInstance(nsnull, templContent, aCopyRoot, content, getter_AddRefs(realContent)); } else { // The only insertion point specified was actually a filtered insertion point. Loading Loading @@ -964,30 +964,94 @@ nsXBLPrototypeBinding::ConstructHandlers() } void nsXBLPrototypeBinding::LocateInstance(nsIContent* aTemplRoot, nsIContent* aCopyRoot, nsXBLPrototypeBinding::LocateInstance(nsIContent* aBoundElement, nsIContent* aTemplRoot, nsIContent* aCopyRoot, nsIContent* aTemplChild, nsIContent** aCopyResult) { // XXX We will get in trouble if the binding instantiation deviates from the template // in the prototype. if (aTemplChild == aTemplRoot) { if (aTemplChild == aTemplRoot || !aTemplChild) { *aCopyResult = nsnull; return; } nsCOMPtr<nsIContent> templParent; nsCOMPtr<nsIContent> copyParent; nsCOMPtr<nsIContent> childPoint; aTemplChild->GetParent(*getter_AddRefs(templParent)); if (aBoundElement) { nsCOMPtr<nsIAtom> tag; templParent->GetTag(*getter_AddRefs(tag)); if (tag == kChildrenAtom) { childPoint = templParent; childPoint->GetParent(*getter_AddRefs(templParent)); } } if (!templParent) return; if (templParent.get() == aTemplRoot) copyParent = aCopyRoot; else LocateInstance(aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent)); LocateInstance(aBoundElement, aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent)); if (childPoint && aBoundElement) { // First we have to locate this insertion point and use its index and its // count to detemine our precise position within the template. nsCOMPtr<nsIDocument> doc; aBoundElement->GetDocument(*getter_AddRefs(doc)); nsCOMPtr<nsIBindingManager> bm; doc->GetBindingManager(getter_AddRefs(bm)); nsCOMPtr<nsIXBLBinding> binding; bm->GetBinding(aBoundElement, getter_AddRefs(binding)); nsCOMPtr<nsIXBLBinding> currBinding = binding; while (currBinding) { nsCOMPtr<nsIContent> anonContent; currBinding->GetAnonymousContent(getter_AddRefs(anonContent)); if (anonContent) break; nsCOMPtr<nsIXBLBinding> tempBinding = currBinding; tempBinding->GetBaseBinding(getter_AddRefs(currBinding)); } nsCOMPtr<nsISupportsArray> points; currBinding->GetInsertionPointsFor(copyParent, getter_AddRefs(points)); nsCOMPtr<nsIXBLInsertionPoint> insertionPoint; PRUint32 count; points->Count(&count); for (PRUint32 i = 0; i < count; i++) { // Next we have to find the real insertion point for this proto insertion // point. If it does not contain any default content, then we should // return null, since the content is not in the clone. nsCOMPtr<nsIXBLInsertionPoint> currPoint = getter_AddRefs((nsIXBLInsertionPoint*)points->ElementAt(i)); nsCOMPtr<nsIContent> defContent; currPoint->GetDefaultContentTemplate(getter_AddRefs(defContent)); if (defContent == childPoint) { // Now check to see if we even built default content at this // insertion point. currPoint->GetDefaultContent(getter_AddRefs(defContent)); if (defContent) { // Find out the index of the template element within the <children> elt. PRInt32 index; childPoint->IndexOf(aTemplChild, index); // Now we just have to find the corresponding elt underneath the cloned // default content. defContent->ChildAt(index, *aCopyResult); } break; } } } else if (copyParent) { PRInt32 index; templParent->IndexOf(aTemplChild, index); copyParent->ChildAt(index, *aCopyResult); // Addref happens here. } } struct nsXBLAttrChangeData { Loading Loading @@ -1039,7 +1103,8 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure) curr->GetElement(getter_AddRefs(element)); nsCOMPtr<nsIContent> realElement; changeData->mProto->LocateInstance(content, changeData->mContent, element, getter_AddRefs(realElement)); changeData->mProto->LocateInstance(changeData->mBoundElement, content, changeData->mContent, element, getter_AddRefs(realElement)); if (realElement) { realElement->SetAttribute(kNameSpaceID_None, dst, value, PR_FALSE); nsCOMPtr<nsIAtom> tag; Loading Loading @@ -1240,7 +1305,7 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent) nsISupportsKey key(atom); mInsertionPointTable->Put(&key, xblIns); token = nsCRT::strtok( newStr, ", ", &newStr ); token = nsCRT::strtok( newStr, "| ", &newStr ); } nsMemory::Free(str); Loading @@ -1267,8 +1332,14 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent) // in situations where no content ends up being placed at the insertion point. PRInt32 defaultCount; child->ChildCount(defaultCount); if (defaultCount > 0) if (defaultCount > 0) { // Annotate the insertion point with our default content. xblIns->SetDefaultContent(child); // Reconnect back to our parent for access later. This makes "inherits" easier // to work with on default content. child->SetParent(parent); } } } } Loading