зеркало из https://github.com/mozilla/gecko-dev.git
Fix for 62783. r=danm, sr=waterson
This commit is contained in:
Родитель
04661bbcca
Коммит
4409f43798
|
@ -88,8 +88,10 @@ public:
|
|||
|
||||
NS_IMETHOD GetInsertionPointsFor(nsIContent* aParent, nsISupportsArray** aResult)=0;
|
||||
|
||||
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex) = 0;
|
||||
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRUint32* aIndex, PRBool* aMultipleInsertionPoints) = 0;
|
||||
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex,
|
||||
nsIContent** aDefaultContent) = 0;
|
||||
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRUint32* aIndex,
|
||||
PRBool* aMultipleInsertionPoints, nsIContent** aDefaultContent) = 0;
|
||||
|
||||
NS_IMETHOD IsStyleBinding(PRBool* aResult) = 0;
|
||||
NS_IMETHOD SetIsStyleBinding(PRBool aIsStyle) = 0;
|
||||
|
|
|
@ -39,6 +39,9 @@ public:
|
|||
NS_IMETHOD GetInsertionParent(nsIContent** aParentElement)=0;
|
||||
NS_IMETHOD GetInsertionIndex(PRInt32* aResult)=0;
|
||||
|
||||
NS_IMETHOD SetDefaultContent(nsIContent* aDefaultContent)=0;
|
||||
NS_IMETHOD GetDefaultContent(nsIContent** aDefaultContent)=0;
|
||||
|
||||
NS_IMETHOD AddChild(nsIContent* aChildElement)=0;
|
||||
NS_IMETHOD InsertChildAt(PRInt32 aIndex, nsIContent* aChildElement)=0;
|
||||
NS_IMETHOD RemoveChild(nsIContent* aChildElement)=0;
|
||||
|
@ -51,6 +54,7 @@ public:
|
|||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIXBLInsertionPoint** aResult);
|
||||
NS_NewXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIContent* aDefContent,
|
||||
nsIXBLInsertionPoint** aResult);
|
||||
|
||||
#endif // nsIXBLInsertionPoint_h__
|
||||
|
|
|
@ -82,10 +82,12 @@ public:
|
|||
NS_IMETHOD InstantiateInsertionPoints(nsIXBLBinding* aBinding)=0;
|
||||
|
||||
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||
nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex)=0;
|
||||
nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex,
|
||||
nsIContent** aDefaultContent)=0;
|
||||
|
||||
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||
nsIContent** aResult, PRUint32* aIndex, PRBool* aMultipleInsertionPoints)=0;
|
||||
nsIContent** aResult, PRUint32* aIndex, PRBool* aMultiple,
|
||||
nsIContent** aDefaultContent)=0;
|
||||
|
||||
NS_IMETHOD GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aTag)=0;
|
||||
NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag)=0;
|
||||
|
|
|
@ -815,8 +815,9 @@ nsBindingManager::GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsI
|
|||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
GetBinding(aParent, getter_AddRefs(binding));
|
||||
|
||||
nsCOMPtr<nsIContent> defContent;
|
||||
if (binding)
|
||||
return binding->GetInsertionPoint(aChild, aResult, aIndex);
|
||||
return binding->GetInsertionPoint(aChild, aResult, aIndex, getter_AddRefs(defContent));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -828,8 +829,10 @@ nsBindingManager::GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aRes
|
|||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
GetBinding(aParent, getter_AddRefs(binding));
|
||||
|
||||
nsCOMPtr<nsIContent> defContent;
|
||||
|
||||
if (binding)
|
||||
return binding->GetSingleInsertionPoint(aResult, aIndex, aMultipleInsertionPoints);
|
||||
return binding->GetSingleInsertionPoint(aResult, aIndex, aMultipleInsertionPoints, getter_AddRefs(defContent));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -349,30 +349,27 @@ nsXBLBinding::GetAnonymousContent(nsIContent** aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
||||
void
|
||||
nsXBLBinding::InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement)
|
||||
{
|
||||
// First cache the element.
|
||||
mContent = aParent;
|
||||
|
||||
// Now we need to ensure two things.
|
||||
// We need to ensure two things.
|
||||
// (1) The anonymous content should be fooled into thinking it's in the bound
|
||||
// element's document.
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
mBoundElement->GetDocument(*getter_AddRefs(doc));
|
||||
aElement->GetDocument(*getter_AddRefs(doc));
|
||||
|
||||
mContent->SetDocument(doc, PR_TRUE, AllowScripts());
|
||||
aAnonParent->SetDocument(doc, PR_TRUE, AllowScripts());
|
||||
|
||||
nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
|
||||
|
||||
// (2) The children's parent back pointer should not be to this synthetic root
|
||||
// but should instead point to the bound element.
|
||||
// but should instead point to the enclosing parent element.
|
||||
PRInt32 childCount;
|
||||
mContent->ChildCount(childCount);
|
||||
aAnonParent->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
mContent->ChildAt(i, *getter_AddRefs(child));
|
||||
child->SetParent(mBoundElement);
|
||||
aAnonParent->ChildAt(i, *getter_AddRefs(child));
|
||||
child->SetParent(aElement);
|
||||
child->SetBindingParent(mBoundElement);
|
||||
|
||||
// To make XUL templates work (and other goodies that happen when
|
||||
|
@ -381,7 +378,15 @@ nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
|||
if (xuldoc)
|
||||
xuldoc->AddSubtreeToDocument(child);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
||||
{
|
||||
// First cache the element.
|
||||
mContent = aParent;
|
||||
|
||||
InstallAnonymousContent(mContent, mBoundElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -450,15 +455,24 @@ nsXBLBinding::HasStyleSheets(PRBool* aResolveStyle)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
struct ContentListData {
|
||||
struct EnumData {
|
||||
nsXBLBinding* mBinding;
|
||||
|
||||
EnumData(nsXBLBinding* aBinding)
|
||||
:mBinding(aBinding)
|
||||
{};
|
||||
};
|
||||
|
||||
struct ContentListData : public EnumData {
|
||||
nsIBindingManager* mBindingManager;
|
||||
|
||||
ContentListData(nsXBLBinding* aBinding, nsIBindingManager* aManager)
|
||||
:mBinding(aBinding), mBindingManager(aManager)
|
||||
:EnumData(aBinding), mBindingManager(aManager)
|
||||
{};
|
||||
};
|
||||
|
||||
|
||||
|
||||
PRBool PR_CALLBACK BuildContentLists(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
{
|
||||
ContentListData* data = (ContentListData*)aClosure;
|
||||
|
@ -522,7 +536,7 @@ PRBool PR_CALLBACK BuildContentLists(nsHashKey* aKey, void* aData, void* aClosur
|
|||
}
|
||||
|
||||
if (!pseudoPoint) {
|
||||
NS_NewXBLInsertionPoint(parent, -1, getter_AddRefs(pseudoPoint));
|
||||
NS_NewXBLInsertionPoint(parent, -1, nsnull, getter_AddRefs(pseudoPoint));
|
||||
contentList->AppendElement(pseudoPoint);
|
||||
}
|
||||
|
||||
|
@ -546,6 +560,82 @@ PRBool PR_CALLBACK BuildContentLists(nsHashKey* aKey, void* aData, void* aClosur
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool PR_CALLBACK RealizeDefaultContent(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
{
|
||||
ContentListData* data = (ContentListData*)aClosure;
|
||||
nsIBindingManager* bm = data->mBindingManager;
|
||||
nsXBLBinding* binding = data->mBinding;
|
||||
|
||||
nsCOMPtr<nsIContent> boundElement;
|
||||
binding->GetBoundElement(getter_AddRefs(boundElement));
|
||||
|
||||
nsISupportsArray* arr = (nsISupportsArray*)aData;
|
||||
PRUint32 count;
|
||||
arr->Count(&count);
|
||||
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsIXBLInsertionPoint> currPoint = getter_AddRefs((nsIXBLInsertionPoint*)arr->ElementAt(i));
|
||||
PRUint32 insCount;
|
||||
currPoint->ChildCount(&insCount);
|
||||
|
||||
if (insCount == 0) {
|
||||
nsCOMPtr<nsIContent> defContent;
|
||||
currPoint->GetDefaultContent(getter_AddRefs(defContent));
|
||||
if (defContent) {
|
||||
// We need to take this template and use it to realize the
|
||||
// actual default content (through cloning).
|
||||
// Clone this insertion point element.
|
||||
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(defContent));
|
||||
nsCOMPtr<nsIDOMNode> clonedNode;
|
||||
elt->CloneNode(PR_TRUE, getter_AddRefs(clonedNode));
|
||||
|
||||
nsCOMPtr<nsIContent> insParent;
|
||||
currPoint->GetInsertionParent(getter_AddRefs(insParent));
|
||||
|
||||
// Now that we have the cloned content, install the default content as
|
||||
// if it were additional anonymous content.
|
||||
nsCOMPtr<nsIContent> clonedContent(do_QueryInterface(clonedNode));
|
||||
binding->InstallAnonymousContent(clonedContent, insParent);
|
||||
|
||||
// Cache the clone so that it can be properly destroyed if/when our
|
||||
// other anonymous content is destroyed.
|
||||
currPoint->SetDefaultContent(clonedContent);
|
||||
|
||||
// Now make sure the kids of the clone are added to the insertion point as
|
||||
// children.
|
||||
PRInt32 cloneKidCount;
|
||||
clonedContent->ChildCount(cloneKidCount);
|
||||
for (PRInt32 k = 0; k < cloneKidCount; k++) {
|
||||
nsCOMPtr<nsIContent> cloneChild;
|
||||
clonedContent->ChildAt(k, *getter_AddRefs(cloneChild));
|
||||
bm->SetInsertionParent(cloneChild, insParent);
|
||||
currPoint->AddChild(cloneChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool PR_CALLBACK ChangeDocumentForDefaultContent(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
{
|
||||
nsISupportsArray* arr = (nsISupportsArray*)aData;
|
||||
PRUint32 count;
|
||||
arr->Count(&count);
|
||||
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsIXBLInsertionPoint> currPoint = getter_AddRefs((nsIXBLInsertionPoint*)arr->ElementAt(i));
|
||||
nsCOMPtr<nsIContent> defContent;
|
||||
currPoint->GetDefaultContent(getter_AddRefs(defContent));
|
||||
|
||||
if (defContent)
|
||||
defContent->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::GenerateAnonymousContent()
|
||||
{
|
||||
|
@ -657,7 +747,9 @@ nsXBLBinding::GenerateAnonymousContent()
|
|||
nsCOMPtr<nsIContent> singlePoint;
|
||||
PRUint32 index = 0;
|
||||
PRBool multiplePoints = PR_FALSE;
|
||||
GetSingleInsertionPoint(getter_AddRefs(singlePoint), &index, &multiplePoints);
|
||||
nsCOMPtr<nsIContent> singleDefaultContent;
|
||||
GetSingleInsertionPoint(getter_AddRefs(singlePoint), &index,
|
||||
&multiplePoints, getter_AddRefs(singleDefaultContent));
|
||||
|
||||
if (children) {
|
||||
if (multiplePoints) {
|
||||
|
@ -674,7 +766,8 @@ nsXBLBinding::GenerateAnonymousContent()
|
|||
// Now determine the insertion point in the prototype table.
|
||||
nsCOMPtr<nsIContent> point;
|
||||
PRUint32 index;
|
||||
GetInsertionPoint(content, getter_AddRefs(point), &index);
|
||||
nsCOMPtr<nsIContent> defContent;
|
||||
GetInsertionPoint(content, getter_AddRefs(point), &index, getter_AddRefs(defContent));
|
||||
bindingManager->SetInsertionParent(content, point);
|
||||
|
||||
// Find the correct nsIXBLInsertion point in our table.
|
||||
|
@ -708,6 +801,7 @@ nsXBLBinding::GenerateAnonymousContent()
|
|||
nsCOMPtr<nsIContent> content;
|
||||
PRUint32 length;
|
||||
children->GetLength(&length);
|
||||
|
||||
for (PRUint32 i = 0; i < length; i++) {
|
||||
children->Item(i, getter_AddRefs(node));
|
||||
content = do_QueryInterface(node);
|
||||
|
@ -716,6 +810,11 @@ nsXBLBinding::GenerateAnonymousContent()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that all of our children have been added, we need to walk all of our
|
||||
// nsIXBLInsertion points to see if any of them have default content that
|
||||
// needs to be built.
|
||||
mInsertionPointTable->Enumerate(RealizeDefaultContent, &data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1322,25 +1421,18 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
|||
nsCOMPtr<nsIContent> anonymous;
|
||||
GetAnonymousContent(getter_AddRefs(anonymous));
|
||||
if (anonymous) {
|
||||
// Also kill the default content within all our insertion points.
|
||||
if (mInsertionPointTable)
|
||||
mInsertionPointTable->Enumerate(ChangeDocumentForDefaultContent, nsnull);
|
||||
|
||||
// To make XUL templates work (and other XUL-specific stuff),
|
||||
// we'll need to notify it using its add & remove APIs. Grab the
|
||||
// interface now...
|
||||
nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(aOldDocument));
|
||||
|
||||
if (mIsStyleBinding) {
|
||||
anonymous->SetDocument(nsnull, PR_TRUE, PR_TRUE); // Kill it.
|
||||
if (xuldoc)
|
||||
xuldoc->RemoveSubtreeFromDocument(anonymous);
|
||||
}
|
||||
else {
|
||||
anonymous->SetDocument(aNewDocument, PR_TRUE, AllowScripts()); // Keep it around.
|
||||
if (xuldoc)
|
||||
xuldoc->RemoveSubtreeFromDocument(anonymous);
|
||||
|
||||
xuldoc = do_QueryInterface(aNewDocument);
|
||||
if (xuldoc)
|
||||
xuldoc->AddSubtreeToDocument(anonymous);
|
||||
}
|
||||
anonymous->SetDocument(nsnull, PR_TRUE, PR_TRUE); // Kill it.
|
||||
if (xuldoc)
|
||||
xuldoc->RemoveSubtreeFromDocument(anonymous);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1667,25 +1759,30 @@ nsXBLBinding::GetInsertionPointsFor(nsIContent* aParent, nsISupportsArray** aRes
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex)
|
||||
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex,
|
||||
nsIContent** aDefaultContent)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
*aDefaultContent = nsnull;
|
||||
if (mContent)
|
||||
return mPrototypeBinding->GetInsertionPoint(mBoundElement, mContent, aChild, aResult, aIndex);
|
||||
return mPrototypeBinding->GetInsertionPoint(mBoundElement, mContent, aChild, aResult, aIndex, aDefaultContent);
|
||||
else if (mNextBinding)
|
||||
return mNextBinding->GetInsertionPoint(aChild, aResult, aIndex);
|
||||
return mNextBinding->GetInsertionPoint(aChild, aResult, aIndex, aDefaultContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLBinding::GetSingleInsertionPoint(nsIContent** aResult, PRUint32* aIndex, PRBool* aMultipleInsertionPoints)
|
||||
nsXBLBinding::GetSingleInsertionPoint(nsIContent** aResult, PRUint32* aIndex, PRBool* aMultipleInsertionPoints,
|
||||
nsIContent** aDefaultContent)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
*aDefaultContent = nsnull;
|
||||
*aMultipleInsertionPoints = PR_FALSE;
|
||||
if (mContent)
|
||||
return mPrototypeBinding->GetSingleInsertionPoint(mBoundElement, mContent, aResult, aIndex, aMultipleInsertionPoints);
|
||||
return mPrototypeBinding->GetSingleInsertionPoint(mBoundElement, mContent, aResult, aIndex,
|
||||
aMultipleInsertionPoints, aDefaultContent);
|
||||
else if (mNextBinding)
|
||||
return mNextBinding->GetSingleInsertionPoint(aResult, aIndex, aMultipleInsertionPoints);
|
||||
return mNextBinding->GetSingleInsertionPoint(aResult, aIndex, aMultipleInsertionPoints, aDefaultContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,8 +82,9 @@ class nsXBLBinding: public nsIXBLBinding
|
|||
|
||||
NS_IMETHOD GetInsertionPointsFor(nsIContent* aParent, nsISupportsArray** aResult);
|
||||
|
||||
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex);
|
||||
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRUint32* aIndex, PRBool* aMultipleInsertionPoints);
|
||||
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex, nsIContent** aDefaultContent);
|
||||
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRUint32* aIndex,
|
||||
PRBool* aMultipleInsertionPoints, nsIContent** aDefaultContent);
|
||||
|
||||
NS_IMETHOD IsStyleBinding(PRBool* aResult) { *aResult = mIsStyleBinding; return NS_OK; };
|
||||
NS_IMETHOD SetIsStyleBinding(PRBool aIsStyle) { mIsStyleBinding = aIsStyle; return NS_OK; };
|
||||
|
@ -110,7 +111,8 @@ public:
|
|||
NS_IMETHOD AddScriptEventListener(nsIContent* aElement, nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
|
||||
|
||||
PRBool AllowScripts();
|
||||
|
||||
void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement);
|
||||
|
||||
static nsresult GetTextData(nsIContent *aParent, nsString& aResult);
|
||||
|
||||
// Static members
|
||||
|
@ -164,6 +166,7 @@ protected:
|
|||
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
||||
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
|
||||
|
||||
|
||||
// MEMBER VARIABLES
|
||||
protected:
|
||||
nsCOMPtr<nsIXBLPrototypeBinding> mPrototypeBinding; // Strong. As long as we're around, the binding can't go away.
|
||||
|
|
|
@ -26,12 +26,13 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex)
|
||||
nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIContent* aDefaultContent)
|
||||
:mElements(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mParentElement = aParentElement;
|
||||
mIndex = aIndex;
|
||||
mDefaultContent = aDefaultContent;
|
||||
}
|
||||
|
||||
nsXBLInsertionPoint::~nsXBLInsertionPoint()
|
||||
|
@ -55,6 +56,21 @@ nsXBLInsertionPoint::GetInsertionIndex(PRInt32 *aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLInsertionPoint::SetDefaultContent(nsIContent* aDefaultContent)
|
||||
{
|
||||
mDefaultContent = aDefaultContent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLInsertionPoint::GetDefaultContent(nsIContent** aDefaultContent)
|
||||
{
|
||||
*aDefaultContent = mDefaultContent;
|
||||
NS_IF_ADDREF(*aDefaultContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLInsertionPoint::AddChild(nsIContent* aChildElement)
|
||||
{
|
||||
|
@ -116,9 +132,10 @@ nsXBLInsertionPoint::Matches(nsIContent* aContent, PRUint32 aIndex, PRBool* aRes
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIXBLInsertionPoint** aResult)
|
||||
NS_NewXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIContent* aDefContent,
|
||||
nsIXBLInsertionPoint** aResult)
|
||||
{
|
||||
*aResult = new nsXBLInsertionPoint(aParentElement, aIndex);
|
||||
*aResult = new nsXBLInsertionPoint(aParentElement, aIndex, aDefContent);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
|
||||
#include "nsIXBLInsertionPoint.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
class nsXBLInsertionPoint : public nsIXBLInsertionPoint
|
||||
{
|
||||
public:
|
||||
nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex);
|
||||
nsXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIContent* aDefContent);
|
||||
virtual ~nsXBLInsertionPoint();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -39,6 +40,9 @@ public:
|
|||
NS_IMETHOD GetInsertionParent(nsIContent** aParentElement);
|
||||
NS_IMETHOD GetInsertionIndex(PRInt32* aIndex);
|
||||
|
||||
NS_IMETHOD SetDefaultContent(nsIContent* aDefaultContent);
|
||||
NS_IMETHOD GetDefaultContent(nsIContent** aDefaultContent);
|
||||
|
||||
NS_IMETHOD AddChild(nsIContent* aChildElement);
|
||||
NS_IMETHOD InsertChildAt(PRInt32 aIndex, nsIContent* aChildElement);
|
||||
NS_IMETHOD RemoveChild(nsIContent* aChildElement);
|
||||
|
@ -53,9 +57,11 @@ 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.
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIXBLInsertionPoint** aResult);
|
||||
NS_NewXBLInsertionPoint(nsIContent* aParentElement, PRUint32 aIndex, nsIContent* aDefContent,
|
||||
nsIXBLInsertionPoint** aResult);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -129,6 +129,9 @@ public:
|
|||
|
||||
NS_IMETHOD GetInsertionIndex(PRUint32* aResult)=0;
|
||||
NS_IMETHOD SetInsertionIndex(PRUint32 aIndex)=0;
|
||||
|
||||
NS_IMETHOD GetDefaultContent(nsIContent** aResult)=0;
|
||||
NS_IMETHOD SetDefaultContent(nsIContent* aChildren)=0;
|
||||
};
|
||||
|
||||
class nsXBLInsertionPointEntry : public nsIXBLInsertionPointEntry {
|
||||
|
@ -143,7 +146,11 @@ public:
|
|||
NS_IMETHOD GetInsertionIndex(PRUint32* aResult) { *aResult = mInsertionIndex; return NS_OK; };
|
||||
NS_IMETHOD SetInsertionIndex(PRUint32 aIndex) { mInsertionIndex = aIndex; return NS_OK; };
|
||||
|
||||
NS_IMETHOD GetDefaultContent(nsIContent** aResult) { *aResult = mDefaultContent; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||
NS_IMETHOD SetDefaultContent(nsIContent* aChildren) { mDefaultContent = aChildren; return NS_OK; };
|
||||
|
||||
nsCOMPtr<nsIContent> mInsertionParent;
|
||||
nsCOMPtr<nsIContent> mDefaultContent;
|
||||
PRUint32 mInsertionIndex;
|
||||
|
||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||
|
@ -626,7 +633,9 @@ PRBool PR_CALLBACK InstantiateInsertionPoint(nsHashKey* aKey, void* aData, void*
|
|||
entry->GetInsertionParent(getter_AddRefs(content));
|
||||
PRUint32 index;
|
||||
entry->GetInsertionIndex(&index);
|
||||
|
||||
nsCOMPtr<nsIContent> defContent;
|
||||
entry->GetDefaultContent(getter_AddRefs(defContent));
|
||||
|
||||
// Locate the real content.
|
||||
nsCOMPtr<nsIContent> realContent;
|
||||
nsCOMPtr<nsIContent> instanceRoot;
|
||||
|
@ -645,6 +654,7 @@ PRBool PR_CALLBACK InstantiateInsertionPoint(nsHashKey* aKey, void* aData, void*
|
|||
points->Count(&count);
|
||||
PRUint32 i = 0;
|
||||
PRInt32 currIndex = 0;
|
||||
|
||||
for ( ; i < count; i++) {
|
||||
nsCOMPtr<nsIXBLInsertionPoint> currPoint = getter_AddRefs((nsIXBLInsertionPoint*)points->ElementAt(i));
|
||||
currPoint->GetInsertionIndex(&currIndex);
|
||||
|
@ -661,7 +671,7 @@ PRBool PR_CALLBACK InstantiateInsertionPoint(nsHashKey* aKey, void* aData, void*
|
|||
|
||||
if (!insertionPoint) {
|
||||
// We need to make a new insertion point.
|
||||
NS_NewXBLInsertionPoint(realContent, index, getter_AddRefs(insertionPoint));
|
||||
NS_NewXBLInsertionPoint(realContent, index, defContent, getter_AddRefs(insertionPoint));
|
||||
points->InsertElementAt(insertionPoint, i);
|
||||
}
|
||||
|
||||
|
@ -679,7 +689,8 @@ nsXBLPrototypeBinding::InstantiateInsertionPoints(nsIXBLBinding* aBinding)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||
nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex)
|
||||
nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex,
|
||||
nsIContent** aDefaultContent)
|
||||
{
|
||||
if (mInsertionPointTable) {
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
@ -697,6 +708,7 @@ nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent*
|
|||
nsCOMPtr<nsIContent> content;
|
||||
entry->GetInsertionParent(getter_AddRefs(content));
|
||||
entry->GetInsertionIndex(aIndex);
|
||||
entry->GetDefaultContent(aDefaultContent); // Addref happens here.
|
||||
nsCOMPtr<nsIContent> templContent;
|
||||
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
|
||||
LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent));
|
||||
|
@ -716,7 +728,8 @@ NS_IMETHODIMP
|
|||
nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement,
|
||||
nsIContent* aCopyRoot,
|
||||
nsIContent** aResult, PRUint32* aIndex,
|
||||
PRBool* aMultipleInsertionPoints)
|
||||
PRBool* aMultipleInsertionPoints,
|
||||
nsIContent** aDefaultContent)
|
||||
{
|
||||
if (mInsertionPointTable) {
|
||||
if(mInsertionPointTable->Count() == 1) {
|
||||
|
@ -728,6 +741,7 @@ nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement,
|
|||
nsCOMPtr<nsIContent> content;
|
||||
entry->GetInsertionParent(getter_AddRefs(content));
|
||||
entry->GetInsertionIndex(aIndex);
|
||||
entry->GetDefaultContent(aDefaultContent); // Addref happens here.
|
||||
nsCOMPtr<nsIContent> templContent;
|
||||
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
|
||||
LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent));
|
||||
|
@ -1109,6 +1123,14 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
|
|||
// binding instantiation will not contain a clone of the <children> element when
|
||||
// it clones the binding template.
|
||||
parent->RemoveChildAt(index, PR_FALSE);
|
||||
|
||||
// See if the insertion point contains default content. Default content must
|
||||
// be cached in our insertion point entry, since it will need to be cloned
|
||||
// in situations where no content ends up being placed at the insertion point.
|
||||
PRInt32 defaultCount;
|
||||
child->ChildCount(defaultCount);
|
||||
if (defaultCount > 0)
|
||||
xblIns->SetDefaultContent(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,10 +80,12 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding
|
|||
NS_IMETHOD InstantiateInsertionPoints(nsIXBLBinding* aBinding);
|
||||
|
||||
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||
nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex);
|
||||
nsIContent* aChild, nsIContent** aResult, PRUint32* aIndex,
|
||||
nsIContent** aDefaultContent);
|
||||
|
||||
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||
nsIContent** aResult, PRUint32* aIndex, PRBool* aMultiple);
|
||||
nsIContent** aResult, PRUint32* aIndex, PRBool* aMultiple,
|
||||
nsIContent** aDefaultContent);
|
||||
|
||||
NS_IMETHOD GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aTag);
|
||||
NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag);
|
||||
|
|
|
@ -251,7 +251,11 @@
|
|||
|
||||
<binding id="tree">
|
||||
<content>
|
||||
<children/>
|
||||
<children>
|
||||
<xul:treecolgroup>
|
||||
<xul:treecol flex="1"/>
|
||||
</xul:treecolgroup>
|
||||
</children>
|
||||
<xul:treerows class="tree-container-treerows" inherits="dragover,dragdroptree">
|
||||
<children includes="treehead|treechildren"/>
|
||||
</xul:treerows>
|
||||
|
|
Загрузка…
Ссылка в новой задаче