supporting multiple insertion points r=ben

This commit is contained in:
hyatt%netscape.com 2000-05-22 08:23:09 +00:00
Родитель 1f97f6d018
Коммит d3df058e84
12 изменённых файлов: 336 добавлений и 46 удалений

Просмотреть файл

@ -51,6 +51,10 @@ public:
NS_IMETHOD SetBinding(nsIContent* aContent, nsIXBLBinding* aBinding) = 0;
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult) = 0;
NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult) = 0;
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult,
PRBool* aMultipleInsertionPoints) = 0;
};
#endif // nsIBinding_Manager_h__

Просмотреть файл

@ -57,8 +57,6 @@ public:
NS_IMETHOD GetBindingElement(nsIContent** aResult) = 0;
NS_IMETHOD SetBindingElement(nsIContent* aElement) = 0;
NS_IMETHOD GetInsertionPoint(nsIContent** aResult) = 0;
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement) = 0;
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement) = 0;
NS_IMETHOD InstallProperties(nsIContent* aBoundElement) = 0;
@ -71,6 +69,9 @@ public:
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) = 0;
NS_IMETHOD GetBindingURI(nsString& aResult) = 0;
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult) = 0;
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleInsertionPoints) = 0;
};
extern nsresult

Просмотреть файл

@ -58,7 +58,8 @@ public:
// For a given element, returns a flat list of all the anonymous children that need
// frames built.
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement) = 0;
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement,
PRBool* aMultipleInsertionPoints) = 0;
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult) = 0;

Просмотреть файл

@ -65,6 +65,10 @@ public:
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult);
NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult);
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult,
PRBool* aMultipleInsertionPoints);
// MEMBER VARIABLES
protected:
nsSupportsHashtable* mBindingTable;
@ -144,6 +148,31 @@ nsBindingManager::ResolveTag(nsIContent* aContent, nsIAtom** aResult)
return aContent->GetTag(*aResult);
}
NS_IMETHODIMP
nsBindingManager::GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult)
{
nsCOMPtr<nsIXBLBinding> binding;
GetBinding(aParent, getter_AddRefs(binding));
if (binding)
return binding->GetInsertionPoint(aChild, aResult);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult,
PRBool* aMultipleInsertionPoints)
{
nsCOMPtr<nsIXBLBinding> binding;
GetBinding(aParent, getter_AddRefs(binding));
if (binding)
return binding->GetSingleInsertionPoint( aResult, aMultipleInsertionPoints);
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////
nsresult

Просмотреть файл

@ -145,8 +145,6 @@ class nsXBLBinding: public nsIXBLBinding, public nsIScriptObjectOwner
NS_IMETHOD GetBindingElement(nsIContent** aResult);
NS_IMETHOD SetBindingElement(nsIContent* aElement);
NS_IMETHOD GetInsertionPoint(nsIContent** aResult);
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement);
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement);
NS_IMETHOD InstallProperties(nsIContent* aBoundElement);
@ -158,6 +156,9 @@ class nsXBLBinding: public nsIXBLBinding, public nsIScriptObjectOwner
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument);
NS_IMETHOD GetBindingURI(nsString& aResult);
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult);
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleInsertionPoints);
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
@ -180,6 +181,7 @@ public:
static nsIAtom* kInterfaceAtom;
static nsIAtom* kHandlersAtom;
static nsIAtom* kExcludesAtom;
static nsIAtom* kIncludesAtom;
static nsIAtom* kInheritsAtom;
static nsIAtom* kTypeAtom;
static nsIAtom* kCapturerAtom;
@ -214,6 +216,9 @@ protected:
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
void GetNestedChild(nsIAtom* aTag, nsIContent* aContent, nsIContent** aResult);
void GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, nsISupportsArray* aList);
void BuildInsertionTable();
void GetNestedChildren();
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
NS_IMETHOD ConstructAttributeTable(nsIContent* aElement);
@ -230,12 +235,12 @@ protected:
nsCOMPtr<nsIContent> mBinding; // Strong. As long as we're around, the binding can't go away.
nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
nsCOMPtr<nsIContent> mChildrenElement; // Strong. One of our anonymous content children.
void* mScriptObject; // Strong
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
nsSupportsHashtable* mAttributeTable; // A table for attribute entries.
nsSupportsHashtable* mInsertionPointTable; // A table of insertion points.
};
// Static initialization
@ -245,6 +250,7 @@ nsIAtom* nsXBLBinding::kContentAtom = nsnull;
nsIAtom* nsXBLBinding::kInterfaceAtom = nsnull;
nsIAtom* nsXBLBinding::kHandlersAtom = nsnull;
nsIAtom* nsXBLBinding::kExcludesAtom = nsnull;
nsIAtom* nsXBLBinding::kIncludesAtom = nsnull;
nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
nsIAtom* nsXBLBinding::kTypeAtom = nsnull;
nsIAtom* nsXBLBinding::kCapturerAtom = nsnull;
@ -319,7 +325,8 @@ NS_IMPL_ISUPPORTS2(nsXBLBinding, nsIXBLBinding, nsIScriptObjectOwner)
// Constructors/Destructors
nsXBLBinding::nsXBLBinding(void)
: mScriptObject(nsnull),
mAttributeTable(nsnull)
mAttributeTable(nsnull),
mInsertionPointTable(nsnull)
{
NS_INIT_REFCNT();
gRefCnt++;
@ -328,6 +335,7 @@ nsXBLBinding::nsXBLBinding(void)
kInterfaceAtom = NS_NewAtom("interface");
kHandlersAtom = NS_NewAtom("handlers");
kExcludesAtom = NS_NewAtom("excludes");
kIncludesAtom = NS_NewAtom("includes");
kInheritsAtom = NS_NewAtom("inherits");
kTypeAtom = NS_NewAtom("type");
kCapturerAtom = NS_NewAtom("capturer");
@ -362,6 +370,7 @@ nsXBLBinding::nsXBLBinding(void)
nsXBLBinding::~nsXBLBinding(void)
{
delete mAttributeTable;
delete mInsertionPointTable;
gRefCnt--;
if (gRefCnt == 0) {
@ -369,6 +378,7 @@ nsXBLBinding::~nsXBLBinding(void)
NS_RELEASE(kInterfaceAtom);
NS_RELEASE(kHandlersAtom);
NS_RELEASE(kExcludesAtom);
NS_RELEASE(kIncludesAtom);
NS_RELEASE(kInheritsAtom);
NS_RELEASE(kTypeAtom);
NS_RELEASE(kCapturerAtom);
@ -468,14 +478,6 @@ nsXBLBinding::SetBindingElement(nsIContent* aElement)
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GetInsertionPoint(nsIContent** aResult)
{
*aResult = mChildrenElement;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
{
@ -569,9 +571,8 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
SetAnonymousContent(clonedContent);
if (childrenElement) {
GetNestedChild(kChildrenAtom, clonedContent, getter_AddRefs(mChildrenElement));
}
if (childrenElement)
BuildInsertionTable();
}
if (mNextBinding) {
@ -1215,10 +1216,76 @@ nsXBLBinding::GetNestedChild(nsIAtom* aTag, nsIContent* aContent, nsIContent** a
return;
}
}
return;
}
void
nsXBLBinding::GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, nsISupportsArray* aList)
{
PRInt32 childCount;
aContent->ChildCount(childCount);
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
aContent->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (aTag == tag.get())
aList->AppendElement(child);
else
GetNestedChildren(aTag, child, aList);
}
}
void
nsXBLBinding::BuildInsertionTable()
{
if (!mInsertionPointTable)
mInsertionPointTable = new nsSupportsHashtable;
nsCOMPtr<nsISupportsArray> childrenElements;
NS_NewISupportsArray(getter_AddRefs(childrenElements));
GetNestedChildren(kChildrenAtom, mContent, childrenElements);
PRUint32 count;
childrenElements->Count(&count);
for (PRUint32 i = 0; i < count; i++) {
nsCOMPtr<nsISupports> supp;
childrenElements->GetElementAt(i, getter_AddRefs(supp));
nsCOMPtr<nsIContent> child(do_QueryInterface(supp));
if (child) {
nsCOMPtr<nsIContent> parent;
child->GetParent(*getter_AddRefs(parent));
nsAutoString includes;
child->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
if (includes.IsEmpty()) {
nsISupportsKey key(kChildrenAtom);
mInsertionPointTable->Put(&key, parent);
}
else {
// The user specified at least one attribute.
char* str = includes.ToNewCString();
char* newStr;
// XXX We should use a strtok function that tokenizes PRUnichar's
// so that we don't have to convert from Unicode to ASCII and then back
char* token = nsCRT::strtok( str, ", ", &newStr );
while( token != NULL ) {
// Build an atom out of this string.
nsCOMPtr<nsIAtom> atom;
nsAutoString tok; tok.AssignWithConversion(token);
atom = getter_AddRefs(NS_NewAtom(tok.GetUnicode()));
nsISupportsKey key(atom);
mInsertionPointTable->Put(&key, parent);
token = nsCRT::strtok( newStr, ", ", &newStr );
}
nsAllocator::Free(str);
}
}
}
}
PRBool
nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
@ -1478,6 +1545,46 @@ nsXBLBinding::AllowScripts()
return PR_FALSE;
}
NS_IMETHODIMP
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult)
{
*aResult = nsnull;
if (mInsertionPointTable) {
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(*getter_AddRefs(tag));
nsISupportsKey key(tag);
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
mInsertionPointTable->Get(&key)));
if (!content) {
nsISupportsKey key2(kChildrenAtom);
content = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mInsertionPointTable->Get(&key2)));
}
*aResult = content;
NS_IF_ADDREF(*aResult);
}
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleInsertionPoints)
{
*aResult = nsnull;
*aMultipleInsertionPoints = PR_FALSE;
if (mInsertionPointTable) {
if(mInsertionPointTable->Count() == 1) {
nsISupportsKey key(kChildrenAtom);
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
mInsertionPointTable->Get(&key)));
*aResult = content;
NS_IF_ADDREF(*aResult);
}
else
*aMultipleInsertionPoints = PR_TRUE;
}
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////
nsresult

Просмотреть файл

@ -127,7 +127,8 @@ class nsXBLService: public nsIXBLService
// For a given element, returns a flat list of all the anonymous children that need
// frames built.
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement);
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement,
PRBool* aMultipleInsertionPoints);
// Gets the object's base class type.
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult);
@ -290,12 +291,14 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsString& aURL)
// For a given element, returns a flat list of all the anonymous children that need
// frames built.
NS_IMETHODIMP
nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aParent)
nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aParent,
PRBool* aMultipleInsertionPoints)
{
// Iterate over all of the bindings one by one and build up an array
// of anonymous items.
*aResult = nsnull;
*aParent = nsnull;
*aMultipleInsertionPoints = PR_FALSE;
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
@ -323,7 +326,7 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult, n
(*aResult)->AppendElement(anonymousChild);
}
binding->GetInsertionPoint(aParent);
binding->GetSingleInsertionPoint(aParent, aMultipleInsertionPoints);
return NS_OK;
}

Просмотреть файл

@ -51,6 +51,10 @@ public:
NS_IMETHOD SetBinding(nsIContent* aContent, nsIXBLBinding* aBinding) = 0;
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult) = 0;
NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult) = 0;
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult,
PRBool* aMultipleInsertionPoints) = 0;
};
#endif // nsIBinding_Manager_h__

Просмотреть файл

@ -57,8 +57,6 @@ public:
NS_IMETHOD GetBindingElement(nsIContent** aResult) = 0;
NS_IMETHOD SetBindingElement(nsIContent* aElement) = 0;
NS_IMETHOD GetInsertionPoint(nsIContent** aResult) = 0;
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement) = 0;
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement) = 0;
NS_IMETHOD InstallProperties(nsIContent* aBoundElement) = 0;
@ -71,6 +69,9 @@ public:
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) = 0;
NS_IMETHOD GetBindingURI(nsString& aResult) = 0;
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult) = 0;
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleInsertionPoints) = 0;
};
extern nsresult

Просмотреть файл

@ -58,7 +58,8 @@ public:
// For a given element, returns a flat list of all the anonymous children that need
// frames built.
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement) = 0;
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement,
PRBool* aMultipleInsertionPoints) = 0;
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult) = 0;

Просмотреть файл

@ -65,6 +65,10 @@ public:
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult);
NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult);
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult,
PRBool* aMultipleInsertionPoints);
// MEMBER VARIABLES
protected:
nsSupportsHashtable* mBindingTable;
@ -144,6 +148,31 @@ nsBindingManager::ResolveTag(nsIContent* aContent, nsIAtom** aResult)
return aContent->GetTag(*aResult);
}
NS_IMETHODIMP
nsBindingManager::GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult)
{
nsCOMPtr<nsIXBLBinding> binding;
GetBinding(aParent, getter_AddRefs(binding));
if (binding)
return binding->GetInsertionPoint(aChild, aResult);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::GetSingleInsertionPoint(nsIContent* aParent, nsIContent** aResult,
PRBool* aMultipleInsertionPoints)
{
nsCOMPtr<nsIXBLBinding> binding;
GetBinding(aParent, getter_AddRefs(binding));
if (binding)
return binding->GetSingleInsertionPoint( aResult, aMultipleInsertionPoints);
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////
nsresult

Просмотреть файл

@ -145,8 +145,6 @@ class nsXBLBinding: public nsIXBLBinding, public nsIScriptObjectOwner
NS_IMETHOD GetBindingElement(nsIContent** aResult);
NS_IMETHOD SetBindingElement(nsIContent* aElement);
NS_IMETHOD GetInsertionPoint(nsIContent** aResult);
NS_IMETHOD GenerateAnonymousContent(nsIContent* aBoundElement);
NS_IMETHOD InstallEventHandlers(nsIContent* aBoundElement);
NS_IMETHOD InstallProperties(nsIContent* aBoundElement);
@ -158,6 +156,9 @@ class nsXBLBinding: public nsIXBLBinding, public nsIScriptObjectOwner
NS_IMETHOD ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument);
NS_IMETHOD GetBindingURI(nsString& aResult);
NS_IMETHOD GetInsertionPoint(nsIContent* aChild, nsIContent** aResult);
NS_IMETHOD GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleInsertionPoints);
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
@ -180,6 +181,7 @@ public:
static nsIAtom* kInterfaceAtom;
static nsIAtom* kHandlersAtom;
static nsIAtom* kExcludesAtom;
static nsIAtom* kIncludesAtom;
static nsIAtom* kInheritsAtom;
static nsIAtom* kTypeAtom;
static nsIAtom* kCapturerAtom;
@ -214,6 +216,9 @@ protected:
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
void GetNestedChild(nsIAtom* aTag, nsIContent* aContent, nsIContent** aResult);
void GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, nsISupportsArray* aList);
void BuildInsertionTable();
void GetNestedChildren();
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
NS_IMETHOD ConstructAttributeTable(nsIContent* aElement);
@ -230,12 +235,12 @@ protected:
nsCOMPtr<nsIContent> mBinding; // Strong. As long as we're around, the binding can't go away.
nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
nsCOMPtr<nsIContent> mChildrenElement; // Strong. One of our anonymous content children.
void* mScriptObject; // Strong
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
nsSupportsHashtable* mAttributeTable; // A table for attribute entries.
nsSupportsHashtable* mInsertionPointTable; // A table of insertion points.
};
// Static initialization
@ -245,6 +250,7 @@ nsIAtom* nsXBLBinding::kContentAtom = nsnull;
nsIAtom* nsXBLBinding::kInterfaceAtom = nsnull;
nsIAtom* nsXBLBinding::kHandlersAtom = nsnull;
nsIAtom* nsXBLBinding::kExcludesAtom = nsnull;
nsIAtom* nsXBLBinding::kIncludesAtom = nsnull;
nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
nsIAtom* nsXBLBinding::kTypeAtom = nsnull;
nsIAtom* nsXBLBinding::kCapturerAtom = nsnull;
@ -319,7 +325,8 @@ NS_IMPL_ISUPPORTS2(nsXBLBinding, nsIXBLBinding, nsIScriptObjectOwner)
// Constructors/Destructors
nsXBLBinding::nsXBLBinding(void)
: mScriptObject(nsnull),
mAttributeTable(nsnull)
mAttributeTable(nsnull),
mInsertionPointTable(nsnull)
{
NS_INIT_REFCNT();
gRefCnt++;
@ -328,6 +335,7 @@ nsXBLBinding::nsXBLBinding(void)
kInterfaceAtom = NS_NewAtom("interface");
kHandlersAtom = NS_NewAtom("handlers");
kExcludesAtom = NS_NewAtom("excludes");
kIncludesAtom = NS_NewAtom("includes");
kInheritsAtom = NS_NewAtom("inherits");
kTypeAtom = NS_NewAtom("type");
kCapturerAtom = NS_NewAtom("capturer");
@ -362,6 +370,7 @@ nsXBLBinding::nsXBLBinding(void)
nsXBLBinding::~nsXBLBinding(void)
{
delete mAttributeTable;
delete mInsertionPointTable;
gRefCnt--;
if (gRefCnt == 0) {
@ -369,6 +378,7 @@ nsXBLBinding::~nsXBLBinding(void)
NS_RELEASE(kInterfaceAtom);
NS_RELEASE(kHandlersAtom);
NS_RELEASE(kExcludesAtom);
NS_RELEASE(kIncludesAtom);
NS_RELEASE(kInheritsAtom);
NS_RELEASE(kTypeAtom);
NS_RELEASE(kCapturerAtom);
@ -468,14 +478,6 @@ nsXBLBinding::SetBindingElement(nsIContent* aElement)
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GetInsertionPoint(nsIContent** aResult)
{
*aResult = mChildrenElement;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
{
@ -569,9 +571,8 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
SetAnonymousContent(clonedContent);
if (childrenElement) {
GetNestedChild(kChildrenAtom, clonedContent, getter_AddRefs(mChildrenElement));
}
if (childrenElement)
BuildInsertionTable();
}
if (mNextBinding) {
@ -1215,10 +1216,76 @@ nsXBLBinding::GetNestedChild(nsIAtom* aTag, nsIContent* aContent, nsIContent** a
return;
}
}
return;
}
void
nsXBLBinding::GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, nsISupportsArray* aList)
{
PRInt32 childCount;
aContent->ChildCount(childCount);
for (PRInt32 i = 0; i < childCount; i++) {
nsCOMPtr<nsIContent> child;
aContent->ChildAt(i, *getter_AddRefs(child));
nsCOMPtr<nsIAtom> tag;
child->GetTag(*getter_AddRefs(tag));
if (aTag == tag.get())
aList->AppendElement(child);
else
GetNestedChildren(aTag, child, aList);
}
}
void
nsXBLBinding::BuildInsertionTable()
{
if (!mInsertionPointTable)
mInsertionPointTable = new nsSupportsHashtable;
nsCOMPtr<nsISupportsArray> childrenElements;
NS_NewISupportsArray(getter_AddRefs(childrenElements));
GetNestedChildren(kChildrenAtom, mContent, childrenElements);
PRUint32 count;
childrenElements->Count(&count);
for (PRUint32 i = 0; i < count; i++) {
nsCOMPtr<nsISupports> supp;
childrenElements->GetElementAt(i, getter_AddRefs(supp));
nsCOMPtr<nsIContent> child(do_QueryInterface(supp));
if (child) {
nsCOMPtr<nsIContent> parent;
child->GetParent(*getter_AddRefs(parent));
nsAutoString includes;
child->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
if (includes.IsEmpty()) {
nsISupportsKey key(kChildrenAtom);
mInsertionPointTable->Put(&key, parent);
}
else {
// The user specified at least one attribute.
char* str = includes.ToNewCString();
char* newStr;
// XXX We should use a strtok function that tokenizes PRUnichar's
// so that we don't have to convert from Unicode to ASCII and then back
char* token = nsCRT::strtok( str, ", ", &newStr );
while( token != NULL ) {
// Build an atom out of this string.
nsCOMPtr<nsIAtom> atom;
nsAutoString tok; tok.AssignWithConversion(token);
atom = getter_AddRefs(NS_NewAtom(tok.GetUnicode()));
nsISupportsKey key(atom);
mInsertionPointTable->Put(&key, parent);
token = nsCRT::strtok( newStr, ", ", &newStr );
}
nsAllocator::Free(str);
}
}
}
}
PRBool
nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
@ -1478,6 +1545,46 @@ nsXBLBinding::AllowScripts()
return PR_FALSE;
}
NS_IMETHODIMP
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult)
{
*aResult = nsnull;
if (mInsertionPointTable) {
nsCOMPtr<nsIAtom> tag;
aChild->GetTag(*getter_AddRefs(tag));
nsISupportsKey key(tag);
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
mInsertionPointTable->Get(&key)));
if (!content) {
nsISupportsKey key2(kChildrenAtom);
content = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mInsertionPointTable->Get(&key2)));
}
*aResult = content;
NS_IF_ADDREF(*aResult);
}
return NS_OK;
}
NS_IMETHODIMP
nsXBLBinding::GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleInsertionPoints)
{
*aResult = nsnull;
*aMultipleInsertionPoints = PR_FALSE;
if (mInsertionPointTable) {
if(mInsertionPointTable->Count() == 1) {
nsISupportsKey key(kChildrenAtom);
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
mInsertionPointTable->Get(&key)));
*aResult = content;
NS_IF_ADDREF(*aResult);
}
else
*aMultipleInsertionPoints = PR_TRUE;
}
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////
nsresult

Просмотреть файл

@ -127,7 +127,8 @@ class nsXBLService: public nsIXBLService
// For a given element, returns a flat list of all the anonymous children that need
// frames built.
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement);
NS_IMETHOD GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aChildElement,
PRBool* aMultipleInsertionPoints);
// Gets the object's base class type.
NS_IMETHOD ResolveTag(nsIContent* aContent, nsIAtom** aResult);
@ -290,12 +291,14 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsString& aURL)
// For a given element, returns a flat list of all the anonymous children that need
// frames built.
NS_IMETHODIMP
nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aParent)
nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult, nsIContent** aParent,
PRBool* aMultipleInsertionPoints)
{
// Iterate over all of the bindings one by one and build up an array
// of anonymous items.
*aResult = nsnull;
*aParent = nsnull;
*aMultipleInsertionPoints = PR_FALSE;
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
@ -323,7 +326,7 @@ nsXBLService::GetContentList(nsIContent* aContent, nsISupportsArray** aResult, n
(*aResult)->AppendElement(anonymousChild);
}
binding->GetInsertionPoint(aParent);
binding->GetSingleInsertionPoint(aParent, aMultipleInsertionPoints);
return NS_OK;
}