зеркало из https://github.com/mozilla/gecko-dev.git
Fix for 53417. r=brendan, a=brendan
This commit is contained in:
Родитель
8e3f2ce2da
Коммит
bc40a1821f
|
@ -79,7 +79,7 @@ CSS_PROP(background-position, background_position, VISUAL)
|
||||||
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
||||||
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-moz-binding, behavior, REFLOW) // XXX bug 3935
|
CSS_PROP(-moz-binding, behavior, FRAMECHANGE) // XXX bug 3935
|
||||||
CSS_PROP(border, border, REFLOW)
|
CSS_PROP(border, border, REFLOW)
|
||||||
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
||||||
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
||||||
|
|
|
@ -79,7 +79,7 @@ CSS_PROP(background-position, background_position, VISUAL)
|
||||||
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
||||||
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-moz-binding, behavior, REFLOW) // XXX bug 3935
|
CSS_PROP(-moz-binding, behavior, FRAMECHANGE) // XXX bug 3935
|
||||||
CSS_PROP(border, border, REFLOW)
|
CSS_PROP(border, border, REFLOW)
|
||||||
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
||||||
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
||||||
|
|
|
@ -33,6 +33,7 @@ EXPORTS = \
|
||||||
nsIXBLBinding.h \
|
nsIXBLBinding.h \
|
||||||
nsIXBLBindingAttachedHandler.h \
|
nsIXBLBindingAttachedHandler.h \
|
||||||
nsIXBLDocumentInfo.h \
|
nsIXBLDocumentInfo.h \
|
||||||
|
nsIXBLPrototypeBinding.h \
|
||||||
nsIXBLPrototypeHandler.h \
|
nsIXBLPrototypeHandler.h \
|
||||||
nsIXBLService.h \
|
nsIXBLService.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -2,6 +2,6 @@ nsIBindingManager.h
|
||||||
nsIXBLBinding.h
|
nsIXBLBinding.h
|
||||||
nsIXBLBindingAttachedHandler.h
|
nsIXBLBindingAttachedHandler.h
|
||||||
nsIXBLDocumentInfo.h
|
nsIXBLDocumentInfo.h
|
||||||
|
nsIXBLPrototypeBinding.h
|
||||||
nsIXBLPrototypeHandler.h
|
nsIXBLPrototypeHandler.h
|
||||||
nsIXBLService.h
|
nsIXBLService.h
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ EXPORTS = \
|
||||||
nsIXBLBinding.h \
|
nsIXBLBinding.h \
|
||||||
nsIXBLBindingAttachedHandler.h \
|
nsIXBLBindingAttachedHandler.h \
|
||||||
nsIXBLDocumentInfo.h \
|
nsIXBLDocumentInfo.h \
|
||||||
|
nsIXBLPrototypeBinding.h \
|
||||||
nsIXBLPrototypeHandler.h \
|
nsIXBLPrototypeHandler.h \
|
||||||
nsIXBLService.h \
|
nsIXBLService.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
|
class nsIXBLPrototypeBinding;
|
||||||
|
|
||||||
// {DDDBAD20-C8DF-11d3-97FB-00400553EEF0}
|
// {DDDBAD20-C8DF-11d3-97FB-00400553EEF0}
|
||||||
#define NS_IXBLBINDING_IID \
|
#define NS_IXBLBINDING_IID \
|
||||||
|
@ -48,6 +49,9 @@ class nsIXBLBinding : public nsISupports
|
||||||
public:
|
public:
|
||||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLBINDING_IID; return iid; }
|
static const nsIID& GetIID() { static nsIID iid = NS_IXBLBINDING_IID; return iid; }
|
||||||
|
|
||||||
|
NS_IMETHOD GetPrototypeBinding(nsIXBLPrototypeBinding** aResult)=0;
|
||||||
|
NS_IMETHOD SetPrototypeBinding(nsIXBLPrototypeBinding* aProtoBinding)=0;
|
||||||
|
|
||||||
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult) = 0;
|
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult) = 0;
|
||||||
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding) = 0;
|
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding) = 0;
|
||||||
|
|
||||||
|
@ -92,13 +96,11 @@ public:
|
||||||
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
||||||
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)=0;
|
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)=0;
|
||||||
|
|
||||||
NS_IMETHOD SetAllowScripts(PRBool aFlag)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD MarkForDeath()=0;
|
NS_IMETHOD MarkForDeath()=0;
|
||||||
NS_IMETHOD MarkedForDeath(PRBool* aResult)=0;
|
NS_IMETHOD MarkedForDeath(PRBool* aResult)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsresult
|
extern nsresult
|
||||||
NS_NewXBLBinding(const nsCString& aDocURI, const nsCString& aID, nsIXBLBinding** aResult);
|
NS_NewXBLBinding(nsIXBLPrototypeBinding* aProtoBinding, nsIXBLBinding** aResult);
|
||||||
|
|
||||||
#endif // nsIXBLBinding_h__
|
#endif // nsIXBLBinding_h__
|
||||||
|
|
|
@ -39,6 +39,7 @@ class nsIContent;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
class nsIXBLPrototypeHandler;
|
class nsIXBLPrototypeHandler;
|
||||||
|
class nsIXBLPrototypeBinding;
|
||||||
|
|
||||||
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
|
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
|
||||||
#define NS_IXBLDOCUMENTINFO_IID \
|
#define NS_IXBLDOCUMENTINFO_IID \
|
||||||
|
@ -55,8 +56,10 @@ public:
|
||||||
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
|
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
|
||||||
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
|
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
|
||||||
|
|
||||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)=0;
|
NS_IMETHOD GetDocumentURI(nsCString& aDocURI)=0;
|
||||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)=0;
|
|
||||||
|
NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult)=0;
|
||||||
|
NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsresult
|
extern nsresult
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS
|
||||||
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||||
|
* implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||||||
|
* Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef nsIXBLPrototypeBinding_h__
|
||||||
|
#define nsIXBLPrototypeBinding_h__
|
||||||
|
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
class nsIContent;
|
||||||
|
class nsIDocument;
|
||||||
|
class nsIXBLDocumentInfo;
|
||||||
|
class nsIXBLPrototypeHandler;
|
||||||
|
|
||||||
|
// {34D700F5-C1A2-4408-A0B1-DD8F891DD1FE}
|
||||||
|
#define NS_IXBLPROTOTYPEBINDING_IID \
|
||||||
|
{ 0x34d700f5, 0xc1a2, 0x4408, { 0xa0, 0xb1, 0xdd, 0x8f, 0x89, 0x1d, 0xd1, 0xfe } }
|
||||||
|
|
||||||
|
class nsIXBLPrototypeBinding : public nsISupports
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const nsIID& GetIID() { static nsIID iid = NS_IXBLPROTOTYPEBINDING_IID; return iid; }
|
||||||
|
|
||||||
|
NS_IMETHOD GetBindingElement(nsIContent** aResult)=0;
|
||||||
|
NS_IMETHOD SetBindingElement(nsIContent* aElement)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetBindingURI(nsCString& aResult)=0;
|
||||||
|
NS_IMETHOD GetDocURI(nsCString& aResult)=0;
|
||||||
|
NS_IMETHOD GetID(nsCString& aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetAllowScripts(PRBool* aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler)=0;
|
||||||
|
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||||
|
nsIContent* aChangedElement, nsIContent* aAnonymousContent)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD SetBasePrototype(nsIXBLPrototypeBinding* aBinding)=0;
|
||||||
|
NS_IMETHOD GetBasePrototype(nsIXBLPrototypeBinding** aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD HasBasePrototype(PRBool* aResult)=0;
|
||||||
|
NS_IMETHOD SetHasBasePrototype(PRBool aHasBase)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetXBLDocumentInfo(nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD HasInsertionPoints(PRBool* aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aChild, nsIContent** aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent** aResult, PRBool* aMultipleInsertionPoints)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aTag)=0;
|
||||||
|
NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern nsresult
|
||||||
|
NS_NewXBLPrototypeBinding(const nsCString& aRef,
|
||||||
|
nsIContent* aElement, nsIXBLDocumentInfo* aInfo,
|
||||||
|
nsIXBLPrototypeBinding** aResult);
|
||||||
|
|
||||||
|
#endif // nsIXBLPrototypeBinding_h__
|
|
@ -28,6 +28,7 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
CPPSRCS= \
|
CPPSRCS= \
|
||||||
nsXBLBinding.cpp \
|
nsXBLBinding.cpp \
|
||||||
|
nsXBLPrototypeBinding.cpp \
|
||||||
nsXBLService.cpp \
|
nsXBLService.cpp \
|
||||||
nsXBLEventHandler.cpp \
|
nsXBLEventHandler.cpp \
|
||||||
nsXBLWindowKeyHandler.cpp \
|
nsXBLWindowKeyHandler.cpp \
|
||||||
|
@ -46,6 +47,7 @@ CPPSRCS= \
|
||||||
|
|
||||||
CPP_OBJS= \
|
CPP_OBJS= \
|
||||||
.\$(OBJDIR)\nsXBLBinding.obj \
|
.\$(OBJDIR)\nsXBLBinding.obj \
|
||||||
|
.\$(OBJDIR)\nsXBLPrototypeBinding.obj \
|
||||||
.\$(OBJDIR)\nsXBLEventHandler.obj \
|
.\$(OBJDIR)\nsXBLEventHandler.obj \
|
||||||
.\$(OBJDIR)\nsXBLWindowKeyHandler.obj \
|
.\$(OBJDIR)\nsXBLWindowKeyHandler.obj \
|
||||||
.\$(OBJDIR)\nsXBLKeyHandler.obj \
|
.\$(OBJDIR)\nsXBLKeyHandler.obj \
|
||||||
|
|
|
@ -58,19 +58,20 @@
|
||||||
|
|
||||||
#include "nsIStyleRuleProcessor.h"
|
#include "nsIStyleRuleProcessor.h"
|
||||||
#include "nsIStyleSet.h"
|
#include "nsIStyleSet.h"
|
||||||
#include "nsIXBLPrototypeHandler.h"
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
#include "nsIWeakReference.h"
|
||||||
|
|
||||||
// Static IIDs/CIDs. Try to minimize these.
|
// Static IIDs/CIDs. Try to minimize these.
|
||||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||||
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
||||||
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX What's up with this???
|
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX What's up with this???
|
||||||
|
|
||||||
class nsXBLDocumentInfo : public nsIXBLDocumentInfo
|
class nsXBLDocumentInfo : public nsIXBLDocumentInfo, public nsSupportsWeakReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
nsXBLDocumentInfo(nsIDocument* aDocument);
|
nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument);
|
||||||
virtual ~nsXBLDocumentInfo();
|
virtual ~nsXBLDocumentInfo();
|
||||||
|
|
||||||
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
|
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
@ -79,32 +80,36 @@ public:
|
||||||
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
|
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
|
||||||
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
|
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
|
||||||
|
|
||||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult);
|
NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; };
|
||||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler);
|
|
||||||
|
NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult);
|
||||||
|
NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<nsIDocument> mDocument;
|
nsCOMPtr<nsIDocument> mDocument;
|
||||||
|
nsCString mDocURI;
|
||||||
nsCOMPtr<nsISupportsArray> mRuleProcessors;
|
nsCOMPtr<nsISupportsArray> mRuleProcessors;
|
||||||
PRBool mScriptAccess;
|
PRBool mScriptAccess;
|
||||||
nsSupportsHashtable* mHandlerTable;
|
nsSupportsHashtable* mBindingTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Implementation file */
|
/* Implementation file */
|
||||||
NS_IMPL_ISUPPORTS1(nsXBLDocumentInfo, nsIXBLDocumentInfo)
|
NS_IMPL_ISUPPORTS2(nsXBLDocumentInfo, nsIXBLDocumentInfo, nsISupportsWeakReference)
|
||||||
|
|
||||||
nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
|
nsXBLDocumentInfo::nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument)
|
||||||
{
|
{
|
||||||
NS_INIT_ISUPPORTS();
|
NS_INIT_ISUPPORTS();
|
||||||
/* member initializers and constructor code */
|
/* member initializers and constructor code */
|
||||||
|
mDocURI = aDocURI;
|
||||||
mDocument = aDocument;
|
mDocument = aDocument;
|
||||||
mScriptAccess = PR_TRUE;
|
mScriptAccess = PR_TRUE;
|
||||||
mHandlerTable = nsnull;
|
mBindingTable = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
||||||
{
|
{
|
||||||
/* destructor code */
|
/* destructor code */
|
||||||
delete mHandlerTable;
|
delete mBindingTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -144,33 +149,39 @@ nsXBLDocumentInfo::GetRuleProcessors(nsISupportsArray** aResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLDocumentInfo::GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)
|
nsXBLDocumentInfo::GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult)
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
if (!mHandlerTable)
|
if (!mBindingTable)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsCStringKey key(aRef);
|
nsCStringKey key(aRef);
|
||||||
*aResult = NS_STATIC_CAST(nsIXBLPrototypeHandler*, mHandlerTable->Get(&key)); // Addref happens here.
|
*aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here.
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLDocumentInfo::SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)
|
nsXBLDocumentInfo::SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding)
|
||||||
{
|
{
|
||||||
if (!mHandlerTable)
|
if (!mBindingTable)
|
||||||
mHandlerTable = new nsSupportsHashtable();
|
mBindingTable = new nsSupportsHashtable();
|
||||||
|
|
||||||
nsCStringKey key(aRef);
|
nsCStringKey key(aRef);
|
||||||
mHandlerTable->Put(&key, aHandler);
|
mBindingTable->Put(&key, aBinding);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
|
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
|
||||||
{
|
{
|
||||||
*aResult = new nsXBLDocumentInfo(aDocument);
|
nsCOMPtr<nsIURI> url = getter_AddRefs(aDocument->GetDocumentURL());
|
||||||
|
|
||||||
|
nsXPIDLCString str;
|
||||||
|
url->GetSpec(getter_Copies(str));
|
||||||
|
|
||||||
|
*aResult = new nsXBLDocumentInfo((const char*)str, aDocument);
|
||||||
|
|
||||||
NS_IF_ADDREF(*aResult);
|
NS_IF_ADDREF(*aResult);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -683,10 +694,7 @@ nsBindingManager::RemoveLoadingDocListener(const nsCString& aURL)
|
||||||
PRBool PR_CALLBACK MarkForDeath(nsHashKey* aKey, void* aData, void* aClosure)
|
PRBool PR_CALLBACK MarkForDeath(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
{
|
{
|
||||||
nsIXBLBinding* binding = (nsIXBLBinding*)aData;
|
nsIXBLBinding* binding = (nsIXBLBinding*)aData;
|
||||||
nsCAutoString docURI;
|
binding->MarkForDeath();
|
||||||
binding->GetDocURI(docURI);
|
|
||||||
if (!docURI.CompareWithConversion("chrome", PR_FALSE, 6))
|
|
||||||
binding->MarkForDeath();
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,51 +85,6 @@
|
||||||
static char kNameSpaceSeparator = ':';
|
static char kNameSpaceSeparator = ':';
|
||||||
|
|
||||||
// Helper classes
|
// Helper classes
|
||||||
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
|
||||||
#define NS_IXBLATTR_IID \
|
|
||||||
{ 0xa2892b81, 0xced9, 0x11d3, { 0x97, 0xfb, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
|
||||||
|
|
||||||
class nsIXBLAttributeEntry : public nsISupports {
|
|
||||||
public:
|
|
||||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLATTR_IID; return iid; }
|
|
||||||
|
|
||||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) = 0;
|
|
||||||
NS_IMETHOD GetElement(nsIContent** aResult) = 0;
|
|
||||||
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) = 0;
|
|
||||||
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class nsXBLAttributeEntry : public nsIXBLAttributeEntry {
|
|
||||||
public:
|
|
||||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) { *aResult = mAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
|
||||||
NS_IMETHOD GetElement(nsIContent** aResult) { *aResult = mElement; NS_IF_ADDREF(*aResult); return NS_OK; };
|
|
||||||
|
|
||||||
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) { NS_IF_ADDREF(*aResult = mNext); return NS_OK; }
|
|
||||||
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) { mNext = aEntry; return NS_OK; }
|
|
||||||
|
|
||||||
nsIContent* mElement;
|
|
||||||
nsCOMPtr<nsIAtom> mAttribute;
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> mNext;
|
|
||||||
|
|
||||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
|
||||||
return aAllocator.Alloc(aSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void operator delete(void* aPtr, size_t aSize) {
|
|
||||||
nsFixedSizeAllocator::Free(aPtr, aSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsXBLAttributeEntry(nsIAtom* aAtom, nsIContent* aContent) {
|
|
||||||
NS_INIT_REFCNT(); mAttribute = aAtom; mElement = aContent;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~nsXBLAttributeEntry() {};
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
//
|
//
|
||||||
|
@ -193,10 +148,7 @@ nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kEventAtom = nsnull;
|
nsIAtom* nsXBLBinding::kEventAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kPhaseAtom = nsnull;
|
nsIAtom* nsXBLBinding::kPhaseAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
|
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kChildrenAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLBinding::kValueAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLBinding::kActionAtom = nsnull;
|
nsIAtom* nsXBLBinding::kActionAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kHTMLAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLBinding::kMethodAtom = nsnull;
|
nsIAtom* nsXBLBinding::kMethodAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kParameterAtom = nsnull;
|
nsIAtom* nsXBLBinding::kParameterAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kBodyAtom = nsnull;
|
nsIAtom* nsXBLBinding::kBodyAtom = nsnull;
|
||||||
|
@ -210,19 +162,6 @@ nsIAtom* nsXBLBinding::kReadOnlyAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
|
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kBindingAttachedAtom = nsnull;
|
nsIAtom* nsXBLBinding::kBindingAttachedAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kBindingDetachedAtom = nsnull;
|
nsIAtom* nsXBLBinding::kBindingDetachedAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kInheritStyleAtom = nsnull;
|
|
||||||
|
|
||||||
nsIXBLService* nsXBLBinding::gXBLService = nsnull;
|
|
||||||
|
|
||||||
nsFixedSizeAllocator nsXBLBinding::kPool;
|
|
||||||
|
|
||||||
static const size_t kBucketSizes[] = {
|
|
||||||
sizeof(nsXBLAttributeEntry)
|
|
||||||
};
|
|
||||||
|
|
||||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes)/sizeof(size_t);
|
|
||||||
static const PRInt32 kNumElements = 128;
|
|
||||||
static const PRInt32 kInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLAttributeEntry))) * kNumElements;
|
|
||||||
|
|
||||||
nsXBLBinding::EventHandlerMapEntry
|
nsXBLBinding::EventHandlerMapEntry
|
||||||
nsXBLBinding::kEventHandlerMap[] = {
|
nsXBLBinding::kEventHandlerMap[] = {
|
||||||
|
@ -283,22 +222,17 @@ nsXBLBinding::kEventHandlerMap[] = {
|
||||||
NS_IMPL_ISUPPORTS1(nsXBLBinding, nsIXBLBinding)
|
NS_IMPL_ISUPPORTS1(nsXBLBinding, nsIXBLBinding)
|
||||||
|
|
||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
nsXBLBinding::nsXBLBinding(nsIXBLPrototypeBinding* aBinding)
|
||||||
: mDocURI(aDocURI), mID(aID), mFirstHandler(nsnull),
|
: mFirstHandler(nsnull),
|
||||||
mIsStyleBinding(PR_TRUE),
|
mIsStyleBinding(PR_TRUE),
|
||||||
mAllowScripts(PR_TRUE),
|
mMarkedForDeath(PR_FALSE)
|
||||||
mInheritStyle(PR_TRUE),
|
|
||||||
mMarkedForDeath(PR_FALSE),
|
|
||||||
mAttributeTable(nsnull),
|
|
||||||
mInsertionPointTable(nsnull)
|
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
mPrototypeBinding = aBinding;
|
||||||
gRefCnt++;
|
gRefCnt++;
|
||||||
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
|
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
|
||||||
|
|
||||||
if (gRefCnt == 1) {
|
if (gRefCnt == 1) {
|
||||||
kPool.Init("XBL Attribute Entries", kBucketSizes, kNumBuckets, kInitialSize);
|
|
||||||
|
|
||||||
kXULTemplateAtom = NS_NewAtom("template");
|
kXULTemplateAtom = NS_NewAtom("template");
|
||||||
kXULObservesAtom = NS_NewAtom("observes");
|
kXULObservesAtom = NS_NewAtom("observes");
|
||||||
|
|
||||||
|
@ -311,9 +245,6 @@ nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
||||||
kEventAtom = NS_NewAtom("event");
|
kEventAtom = NS_NewAtom("event");
|
||||||
kPhaseAtom = NS_NewAtom("phase");
|
kPhaseAtom = NS_NewAtom("phase");
|
||||||
kExtendsAtom = NS_NewAtom("extends");
|
kExtendsAtom = NS_NewAtom("extends");
|
||||||
kChildrenAtom = NS_NewAtom("children");
|
|
||||||
kHTMLAtom = NS_NewAtom("html");
|
|
||||||
kValueAtom = NS_NewAtom("value");
|
|
||||||
kActionAtom = NS_NewAtom("action");
|
kActionAtom = NS_NewAtom("action");
|
||||||
kMethodAtom = NS_NewAtom("method");
|
kMethodAtom = NS_NewAtom("method");
|
||||||
kParameterAtom = NS_NewAtom("parameter");
|
kParameterAtom = NS_NewAtom("parameter");
|
||||||
|
@ -328,11 +259,6 @@ nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
||||||
kAttachToAtom = NS_NewAtom("attachto");
|
kAttachToAtom = NS_NewAtom("attachto");
|
||||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||||
kInheritStyleAtom = NS_NewAtom("inheritstyle");
|
|
||||||
|
|
||||||
nsServiceManager::GetService("@mozilla.org/xbl;1",
|
|
||||||
NS_GET_IID(nsIXBLService),
|
|
||||||
(nsISupports**) &gXBLService);
|
|
||||||
|
|
||||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||||
while (entry->mAttributeName) {
|
while (entry->mAttributeName) {
|
||||||
|
@ -345,9 +271,6 @@ nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
||||||
|
|
||||||
nsXBLBinding::~nsXBLBinding(void)
|
nsXBLBinding::~nsXBLBinding(void)
|
||||||
{
|
{
|
||||||
delete mAttributeTable;
|
|
||||||
delete mInsertionPointTable;
|
|
||||||
|
|
||||||
gRefCnt--;
|
gRefCnt--;
|
||||||
// printf("REF COUNT DOWN: %d %s\n", gRefCnt, (const char*)mID);
|
// printf("REF COUNT DOWN: %d %s\n", gRefCnt, (const char*)mID);
|
||||||
|
|
||||||
|
@ -364,9 +287,6 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||||
NS_RELEASE(kEventAtom);
|
NS_RELEASE(kEventAtom);
|
||||||
NS_RELEASE(kPhaseAtom);
|
NS_RELEASE(kPhaseAtom);
|
||||||
NS_RELEASE(kExtendsAtom);
|
NS_RELEASE(kExtendsAtom);
|
||||||
NS_RELEASE(kChildrenAtom);
|
|
||||||
NS_RELEASE(kHTMLAtom);
|
|
||||||
NS_RELEASE(kValueAtom);
|
|
||||||
NS_RELEASE(kActionAtom);
|
NS_RELEASE(kActionAtom);
|
||||||
NS_RELEASE(kMethodAtom);
|
NS_RELEASE(kMethodAtom);
|
||||||
NS_RELEASE(kParameterAtom);
|
NS_RELEASE(kParameterAtom);
|
||||||
|
@ -380,10 +300,6 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||||
NS_RELEASE(kReadOnlyAtom);
|
NS_RELEASE(kReadOnlyAtom);
|
||||||
NS_RELEASE(kAttachToAtom);
|
NS_RELEASE(kAttachToAtom);
|
||||||
NS_RELEASE(kBindingAttachedAtom);
|
NS_RELEASE(kBindingAttachedAtom);
|
||||||
NS_RELEASE(kInheritStyleAtom);
|
|
||||||
|
|
||||||
nsServiceManager::ReleaseService("@mozilla.org/xbl;1", gXBLService);
|
|
||||||
gXBLService = nsnull;
|
|
||||||
|
|
||||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||||
while (entry->mAttributeName) {
|
while (entry->mAttributeName) {
|
||||||
|
@ -448,32 +364,34 @@ nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
||||||
child->SetBindingParent(mBoundElement);
|
child->SetBindingParent(mBoundElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (3) We need to insert entries into our attribute table for any elements
|
return NS_OK;
|
||||||
// that are inheriting attributes. This table allows us to quickly determine
|
}
|
||||||
// which elements in our anonymous content need to be updated when attributes change.
|
|
||||||
ConstructAttributeTable(aParent);
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLBinding::GetPrototypeBinding(nsIXBLPrototypeBinding** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mPrototypeBinding;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLBinding::SetPrototypeBinding(nsIXBLPrototypeBinding* aProtoBinding)
|
||||||
|
{
|
||||||
|
mPrototypeBinding = aProtoBinding;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetBindingElement(nsIContent** aResult)
|
nsXBLBinding::GetBindingElement(nsIContent** aResult)
|
||||||
{
|
{
|
||||||
*aResult = mBinding;
|
return mPrototypeBinding->GetBindingElement(aResult);
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::SetBindingElement(nsIContent* aElement)
|
nsXBLBinding::SetBindingElement(nsIContent* aElement)
|
||||||
{
|
{
|
||||||
mBinding = aElement;
|
return mPrototypeBinding->SetBindingElement(aElement);
|
||||||
nsAutoString inheritStyle;
|
|
||||||
mBinding->GetAttribute(kNameSpaceID_None, kInheritStyleAtom, inheritStyle);
|
|
||||||
if (inheritStyle == NS_LITERAL_STRING("false"))
|
|
||||||
mInheritStyle = PR_FALSE;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -499,7 +417,7 @@ nsXBLBinding::HasStyleSheets(PRBool* aResolveStyle)
|
||||||
// Find out if we need to re-resolve style. We'll need to do this
|
// Find out if we need to re-resolve style. We'll need to do this
|
||||||
// if we have additional stylesheets in our binding document.
|
// if we have additional stylesheets in our binding document.
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
mPrototypeBinding->GetXBLDocumentInfo(mBoundElement, getter_AddRefs(info));
|
||||||
if (!info)
|
if (!info)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nsCOMPtr<nsISupportsArray> rules;
|
nsCOMPtr<nsISupportsArray> rules;
|
||||||
|
@ -528,87 +446,86 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
||||||
else return NS_OK;
|
else return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plan to build the content by default.
|
// Find out if we're really building kids or if we're just
|
||||||
PRBool buildContent = PR_TRUE;
|
// using the attribute-setting shorthand hack.
|
||||||
|
PRInt32 contentCount;
|
||||||
|
content->ChildCount(contentCount);
|
||||||
|
|
||||||
// See if there's an includes attribute.
|
// Plan to build the content by default.
|
||||||
nsAutoString includes;
|
PRBool hasContent = (contentCount > 0);
|
||||||
content->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
|
PRBool hasInsertionPoints;
|
||||||
if ( includes != NS_LITERAL_STRING("*")) {
|
mPrototypeBinding->HasInsertionPoints(&hasInsertionPoints);
|
||||||
PRInt32 childCount;
|
|
||||||
aBoundElement->ChildCount(childCount);
|
if (hasContent && !hasInsertionPoints) {
|
||||||
if (childCount > 0) {
|
// See if there's an includes attribute.
|
||||||
// We'll only build content if all the explicit children are
|
nsAutoString includes;
|
||||||
// in the includes list.
|
content->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
|
||||||
// Walk the children and ensure that all of them
|
if (includes != NS_LITERAL_STRING("*")) {
|
||||||
// are in the includes array.
|
PRInt32 childCount;
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
aBoundElement->ChildCount(childCount);
|
||||||
nsCOMPtr<nsIContent> child;
|
if (childCount > 0) {
|
||||||
aBoundElement->ChildAt(i, *getter_AddRefs(child));
|
// We'll only build content if all the explicit children are
|
||||||
nsCOMPtr<nsIAtom> tag;
|
// in the includes list.
|
||||||
child->GetTag(*getter_AddRefs(tag));
|
// Walk the children and ensure that all of them
|
||||||
if (!IsInExcludesList(tag, includes)) {
|
// are in the includes array.
|
||||||
// XXX HACK! Ignore <template> and <observes>
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
if (tag.get() != kXULTemplateAtom &&
|
nsCOMPtr<nsIContent> child;
|
||||||
tag.get() != kXULObservesAtom) {
|
aBoundElement->ChildAt(i, *getter_AddRefs(child));
|
||||||
buildContent = PR_FALSE;
|
nsCOMPtr<nsIAtom> tag;
|
||||||
break;
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
|
if (!IsInExcludesList(tag, includes)) {
|
||||||
|
// XXX HACK! Ignore <template> and <observes>
|
||||||
|
if (tag.get() != kXULTemplateAtom &&
|
||||||
|
tag.get() != kXULObservesAtom) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> childrenElement;
|
if (hasContent) {
|
||||||
// see if we have a <children/> element
|
nsCOMPtr<nsIContent> clonedContent;
|
||||||
GetNestedChild(kChildrenAtom, content, getter_AddRefs(childrenElement));
|
|
||||||
if (childrenElement)
|
|
||||||
buildContent = PR_TRUE;
|
|
||||||
|
|
||||||
if (buildContent) {
|
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content));
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content));
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> clonedNode;
|
nsCOMPtr<nsIDOMNode> clonedNode;
|
||||||
domElement->CloneNode(PR_TRUE, getter_AddRefs(clonedNode));
|
domElement->CloneNode(PR_TRUE, getter_AddRefs(clonedNode));
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
|
clonedContent = do_QueryInterface(clonedNode);
|
||||||
SetAnonymousContent(clonedContent);
|
SetAnonymousContent(clonedContent);
|
||||||
|
}
|
||||||
|
|
||||||
// Always check the content element for potential attributes.
|
// Always check the content element for potential attributes.
|
||||||
PRInt32 length;
|
// This shorthand hack always happens, even when we didn't
|
||||||
clonedContent->GetAttributeCount(length);
|
// build anonymous content.
|
||||||
|
PRInt32 length;
|
||||||
|
content->GetAttributeCount(length);
|
||||||
|
|
||||||
PRInt32 namespaceID;
|
PRInt32 namespaceID;
|
||||||
nsCOMPtr<nsIAtom> name;
|
nsCOMPtr<nsIAtom> name;
|
||||||
nsCOMPtr<nsIAtom> prefix;
|
nsCOMPtr<nsIAtom> prefix;
|
||||||
|
|
||||||
for (PRInt32 i = 0; i < length; ++i)
|
for (PRInt32 i = 0; i < length; ++i) {
|
||||||
{
|
content->GetAttributeNameAt(0, namespaceID, *getter_AddRefs(name), *getter_AddRefs(prefix));
|
||||||
clonedContent->GetAttributeNameAt(0, namespaceID, *getter_AddRefs(name), *getter_AddRefs(prefix));
|
|
||||||
|
|
||||||
if (name.get() != kIncludesAtom) {
|
if (name.get() != kIncludesAtom) {
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
mBoundElement->GetAttribute(namespaceID, name, value);
|
mBoundElement->GetAttribute(namespaceID, name, value);
|
||||||
if (value.IsEmpty()) {
|
if (value.IsEmpty()) {
|
||||||
nsAutoString value2;
|
nsAutoString value2;
|
||||||
clonedContent->GetAttribute(namespaceID, name, value2);
|
content->GetAttribute(namespaceID, name, value2);
|
||||||
mBoundElement->SetAttribute(namespaceID, name, value2, PR_FALSE);
|
mBoundElement->SetAttribute(namespaceID, name, value2, PR_FALSE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conserve space by wiping the attributes off the clone.
|
|
||||||
clonedContent->UnsetAttribute(namespaceID, name, PR_FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childrenElement)
|
// Conserve space by wiping the attributes off the clone.
|
||||||
BuildInsertionTable();
|
if (mContent)
|
||||||
|
mContent->UnsetAttribute(namespaceID, name, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX Handle selective decision to build anonymous content.
|
if (mContent)
|
||||||
if (mNextBinding) {
|
mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent);
|
||||||
return mNextBinding->GenerateAnonymousContent(aBoundElement);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -620,12 +537,12 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||||
if (AllowScripts()) {
|
if (AllowScripts()) {
|
||||||
// Fetch the handlers prototypes for this binding.
|
// Fetch the handlers prototypes for this binding.
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
mPrototypeBinding->GetXBLDocumentInfo(mBoundElement, getter_AddRefs(info));
|
||||||
if (!info)
|
if (!info)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
||||||
info->GetPrototypeHandler(mID, getter_AddRefs(handlerChain));
|
mPrototypeBinding->GetPrototypeHandler(getter_AddRefs(handlerChain));
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
||||||
nsXBLEventHandler* currHandler = nsnull;
|
nsXBLEventHandler* currHandler = nsnull;
|
||||||
|
@ -1058,116 +975,20 @@ nsXBLBinding::GetBaseTag(PRInt32* aNameSpaceID, nsIAtom** aResult)
|
||||||
{
|
{
|
||||||
if (mNextBinding)
|
if (mNextBinding)
|
||||||
return mNextBinding->GetBaseTag(aNameSpaceID, aResult);
|
return mNextBinding->GetBaseTag(aNameSpaceID, aResult);
|
||||||
|
return mPrototypeBinding->GetBaseTag(aNameSpaceID, aResult);
|
||||||
// XXX Cache the value as a "base" attribute so that we don't do this
|
|
||||||
// check over and over each time the bound element occurs.
|
|
||||||
|
|
||||||
// We are the base binding. Obtain the extends attribute.
|
|
||||||
nsAutoString extends;
|
|
||||||
mBinding->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
|
||||||
|
|
||||||
if (!extends.IsEmpty()) {
|
|
||||||
// Obtain the namespace prefix.
|
|
||||||
nsAutoString prefix;
|
|
||||||
PRInt32 offset = extends.FindChar(kNameSpaceSeparator);
|
|
||||||
if (-1 != offset) {
|
|
||||||
extends.Left(prefix, offset);
|
|
||||||
extends.Cut(0, offset+1);
|
|
||||||
}
|
|
||||||
if (prefix.Length() > 0) {
|
|
||||||
// Look up the prefix.
|
|
||||||
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
|
||||||
nsCOMPtr<nsINameSpace> nameSpace;
|
|
||||||
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(mBinding));
|
|
||||||
if (xmlContent) {
|
|
||||||
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
|
||||||
|
|
||||||
if (nameSpace) {
|
|
||||||
nsCOMPtr<nsINameSpace> tagSpace;
|
|
||||||
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
|
||||||
if (tagSpace) {
|
|
||||||
// Score! Return the tag.
|
|
||||||
tagSpace->GetNameSpaceID(*aNameSpaceID);
|
|
||||||
*aResult = NS_NewAtom(extends); // The addref happens here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
||||||
{
|
{
|
||||||
// XXX check to see if we inherit anonymous content from a base binding
|
// XXX Change if we ever allow multiple bindings in a chain to contribute anonymous content
|
||||||
// if (mNextBinding)
|
if (!mContent) {
|
||||||
// mNextBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag);
|
if (mNextBinding)
|
||||||
|
return mNextBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag);
|
||||||
if (!mAttributeTable)
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsISupportsKey key(aAttribute);
|
|
||||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
|
||||||
mAttributeTable->Get(&key)));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> xblAttr = do_QueryInterface(supports);
|
|
||||||
if (!xblAttr)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Iterate over the elements in the array.
|
|
||||||
|
|
||||||
while (xblAttr) {
|
|
||||||
nsCOMPtr<nsIContent> element;
|
|
||||||
nsCOMPtr<nsIAtom> setAttr;
|
|
||||||
xblAttr->GetElement(getter_AddRefs(element));
|
|
||||||
xblAttr->GetAttribute(getter_AddRefs(setAttr));
|
|
||||||
|
|
||||||
if (aRemoveFlag)
|
|
||||||
element->UnsetAttribute(aNameSpaceID, setAttr, PR_TRUE);
|
|
||||||
else {
|
|
||||||
nsAutoString value;
|
|
||||||
nsresult result = mBoundElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
|
||||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
|
||||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
|
||||||
|
|
||||||
if (attrPresent)
|
|
||||||
element->SetAttribute(aNameSpaceID, setAttr, value, PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if we're the <html> tag in XUL, and see if value is being
|
|
||||||
// set or unset on us.
|
|
||||||
nsCOMPtr<nsIAtom> tag;
|
|
||||||
element->GetTag(*getter_AddRefs(tag));
|
|
||||||
if ((tag.get() == kHTMLAtom) && (setAttr.get() == kValueAtom)) {
|
|
||||||
// Flush out all our kids.
|
|
||||||
PRInt32 childCount;
|
|
||||||
element->ChildCount(childCount);
|
|
||||||
for (PRInt32 i = 0; i < childCount; i++)
|
|
||||||
element->RemoveChildAt(0, PR_TRUE);
|
|
||||||
|
|
||||||
if (!aRemoveFlag) {
|
|
||||||
// Construct a new text node and insert it.
|
|
||||||
nsAutoString value;
|
|
||||||
mBoundElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
|
||||||
if (!value.IsEmpty()) {
|
|
||||||
nsCOMPtr<nsIDOMText> textNode;
|
|
||||||
nsCOMPtr<nsIDocument> doc;
|
|
||||||
mBoundElement->GetDocument(*getter_AddRefs(doc));
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
|
||||||
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
|
||||||
nsCOMPtr<nsIDOMNode> dummy;
|
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(element));
|
|
||||||
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = xblAttr;
|
|
||||||
tmpAttr->GetNext(getter_AddRefs(xblAttr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return mPrototypeBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag, mBoundElement, mContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1254,7 +1075,7 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
||||||
GetAnonymousContent(getter_AddRefs(anonymous));
|
GetAnonymousContent(getter_AddRefs(anonymous));
|
||||||
if (anonymous) {
|
if (anonymous) {
|
||||||
if (mIsStyleBinding)
|
if (mIsStyleBinding)
|
||||||
anonymous->SetDocument(nsnull, PR_TRUE, AllowScripts()); // Kill it.
|
anonymous->SetDocument(nsnull, PR_TRUE, PR_TRUE); // Kill it.
|
||||||
else anonymous->SetDocument(aNewDocument, PR_TRUE, AllowScripts()); // Keep it around.
|
else anonymous->SetDocument(aNewDocument, PR_TRUE, AllowScripts()); // Keep it around.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1265,32 +1086,32 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetBindingURI(nsCString& aResult)
|
nsXBLBinding::GetBindingURI(nsCString& aResult)
|
||||||
{
|
{
|
||||||
aResult = mDocURI;
|
return mPrototypeBinding->GetBindingURI(aResult);
|
||||||
aResult += "#";
|
|
||||||
aResult += mID;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetDocURI(nsCString& aResult)
|
nsXBLBinding::GetDocURI(nsCString& aResult)
|
||||||
{
|
{
|
||||||
aResult = mDocURI;
|
return mPrototypeBinding->GetDocURI(aResult);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetID(nsCString& aResult)
|
nsXBLBinding::GetID(nsCString& aResult)
|
||||||
{
|
{
|
||||||
aResult = mID;
|
return mPrototypeBinding->GetID(aResult);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::InheritsStyle(PRBool* aResult)
|
nsXBLBinding::InheritsStyle(PRBool* aResult)
|
||||||
{
|
{
|
||||||
|
// XXX Will have to change if we ever allow multiple bindings to contribute anonymous content.
|
||||||
|
// Most derived binding with anonymous content determines style inheritance for now.
|
||||||
|
|
||||||
|
// XXX What about bindings with <content> but no kids, e.g., my treecell-text binding?
|
||||||
if (mContent)
|
if (mContent)
|
||||||
*aResult = mInheritStyle;
|
return mPrototypeBinding->InheritsStyle(aResult);
|
||||||
else if (mNextBinding)
|
|
||||||
|
if (mNextBinding)
|
||||||
return mNextBinding->InheritsStyle(aResult);
|
return mNextBinding->InheritsStyle(aResult);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1307,7 +1128,7 @@ nsXBLBinding::WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
mPrototypeBinding->GetXBLDocumentInfo(mBoundElement, getter_AddRefs(info));
|
||||||
if (!info)
|
if (!info)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nsCOMPtr<nsISupportsArray> rules;
|
nsCOMPtr<nsISupportsArray> rules;
|
||||||
|
@ -1422,12 +1243,15 @@ nsXBLBinding::InitClass(const nsCString& aClassName, nsIScriptContext* aContext,
|
||||||
void
|
void
|
||||||
nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIContent> binding;
|
||||||
|
mPrototypeBinding->GetBindingElement(getter_AddRefs(binding));
|
||||||
|
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
PRInt32 childCount;
|
PRInt32 childCount;
|
||||||
mBinding->ChildCount(childCount);
|
binding->ChildCount(childCount);
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
nsCOMPtr<nsIContent> child;
|
nsCOMPtr<nsIContent> child;
|
||||||
mBinding->ChildAt(i, *getter_AddRefs(child));
|
binding->ChildAt(i, *getter_AddRefs(child));
|
||||||
nsCOMPtr<nsIAtom> tag;
|
nsCOMPtr<nsIAtom> tag;
|
||||||
child->GetTag(*getter_AddRefs(tag));
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
if (aTag == tag.get()) {
|
if (aTag == tag.get()) {
|
||||||
|
@ -1440,114 +1264,6 @@ nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsXBLBinding::GetNestedChild(nsIAtom* aTag, nsIContent* aContent, nsIContent** aResult)
|
|
||||||
{
|
|
||||||
*aResult = nsnull;
|
|
||||||
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()) {
|
|
||||||
*aResult = aContent; // We return the parent of the correct child.
|
|
||||||
NS_ADDREF(*aResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GetNestedChild(aTag, child, aResult);
|
|
||||||
if (*aResult)
|
|
||||||
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);
|
|
||||||
PRUint32 i;
|
|
||||||
for (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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
nsMemory::Free(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove the <children> elements.
|
|
||||||
for (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));
|
|
||||||
PRInt32 index;
|
|
||||||
parent->IndexOf(child, index);
|
|
||||||
parent->RemoveChildAt(index, PR_FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
||||||
{
|
{
|
||||||
|
@ -1578,113 +1294,6 @@ nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXBLBinding::ConstructAttributeTable(nsIContent* aElement)
|
|
||||||
{
|
|
||||||
nsAutoString inherits;
|
|
||||||
aElement->GetAttribute(kNameSpaceID_None, kInheritsAtom, inherits);
|
|
||||||
if (!inherits.IsEmpty()) {
|
|
||||||
if (!mAttributeTable) {
|
|
||||||
mAttributeTable = new nsSupportsHashtable(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The user specified at least one attribute.
|
|
||||||
char* str = inherits.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 attribute.
|
|
||||||
nsCOMPtr<nsIAtom> atom;
|
|
||||||
nsCOMPtr<nsIAtom> attribute;
|
|
||||||
|
|
||||||
// Figure out if this token contains a :.
|
|
||||||
nsAutoString attrTok; attrTok.AssignWithConversion(token);
|
|
||||||
PRInt32 index = attrTok.Find("=", PR_TRUE);
|
|
||||||
if (index != -1) {
|
|
||||||
// This attribute maps to something different.
|
|
||||||
nsAutoString left, right;
|
|
||||||
attrTok.Left(left, index);
|
|
||||||
attrTok.Right(right, attrTok.Length()-index-1);
|
|
||||||
|
|
||||||
atom = getter_AddRefs(NS_NewAtom(right.GetUnicode()));
|
|
||||||
attribute = getter_AddRefs(NS_NewAtom(left.GetUnicode()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsAutoString tok; tok.AssignWithConversion(token);
|
|
||||||
atom = getter_AddRefs(NS_NewAtom(tok.GetUnicode()));
|
|
||||||
attribute = atom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an XBL attribute entry.
|
|
||||||
nsXBLAttributeEntry* xblAttr = new (kPool) nsXBLAttributeEntry(attribute, aElement);
|
|
||||||
|
|
||||||
// Now we should see if some element within our anonymous
|
|
||||||
// content is already observing this attribute.
|
|
||||||
nsISupportsKey key(atom);
|
|
||||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
|
||||||
mAttributeTable->Get(&key)));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> entry = do_QueryInterface(supports);
|
|
||||||
if (!entry) {
|
|
||||||
// Put it in the table.
|
|
||||||
mAttributeTable->Put(&key, xblAttr);
|
|
||||||
} else {
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> attr = entry;
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = entry;
|
|
||||||
do {
|
|
||||||
attr = tmpAttr;
|
|
||||||
attr->GetNext(getter_AddRefs(tmpAttr));
|
|
||||||
} while (tmpAttr);
|
|
||||||
attr->SetNext(xblAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now make sure that this attribute is initially set.
|
|
||||||
// XXX How to deal with NAMESPACES!!!?
|
|
||||||
nsAutoString value;
|
|
||||||
nsresult result = mBoundElement->GetAttribute(kNameSpaceID_None, atom, value);
|
|
||||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
|
||||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
|
||||||
|
|
||||||
if (attrPresent) {
|
|
||||||
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_FALSE);
|
|
||||||
nsCOMPtr<nsIAtom> tag;
|
|
||||||
aElement->GetTag(*getter_AddRefs(tag));
|
|
||||||
if ((tag.get() == kHTMLAtom) && (attribute.get() == kValueAtom) && !value.IsEmpty()) {
|
|
||||||
nsCOMPtr<nsIDOMText> textNode;
|
|
||||||
nsCOMPtr<nsIDocument> doc;
|
|
||||||
mBoundElement->GetDocument(*getter_AddRefs(doc));
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
|
||||||
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
|
||||||
nsCOMPtr<nsIDOMNode> dummy;
|
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(aElement));
|
|
||||||
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove the inherits attribute from the cloned element. It is used
|
|
||||||
// on the template only, and we don't need it anymore.
|
|
||||||
aElement->UnsetAttribute(kNameSpaceID_None, kInheritsAtom, PR_FALSE);
|
|
||||||
|
|
||||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
|
||||||
}
|
|
||||||
|
|
||||||
nsMemory::Free(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recur into our children.
|
|
||||||
PRInt32 childCount;
|
|
||||||
aElement->ChildCount(childCount);
|
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
|
||||||
nsCOMPtr<nsIContent> child;
|
|
||||||
aElement->ChildAt(i, *getter_AddRefs(child));
|
|
||||||
ConstructAttributeTable(child);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsXBLBinding::GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound)
|
nsXBLBinding::GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound)
|
||||||
{
|
{
|
||||||
|
@ -1771,28 +1380,19 @@ nsXBLBinding::GetTextData(nsIContent *aParent, nsString& aResult)
|
||||||
PRBool
|
PRBool
|
||||||
nsXBLBinding::AllowScripts()
|
nsXBLBinding::AllowScripts()
|
||||||
{
|
{
|
||||||
return mAllowScripts;
|
PRBool result;
|
||||||
|
mPrototypeBinding->GetAllowScripts(&result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult)
|
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult)
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
if (mInsertionPointTable) {
|
if (!mContent)
|
||||||
nsCOMPtr<nsIAtom> tag;
|
return NS_OK;
|
||||||
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;
|
return mPrototypeBinding->GetInsertionPoint(mBoundElement, mContent, aChild, aResult);
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1800,18 +1400,10 @@ nsXBLBinding::GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleIns
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
*aMultipleInsertionPoints = PR_FALSE;
|
*aMultipleInsertionPoints = PR_FALSE;
|
||||||
if (mInsertionPointTable) {
|
if (!mContent)
|
||||||
if(mInsertionPointTable->Count() == 1) {
|
return NS_OK;
|
||||||
nsISupportsKey key(kChildrenAtom);
|
|
||||||
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
|
return mPrototypeBinding->GetSingleInsertionPoint(mBoundElement, mContent, aResult, aMultipleInsertionPoints);
|
||||||
mInsertionPointTable->Get(&key)));
|
|
||||||
*aResult = content;
|
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*aMultipleInsertionPoints = PR_TRUE;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1844,6 +1436,7 @@ NS_IMETHODIMP
|
||||||
nsXBLBinding::MarkForDeath()
|
nsXBLBinding::MarkForDeath()
|
||||||
{
|
{
|
||||||
mMarkedForDeath = PR_TRUE;
|
mMarkedForDeath = PR_TRUE;
|
||||||
|
ExecuteDetachedHandler();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1857,12 +1450,11 @@ nsXBLBinding::MarkedForDeath(PRBool* aResult)
|
||||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewXBLBinding(const nsCString& aDocURI, const nsCString& aRef, nsIXBLBinding** aResult)
|
NS_NewXBLBinding(nsIXBLPrototypeBinding* aBinding, nsIXBLBinding** aResult)
|
||||||
{
|
{
|
||||||
*aResult = new nsXBLBinding(aDocURI, aRef);
|
*aResult = new nsXBLBinding(aBinding);
|
||||||
if (!*aResult)
|
if (!*aResult)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
NS_ADDREF(*aResult);
|
NS_ADDREF(*aResult);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIXBLBinding.h"
|
#include "nsIXBLBinding.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
@ -42,6 +43,9 @@ class nsXBLBinding: public nsIXBLBinding
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
// nsIXBLBinding
|
// nsIXBLBinding
|
||||||
|
NS_IMETHOD GetPrototypeBinding(nsIXBLPrototypeBinding** aResult);
|
||||||
|
NS_IMETHOD SetPrototypeBinding(nsIXBLPrototypeBinding* aProtoBinding);
|
||||||
|
|
||||||
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult);
|
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult);
|
||||||
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding);
|
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding);
|
||||||
|
|
||||||
|
@ -86,13 +90,11 @@ class nsXBLBinding: public nsIXBLBinding
|
||||||
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
||||||
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData);
|
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData);
|
||||||
|
|
||||||
NS_IMETHOD SetAllowScripts(PRBool aFlag) { mAllowScripts = aFlag; return NS_OK; };
|
|
||||||
|
|
||||||
NS_IMETHOD MarkForDeath();
|
NS_IMETHOD MarkForDeath();
|
||||||
NS_IMETHOD MarkedForDeath(PRBool* aResult);
|
NS_IMETHOD MarkedForDeath(PRBool* aResult);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsXBLBinding(const nsCString& aDocURI, const nsCString& aRef);
|
nsXBLBinding(nsIXBLPrototypeBinding* aProtoBinding);
|
||||||
virtual ~nsXBLBinding();
|
virtual ~nsXBLBinding();
|
||||||
|
|
||||||
NS_IMETHOD AddScriptEventListener(nsIContent* aElement, nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
|
NS_IMETHOD AddScriptEventListener(nsIContent* aElement, nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
|
||||||
|
@ -125,17 +127,12 @@ public:
|
||||||
static nsIAtom* kOnGetAtom;
|
static nsIAtom* kOnGetAtom;
|
||||||
static nsIAtom* kGetterAtom;
|
static nsIAtom* kGetterAtom;
|
||||||
static nsIAtom* kSetterAtom;
|
static nsIAtom* kSetterAtom;
|
||||||
static nsIAtom* kHTMLAtom;
|
|
||||||
static nsIAtom* kValueAtom;
|
|
||||||
static nsIAtom* kActionAtom;
|
static nsIAtom* kActionAtom;
|
||||||
static nsIAtom* kNameAtom;
|
static nsIAtom* kNameAtom;
|
||||||
static nsIAtom* kReadOnlyAtom;
|
static nsIAtom* kReadOnlyAtom;
|
||||||
static nsIAtom* kAttachToAtom;
|
static nsIAtom* kAttachToAtom;
|
||||||
static nsIAtom* kBindingAttachedAtom;
|
static nsIAtom* kBindingAttachedAtom;
|
||||||
static nsIAtom* kBindingDetachedAtom;
|
static nsIAtom* kBindingDetachedAtom;
|
||||||
static nsIAtom* kInheritStyleAtom;
|
|
||||||
|
|
||||||
static nsIXBLService* gXBLService;
|
|
||||||
|
|
||||||
// Used to easily obtain the correct IID for an event.
|
// Used to easily obtain the correct IID for an event.
|
||||||
struct EventHandlerMapEntry {
|
struct EventHandlerMapEntry {
|
||||||
|
@ -148,8 +145,6 @@ public:
|
||||||
|
|
||||||
static PRBool IsSupportedHandler(const nsIID* aIID);
|
static PRBool IsSupportedHandler(const nsIID* aIID);
|
||||||
|
|
||||||
static nsFixedSizeAllocator kPool;
|
|
||||||
|
|
||||||
static void GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound);
|
static void GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound);
|
||||||
|
|
||||||
// Internal member functions
|
// Internal member functions
|
||||||
|
@ -159,21 +154,11 @@ protected:
|
||||||
void** aScriptObject, void** aClassObject);
|
void** aScriptObject, void** aClassObject);
|
||||||
|
|
||||||
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
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);
|
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
|
||||||
|
|
||||||
NS_IMETHOD ConstructAttributeTable(nsIContent* aElement);
|
|
||||||
|
|
||||||
|
|
||||||
// MEMBER VARIABLES
|
// MEMBER VARIABLES
|
||||||
protected:
|
protected:
|
||||||
nsCString mDocURI;
|
nsCOMPtr<nsIXBLPrototypeBinding> mPrototypeBinding; // Strong. As long as we're around, the binding can't go away.
|
||||||
nsCString mID;
|
|
||||||
|
|
||||||
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<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
|
||||||
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
|
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
|
||||||
|
|
||||||
|
@ -183,10 +168,5 @@ protected:
|
||||||
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
|
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
|
||||||
|
|
||||||
PRPackedBool mIsStyleBinding;
|
PRPackedBool mIsStyleBinding;
|
||||||
PRPackedBool mAllowScripts;
|
|
||||||
PRPackedBool mInheritStyle;
|
|
||||||
PRPackedBool mMarkedForDeath;
|
PRPackedBool mMarkedForDeath;
|
||||||
|
|
||||||
nsSupportsHashtable* mAttributeTable; // A table for attribute entries.
|
|
||||||
nsSupportsHashtable* mInsertionPointTable; // A table of insertion points.
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,805 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS
|
||||||
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||||
|
* implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||||||
|
* Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
#include "nsIXBLDocumentInfo.h"
|
||||||
|
#include "nsIInputStream.h"
|
||||||
|
#include "nsINameSpaceManager.h"
|
||||||
|
#include "nsHashtable.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
|
#include "nsIURL.h"
|
||||||
|
#include "nsIDOMEventReceiver.h"
|
||||||
|
#include "nsIChannel.h"
|
||||||
|
#include "nsXPIDLString.h"
|
||||||
|
#include "nsIParser.h"
|
||||||
|
#include "nsParserCIID.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
#include "plstr.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIXMLContent.h"
|
||||||
|
#include "nsIXULContent.h"
|
||||||
|
#include "nsIXMLContentSink.h"
|
||||||
|
#include "nsLayoutCID.h"
|
||||||
|
#include "nsXMLDocument.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
#include "nsIDOMText.h"
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
#include "nsINameSpace.h"
|
||||||
|
#include "nsXBLService.h"
|
||||||
|
#include "nsXBLPrototypeBinding.h"
|
||||||
|
#include "nsFixedSizeAllocator.h"
|
||||||
|
|
||||||
|
// Helper Classes =====================================================================
|
||||||
|
|
||||||
|
// nsIXBLAttributeEntry and helpers. This class is used to efficiently handle
|
||||||
|
// attribute changes in anonymous content.
|
||||||
|
|
||||||
|
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
||||||
|
#define NS_IXBLATTR_IID \
|
||||||
|
{ 0xa2892b81, 0xced9, 0x11d3, { 0x97, 0xfb, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
||||||
|
|
||||||
|
class nsIXBLAttributeEntry : public nsISupports {
|
||||||
|
public:
|
||||||
|
static const nsIID& GetIID() { static nsIID iid = NS_IXBLATTR_IID; return iid; }
|
||||||
|
|
||||||
|
NS_IMETHOD GetSrcAttribute(nsIAtom** aResult) = 0;
|
||||||
|
NS_IMETHOD GetDstAttribute(nsIAtom** aResult) = 0;
|
||||||
|
NS_IMETHOD GetElement(nsIContent** aResult) = 0;
|
||||||
|
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) = 0;
|
||||||
|
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsXBLAttributeEntry : public nsIXBLAttributeEntry {
|
||||||
|
public:
|
||||||
|
NS_IMETHOD GetSrcAttribute(nsIAtom** aResult) { *aResult = mSrcAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
NS_IMETHOD GetDstAttribute(nsIAtom** aResult) { *aResult = mDstAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
|
||||||
|
NS_IMETHOD GetElement(nsIContent** aResult) { *aResult = mElement; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
|
||||||
|
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) { NS_IF_ADDREF(*aResult = mNext); return NS_OK; }
|
||||||
|
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) { mNext = aEntry; return NS_OK; }
|
||||||
|
|
||||||
|
nsIContent* mElement;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIAtom> mSrcAttribute;
|
||||||
|
nsCOMPtr<nsIAtom> mDstAttribute;
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> mNext;
|
||||||
|
|
||||||
|
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||||
|
return aAllocator.Alloc(aSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void operator delete(void* aPtr, size_t aSize) {
|
||||||
|
nsFixedSizeAllocator::Free(aPtr, aSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXBLAttributeEntry(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, nsIContent* aContent) {
|
||||||
|
NS_INIT_REFCNT(); mSrcAttribute = aSrcAtom; mDstAttribute = aDstAtom; mElement = aContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~nsXBLAttributeEntry() {};
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// Static initialization
|
||||||
|
PRUint32 nsXBLPrototypeBinding::gRefCnt = 0;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kInheritStyleAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kHandlersAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kChildrenAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kIncludesAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kContentAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kInheritsAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kHTMLAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kValueAtom = nsnull;
|
||||||
|
|
||||||
|
nsIXBLService* nsXBLPrototypeBinding::gXBLService = nsnull;
|
||||||
|
nsFixedSizeAllocator nsXBLPrototypeBinding::kPool;
|
||||||
|
|
||||||
|
static const size_t kBucketSizes[] = {
|
||||||
|
sizeof(nsXBLAttributeEntry)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PRInt32 kNumBuckets = sizeof(kBucketSizes)/sizeof(size_t);
|
||||||
|
static const PRInt32 kNumElements = 128;
|
||||||
|
static const PRInt32 kInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLAttributeEntry))) * kNumElements;
|
||||||
|
|
||||||
|
// Implementation /////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Implement our nsISupports methods
|
||||||
|
NS_IMPL_ISUPPORTS1(nsXBLPrototypeBinding, nsIXBLPrototypeBinding)
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsCString& aID, nsIContent* aElement,
|
||||||
|
nsIXBLDocumentInfo* aInfo)
|
||||||
|
: mID(aID),
|
||||||
|
mInheritStyle(PR_TRUE),
|
||||||
|
mHasBaseProto(PR_TRUE),
|
||||||
|
mAttributeTable(nsnull),
|
||||||
|
mInsertionPointTable(nsnull)
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
mXBLDocInfoWeak = getter_AddRefs(NS_GetWeakReference(aInfo));
|
||||||
|
|
||||||
|
gRefCnt++;
|
||||||
|
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
|
||||||
|
|
||||||
|
if (gRefCnt == 1) {
|
||||||
|
kPool.Init("XBL Attribute Entries", kBucketSizes, kNumBuckets, kInitialSize);
|
||||||
|
|
||||||
|
kInheritStyleAtom = NS_NewAtom("inheritstyle");
|
||||||
|
kHandlersAtom = NS_NewAtom("handlers");
|
||||||
|
kChildrenAtom = NS_NewAtom("children");
|
||||||
|
kContentAtom = NS_NewAtom("content");
|
||||||
|
kIncludesAtom = NS_NewAtom("includes");
|
||||||
|
kInheritsAtom = NS_NewAtom("inherits");
|
||||||
|
kHTMLAtom = NS_NewAtom("html");
|
||||||
|
kValueAtom = NS_NewAtom("value");
|
||||||
|
|
||||||
|
nsServiceManager::GetService("@mozilla.org/xbl;1",
|
||||||
|
NS_GET_IID(nsIXBLService),
|
||||||
|
(nsISupports**) &gXBLService);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These all use atoms, so we have to do these ops last to ensure
|
||||||
|
// the atoms exist.
|
||||||
|
SetBindingElement(aElement);
|
||||||
|
|
||||||
|
PRBool allowScripts;
|
||||||
|
aInfo->GetScriptAccess(&allowScripts);
|
||||||
|
if (allowScripts) {
|
||||||
|
ConstructHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(content));
|
||||||
|
if (content) {
|
||||||
|
ConstructAttributeTable(content);
|
||||||
|
ConstructInsertionTable(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
|
||||||
|
{
|
||||||
|
delete mAttributeTable;
|
||||||
|
delete mInsertionPointTable;
|
||||||
|
gRefCnt--;
|
||||||
|
if (gRefCnt == 0) {
|
||||||
|
NS_RELEASE(kInheritStyleAtom);
|
||||||
|
NS_RELEASE(kHandlersAtom);
|
||||||
|
NS_RELEASE(kChildrenAtom);
|
||||||
|
NS_RELEASE(kContentAtom);
|
||||||
|
NS_RELEASE(kIncludesAtom);
|
||||||
|
NS_RELEASE(kInheritsAtom);
|
||||||
|
NS_RELEASE(kHTMLAtom);
|
||||||
|
NS_RELEASE(kValueAtom);
|
||||||
|
|
||||||
|
nsServiceManager::ReleaseService("@mozilla.org/xbl;1", gXBLService);
|
||||||
|
gXBLService = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nsIXBLPrototypeBinding Interface ////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBasePrototype(nsIXBLPrototypeBinding** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mBaseBinding;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetBasePrototype(nsIXBLPrototypeBinding* aBinding)
|
||||||
|
{
|
||||||
|
if (mBaseBinding.get() == aBinding)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (mBaseBinding) {
|
||||||
|
NS_ERROR("Base XBL prototype binding is already defined!");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBaseBinding = aBinding; // Comptr handles rel/add
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBindingElement(nsIContent** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mBinding;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetBindingElement(nsIContent* aElement)
|
||||||
|
{
|
||||||
|
mBinding = aElement;
|
||||||
|
nsAutoString inheritStyle;
|
||||||
|
mBinding->GetAttribute(kNameSpaceID_None, kInheritStyleAtom, inheritStyle);
|
||||||
|
if (inheritStyle == NS_LITERAL_STRING("false"))
|
||||||
|
mInheritStyle = PR_FALSE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBindingURI(nsCString& aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
|
GetXBLDocumentInfo(nsnull, getter_AddRefs(info));
|
||||||
|
|
||||||
|
info->GetDocumentURI(aResult);
|
||||||
|
aResult += "#";
|
||||||
|
aResult += mID;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetDocURI(nsCString& aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
|
GetXBLDocumentInfo(nsnull, getter_AddRefs(info));
|
||||||
|
|
||||||
|
info->GetDocumentURI(aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetID(nsCString& aResult)
|
||||||
|
{
|
||||||
|
aResult = mID;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetAllowScripts(PRBool* aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
|
GetXBLDocumentInfo(nsnull, getter_AddRefs(info));
|
||||||
|
return info->GetScriptAccess(aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::InheritsStyle(PRBool* aResult)
|
||||||
|
{
|
||||||
|
*aResult = mInheritStyle;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetXBLDocumentInfo(nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info(do_QueryReferent(mXBLDocInfoWeak));
|
||||||
|
if (info) {
|
||||||
|
*aResult = info;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
else *aResult=nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::HasBasePrototype(PRBool* aResult)
|
||||||
|
{
|
||||||
|
*aResult = mHasBaseProto;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetHasBasePrototype(PRBool aHasBase)
|
||||||
|
{
|
||||||
|
mHasBaseProto = aHasBase;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetPrototypeHandler(nsIXBLPrototypeHandler** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mPrototypeHandler;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)
|
||||||
|
{
|
||||||
|
mPrototypeHandler = aHandler;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||||
|
nsIContent* aChangedElement, nsIContent* aAnonymousContent)
|
||||||
|
{
|
||||||
|
if (!mAttributeTable)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsISupportsKey key(aAttribute);
|
||||||
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||||
|
mAttributeTable->Get(&key)));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> xblAttr = do_QueryInterface(supports);
|
||||||
|
if (!xblAttr)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// Iterate over the elements in the array.
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(content));
|
||||||
|
while (xblAttr) {
|
||||||
|
nsCOMPtr<nsIContent> element;
|
||||||
|
nsCOMPtr<nsIAtom> dstAttr;
|
||||||
|
xblAttr->GetElement(getter_AddRefs(element));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> realElement;
|
||||||
|
LocateInstance(content, aAnonymousContent, element, getter_AddRefs(realElement));
|
||||||
|
|
||||||
|
xblAttr->GetDstAttribute(getter_AddRefs(dstAttr));
|
||||||
|
|
||||||
|
if (aRemoveFlag)
|
||||||
|
realElement->UnsetAttribute(aNameSpaceID, dstAttr, PR_TRUE);
|
||||||
|
else {
|
||||||
|
nsAutoString value;
|
||||||
|
nsresult result = aChangedElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
||||||
|
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||||
|
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||||
|
|
||||||
|
if (attrPresent)
|
||||||
|
realElement->SetAttribute(aNameSpaceID, dstAttr, value, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if we're the <html> tag in XUL, and see if value is being
|
||||||
|
// set or unset on us.
|
||||||
|
nsCOMPtr<nsIAtom> tag;
|
||||||
|
realElement->GetTag(*getter_AddRefs(tag));
|
||||||
|
if ((tag.get() == kHTMLAtom) && (dstAttr.get() == kValueAtom)) {
|
||||||
|
// Flush out all our kids.
|
||||||
|
PRInt32 childCount;
|
||||||
|
realElement->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++)
|
||||||
|
realElement->RemoveChildAt(0, PR_TRUE);
|
||||||
|
|
||||||
|
if (!aRemoveFlag) {
|
||||||
|
// Construct a new text node and insert it.
|
||||||
|
nsAutoString value;
|
||||||
|
aChangedElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
||||||
|
if (!value.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIDOMText> textNode;
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
aChangedElement->GetDocument(*getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
||||||
|
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
||||||
|
nsCOMPtr<nsIDOMNode> dummy;
|
||||||
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(realElement));
|
||||||
|
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = xblAttr;
|
||||||
|
tmpAttr->GetNext(getter_AddRefs(xblAttr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aChild, nsIContent** aResult)
|
||||||
|
{
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> realContent;
|
||||||
|
nsCOMPtr<nsIContent> templContent;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
|
||||||
|
LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent));
|
||||||
|
if (realContent)
|
||||||
|
*aResult = realContent;
|
||||||
|
else *aResult = aBoundElement;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement,
|
||||||
|
nsIContent* aCopyRoot,
|
||||||
|
nsIContent** aResult, PRBool* aMultipleInsertionPoints)
|
||||||
|
{
|
||||||
|
if (mInsertionPointTable) {
|
||||||
|
if(mInsertionPointTable->Count() == 1) {
|
||||||
|
nsISupportsKey key(kChildrenAtom);
|
||||||
|
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
|
||||||
|
mInsertionPointTable->Get(&key)));
|
||||||
|
nsCOMPtr<nsIContent> realContent;
|
||||||
|
nsCOMPtr<nsIContent> templContent;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
|
||||||
|
LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent));
|
||||||
|
if (realContent)
|
||||||
|
*aResult = realContent;
|
||||||
|
else *aResult = aBoundElement;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*aMultipleInsertionPoints = PR_TRUE;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag)
|
||||||
|
{
|
||||||
|
mBaseNameSpaceID = aNamespaceID;
|
||||||
|
mBaseTag = aTag;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aResult)
|
||||||
|
{
|
||||||
|
if (mBaseTag) {
|
||||||
|
*aResult = mBaseTag;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
*aNamespaceID = mBaseNameSpaceID;
|
||||||
|
}
|
||||||
|
else *aResult = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helpers ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
PRInt32 childCount;
|
||||||
|
mBinding->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
|
nsCOMPtr<nsIContent> child;
|
||||||
|
mBinding->ChildAt(i, *getter_AddRefs(child));
|
||||||
|
nsCOMPtr<nsIAtom> tag;
|
||||||
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
|
if (aTag == tag.get()) {
|
||||||
|
*aResult = child;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::ConstructHandlers()
|
||||||
|
{
|
||||||
|
// See if this binding has a handler elt.
|
||||||
|
nsCOMPtr<nsIContent> handlers;
|
||||||
|
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||||
|
if (handlers) {
|
||||||
|
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||||
|
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(firstHandler));
|
||||||
|
SetPrototypeHandler(firstHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::LocateInstance(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) {
|
||||||
|
*aCopyResult = nsnull;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> templParent;
|
||||||
|
nsCOMPtr<nsIContent> copyParent;
|
||||||
|
|
||||||
|
aTemplChild->GetParent(*getter_AddRefs(templParent));
|
||||||
|
|
||||||
|
if (templParent.get() == aTemplRoot)
|
||||||
|
copyParent = aCopyRoot;
|
||||||
|
else
|
||||||
|
LocateInstance(aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent));
|
||||||
|
|
||||||
|
PRInt32 index;
|
||||||
|
templParent->IndexOf(aTemplChild, index);
|
||||||
|
copyParent->ChildAt(index, *aCopyResult); // Addref happens here.
|
||||||
|
}
|
||||||
|
|
||||||
|
struct nsXBLAttrChangeData
|
||||||
|
{
|
||||||
|
nsXBLPrototypeBinding* mProto;
|
||||||
|
nsIContent* mBoundElement;
|
||||||
|
nsIContent* mContent;
|
||||||
|
|
||||||
|
nsXBLAttrChangeData(nsXBLPrototypeBinding* aProto,
|
||||||
|
nsIContent* aElt, nsIContent* aContent)
|
||||||
|
:mProto(aProto), mBoundElement(aElt), mContent(aContent) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
|
{
|
||||||
|
// XXX How to deal with NAMESPACES!!!?
|
||||||
|
nsIXBLAttributeEntry* entry = (nsIXBLAttributeEntry*)aData;
|
||||||
|
nsXBLAttrChangeData* changeData = (nsXBLAttrChangeData*)aClosure;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIAtom> src;
|
||||||
|
entry->GetSrcAttribute(getter_AddRefs(src));
|
||||||
|
|
||||||
|
nsAutoString value;
|
||||||
|
nsresult result = changeData->mBoundElement->GetAttribute(kNameSpaceID_None, src, value);
|
||||||
|
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||||
|
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||||
|
if (attrPresent) {
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
changeData->mProto->GetImmediateChild(nsXBLPrototypeBinding::kContentAtom, getter_AddRefs(content));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> curr = entry;
|
||||||
|
while (curr) {
|
||||||
|
nsCOMPtr<nsIAtom> dst;
|
||||||
|
nsCOMPtr<nsIContent> element;
|
||||||
|
curr->GetDstAttribute(getter_AddRefs(dst));
|
||||||
|
curr->GetElement(getter_AddRefs(element));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> realElement;
|
||||||
|
changeData->mProto->LocateInstance(content, changeData->mContent, element, getter_AddRefs(realElement));
|
||||||
|
if (realElement) {
|
||||||
|
realElement->SetAttribute(kNameSpaceID_None, dst, value, PR_FALSE);
|
||||||
|
nsCOMPtr<nsIAtom> tag;
|
||||||
|
realElement->GetTag(*getter_AddRefs(tag));
|
||||||
|
if ((tag.get() == nsXBLPrototypeBinding::kHTMLAtom) && (dst.get() == nsXBLPrototypeBinding::kValueAtom) && !value.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIDOMText> textNode;
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
changeData->mBoundElement->GetDocument(*getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
||||||
|
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
||||||
|
nsCOMPtr<nsIDOMNode> dummy;
|
||||||
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(realElement));
|
||||||
|
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> next = curr;
|
||||||
|
curr->GetNext(getter_AddRefs(next));
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)
|
||||||
|
{
|
||||||
|
if (mAttributeTable) {
|
||||||
|
nsXBLAttrChangeData data(this, aBoundElement, aAnonymousContent);
|
||||||
|
mAttributeTable->Enumerate(SetAttrs, (void*)&data);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||||
|
{
|
||||||
|
nsAutoString inherits;
|
||||||
|
aElement->GetAttribute(kNameSpaceID_None, kInheritsAtom, inherits);
|
||||||
|
if (!inherits.IsEmpty()) {
|
||||||
|
if (!mAttributeTable) {
|
||||||
|
mAttributeTable = new nsSupportsHashtable(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The user specified at least one attribute.
|
||||||
|
char* str = inherits.ToNewCString();
|
||||||
|
char* newStr;
|
||||||
|
// XXX We should use a strtok function that tokenizes PRUnichars
|
||||||
|
// 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 attribute.
|
||||||
|
nsCOMPtr<nsIAtom> atom;
|
||||||
|
nsCOMPtr<nsIAtom> attribute;
|
||||||
|
|
||||||
|
// Figure out if this token contains a :.
|
||||||
|
nsAutoString attrTok; attrTok.AssignWithConversion(token);
|
||||||
|
PRInt32 index = attrTok.Find("=", PR_TRUE);
|
||||||
|
if (index != -1) {
|
||||||
|
// This attribute maps to something different.
|
||||||
|
nsAutoString left, right;
|
||||||
|
attrTok.Left(left, index);
|
||||||
|
attrTok.Right(right, attrTok.Length()-index-1);
|
||||||
|
|
||||||
|
atom = getter_AddRefs(NS_NewAtom(right.GetUnicode()));
|
||||||
|
attribute = getter_AddRefs(NS_NewAtom(left.GetUnicode()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nsAutoString tok; tok.AssignWithConversion(token);
|
||||||
|
atom = getter_AddRefs(NS_NewAtom(tok.GetUnicode()));
|
||||||
|
attribute = atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an XBL attribute entry.
|
||||||
|
nsXBLAttributeEntry* xblAttr = new (kPool) nsXBLAttributeEntry(atom, attribute, aElement);
|
||||||
|
|
||||||
|
// Now we should see if some element within our anonymous
|
||||||
|
// content is already observing this attribute.
|
||||||
|
nsISupportsKey key(atom);
|
||||||
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||||
|
mAttributeTable->Get(&key)));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> entry = do_QueryInterface(supports);
|
||||||
|
if (!entry) {
|
||||||
|
// Put it in the table.
|
||||||
|
mAttributeTable->Put(&key, xblAttr);
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> attr = entry;
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = entry;
|
||||||
|
do {
|
||||||
|
attr = tmpAttr;
|
||||||
|
attr->GetNext(getter_AddRefs(tmpAttr));
|
||||||
|
} while (tmpAttr);
|
||||||
|
attr->SetNext(xblAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove the inherits attribute from the element so that it doesn't
|
||||||
|
// show up on clones of the element. It is used
|
||||||
|
// by the template only, and we don't need it anymore.
|
||||||
|
aElement->UnsetAttribute(kNameSpaceID_None, kInheritsAtom, PR_FALSE);
|
||||||
|
|
||||||
|
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMemory::Free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recur into our children.
|
||||||
|
PRInt32 childCount;
|
||||||
|
aElement->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
|
nsCOMPtr<nsIContent> child;
|
||||||
|
aElement->ChildAt(i, *getter_AddRefs(child));
|
||||||
|
ConstructAttributeTable(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupportsArray> childrenElements;
|
||||||
|
GetNestedChildren(kChildrenAtom, aContent, getter_AddRefs(childrenElements));
|
||||||
|
|
||||||
|
if (!childrenElements)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mInsertionPointTable = new nsSupportsHashtable;
|
||||||
|
|
||||||
|
PRUint32 count;
|
||||||
|
childrenElements->Count(&count);
|
||||||
|
PRUint32 i;
|
||||||
|
for (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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMemory::Free(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove the <children> elements.
|
||||||
|
for (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));
|
||||||
|
PRInt32 index;
|
||||||
|
parent->IndexOf(child, index);
|
||||||
|
parent->RemoveChildAt(index, PR_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::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()) {
|
||||||
|
if (!*aList)
|
||||||
|
NS_NewISupportsArray(aList); // Addref happens here.
|
||||||
|
(*aList)->AppendElement(child);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GetNestedChildren(aTag, child, aList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_NewXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement,
|
||||||
|
nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult)
|
||||||
|
{
|
||||||
|
*aResult = new nsXBLPrototypeBinding(aRef, aElement, aInfo);
|
||||||
|
if (!*aResult)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS
|
||||||
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||||
|
* implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||||||
|
* Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
#include "nsIXBLPrototypeHandler.h"
|
||||||
|
|
||||||
|
class nsIContent;
|
||||||
|
class nsIAtom;
|
||||||
|
class nsIDocument;
|
||||||
|
class nsIScriptContext;
|
||||||
|
class nsISupportsArray;
|
||||||
|
class nsSupportsHashtable;
|
||||||
|
class nsIXBLService;
|
||||||
|
class nsFixedSizeAllocator;
|
||||||
|
|
||||||
|
// *********************************************************************/
|
||||||
|
// The XBLPrototypeBinding class
|
||||||
|
|
||||||
|
class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding
|
||||||
|
{
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIXBLPrototypeBinding
|
||||||
|
NS_IMETHOD GetBindingElement(nsIContent** aResult);
|
||||||
|
NS_IMETHOD SetBindingElement(nsIContent* aElement);
|
||||||
|
|
||||||
|
NS_IMETHOD GetBindingURI(nsCString& aResult);
|
||||||
|
NS_IMETHOD GetDocURI(nsCString& aResult);
|
||||||
|
NS_IMETHOD GetID(nsCString& aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetAllowScripts(PRBool* aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler);
|
||||||
|
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler);
|
||||||
|
|
||||||
|
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||||
|
nsIContent* aChangedElement, nsIContent* aAnonymousContent);
|
||||||
|
|
||||||
|
NS_IMETHOD SetBasePrototype(nsIXBLPrototypeBinding* aBinding);
|
||||||
|
NS_IMETHOD GetBasePrototype(nsIXBLPrototypeBinding** aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetXBLDocumentInfo(nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD HasBasePrototype(PRBool* aResult);
|
||||||
|
NS_IMETHOD SetHasBasePrototype(PRBool aHasBase);
|
||||||
|
|
||||||
|
NS_IMETHOD SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
|
||||||
|
|
||||||
|
NS_IMETHOD HasInsertionPoints(PRBool* aResult) { *aResult = (mInsertionPointTable != nsnull); return NS_OK; };
|
||||||
|
|
||||||
|
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aChild, nsIContent** aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent** aResult, PRBool* aMultiple);
|
||||||
|
|
||||||
|
NS_IMETHOD GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aTag);
|
||||||
|
NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag);
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement,
|
||||||
|
nsIXBLDocumentInfo* aInfo);
|
||||||
|
virtual ~nsXBLPrototypeBinding();
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
static PRUint32 gRefCnt;
|
||||||
|
static nsIXBLService* gXBLService;
|
||||||
|
static nsIAtom* kInheritStyleAtom;
|
||||||
|
static nsIAtom* kHandlersAtom;
|
||||||
|
static nsIAtom* kChildrenAtom;
|
||||||
|
static nsIAtom* kIncludesAtom;
|
||||||
|
static nsIAtom* kContentAtom;
|
||||||
|
static nsIAtom* kInheritsAtom;
|
||||||
|
static nsIAtom* kHTMLAtom;
|
||||||
|
static nsIAtom* kValueAtom;
|
||||||
|
|
||||||
|
static nsFixedSizeAllocator kPool;
|
||||||
|
|
||||||
|
// Internal member functions
|
||||||
|
public:
|
||||||
|
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
||||||
|
void LocateInstance(nsIContent* aTemplRoot, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aTemplChild, nsIContent** aCopyResult);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ConstructHandlers();
|
||||||
|
void ConstructAttributeTable(nsIContent* aElement);
|
||||||
|
void ConstructInsertionTable(nsIContent* aElement);
|
||||||
|
void GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, nsISupportsArray** aList);
|
||||||
|
|
||||||
|
// MEMBER VARIABLES
|
||||||
|
protected:
|
||||||
|
nsCString mID;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
|
||||||
|
nsCOMPtr<nsIXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
|
||||||
|
nsCOMPtr<nsIXBLPrototypeBinding> mBaseBinding; // Strong. We own the base binding in our explicit inheritance chain.
|
||||||
|
PRPackedBool mInheritStyle;
|
||||||
|
PRPackedBool mHasBaseProto;
|
||||||
|
|
||||||
|
nsWeakPtr mXBLDocInfoWeak; // A pointer back to our doc info. Weak, since it owns us.
|
||||||
|
|
||||||
|
nsSupportsHashtable* mAttributeTable; // A table for attribute entries. Used to efficiently
|
||||||
|
// handle attribute changes.
|
||||||
|
|
||||||
|
nsSupportsHashtable* mInsertionPointTable; // A table of insertion points for placing explicit content
|
||||||
|
// underneath anonymous content.
|
||||||
|
|
||||||
|
PRInt32 mBaseNameSpaceID; // If we extend a tagname/namespace, then that information will
|
||||||
|
nsCOMPtr<nsIAtom> mBaseTag; // be stored in here.
|
||||||
|
};
|
|
@ -54,6 +54,7 @@
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
|
||||||
#include "nsIXBLBinding.h"
|
#include "nsIXBLBinding.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
#include "nsIXBLDocumentInfo.h"
|
#include "nsIXBLDocumentInfo.h"
|
||||||
|
|
||||||
#include "nsIXBLPrototypeHandler.h"
|
#include "nsIXBLPrototypeHandler.h"
|
||||||
|
@ -343,9 +344,6 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
|
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
|
||||||
|
|
||||||
// Construct our prototype handlers.
|
|
||||||
nsXBLService::ConstructPrototypeHandlers(info);
|
|
||||||
|
|
||||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||||
PRBool cached = PR_FALSE;
|
PRBool cached = PR_FALSE;
|
||||||
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
||||||
|
@ -486,7 +484,6 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
||||||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||||
|
|
||||||
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
||||||
nsIAtom* nsXBLService::kHandlersAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
||||||
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
||||||
|
|
||||||
|
@ -526,7 +523,6 @@ nsXBLService::nsXBLService(void)
|
||||||
|
|
||||||
// Create our atoms
|
// Create our atoms
|
||||||
kExtendsAtom = NS_NewAtom("extends");
|
kExtendsAtom = NS_NewAtom("extends");
|
||||||
kHandlersAtom = NS_NewAtom("handlers");
|
|
||||||
kScrollbarAtom = NS_NewAtom("scrollbar");
|
kScrollbarAtom = NS_NewAtom("scrollbar");
|
||||||
kInputAtom = NS_NewAtom("input");
|
kInputAtom = NS_NewAtom("input");
|
||||||
|
|
||||||
|
@ -558,7 +554,6 @@ nsXBLService::~nsXBLService(void)
|
||||||
|
|
||||||
// Release our atoms
|
// Release our atoms
|
||||||
NS_RELEASE(kExtendsAtom);
|
NS_RELEASE(kExtendsAtom);
|
||||||
NS_RELEASE(kHandlersAtom);
|
|
||||||
NS_RELEASE(kScrollbarAtom);
|
NS_RELEASE(kScrollbarAtom);
|
||||||
NS_RELEASE(kInputAtom);
|
NS_RELEASE(kInputAtom);
|
||||||
|
|
||||||
|
@ -915,77 +910,114 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
|
||||||
PRBool allowScripts;
|
PRBool allowScripts;
|
||||||
docInfo->GetScriptAccess(&allowScripts);
|
docInfo->GetScriptAccess(&allowScripts);
|
||||||
|
|
||||||
// We have a doc. Obtain our specific binding element.
|
nsCOMPtr<nsIXBLPrototypeBinding> protoBinding;
|
||||||
// Walk the children looking for the binding that matches the ref
|
docInfo->GetPrototypeBinding(ref, getter_AddRefs(protoBinding));
|
||||||
// specified in the URL.
|
nsCOMPtr<nsIContent> child;
|
||||||
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
if (!protoBinding) {
|
||||||
if (!root)
|
// We have a doc. Obtain our specific binding element.
|
||||||
return NS_ERROR_FAILURE;
|
// Walk the children looking for the binding that matches the ref
|
||||||
|
// specified in the URL.
|
||||||
|
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||||
|
if (!root)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsAutoString bindingName; bindingName.AssignWithConversion( NS_STATIC_CAST(const char*, ref) );
|
nsAutoString bindingName; bindingName.AssignWithConversion( NS_STATIC_CAST(const char*, ref) );
|
||||||
|
|
||||||
PRInt32 count;
|
PRInt32 count;
|
||||||
root->ChildCount(count);
|
root->ChildCount(count);
|
||||||
|
|
||||||
for (PRInt32 i = 0; i < count; i++) {
|
for (PRInt32 i = 0; i < count; i++) {
|
||||||
nsCOMPtr<nsIContent> child;
|
root->ChildAt(i, *getter_AddRefs(child));
|
||||||
root->ChildAt(i, *getter_AddRefs(child));
|
|
||||||
|
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, value);
|
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, value);
|
||||||
|
|
||||||
// If no ref is specified just use this.
|
// If no ref is specified just use this.
|
||||||
if ((bindingName.IsEmpty()) || (bindingName == value)) {
|
if ((bindingName.IsEmpty()) || (bindingName == value)) {
|
||||||
// Check for the presence of an extends attribute
|
// Construct a prototype binding.
|
||||||
nsAutoString extends;
|
NS_NewXBLPrototypeBinding(ref, child, docInfo, getter_AddRefs(protoBinding));
|
||||||
nsCOMPtr<nsIXBLBinding> baseBinding;
|
docInfo->SetPrototypeBinding(ref, protoBinding);
|
||||||
child->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
break;
|
||||||
value = extends;
|
}
|
||||||
if (!extends.IsEmpty()) {
|
}
|
||||||
nsAutoString prefix;
|
}
|
||||||
PRInt32 offset = extends.FindChar(':');
|
else
|
||||||
if (-1 != offset) {
|
protoBinding->GetBindingElement(getter_AddRefs(child));
|
||||||
extends.Left(prefix, offset);
|
|
||||||
extends.Cut(0, offset+1);
|
// If our prototype already has a base, then don't check for an "extends" attribute.
|
||||||
}
|
nsCOMPtr<nsIXBLBinding> baseBinding;
|
||||||
if (prefix.Length() > 0) {
|
nsCOMPtr<nsIXBLPrototypeBinding> baseProto;
|
||||||
// Look up the prefix.
|
PRBool hasBase;
|
||||||
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
protoBinding->HasBasePrototype(&hasBase);
|
||||||
nsCOMPtr<nsINameSpace> nameSpace;
|
protoBinding->GetBasePrototype(getter_AddRefs(baseProto));
|
||||||
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(child));
|
if (baseProto) {
|
||||||
if (xmlContent) {
|
nsCAutoString url;
|
||||||
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
baseProto->GetBindingURI(url);
|
||||||
if (nameSpace) {
|
if (NS_FAILED(GetBindingInternal(aBoundElement, url, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
|
||||||
nsCOMPtr<nsINameSpace> tagSpace;
|
return NS_ERROR_FAILURE; // We aren't ready yet.
|
||||||
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
if (!aPeekOnly) {
|
||||||
if (!tagSpace) {
|
// Make sure to set the base prototype.
|
||||||
// We have a base class binding. Load it right now.
|
baseBinding->GetPrototypeBinding(getter_AddRefs(baseProto));
|
||||||
nsCAutoString urlCString; urlCString.AssignWithConversion(value);
|
protoBinding->SetBasePrototype(baseProto);
|
||||||
GetBindingInternal(aBoundElement, urlCString, aPeekOnly, aIsReady, getter_AddRefs(baseBinding));
|
}
|
||||||
if (!*aIsReady)
|
}
|
||||||
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
|
else if (hasBase) {
|
||||||
|
// Check for the presence of an extends attribute
|
||||||
|
nsAutoString extends;
|
||||||
|
child->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
||||||
|
nsAutoString value(extends);
|
||||||
|
if (extends.IsEmpty())
|
||||||
|
protoBinding->SetHasBasePrototype(PR_FALSE);
|
||||||
|
else {
|
||||||
|
nsAutoString prefix;
|
||||||
|
PRInt32 offset = extends.FindChar(':');
|
||||||
|
if (-1 != offset) {
|
||||||
|
extends.Left(prefix, offset);
|
||||||
|
extends.Cut(0, offset+1);
|
||||||
|
}
|
||||||
|
if (prefix.Length() > 0) {
|
||||||
|
// Look up the prefix.
|
||||||
|
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
||||||
|
nsCOMPtr<nsINameSpace> nameSpace;
|
||||||
|
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(child));
|
||||||
|
if (xmlContent) {
|
||||||
|
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
||||||
|
if (nameSpace) {
|
||||||
|
nsCOMPtr<nsINameSpace> tagSpace;
|
||||||
|
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
||||||
|
if (tagSpace) {
|
||||||
|
// We extend some widget/frame. We don't really have a base binding.
|
||||||
|
protoBinding->SetHasBasePrototype(PR_FALSE);
|
||||||
|
PRInt32 nameSpaceID;
|
||||||
|
tagSpace->GetNameSpaceID(nameSpaceID);
|
||||||
|
nsCOMPtr<nsIAtom> tagName = getter_AddRefs(NS_NewAtom(extends));
|
||||||
|
protoBinding->SetBaseTag(nameSpaceID, tagName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We have a base class binding. Load it right now.
|
||||||
|
nsCAutoString urlCString; urlCString.AssignWithConversion(value);
|
||||||
|
if (NS_FAILED(GetBindingInternal(aBoundElement, urlCString, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
|
||||||
|
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
|
||||||
|
if (!aPeekOnly) {
|
||||||
|
// Make sure to set the base prototype.
|
||||||
|
baseBinding->GetPrototypeBinding(getter_AddRefs(baseProto));
|
||||||
|
protoBinding->SetBasePrototype(baseProto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*aIsReady = PR_TRUE;
|
|
||||||
if (!aPeekOnly) {
|
|
||||||
// Make a new binding
|
|
||||||
NS_NewXBLBinding(uri, ref, aResult);
|
|
||||||
|
|
||||||
// Initialize its bound element.
|
|
||||||
(*aResult)->SetBindingElement(child);
|
|
||||||
(*aResult)->SetAllowScripts(allowScripts);
|
|
||||||
|
|
||||||
if (baseBinding)
|
|
||||||
(*aResult)->SetBaseBinding(baseBinding);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*aIsReady = PR_TRUE;
|
||||||
|
if (!aPeekOnly) {
|
||||||
|
// Make a new binding
|
||||||
|
NS_NewXBLBinding(protoBinding, aResult);
|
||||||
|
if (baseBinding)
|
||||||
|
(*aResult)->SetBaseBinding(baseBinding);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,9 +1090,6 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
|
||||||
if (document) {
|
if (document) {
|
||||||
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
|
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
|
||||||
|
|
||||||
// Construct our prototype handlers.
|
|
||||||
ConstructPrototypeHandlers(info);
|
|
||||||
|
|
||||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||||
PRBool cached = PR_FALSE;
|
PRBool cached = PR_FALSE;
|
||||||
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
||||||
|
@ -1288,40 +1317,6 @@ nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** a
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsXBLService::ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDocument> doc;
|
|
||||||
aInfo->GetDocument(getter_AddRefs(doc));
|
|
||||||
nsCOMPtr<nsIContent> bindings = getter_AddRefs(doc->GetRootContent());
|
|
||||||
PRInt32 childCount;
|
|
||||||
bindings->ChildCount(childCount);
|
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
|
||||||
nsCOMPtr<nsIContent> binding;
|
|
||||||
bindings->ChildAt(i, *getter_AddRefs(binding));
|
|
||||||
|
|
||||||
// See if this binding has a handler elt.
|
|
||||||
nsCOMPtr<nsIContent> handlers;
|
|
||||||
GetImmediateChild(kHandlersAtom, binding, getter_AddRefs(handlers));
|
|
||||||
if (handlers) {
|
|
||||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
|
||||||
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(firstHandler));
|
|
||||||
|
|
||||||
if (firstHandler) {
|
|
||||||
nsAutoString ref;
|
|
||||||
binding->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, ref);
|
|
||||||
|
|
||||||
nsCAutoString cref;
|
|
||||||
cref.AssignWithConversion(ref);
|
|
||||||
|
|
||||||
aInfo->SetPrototypeHandler(cref, firstHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -103,7 +103,6 @@ public:
|
||||||
// This method walks a binding document and removes any text nodes
|
// This method walks a binding document and removes any text nodes
|
||||||
// that contain only whitespace.
|
// that contain only whitespace.
|
||||||
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
||||||
static nsresult ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo);
|
|
||||||
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
|
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
|
||||||
|
|
||||||
// MEMBER VARIABLES
|
// MEMBER VARIABLES
|
||||||
|
@ -126,7 +125,6 @@ public:
|
||||||
|
|
||||||
// XBL Atoms
|
// XBL Atoms
|
||||||
static nsIAtom* kExtendsAtom;
|
static nsIAtom* kExtendsAtom;
|
||||||
static nsIAtom* kHandlersAtom;
|
|
||||||
static nsIAtom* kScrollbarAtom;
|
static nsIAtom* kScrollbarAtom;
|
||||||
static nsIAtom* kInputAtom;
|
static nsIAtom* kInputAtom;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIXBLPrototypeHandler.h"
|
#include "nsIXBLPrototypeHandler.h"
|
||||||
#include "nsXBLWindowKeyHandler.h"
|
#include "nsXBLWindowKeyHandler.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIAtom.h"
|
#include "nsIAtom.h"
|
||||||
#include "nsIDOMNSUIEvent.h"
|
#include "nsIDOMNSUIEvent.h"
|
||||||
|
@ -41,6 +42,9 @@
|
||||||
#include "nsIDOMXULCommandDispatcher.h"
|
#include "nsIDOMXULCommandDispatcher.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
|
#include "nsIDOMDocument.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
|
||||||
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
|
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
|
||||||
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
|
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
|
||||||
|
@ -115,6 +119,33 @@ nsXBLWindowKeyHandler::IsEditor()
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsCString& aDocURI,
|
||||||
|
const nsCString& aRef, nsIXBLPrototypeHandler** aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLPrototypeBinding> binding;
|
||||||
|
aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding));
|
||||||
|
if (!binding) {
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
aInfo->GetDocument(getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||||
|
PRInt32 childCount;
|
||||||
|
root->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
|
nsCOMPtr<nsIContent> child;
|
||||||
|
root->ChildAt(i, *getter_AddRefs(child));
|
||||||
|
nsAutoString id;
|
||||||
|
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
|
||||||
|
if (id.EqualsWithConversion(aRef)) {
|
||||||
|
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
|
||||||
|
aInfo->SetPrototypeBinding(aRef, binding);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding->GetPrototypeHandler(aResult); // Addref happens here.
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLWindowKeyHandler::EnsureHandlers()
|
nsXBLWindowKeyHandler::EnsureHandlers()
|
||||||
{
|
{
|
||||||
|
@ -158,16 +189,24 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
||||||
|
|
||||||
// Now determine which handlers we should be using.
|
// Now determine which handlers we should be using.
|
||||||
if (IsEditor()) {
|
if (IsEditor()) {
|
||||||
mXBLSpecialDocInfo->mPlatformHTMLBindings->GetPrototypeHandler(nsCAutoString("editor"),
|
GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings,
|
||||||
getter_AddRefs(mPlatformHandler));
|
nsCAutoString("chrome://global/content/platformHTMLBindings.xml"),
|
||||||
mXBLSpecialDocInfo->mHTMLBindings->GetPrototypeHandler(nsCAutoString("editorBase"),
|
nsCAutoString("editor"),
|
||||||
getter_AddRefs(mHandler));
|
getter_AddRefs(mPlatformHandler));
|
||||||
|
GetHandlers(mXBLSpecialDocInfo->mHTMLBindings,
|
||||||
|
nsCAutoString("chrome://global/content/htmlBindings.xml"),
|
||||||
|
nsCAutoString("editorBase"),
|
||||||
|
getter_AddRefs(mHandler));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mXBLSpecialDocInfo->mPlatformHTMLBindings->GetPrototypeHandler(nsCAutoString("browser"),
|
GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings,
|
||||||
getter_AddRefs(mPlatformHandler));
|
nsCAutoString("chrome://global/content/platformHTMLBindings.xml"),
|
||||||
mXBLSpecialDocInfo->mHTMLBindings->GetPrototypeHandler(nsCAutoString("browserBase"),
|
nsCAutoString("browser"),
|
||||||
getter_AddRefs(mHandler));
|
getter_AddRefs(mPlatformHandler));
|
||||||
|
GetHandlers(mXBLSpecialDocInfo->mHTMLBindings,
|
||||||
|
nsCAutoString("chrome://global/content/htmlBindings.xml"),
|
||||||
|
nsCAutoString("browserBase"),
|
||||||
|
getter_AddRefs(mHandler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5278,14 +5278,7 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
|
||||||
if (!xblService)
|
if (!xblService)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
// Load the bindings.
|
// Retrieve the anonymous content that we should build.
|
||||||
nsCOMPtr<nsIXBLBinding> binding;
|
|
||||||
PRBool dummy;
|
|
||||||
rv = xblService->LoadBindings(aParent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding), &dummy);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Retrieve the anonymous content that we should build.
|
|
||||||
nsCOMPtr<nsISupportsArray> anonymousItems;
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
||||||
nsCOMPtr<nsIContent> childElement;
|
nsCOMPtr<nsIContent> childElement;
|
||||||
PRBool multiple;
|
PRBool multiple;
|
||||||
|
@ -5524,13 +5517,6 @@ nsCSSFrameConstructor::CreateAnonymousTableCellFrames(nsIPresShell* aPres
|
||||||
if (!xblService)
|
if (!xblService)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
// Load the bindings.
|
|
||||||
nsCOMPtr<nsIXBLBinding> binding;
|
|
||||||
PRBool dummy;
|
|
||||||
rv = xblService->LoadBindings(aParent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding), &dummy);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Retrieve the anonymous content that we should build.
|
// Retrieve the anonymous content that we should build.
|
||||||
nsCOMPtr<nsIContent> childElement;
|
nsCOMPtr<nsIContent> childElement;
|
||||||
nsCOMPtr<nsISupportsArray> anonymousItems;
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
||||||
|
|
|
@ -5278,14 +5278,7 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
|
||||||
if (!xblService)
|
if (!xblService)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
// Load the bindings.
|
// Retrieve the anonymous content that we should build.
|
||||||
nsCOMPtr<nsIXBLBinding> binding;
|
|
||||||
PRBool dummy;
|
|
||||||
rv = xblService->LoadBindings(aParent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding), &dummy);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Retrieve the anonymous content that we should build.
|
|
||||||
nsCOMPtr<nsISupportsArray> anonymousItems;
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
||||||
nsCOMPtr<nsIContent> childElement;
|
nsCOMPtr<nsIContent> childElement;
|
||||||
PRBool multiple;
|
PRBool multiple;
|
||||||
|
@ -5524,13 +5517,6 @@ nsCSSFrameConstructor::CreateAnonymousTableCellFrames(nsIPresShell* aPres
|
||||||
if (!xblService)
|
if (!xblService)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
// Load the bindings.
|
|
||||||
nsCOMPtr<nsIXBLBinding> binding;
|
|
||||||
PRBool dummy;
|
|
||||||
rv = xblService->LoadBindings(aParent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding), &dummy);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Retrieve the anonymous content that we should build.
|
// Retrieve the anonymous content that we should build.
|
||||||
nsCOMPtr<nsIContent> childElement;
|
nsCOMPtr<nsIContent> childElement;
|
||||||
nsCOMPtr<nsISupportsArray> anonymousItems;
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
||||||
|
|
|
@ -79,7 +79,7 @@ CSS_PROP(background-position, background_position, VISUAL)
|
||||||
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
||||||
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-moz-binding, behavior, REFLOW) // XXX bug 3935
|
CSS_PROP(-moz-binding, behavior, FRAMECHANGE) // XXX bug 3935
|
||||||
CSS_PROP(border, border, REFLOW)
|
CSS_PROP(border, border, REFLOW)
|
||||||
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
||||||
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
||||||
|
|
|
@ -79,7 +79,7 @@ CSS_PROP(background-position, background_position, VISUAL)
|
||||||
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
CSS_PROP(background-repeat, background_repeat, VISUAL)
|
||||||
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-x-position, background_x_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
CSS_PROP(-x-background-y-position, background_y_position, VISUAL) // XXX bug 3935
|
||||||
CSS_PROP(-moz-binding, behavior, REFLOW) // XXX bug 3935
|
CSS_PROP(-moz-binding, behavior, FRAMECHANGE) // XXX bug 3935
|
||||||
CSS_PROP(border, border, REFLOW)
|
CSS_PROP(border, border, REFLOW)
|
||||||
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
CSS_PROP(border-bottom, border_bottom, REFLOW)
|
||||||
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
||||||
|
|
|
@ -33,6 +33,7 @@ EXPORTS = \
|
||||||
nsIXBLBinding.h \
|
nsIXBLBinding.h \
|
||||||
nsIXBLBindingAttachedHandler.h \
|
nsIXBLBindingAttachedHandler.h \
|
||||||
nsIXBLDocumentInfo.h \
|
nsIXBLDocumentInfo.h \
|
||||||
|
nsIXBLPrototypeBinding.h \
|
||||||
nsIXBLPrototypeHandler.h \
|
nsIXBLPrototypeHandler.h \
|
||||||
nsIXBLService.h \
|
nsIXBLService.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -2,6 +2,6 @@ nsIBindingManager.h
|
||||||
nsIXBLBinding.h
|
nsIXBLBinding.h
|
||||||
nsIXBLBindingAttachedHandler.h
|
nsIXBLBindingAttachedHandler.h
|
||||||
nsIXBLDocumentInfo.h
|
nsIXBLDocumentInfo.h
|
||||||
|
nsIXBLPrototypeBinding.h
|
||||||
nsIXBLPrototypeHandler.h
|
nsIXBLPrototypeHandler.h
|
||||||
nsIXBLService.h
|
nsIXBLService.h
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ EXPORTS = \
|
||||||
nsIXBLBinding.h \
|
nsIXBLBinding.h \
|
||||||
nsIXBLBindingAttachedHandler.h \
|
nsIXBLBindingAttachedHandler.h \
|
||||||
nsIXBLDocumentInfo.h \
|
nsIXBLDocumentInfo.h \
|
||||||
|
nsIXBLPrototypeBinding.h \
|
||||||
nsIXBLPrototypeHandler.h \
|
nsIXBLPrototypeHandler.h \
|
||||||
nsIXBLService.h \
|
nsIXBLService.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
|
class nsIXBLPrototypeBinding;
|
||||||
|
|
||||||
// {DDDBAD20-C8DF-11d3-97FB-00400553EEF0}
|
// {DDDBAD20-C8DF-11d3-97FB-00400553EEF0}
|
||||||
#define NS_IXBLBINDING_IID \
|
#define NS_IXBLBINDING_IID \
|
||||||
|
@ -48,6 +49,9 @@ class nsIXBLBinding : public nsISupports
|
||||||
public:
|
public:
|
||||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLBINDING_IID; return iid; }
|
static const nsIID& GetIID() { static nsIID iid = NS_IXBLBINDING_IID; return iid; }
|
||||||
|
|
||||||
|
NS_IMETHOD GetPrototypeBinding(nsIXBLPrototypeBinding** aResult)=0;
|
||||||
|
NS_IMETHOD SetPrototypeBinding(nsIXBLPrototypeBinding* aProtoBinding)=0;
|
||||||
|
|
||||||
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult) = 0;
|
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult) = 0;
|
||||||
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding) = 0;
|
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding) = 0;
|
||||||
|
|
||||||
|
@ -92,13 +96,11 @@ public:
|
||||||
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
||||||
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)=0;
|
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)=0;
|
||||||
|
|
||||||
NS_IMETHOD SetAllowScripts(PRBool aFlag)=0;
|
|
||||||
|
|
||||||
NS_IMETHOD MarkForDeath()=0;
|
NS_IMETHOD MarkForDeath()=0;
|
||||||
NS_IMETHOD MarkedForDeath(PRBool* aResult)=0;
|
NS_IMETHOD MarkedForDeath(PRBool* aResult)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsresult
|
extern nsresult
|
||||||
NS_NewXBLBinding(const nsCString& aDocURI, const nsCString& aID, nsIXBLBinding** aResult);
|
NS_NewXBLBinding(nsIXBLPrototypeBinding* aProtoBinding, nsIXBLBinding** aResult);
|
||||||
|
|
||||||
#endif // nsIXBLBinding_h__
|
#endif // nsIXBLBinding_h__
|
||||||
|
|
|
@ -39,6 +39,7 @@ class nsIContent;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
class nsIXBLPrototypeHandler;
|
class nsIXBLPrototypeHandler;
|
||||||
|
class nsIXBLPrototypeBinding;
|
||||||
|
|
||||||
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
|
// {5C4D9674-A2CF-4ddf-9F65-E1806C34D28D}
|
||||||
#define NS_IXBLDOCUMENTINFO_IID \
|
#define NS_IXBLDOCUMENTINFO_IID \
|
||||||
|
@ -55,8 +56,10 @@ public:
|
||||||
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
|
NS_IMETHOD GetScriptAccess(PRBool* aResult)=0;
|
||||||
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
|
NS_IMETHOD SetScriptAccess(PRBool aAccess)=0;
|
||||||
|
|
||||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)=0;
|
NS_IMETHOD GetDocumentURI(nsCString& aDocURI)=0;
|
||||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)=0;
|
|
||||||
|
NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult)=0;
|
||||||
|
NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsresult
|
extern nsresult
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS
|
||||||
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||||
|
* implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||||||
|
* Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef nsIXBLPrototypeBinding_h__
|
||||||
|
#define nsIXBLPrototypeBinding_h__
|
||||||
|
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
class nsIContent;
|
||||||
|
class nsIDocument;
|
||||||
|
class nsIXBLDocumentInfo;
|
||||||
|
class nsIXBLPrototypeHandler;
|
||||||
|
|
||||||
|
// {34D700F5-C1A2-4408-A0B1-DD8F891DD1FE}
|
||||||
|
#define NS_IXBLPROTOTYPEBINDING_IID \
|
||||||
|
{ 0x34d700f5, 0xc1a2, 0x4408, { 0xa0, 0xb1, 0xdd, 0x8f, 0x89, 0x1d, 0xd1, 0xfe } }
|
||||||
|
|
||||||
|
class nsIXBLPrototypeBinding : public nsISupports
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const nsIID& GetIID() { static nsIID iid = NS_IXBLPROTOTYPEBINDING_IID; return iid; }
|
||||||
|
|
||||||
|
NS_IMETHOD GetBindingElement(nsIContent** aResult)=0;
|
||||||
|
NS_IMETHOD SetBindingElement(nsIContent* aElement)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetBindingURI(nsCString& aResult)=0;
|
||||||
|
NS_IMETHOD GetDocURI(nsCString& aResult)=0;
|
||||||
|
NS_IMETHOD GetID(nsCString& aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetAllowScripts(PRBool* aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD InheritsStyle(PRBool* aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler)=0;
|
||||||
|
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||||
|
nsIContent* aChangedElement, nsIContent* aAnonymousContent)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD SetBasePrototype(nsIXBLPrototypeBinding* aBinding)=0;
|
||||||
|
NS_IMETHOD GetBasePrototype(nsIXBLPrototypeBinding** aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD HasBasePrototype(PRBool* aResult)=0;
|
||||||
|
NS_IMETHOD SetHasBasePrototype(PRBool aHasBase)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetXBLDocumentInfo(nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD HasInsertionPoints(PRBool* aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aChild, nsIContent** aResult)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent** aResult, PRBool* aMultipleInsertionPoints)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aTag)=0;
|
||||||
|
NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern nsresult
|
||||||
|
NS_NewXBLPrototypeBinding(const nsCString& aRef,
|
||||||
|
nsIContent* aElement, nsIXBLDocumentInfo* aInfo,
|
||||||
|
nsIXBLPrototypeBinding** aResult);
|
||||||
|
|
||||||
|
#endif // nsIXBLPrototypeBinding_h__
|
|
@ -28,6 +28,7 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
CPPSRCS= \
|
CPPSRCS= \
|
||||||
nsXBLBinding.cpp \
|
nsXBLBinding.cpp \
|
||||||
|
nsXBLPrototypeBinding.cpp \
|
||||||
nsXBLService.cpp \
|
nsXBLService.cpp \
|
||||||
nsXBLEventHandler.cpp \
|
nsXBLEventHandler.cpp \
|
||||||
nsXBLWindowKeyHandler.cpp \
|
nsXBLWindowKeyHandler.cpp \
|
||||||
|
@ -46,6 +47,7 @@ CPPSRCS= \
|
||||||
|
|
||||||
CPP_OBJS= \
|
CPP_OBJS= \
|
||||||
.\$(OBJDIR)\nsXBLBinding.obj \
|
.\$(OBJDIR)\nsXBLBinding.obj \
|
||||||
|
.\$(OBJDIR)\nsXBLPrototypeBinding.obj \
|
||||||
.\$(OBJDIR)\nsXBLEventHandler.obj \
|
.\$(OBJDIR)\nsXBLEventHandler.obj \
|
||||||
.\$(OBJDIR)\nsXBLWindowKeyHandler.obj \
|
.\$(OBJDIR)\nsXBLWindowKeyHandler.obj \
|
||||||
.\$(OBJDIR)\nsXBLKeyHandler.obj \
|
.\$(OBJDIR)\nsXBLKeyHandler.obj \
|
||||||
|
|
|
@ -58,19 +58,20 @@
|
||||||
|
|
||||||
#include "nsIStyleRuleProcessor.h"
|
#include "nsIStyleRuleProcessor.h"
|
||||||
#include "nsIStyleSet.h"
|
#include "nsIStyleSet.h"
|
||||||
#include "nsIXBLPrototypeHandler.h"
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
#include "nsIWeakReference.h"
|
||||||
|
|
||||||
// Static IIDs/CIDs. Try to minimize these.
|
// Static IIDs/CIDs. Try to minimize these.
|
||||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||||
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
||||||
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX What's up with this???
|
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX What's up with this???
|
||||||
|
|
||||||
class nsXBLDocumentInfo : public nsIXBLDocumentInfo
|
class nsXBLDocumentInfo : public nsIXBLDocumentInfo, public nsSupportsWeakReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
nsXBLDocumentInfo(nsIDocument* aDocument);
|
nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument);
|
||||||
virtual ~nsXBLDocumentInfo();
|
virtual ~nsXBLDocumentInfo();
|
||||||
|
|
||||||
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
|
NS_IMETHOD GetDocument(nsIDocument** aResult) { *aResult = mDocument; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
@ -79,32 +80,36 @@ public:
|
||||||
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
|
NS_IMETHOD GetScriptAccess(PRBool* aResult) { *aResult = mScriptAccess; return NS_OK; };
|
||||||
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
|
NS_IMETHOD SetScriptAccess(PRBool aAccess) { mScriptAccess = aAccess; return NS_OK; };
|
||||||
|
|
||||||
NS_IMETHOD GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult);
|
NS_IMETHOD GetDocumentURI(nsCString& aDocURI) { aDocURI = mDocURI; return NS_OK; };
|
||||||
NS_IMETHOD SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler);
|
|
||||||
|
NS_IMETHOD GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult);
|
||||||
|
NS_IMETHOD SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<nsIDocument> mDocument;
|
nsCOMPtr<nsIDocument> mDocument;
|
||||||
|
nsCString mDocURI;
|
||||||
nsCOMPtr<nsISupportsArray> mRuleProcessors;
|
nsCOMPtr<nsISupportsArray> mRuleProcessors;
|
||||||
PRBool mScriptAccess;
|
PRBool mScriptAccess;
|
||||||
nsSupportsHashtable* mHandlerTable;
|
nsSupportsHashtable* mBindingTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Implementation file */
|
/* Implementation file */
|
||||||
NS_IMPL_ISUPPORTS1(nsXBLDocumentInfo, nsIXBLDocumentInfo)
|
NS_IMPL_ISUPPORTS2(nsXBLDocumentInfo, nsIXBLDocumentInfo, nsISupportsWeakReference)
|
||||||
|
|
||||||
nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
|
nsXBLDocumentInfo::nsXBLDocumentInfo(const char* aDocURI, nsIDocument* aDocument)
|
||||||
{
|
{
|
||||||
NS_INIT_ISUPPORTS();
|
NS_INIT_ISUPPORTS();
|
||||||
/* member initializers and constructor code */
|
/* member initializers and constructor code */
|
||||||
|
mDocURI = aDocURI;
|
||||||
mDocument = aDocument;
|
mDocument = aDocument;
|
||||||
mScriptAccess = PR_TRUE;
|
mScriptAccess = PR_TRUE;
|
||||||
mHandlerTable = nsnull;
|
mBindingTable = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
||||||
{
|
{
|
||||||
/* destructor code */
|
/* destructor code */
|
||||||
delete mHandlerTable;
|
delete mBindingTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -144,33 +149,39 @@ nsXBLDocumentInfo::GetRuleProcessors(nsISupportsArray** aResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLDocumentInfo::GetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler** aResult)
|
nsXBLDocumentInfo::GetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding** aResult)
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
if (!mHandlerTable)
|
if (!mBindingTable)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsCStringKey key(aRef);
|
nsCStringKey key(aRef);
|
||||||
*aResult = NS_STATIC_CAST(nsIXBLPrototypeHandler*, mHandlerTable->Get(&key)); // Addref happens here.
|
*aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here.
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLDocumentInfo::SetPrototypeHandler(const nsCString& aRef, nsIXBLPrototypeHandler* aHandler)
|
nsXBLDocumentInfo::SetPrototypeBinding(const nsCString& aRef, nsIXBLPrototypeBinding* aBinding)
|
||||||
{
|
{
|
||||||
if (!mHandlerTable)
|
if (!mBindingTable)
|
||||||
mHandlerTable = new nsSupportsHashtable();
|
mBindingTable = new nsSupportsHashtable();
|
||||||
|
|
||||||
nsCStringKey key(aRef);
|
nsCStringKey key(aRef);
|
||||||
mHandlerTable->Put(&key, aHandler);
|
mBindingTable->Put(&key, aBinding);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
|
nsresult NS_NewXBLDocumentInfo(nsIDocument* aDocument, nsIXBLDocumentInfo** aResult)
|
||||||
{
|
{
|
||||||
*aResult = new nsXBLDocumentInfo(aDocument);
|
nsCOMPtr<nsIURI> url = getter_AddRefs(aDocument->GetDocumentURL());
|
||||||
|
|
||||||
|
nsXPIDLCString str;
|
||||||
|
url->GetSpec(getter_Copies(str));
|
||||||
|
|
||||||
|
*aResult = new nsXBLDocumentInfo((const char*)str, aDocument);
|
||||||
|
|
||||||
NS_IF_ADDREF(*aResult);
|
NS_IF_ADDREF(*aResult);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -683,10 +694,7 @@ nsBindingManager::RemoveLoadingDocListener(const nsCString& aURL)
|
||||||
PRBool PR_CALLBACK MarkForDeath(nsHashKey* aKey, void* aData, void* aClosure)
|
PRBool PR_CALLBACK MarkForDeath(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
{
|
{
|
||||||
nsIXBLBinding* binding = (nsIXBLBinding*)aData;
|
nsIXBLBinding* binding = (nsIXBLBinding*)aData;
|
||||||
nsCAutoString docURI;
|
binding->MarkForDeath();
|
||||||
binding->GetDocURI(docURI);
|
|
||||||
if (!docURI.CompareWithConversion("chrome", PR_FALSE, 6))
|
|
||||||
binding->MarkForDeath();
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,51 +85,6 @@
|
||||||
static char kNameSpaceSeparator = ':';
|
static char kNameSpaceSeparator = ':';
|
||||||
|
|
||||||
// Helper classes
|
// Helper classes
|
||||||
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
|
||||||
#define NS_IXBLATTR_IID \
|
|
||||||
{ 0xa2892b81, 0xced9, 0x11d3, { 0x97, 0xfb, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
|
||||||
|
|
||||||
class nsIXBLAttributeEntry : public nsISupports {
|
|
||||||
public:
|
|
||||||
static const nsIID& GetIID() { static nsIID iid = NS_IXBLATTR_IID; return iid; }
|
|
||||||
|
|
||||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) = 0;
|
|
||||||
NS_IMETHOD GetElement(nsIContent** aResult) = 0;
|
|
||||||
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) = 0;
|
|
||||||
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class nsXBLAttributeEntry : public nsIXBLAttributeEntry {
|
|
||||||
public:
|
|
||||||
NS_IMETHOD GetAttribute(nsIAtom** aResult) { *aResult = mAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
|
||||||
NS_IMETHOD GetElement(nsIContent** aResult) { *aResult = mElement; NS_IF_ADDREF(*aResult); return NS_OK; };
|
|
||||||
|
|
||||||
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) { NS_IF_ADDREF(*aResult = mNext); return NS_OK; }
|
|
||||||
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) { mNext = aEntry; return NS_OK; }
|
|
||||||
|
|
||||||
nsIContent* mElement;
|
|
||||||
nsCOMPtr<nsIAtom> mAttribute;
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> mNext;
|
|
||||||
|
|
||||||
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
|
||||||
return aAllocator.Alloc(aSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void operator delete(void* aPtr, size_t aSize) {
|
|
||||||
nsFixedSizeAllocator::Free(aPtr, aSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsXBLAttributeEntry(nsIAtom* aAtom, nsIContent* aContent) {
|
|
||||||
NS_INIT_REFCNT(); mAttribute = aAtom; mElement = aContent;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~nsXBLAttributeEntry() {};
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
//
|
//
|
||||||
|
@ -193,10 +148,7 @@ nsIAtom* nsXBLBinding::kInheritsAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kEventAtom = nsnull;
|
nsIAtom* nsXBLBinding::kEventAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kPhaseAtom = nsnull;
|
nsIAtom* nsXBLBinding::kPhaseAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
|
nsIAtom* nsXBLBinding::kExtendsAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kChildrenAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLBinding::kValueAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLBinding::kActionAtom = nsnull;
|
nsIAtom* nsXBLBinding::kActionAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kHTMLAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLBinding::kMethodAtom = nsnull;
|
nsIAtom* nsXBLBinding::kMethodAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kParameterAtom = nsnull;
|
nsIAtom* nsXBLBinding::kParameterAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kBodyAtom = nsnull;
|
nsIAtom* nsXBLBinding::kBodyAtom = nsnull;
|
||||||
|
@ -210,19 +162,6 @@ nsIAtom* nsXBLBinding::kReadOnlyAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
|
nsIAtom* nsXBLBinding::kAttachToAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kBindingAttachedAtom = nsnull;
|
nsIAtom* nsXBLBinding::kBindingAttachedAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kBindingDetachedAtom = nsnull;
|
nsIAtom* nsXBLBinding::kBindingDetachedAtom = nsnull;
|
||||||
nsIAtom* nsXBLBinding::kInheritStyleAtom = nsnull;
|
|
||||||
|
|
||||||
nsIXBLService* nsXBLBinding::gXBLService = nsnull;
|
|
||||||
|
|
||||||
nsFixedSizeAllocator nsXBLBinding::kPool;
|
|
||||||
|
|
||||||
static const size_t kBucketSizes[] = {
|
|
||||||
sizeof(nsXBLAttributeEntry)
|
|
||||||
};
|
|
||||||
|
|
||||||
static const PRInt32 kNumBuckets = sizeof(kBucketSizes)/sizeof(size_t);
|
|
||||||
static const PRInt32 kNumElements = 128;
|
|
||||||
static const PRInt32 kInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLAttributeEntry))) * kNumElements;
|
|
||||||
|
|
||||||
nsXBLBinding::EventHandlerMapEntry
|
nsXBLBinding::EventHandlerMapEntry
|
||||||
nsXBLBinding::kEventHandlerMap[] = {
|
nsXBLBinding::kEventHandlerMap[] = {
|
||||||
|
@ -283,22 +222,17 @@ nsXBLBinding::kEventHandlerMap[] = {
|
||||||
NS_IMPL_ISUPPORTS1(nsXBLBinding, nsIXBLBinding)
|
NS_IMPL_ISUPPORTS1(nsXBLBinding, nsIXBLBinding)
|
||||||
|
|
||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
nsXBLBinding::nsXBLBinding(nsIXBLPrototypeBinding* aBinding)
|
||||||
: mDocURI(aDocURI), mID(aID), mFirstHandler(nsnull),
|
: mFirstHandler(nsnull),
|
||||||
mIsStyleBinding(PR_TRUE),
|
mIsStyleBinding(PR_TRUE),
|
||||||
mAllowScripts(PR_TRUE),
|
mMarkedForDeath(PR_FALSE)
|
||||||
mInheritStyle(PR_TRUE),
|
|
||||||
mMarkedForDeath(PR_FALSE),
|
|
||||||
mAttributeTable(nsnull),
|
|
||||||
mInsertionPointTable(nsnull)
|
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
mPrototypeBinding = aBinding;
|
||||||
gRefCnt++;
|
gRefCnt++;
|
||||||
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
|
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
|
||||||
|
|
||||||
if (gRefCnt == 1) {
|
if (gRefCnt == 1) {
|
||||||
kPool.Init("XBL Attribute Entries", kBucketSizes, kNumBuckets, kInitialSize);
|
|
||||||
|
|
||||||
kXULTemplateAtom = NS_NewAtom("template");
|
kXULTemplateAtom = NS_NewAtom("template");
|
||||||
kXULObservesAtom = NS_NewAtom("observes");
|
kXULObservesAtom = NS_NewAtom("observes");
|
||||||
|
|
||||||
|
@ -311,9 +245,6 @@ nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
||||||
kEventAtom = NS_NewAtom("event");
|
kEventAtom = NS_NewAtom("event");
|
||||||
kPhaseAtom = NS_NewAtom("phase");
|
kPhaseAtom = NS_NewAtom("phase");
|
||||||
kExtendsAtom = NS_NewAtom("extends");
|
kExtendsAtom = NS_NewAtom("extends");
|
||||||
kChildrenAtom = NS_NewAtom("children");
|
|
||||||
kHTMLAtom = NS_NewAtom("html");
|
|
||||||
kValueAtom = NS_NewAtom("value");
|
|
||||||
kActionAtom = NS_NewAtom("action");
|
kActionAtom = NS_NewAtom("action");
|
||||||
kMethodAtom = NS_NewAtom("method");
|
kMethodAtom = NS_NewAtom("method");
|
||||||
kParameterAtom = NS_NewAtom("parameter");
|
kParameterAtom = NS_NewAtom("parameter");
|
||||||
|
@ -328,11 +259,6 @@ nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
||||||
kAttachToAtom = NS_NewAtom("attachto");
|
kAttachToAtom = NS_NewAtom("attachto");
|
||||||
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
kBindingAttachedAtom = NS_NewAtom("bindingattached");
|
||||||
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
kBindingDetachedAtom = NS_NewAtom("bindingdetached");
|
||||||
kInheritStyleAtom = NS_NewAtom("inheritstyle");
|
|
||||||
|
|
||||||
nsServiceManager::GetService("@mozilla.org/xbl;1",
|
|
||||||
NS_GET_IID(nsIXBLService),
|
|
||||||
(nsISupports**) &gXBLService);
|
|
||||||
|
|
||||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||||
while (entry->mAttributeName) {
|
while (entry->mAttributeName) {
|
||||||
|
@ -345,9 +271,6 @@ nsXBLBinding::nsXBLBinding(const nsCString& aDocURI, const nsCString& aID)
|
||||||
|
|
||||||
nsXBLBinding::~nsXBLBinding(void)
|
nsXBLBinding::~nsXBLBinding(void)
|
||||||
{
|
{
|
||||||
delete mAttributeTable;
|
|
||||||
delete mInsertionPointTable;
|
|
||||||
|
|
||||||
gRefCnt--;
|
gRefCnt--;
|
||||||
// printf("REF COUNT DOWN: %d %s\n", gRefCnt, (const char*)mID);
|
// printf("REF COUNT DOWN: %d %s\n", gRefCnt, (const char*)mID);
|
||||||
|
|
||||||
|
@ -364,9 +287,6 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||||
NS_RELEASE(kEventAtom);
|
NS_RELEASE(kEventAtom);
|
||||||
NS_RELEASE(kPhaseAtom);
|
NS_RELEASE(kPhaseAtom);
|
||||||
NS_RELEASE(kExtendsAtom);
|
NS_RELEASE(kExtendsAtom);
|
||||||
NS_RELEASE(kChildrenAtom);
|
|
||||||
NS_RELEASE(kHTMLAtom);
|
|
||||||
NS_RELEASE(kValueAtom);
|
|
||||||
NS_RELEASE(kActionAtom);
|
NS_RELEASE(kActionAtom);
|
||||||
NS_RELEASE(kMethodAtom);
|
NS_RELEASE(kMethodAtom);
|
||||||
NS_RELEASE(kParameterAtom);
|
NS_RELEASE(kParameterAtom);
|
||||||
|
@ -380,10 +300,6 @@ nsXBLBinding::~nsXBLBinding(void)
|
||||||
NS_RELEASE(kReadOnlyAtom);
|
NS_RELEASE(kReadOnlyAtom);
|
||||||
NS_RELEASE(kAttachToAtom);
|
NS_RELEASE(kAttachToAtom);
|
||||||
NS_RELEASE(kBindingAttachedAtom);
|
NS_RELEASE(kBindingAttachedAtom);
|
||||||
NS_RELEASE(kInheritStyleAtom);
|
|
||||||
|
|
||||||
nsServiceManager::ReleaseService("@mozilla.org/xbl;1", gXBLService);
|
|
||||||
gXBLService = nsnull;
|
|
||||||
|
|
||||||
EventHandlerMapEntry* entry = kEventHandlerMap;
|
EventHandlerMapEntry* entry = kEventHandlerMap;
|
||||||
while (entry->mAttributeName) {
|
while (entry->mAttributeName) {
|
||||||
|
@ -448,32 +364,34 @@ nsXBLBinding::SetAnonymousContent(nsIContent* aParent)
|
||||||
child->SetBindingParent(mBoundElement);
|
child->SetBindingParent(mBoundElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (3) We need to insert entries into our attribute table for any elements
|
return NS_OK;
|
||||||
// that are inheriting attributes. This table allows us to quickly determine
|
}
|
||||||
// which elements in our anonymous content need to be updated when attributes change.
|
|
||||||
ConstructAttributeTable(aParent);
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLBinding::GetPrototypeBinding(nsIXBLPrototypeBinding** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mPrototypeBinding;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLBinding::SetPrototypeBinding(nsIXBLPrototypeBinding* aProtoBinding)
|
||||||
|
{
|
||||||
|
mPrototypeBinding = aProtoBinding;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetBindingElement(nsIContent** aResult)
|
nsXBLBinding::GetBindingElement(nsIContent** aResult)
|
||||||
{
|
{
|
||||||
*aResult = mBinding;
|
return mPrototypeBinding->GetBindingElement(aResult);
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::SetBindingElement(nsIContent* aElement)
|
nsXBLBinding::SetBindingElement(nsIContent* aElement)
|
||||||
{
|
{
|
||||||
mBinding = aElement;
|
return mPrototypeBinding->SetBindingElement(aElement);
|
||||||
nsAutoString inheritStyle;
|
|
||||||
mBinding->GetAttribute(kNameSpaceID_None, kInheritStyleAtom, inheritStyle);
|
|
||||||
if (inheritStyle == NS_LITERAL_STRING("false"))
|
|
||||||
mInheritStyle = PR_FALSE;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -499,7 +417,7 @@ nsXBLBinding::HasStyleSheets(PRBool* aResolveStyle)
|
||||||
// Find out if we need to re-resolve style. We'll need to do this
|
// Find out if we need to re-resolve style. We'll need to do this
|
||||||
// if we have additional stylesheets in our binding document.
|
// if we have additional stylesheets in our binding document.
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
mPrototypeBinding->GetXBLDocumentInfo(mBoundElement, getter_AddRefs(info));
|
||||||
if (!info)
|
if (!info)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nsCOMPtr<nsISupportsArray> rules;
|
nsCOMPtr<nsISupportsArray> rules;
|
||||||
|
@ -528,87 +446,86 @@ nsXBLBinding::GenerateAnonymousContent(nsIContent* aBoundElement)
|
||||||
else return NS_OK;
|
else return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plan to build the content by default.
|
// Find out if we're really building kids or if we're just
|
||||||
PRBool buildContent = PR_TRUE;
|
// using the attribute-setting shorthand hack.
|
||||||
|
PRInt32 contentCount;
|
||||||
|
content->ChildCount(contentCount);
|
||||||
|
|
||||||
// See if there's an includes attribute.
|
// Plan to build the content by default.
|
||||||
nsAutoString includes;
|
PRBool hasContent = (contentCount > 0);
|
||||||
content->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
|
PRBool hasInsertionPoints;
|
||||||
if ( includes != NS_LITERAL_STRING("*")) {
|
mPrototypeBinding->HasInsertionPoints(&hasInsertionPoints);
|
||||||
PRInt32 childCount;
|
|
||||||
aBoundElement->ChildCount(childCount);
|
if (hasContent && !hasInsertionPoints) {
|
||||||
if (childCount > 0) {
|
// See if there's an includes attribute.
|
||||||
// We'll only build content if all the explicit children are
|
nsAutoString includes;
|
||||||
// in the includes list.
|
content->GetAttribute(kNameSpaceID_None, kIncludesAtom, includes);
|
||||||
// Walk the children and ensure that all of them
|
if (includes != NS_LITERAL_STRING("*")) {
|
||||||
// are in the includes array.
|
PRInt32 childCount;
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
aBoundElement->ChildCount(childCount);
|
||||||
nsCOMPtr<nsIContent> child;
|
if (childCount > 0) {
|
||||||
aBoundElement->ChildAt(i, *getter_AddRefs(child));
|
// We'll only build content if all the explicit children are
|
||||||
nsCOMPtr<nsIAtom> tag;
|
// in the includes list.
|
||||||
child->GetTag(*getter_AddRefs(tag));
|
// Walk the children and ensure that all of them
|
||||||
if (!IsInExcludesList(tag, includes)) {
|
// are in the includes array.
|
||||||
// XXX HACK! Ignore <template> and <observes>
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
if (tag.get() != kXULTemplateAtom &&
|
nsCOMPtr<nsIContent> child;
|
||||||
tag.get() != kXULObservesAtom) {
|
aBoundElement->ChildAt(i, *getter_AddRefs(child));
|
||||||
buildContent = PR_FALSE;
|
nsCOMPtr<nsIAtom> tag;
|
||||||
break;
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
|
if (!IsInExcludesList(tag, includes)) {
|
||||||
|
// XXX HACK! Ignore <template> and <observes>
|
||||||
|
if (tag.get() != kXULTemplateAtom &&
|
||||||
|
tag.get() != kXULObservesAtom) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> childrenElement;
|
if (hasContent) {
|
||||||
// see if we have a <children/> element
|
nsCOMPtr<nsIContent> clonedContent;
|
||||||
GetNestedChild(kChildrenAtom, content, getter_AddRefs(childrenElement));
|
|
||||||
if (childrenElement)
|
|
||||||
buildContent = PR_TRUE;
|
|
||||||
|
|
||||||
if (buildContent) {
|
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content));
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content));
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> clonedNode;
|
nsCOMPtr<nsIDOMNode> clonedNode;
|
||||||
domElement->CloneNode(PR_TRUE, getter_AddRefs(clonedNode));
|
domElement->CloneNode(PR_TRUE, getter_AddRefs(clonedNode));
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
|
clonedContent = do_QueryInterface(clonedNode);
|
||||||
SetAnonymousContent(clonedContent);
|
SetAnonymousContent(clonedContent);
|
||||||
|
}
|
||||||
|
|
||||||
// Always check the content element for potential attributes.
|
// Always check the content element for potential attributes.
|
||||||
PRInt32 length;
|
// This shorthand hack always happens, even when we didn't
|
||||||
clonedContent->GetAttributeCount(length);
|
// build anonymous content.
|
||||||
|
PRInt32 length;
|
||||||
|
content->GetAttributeCount(length);
|
||||||
|
|
||||||
PRInt32 namespaceID;
|
PRInt32 namespaceID;
|
||||||
nsCOMPtr<nsIAtom> name;
|
nsCOMPtr<nsIAtom> name;
|
||||||
nsCOMPtr<nsIAtom> prefix;
|
nsCOMPtr<nsIAtom> prefix;
|
||||||
|
|
||||||
for (PRInt32 i = 0; i < length; ++i)
|
for (PRInt32 i = 0; i < length; ++i) {
|
||||||
{
|
content->GetAttributeNameAt(0, namespaceID, *getter_AddRefs(name), *getter_AddRefs(prefix));
|
||||||
clonedContent->GetAttributeNameAt(0, namespaceID, *getter_AddRefs(name), *getter_AddRefs(prefix));
|
|
||||||
|
|
||||||
if (name.get() != kIncludesAtom) {
|
if (name.get() != kIncludesAtom) {
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
mBoundElement->GetAttribute(namespaceID, name, value);
|
mBoundElement->GetAttribute(namespaceID, name, value);
|
||||||
if (value.IsEmpty()) {
|
if (value.IsEmpty()) {
|
||||||
nsAutoString value2;
|
nsAutoString value2;
|
||||||
clonedContent->GetAttribute(namespaceID, name, value2);
|
content->GetAttribute(namespaceID, name, value2);
|
||||||
mBoundElement->SetAttribute(namespaceID, name, value2, PR_FALSE);
|
mBoundElement->SetAttribute(namespaceID, name, value2, PR_FALSE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conserve space by wiping the attributes off the clone.
|
|
||||||
clonedContent->UnsetAttribute(namespaceID, name, PR_FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childrenElement)
|
// Conserve space by wiping the attributes off the clone.
|
||||||
BuildInsertionTable();
|
if (mContent)
|
||||||
|
mContent->UnsetAttribute(namespaceID, name, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX Handle selective decision to build anonymous content.
|
if (mContent)
|
||||||
if (mNextBinding) {
|
mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent);
|
||||||
return mNextBinding->GenerateAnonymousContent(aBoundElement);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -620,12 +537,12 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
||||||
if (AllowScripts()) {
|
if (AllowScripts()) {
|
||||||
// Fetch the handlers prototypes for this binding.
|
// Fetch the handlers prototypes for this binding.
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
mPrototypeBinding->GetXBLDocumentInfo(mBoundElement, getter_AddRefs(info));
|
||||||
if (!info)
|
if (!info)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
nsCOMPtr<nsIXBLPrototypeHandler> handlerChain;
|
||||||
info->GetPrototypeHandler(mID, getter_AddRefs(handlerChain));
|
mPrototypeBinding->GetPrototypeHandler(getter_AddRefs(handlerChain));
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
nsCOMPtr<nsIXBLPrototypeHandler> curr = handlerChain;
|
||||||
nsXBLEventHandler* currHandler = nsnull;
|
nsXBLEventHandler* currHandler = nsnull;
|
||||||
|
@ -1058,116 +975,20 @@ nsXBLBinding::GetBaseTag(PRInt32* aNameSpaceID, nsIAtom** aResult)
|
||||||
{
|
{
|
||||||
if (mNextBinding)
|
if (mNextBinding)
|
||||||
return mNextBinding->GetBaseTag(aNameSpaceID, aResult);
|
return mNextBinding->GetBaseTag(aNameSpaceID, aResult);
|
||||||
|
return mPrototypeBinding->GetBaseTag(aNameSpaceID, aResult);
|
||||||
// XXX Cache the value as a "base" attribute so that we don't do this
|
|
||||||
// check over and over each time the bound element occurs.
|
|
||||||
|
|
||||||
// We are the base binding. Obtain the extends attribute.
|
|
||||||
nsAutoString extends;
|
|
||||||
mBinding->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
|
||||||
|
|
||||||
if (!extends.IsEmpty()) {
|
|
||||||
// Obtain the namespace prefix.
|
|
||||||
nsAutoString prefix;
|
|
||||||
PRInt32 offset = extends.FindChar(kNameSpaceSeparator);
|
|
||||||
if (-1 != offset) {
|
|
||||||
extends.Left(prefix, offset);
|
|
||||||
extends.Cut(0, offset+1);
|
|
||||||
}
|
|
||||||
if (prefix.Length() > 0) {
|
|
||||||
// Look up the prefix.
|
|
||||||
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
|
||||||
nsCOMPtr<nsINameSpace> nameSpace;
|
|
||||||
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(mBinding));
|
|
||||||
if (xmlContent) {
|
|
||||||
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
|
||||||
|
|
||||||
if (nameSpace) {
|
|
||||||
nsCOMPtr<nsINameSpace> tagSpace;
|
|
||||||
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
|
||||||
if (tagSpace) {
|
|
||||||
// Score! Return the tag.
|
|
||||||
tagSpace->GetNameSpaceID(*aNameSpaceID);
|
|
||||||
*aResult = NS_NewAtom(extends); // The addref happens here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag)
|
||||||
{
|
{
|
||||||
// XXX check to see if we inherit anonymous content from a base binding
|
// XXX Change if we ever allow multiple bindings in a chain to contribute anonymous content
|
||||||
// if (mNextBinding)
|
if (!mContent) {
|
||||||
// mNextBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag);
|
if (mNextBinding)
|
||||||
|
return mNextBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag);
|
||||||
if (!mAttributeTable)
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsISupportsKey key(aAttribute);
|
|
||||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
|
||||||
mAttributeTable->Get(&key)));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> xblAttr = do_QueryInterface(supports);
|
|
||||||
if (!xblAttr)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Iterate over the elements in the array.
|
|
||||||
|
|
||||||
while (xblAttr) {
|
|
||||||
nsCOMPtr<nsIContent> element;
|
|
||||||
nsCOMPtr<nsIAtom> setAttr;
|
|
||||||
xblAttr->GetElement(getter_AddRefs(element));
|
|
||||||
xblAttr->GetAttribute(getter_AddRefs(setAttr));
|
|
||||||
|
|
||||||
if (aRemoveFlag)
|
|
||||||
element->UnsetAttribute(aNameSpaceID, setAttr, PR_TRUE);
|
|
||||||
else {
|
|
||||||
nsAutoString value;
|
|
||||||
nsresult result = mBoundElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
|
||||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
|
||||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
|
||||||
|
|
||||||
if (attrPresent)
|
|
||||||
element->SetAttribute(aNameSpaceID, setAttr, value, PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if we're the <html> tag in XUL, and see if value is being
|
|
||||||
// set or unset on us.
|
|
||||||
nsCOMPtr<nsIAtom> tag;
|
|
||||||
element->GetTag(*getter_AddRefs(tag));
|
|
||||||
if ((tag.get() == kHTMLAtom) && (setAttr.get() == kValueAtom)) {
|
|
||||||
// Flush out all our kids.
|
|
||||||
PRInt32 childCount;
|
|
||||||
element->ChildCount(childCount);
|
|
||||||
for (PRInt32 i = 0; i < childCount; i++)
|
|
||||||
element->RemoveChildAt(0, PR_TRUE);
|
|
||||||
|
|
||||||
if (!aRemoveFlag) {
|
|
||||||
// Construct a new text node and insert it.
|
|
||||||
nsAutoString value;
|
|
||||||
mBoundElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
|
||||||
if (!value.IsEmpty()) {
|
|
||||||
nsCOMPtr<nsIDOMText> textNode;
|
|
||||||
nsCOMPtr<nsIDocument> doc;
|
|
||||||
mBoundElement->GetDocument(*getter_AddRefs(doc));
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
|
||||||
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
|
||||||
nsCOMPtr<nsIDOMNode> dummy;
|
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(element));
|
|
||||||
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = xblAttr;
|
|
||||||
tmpAttr->GetNext(getter_AddRefs(xblAttr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return mPrototypeBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag, mBoundElement, mContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1254,7 +1075,7 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
||||||
GetAnonymousContent(getter_AddRefs(anonymous));
|
GetAnonymousContent(getter_AddRefs(anonymous));
|
||||||
if (anonymous) {
|
if (anonymous) {
|
||||||
if (mIsStyleBinding)
|
if (mIsStyleBinding)
|
||||||
anonymous->SetDocument(nsnull, PR_TRUE, AllowScripts()); // Kill it.
|
anonymous->SetDocument(nsnull, PR_TRUE, PR_TRUE); // Kill it.
|
||||||
else anonymous->SetDocument(aNewDocument, PR_TRUE, AllowScripts()); // Keep it around.
|
else anonymous->SetDocument(aNewDocument, PR_TRUE, AllowScripts()); // Keep it around.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1265,32 +1086,32 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetBindingURI(nsCString& aResult)
|
nsXBLBinding::GetBindingURI(nsCString& aResult)
|
||||||
{
|
{
|
||||||
aResult = mDocURI;
|
return mPrototypeBinding->GetBindingURI(aResult);
|
||||||
aResult += "#";
|
|
||||||
aResult += mID;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetDocURI(nsCString& aResult)
|
nsXBLBinding::GetDocURI(nsCString& aResult)
|
||||||
{
|
{
|
||||||
aResult = mDocURI;
|
return mPrototypeBinding->GetDocURI(aResult);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetID(nsCString& aResult)
|
nsXBLBinding::GetID(nsCString& aResult)
|
||||||
{
|
{
|
||||||
aResult = mID;
|
return mPrototypeBinding->GetID(aResult);
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::InheritsStyle(PRBool* aResult)
|
nsXBLBinding::InheritsStyle(PRBool* aResult)
|
||||||
{
|
{
|
||||||
|
// XXX Will have to change if we ever allow multiple bindings to contribute anonymous content.
|
||||||
|
// Most derived binding with anonymous content determines style inheritance for now.
|
||||||
|
|
||||||
|
// XXX What about bindings with <content> but no kids, e.g., my treecell-text binding?
|
||||||
if (mContent)
|
if (mContent)
|
||||||
*aResult = mInheritStyle;
|
return mPrototypeBinding->InheritsStyle(aResult);
|
||||||
else if (mNextBinding)
|
|
||||||
|
if (mNextBinding)
|
||||||
return mNextBinding->InheritsStyle(aResult);
|
return mNextBinding->InheritsStyle(aResult);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1307,7 +1128,7 @@ nsXBLBinding::WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
gXBLService->GetXBLDocumentInfo(mDocURI, mBoundElement, getter_AddRefs(info));
|
mPrototypeBinding->GetXBLDocumentInfo(mBoundElement, getter_AddRefs(info));
|
||||||
if (!info)
|
if (!info)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nsCOMPtr<nsISupportsArray> rules;
|
nsCOMPtr<nsISupportsArray> rules;
|
||||||
|
@ -1422,12 +1243,15 @@ nsXBLBinding::InitClass(const nsCString& aClassName, nsIScriptContext* aContext,
|
||||||
void
|
void
|
||||||
nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIContent> binding;
|
||||||
|
mPrototypeBinding->GetBindingElement(getter_AddRefs(binding));
|
||||||
|
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
PRInt32 childCount;
|
PRInt32 childCount;
|
||||||
mBinding->ChildCount(childCount);
|
binding->ChildCount(childCount);
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
nsCOMPtr<nsIContent> child;
|
nsCOMPtr<nsIContent> child;
|
||||||
mBinding->ChildAt(i, *getter_AddRefs(child));
|
binding->ChildAt(i, *getter_AddRefs(child));
|
||||||
nsCOMPtr<nsIAtom> tag;
|
nsCOMPtr<nsIAtom> tag;
|
||||||
child->GetTag(*getter_AddRefs(tag));
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
if (aTag == tag.get()) {
|
if (aTag == tag.get()) {
|
||||||
|
@ -1440,114 +1264,6 @@ nsXBLBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsXBLBinding::GetNestedChild(nsIAtom* aTag, nsIContent* aContent, nsIContent** aResult)
|
|
||||||
{
|
|
||||||
*aResult = nsnull;
|
|
||||||
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()) {
|
|
||||||
*aResult = aContent; // We return the parent of the correct child.
|
|
||||||
NS_ADDREF(*aResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GetNestedChild(aTag, child, aResult);
|
|
||||||
if (*aResult)
|
|
||||||
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);
|
|
||||||
PRUint32 i;
|
|
||||||
for (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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
nsMemory::Free(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove the <children> elements.
|
|
||||||
for (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));
|
|
||||||
PRInt32 index;
|
|
||||||
parent->IndexOf(child, index);
|
|
||||||
parent->RemoveChildAt(index, PR_FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
||||||
{
|
{
|
||||||
|
@ -1578,113 +1294,6 @@ nsXBLBinding::IsInExcludesList(nsIAtom* aTag, const nsString& aList)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXBLBinding::ConstructAttributeTable(nsIContent* aElement)
|
|
||||||
{
|
|
||||||
nsAutoString inherits;
|
|
||||||
aElement->GetAttribute(kNameSpaceID_None, kInheritsAtom, inherits);
|
|
||||||
if (!inherits.IsEmpty()) {
|
|
||||||
if (!mAttributeTable) {
|
|
||||||
mAttributeTable = new nsSupportsHashtable(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The user specified at least one attribute.
|
|
||||||
char* str = inherits.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 attribute.
|
|
||||||
nsCOMPtr<nsIAtom> atom;
|
|
||||||
nsCOMPtr<nsIAtom> attribute;
|
|
||||||
|
|
||||||
// Figure out if this token contains a :.
|
|
||||||
nsAutoString attrTok; attrTok.AssignWithConversion(token);
|
|
||||||
PRInt32 index = attrTok.Find("=", PR_TRUE);
|
|
||||||
if (index != -1) {
|
|
||||||
// This attribute maps to something different.
|
|
||||||
nsAutoString left, right;
|
|
||||||
attrTok.Left(left, index);
|
|
||||||
attrTok.Right(right, attrTok.Length()-index-1);
|
|
||||||
|
|
||||||
atom = getter_AddRefs(NS_NewAtom(right.GetUnicode()));
|
|
||||||
attribute = getter_AddRefs(NS_NewAtom(left.GetUnicode()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsAutoString tok; tok.AssignWithConversion(token);
|
|
||||||
atom = getter_AddRefs(NS_NewAtom(tok.GetUnicode()));
|
|
||||||
attribute = atom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an XBL attribute entry.
|
|
||||||
nsXBLAttributeEntry* xblAttr = new (kPool) nsXBLAttributeEntry(attribute, aElement);
|
|
||||||
|
|
||||||
// Now we should see if some element within our anonymous
|
|
||||||
// content is already observing this attribute.
|
|
||||||
nsISupportsKey key(atom);
|
|
||||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
|
||||||
mAttributeTable->Get(&key)));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> entry = do_QueryInterface(supports);
|
|
||||||
if (!entry) {
|
|
||||||
// Put it in the table.
|
|
||||||
mAttributeTable->Put(&key, xblAttr);
|
|
||||||
} else {
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> attr = entry;
|
|
||||||
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = entry;
|
|
||||||
do {
|
|
||||||
attr = tmpAttr;
|
|
||||||
attr->GetNext(getter_AddRefs(tmpAttr));
|
|
||||||
} while (tmpAttr);
|
|
||||||
attr->SetNext(xblAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now make sure that this attribute is initially set.
|
|
||||||
// XXX How to deal with NAMESPACES!!!?
|
|
||||||
nsAutoString value;
|
|
||||||
nsresult result = mBoundElement->GetAttribute(kNameSpaceID_None, atom, value);
|
|
||||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
|
||||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
|
||||||
|
|
||||||
if (attrPresent) {
|
|
||||||
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_FALSE);
|
|
||||||
nsCOMPtr<nsIAtom> tag;
|
|
||||||
aElement->GetTag(*getter_AddRefs(tag));
|
|
||||||
if ((tag.get() == kHTMLAtom) && (attribute.get() == kValueAtom) && !value.IsEmpty()) {
|
|
||||||
nsCOMPtr<nsIDOMText> textNode;
|
|
||||||
nsCOMPtr<nsIDocument> doc;
|
|
||||||
mBoundElement->GetDocument(*getter_AddRefs(doc));
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
|
||||||
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
|
||||||
nsCOMPtr<nsIDOMNode> dummy;
|
|
||||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(aElement));
|
|
||||||
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove the inherits attribute from the cloned element. It is used
|
|
||||||
// on the template only, and we don't need it anymore.
|
|
||||||
aElement->UnsetAttribute(kNameSpaceID_None, kInheritsAtom, PR_FALSE);
|
|
||||||
|
|
||||||
token = nsCRT::strtok( newStr, ", ", &newStr );
|
|
||||||
}
|
|
||||||
|
|
||||||
nsMemory::Free(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recur into our children.
|
|
||||||
PRInt32 childCount;
|
|
||||||
aElement->ChildCount(childCount);
|
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
|
||||||
nsCOMPtr<nsIContent> child;
|
|
||||||
aElement->ChildAt(i, *getter_AddRefs(child));
|
|
||||||
ConstructAttributeTable(child);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsXBLBinding::GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound)
|
nsXBLBinding::GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound)
|
||||||
{
|
{
|
||||||
|
@ -1771,28 +1380,19 @@ nsXBLBinding::GetTextData(nsIContent *aParent, nsString& aResult)
|
||||||
PRBool
|
PRBool
|
||||||
nsXBLBinding::AllowScripts()
|
nsXBLBinding::AllowScripts()
|
||||||
{
|
{
|
||||||
return mAllowScripts;
|
PRBool result;
|
||||||
|
mPrototypeBinding->GetAllowScripts(&result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult)
|
nsXBLBinding::GetInsertionPoint(nsIContent* aChild, nsIContent** aResult)
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
if (mInsertionPointTable) {
|
if (!mContent)
|
||||||
nsCOMPtr<nsIAtom> tag;
|
return NS_OK;
|
||||||
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;
|
return mPrototypeBinding->GetInsertionPoint(mBoundElement, mContent, aChild, aResult);
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1800,18 +1400,10 @@ nsXBLBinding::GetSingleInsertionPoint(nsIContent** aResult, PRBool* aMultipleIns
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
*aMultipleInsertionPoints = PR_FALSE;
|
*aMultipleInsertionPoints = PR_FALSE;
|
||||||
if (mInsertionPointTable) {
|
if (!mContent)
|
||||||
if(mInsertionPointTable->Count() == 1) {
|
return NS_OK;
|
||||||
nsISupportsKey key(kChildrenAtom);
|
|
||||||
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
|
return mPrototypeBinding->GetSingleInsertionPoint(mBoundElement, mContent, aResult, aMultipleInsertionPoints);
|
||||||
mInsertionPointTable->Get(&key)));
|
|
||||||
*aResult = content;
|
|
||||||
NS_IF_ADDREF(*aResult);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*aMultipleInsertionPoints = PR_TRUE;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1844,6 +1436,7 @@ NS_IMETHODIMP
|
||||||
nsXBLBinding::MarkForDeath()
|
nsXBLBinding::MarkForDeath()
|
||||||
{
|
{
|
||||||
mMarkedForDeath = PR_TRUE;
|
mMarkedForDeath = PR_TRUE;
|
||||||
|
ExecuteDetachedHandler();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1857,12 +1450,11 @@ nsXBLBinding::MarkedForDeath(PRBool* aResult)
|
||||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewXBLBinding(const nsCString& aDocURI, const nsCString& aRef, nsIXBLBinding** aResult)
|
NS_NewXBLBinding(nsIXBLPrototypeBinding* aBinding, nsIXBLBinding** aResult)
|
||||||
{
|
{
|
||||||
*aResult = new nsXBLBinding(aDocURI, aRef);
|
*aResult = new nsXBLBinding(aBinding);
|
||||||
if (!*aResult)
|
if (!*aResult)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
NS_ADDREF(*aResult);
|
NS_ADDREF(*aResult);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIXBLBinding.h"
|
#include "nsIXBLBinding.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
@ -42,6 +43,9 @@ class nsXBLBinding: public nsIXBLBinding
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
// nsIXBLBinding
|
// nsIXBLBinding
|
||||||
|
NS_IMETHOD GetPrototypeBinding(nsIXBLPrototypeBinding** aResult);
|
||||||
|
NS_IMETHOD SetPrototypeBinding(nsIXBLPrototypeBinding* aProtoBinding);
|
||||||
|
|
||||||
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult);
|
NS_IMETHOD GetBaseBinding(nsIXBLBinding** aResult);
|
||||||
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding);
|
NS_IMETHOD SetBaseBinding(nsIXBLBinding* aBinding);
|
||||||
|
|
||||||
|
@ -86,13 +90,11 @@ class nsXBLBinding: public nsIXBLBinding
|
||||||
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
||||||
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData);
|
NS_IMETHOD WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData);
|
||||||
|
|
||||||
NS_IMETHOD SetAllowScripts(PRBool aFlag) { mAllowScripts = aFlag; return NS_OK; };
|
|
||||||
|
|
||||||
NS_IMETHOD MarkForDeath();
|
NS_IMETHOD MarkForDeath();
|
||||||
NS_IMETHOD MarkedForDeath(PRBool* aResult);
|
NS_IMETHOD MarkedForDeath(PRBool* aResult);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsXBLBinding(const nsCString& aDocURI, const nsCString& aRef);
|
nsXBLBinding(nsIXBLPrototypeBinding* aProtoBinding);
|
||||||
virtual ~nsXBLBinding();
|
virtual ~nsXBLBinding();
|
||||||
|
|
||||||
NS_IMETHOD AddScriptEventListener(nsIContent* aElement, nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
|
NS_IMETHOD AddScriptEventListener(nsIContent* aElement, nsIAtom* aName, const nsString& aValue, REFNSIID aIID);
|
||||||
|
@ -125,17 +127,12 @@ public:
|
||||||
static nsIAtom* kOnGetAtom;
|
static nsIAtom* kOnGetAtom;
|
||||||
static nsIAtom* kGetterAtom;
|
static nsIAtom* kGetterAtom;
|
||||||
static nsIAtom* kSetterAtom;
|
static nsIAtom* kSetterAtom;
|
||||||
static nsIAtom* kHTMLAtom;
|
|
||||||
static nsIAtom* kValueAtom;
|
|
||||||
static nsIAtom* kActionAtom;
|
static nsIAtom* kActionAtom;
|
||||||
static nsIAtom* kNameAtom;
|
static nsIAtom* kNameAtom;
|
||||||
static nsIAtom* kReadOnlyAtom;
|
static nsIAtom* kReadOnlyAtom;
|
||||||
static nsIAtom* kAttachToAtom;
|
static nsIAtom* kAttachToAtom;
|
||||||
static nsIAtom* kBindingAttachedAtom;
|
static nsIAtom* kBindingAttachedAtom;
|
||||||
static nsIAtom* kBindingDetachedAtom;
|
static nsIAtom* kBindingDetachedAtom;
|
||||||
static nsIAtom* kInheritStyleAtom;
|
|
||||||
|
|
||||||
static nsIXBLService* gXBLService;
|
|
||||||
|
|
||||||
// Used to easily obtain the correct IID for an event.
|
// Used to easily obtain the correct IID for an event.
|
||||||
struct EventHandlerMapEntry {
|
struct EventHandlerMapEntry {
|
||||||
|
@ -148,8 +145,6 @@ public:
|
||||||
|
|
||||||
static PRBool IsSupportedHandler(const nsIID* aIID);
|
static PRBool IsSupportedHandler(const nsIID* aIID);
|
||||||
|
|
||||||
static nsFixedSizeAllocator kPool;
|
|
||||||
|
|
||||||
static void GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound);
|
static void GetEventHandlerIID(nsIAtom* aName, nsIID* aIID, PRBool* aFound);
|
||||||
|
|
||||||
// Internal member functions
|
// Internal member functions
|
||||||
|
@ -159,21 +154,11 @@ protected:
|
||||||
void** aScriptObject, void** aClassObject);
|
void** aScriptObject, void** aClassObject);
|
||||||
|
|
||||||
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
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);
|
PRBool IsInExcludesList(nsIAtom* aTag, const nsString& aList);
|
||||||
|
|
||||||
NS_IMETHOD ConstructAttributeTable(nsIContent* aElement);
|
|
||||||
|
|
||||||
|
|
||||||
// MEMBER VARIABLES
|
// MEMBER VARIABLES
|
||||||
protected:
|
protected:
|
||||||
nsCString mDocURI;
|
nsCOMPtr<nsIXBLPrototypeBinding> mPrototypeBinding; // Strong. As long as we're around, the binding can't go away.
|
||||||
nsCString mID;
|
|
||||||
|
|
||||||
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<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
|
||||||
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
|
nsCOMPtr<nsIXBLBinding> mNextBinding; // Strong. The derived binding owns the base class bindings.
|
||||||
|
|
||||||
|
@ -183,10 +168,5 @@ protected:
|
||||||
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
|
nsIContent* mBoundElement; // [WEAK] We have a reference, but we don't own it.
|
||||||
|
|
||||||
PRPackedBool mIsStyleBinding;
|
PRPackedBool mIsStyleBinding;
|
||||||
PRPackedBool mAllowScripts;
|
|
||||||
PRPackedBool mInheritStyle;
|
|
||||||
PRPackedBool mMarkedForDeath;
|
PRPackedBool mMarkedForDeath;
|
||||||
|
|
||||||
nsSupportsHashtable* mAttributeTable; // A table for attribute entries.
|
|
||||||
nsSupportsHashtable* mInsertionPointTable; // A table of insertion points.
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,805 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS
|
||||||
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||||
|
* implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||||||
|
* Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
#include "nsIXBLDocumentInfo.h"
|
||||||
|
#include "nsIInputStream.h"
|
||||||
|
#include "nsINameSpaceManager.h"
|
||||||
|
#include "nsHashtable.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
|
#include "nsIURL.h"
|
||||||
|
#include "nsIDOMEventReceiver.h"
|
||||||
|
#include "nsIChannel.h"
|
||||||
|
#include "nsXPIDLString.h"
|
||||||
|
#include "nsIParser.h"
|
||||||
|
#include "nsParserCIID.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
#include "plstr.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIXMLContent.h"
|
||||||
|
#include "nsIXULContent.h"
|
||||||
|
#include "nsIXMLContentSink.h"
|
||||||
|
#include "nsLayoutCID.h"
|
||||||
|
#include "nsXMLDocument.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
#include "nsIDOMText.h"
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
#include "nsINameSpace.h"
|
||||||
|
#include "nsXBLService.h"
|
||||||
|
#include "nsXBLPrototypeBinding.h"
|
||||||
|
#include "nsFixedSizeAllocator.h"
|
||||||
|
|
||||||
|
// Helper Classes =====================================================================
|
||||||
|
|
||||||
|
// nsIXBLAttributeEntry and helpers. This class is used to efficiently handle
|
||||||
|
// attribute changes in anonymous content.
|
||||||
|
|
||||||
|
// {A2892B81-CED9-11d3-97FB-00400553EEF0}
|
||||||
|
#define NS_IXBLATTR_IID \
|
||||||
|
{ 0xa2892b81, 0xced9, 0x11d3, { 0x97, 0xfb, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
||||||
|
|
||||||
|
class nsIXBLAttributeEntry : public nsISupports {
|
||||||
|
public:
|
||||||
|
static const nsIID& GetIID() { static nsIID iid = NS_IXBLATTR_IID; return iid; }
|
||||||
|
|
||||||
|
NS_IMETHOD GetSrcAttribute(nsIAtom** aResult) = 0;
|
||||||
|
NS_IMETHOD GetDstAttribute(nsIAtom** aResult) = 0;
|
||||||
|
NS_IMETHOD GetElement(nsIContent** aResult) = 0;
|
||||||
|
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) = 0;
|
||||||
|
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsXBLAttributeEntry : public nsIXBLAttributeEntry {
|
||||||
|
public:
|
||||||
|
NS_IMETHOD GetSrcAttribute(nsIAtom** aResult) { *aResult = mSrcAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
NS_IMETHOD GetDstAttribute(nsIAtom** aResult) { *aResult = mDstAttribute; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
|
||||||
|
NS_IMETHOD GetElement(nsIContent** aResult) { *aResult = mElement; NS_IF_ADDREF(*aResult); return NS_OK; };
|
||||||
|
|
||||||
|
NS_IMETHOD GetNext(nsIXBLAttributeEntry** aResult) { NS_IF_ADDREF(*aResult = mNext); return NS_OK; }
|
||||||
|
NS_IMETHOD SetNext(nsIXBLAttributeEntry* aEntry) { mNext = aEntry; return NS_OK; }
|
||||||
|
|
||||||
|
nsIContent* mElement;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIAtom> mSrcAttribute;
|
||||||
|
nsCOMPtr<nsIAtom> mDstAttribute;
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> mNext;
|
||||||
|
|
||||||
|
static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) {
|
||||||
|
return aAllocator.Alloc(aSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void operator delete(void* aPtr, size_t aSize) {
|
||||||
|
nsFixedSizeAllocator::Free(aPtr, aSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXBLAttributeEntry(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, nsIContent* aContent) {
|
||||||
|
NS_INIT_REFCNT(); mSrcAttribute = aSrcAtom; mDstAttribute = aDstAtom; mElement = aContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~nsXBLAttributeEntry() {};
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsXBLAttributeEntry, nsIXBLAttributeEntry)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// Static initialization
|
||||||
|
PRUint32 nsXBLPrototypeBinding::gRefCnt = 0;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kInheritStyleAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kHandlersAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kChildrenAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kIncludesAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kContentAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kInheritsAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kHTMLAtom = nsnull;
|
||||||
|
nsIAtom* nsXBLPrototypeBinding::kValueAtom = nsnull;
|
||||||
|
|
||||||
|
nsIXBLService* nsXBLPrototypeBinding::gXBLService = nsnull;
|
||||||
|
nsFixedSizeAllocator nsXBLPrototypeBinding::kPool;
|
||||||
|
|
||||||
|
static const size_t kBucketSizes[] = {
|
||||||
|
sizeof(nsXBLAttributeEntry)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PRInt32 kNumBuckets = sizeof(kBucketSizes)/sizeof(size_t);
|
||||||
|
static const PRInt32 kNumElements = 128;
|
||||||
|
static const PRInt32 kInitialSize = (NS_SIZE_IN_HEAP(sizeof(nsXBLAttributeEntry))) * kNumElements;
|
||||||
|
|
||||||
|
// Implementation /////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Implement our nsISupports methods
|
||||||
|
NS_IMPL_ISUPPORTS1(nsXBLPrototypeBinding, nsIXBLPrototypeBinding)
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
nsXBLPrototypeBinding::nsXBLPrototypeBinding(const nsCString& aID, nsIContent* aElement,
|
||||||
|
nsIXBLDocumentInfo* aInfo)
|
||||||
|
: mID(aID),
|
||||||
|
mInheritStyle(PR_TRUE),
|
||||||
|
mHasBaseProto(PR_TRUE),
|
||||||
|
mAttributeTable(nsnull),
|
||||||
|
mInsertionPointTable(nsnull)
|
||||||
|
{
|
||||||
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
mXBLDocInfoWeak = getter_AddRefs(NS_GetWeakReference(aInfo));
|
||||||
|
|
||||||
|
gRefCnt++;
|
||||||
|
// printf("REF COUNT UP: %d %s\n", gRefCnt, (const char*)mID);
|
||||||
|
|
||||||
|
if (gRefCnt == 1) {
|
||||||
|
kPool.Init("XBL Attribute Entries", kBucketSizes, kNumBuckets, kInitialSize);
|
||||||
|
|
||||||
|
kInheritStyleAtom = NS_NewAtom("inheritstyle");
|
||||||
|
kHandlersAtom = NS_NewAtom("handlers");
|
||||||
|
kChildrenAtom = NS_NewAtom("children");
|
||||||
|
kContentAtom = NS_NewAtom("content");
|
||||||
|
kIncludesAtom = NS_NewAtom("includes");
|
||||||
|
kInheritsAtom = NS_NewAtom("inherits");
|
||||||
|
kHTMLAtom = NS_NewAtom("html");
|
||||||
|
kValueAtom = NS_NewAtom("value");
|
||||||
|
|
||||||
|
nsServiceManager::GetService("@mozilla.org/xbl;1",
|
||||||
|
NS_GET_IID(nsIXBLService),
|
||||||
|
(nsISupports**) &gXBLService);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These all use atoms, so we have to do these ops last to ensure
|
||||||
|
// the atoms exist.
|
||||||
|
SetBindingElement(aElement);
|
||||||
|
|
||||||
|
PRBool allowScripts;
|
||||||
|
aInfo->GetScriptAccess(&allowScripts);
|
||||||
|
if (allowScripts) {
|
||||||
|
ConstructHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(content));
|
||||||
|
if (content) {
|
||||||
|
ConstructAttributeTable(content);
|
||||||
|
ConstructInsertionTable(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsXBLPrototypeBinding::~nsXBLPrototypeBinding(void)
|
||||||
|
{
|
||||||
|
delete mAttributeTable;
|
||||||
|
delete mInsertionPointTable;
|
||||||
|
gRefCnt--;
|
||||||
|
if (gRefCnt == 0) {
|
||||||
|
NS_RELEASE(kInheritStyleAtom);
|
||||||
|
NS_RELEASE(kHandlersAtom);
|
||||||
|
NS_RELEASE(kChildrenAtom);
|
||||||
|
NS_RELEASE(kContentAtom);
|
||||||
|
NS_RELEASE(kIncludesAtom);
|
||||||
|
NS_RELEASE(kInheritsAtom);
|
||||||
|
NS_RELEASE(kHTMLAtom);
|
||||||
|
NS_RELEASE(kValueAtom);
|
||||||
|
|
||||||
|
nsServiceManager::ReleaseService("@mozilla.org/xbl;1", gXBLService);
|
||||||
|
gXBLService = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nsIXBLPrototypeBinding Interface ////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBasePrototype(nsIXBLPrototypeBinding** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mBaseBinding;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetBasePrototype(nsIXBLPrototypeBinding* aBinding)
|
||||||
|
{
|
||||||
|
if (mBaseBinding.get() == aBinding)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (mBaseBinding) {
|
||||||
|
NS_ERROR("Base XBL prototype binding is already defined!");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBaseBinding = aBinding; // Comptr handles rel/add
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBindingElement(nsIContent** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mBinding;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetBindingElement(nsIContent* aElement)
|
||||||
|
{
|
||||||
|
mBinding = aElement;
|
||||||
|
nsAutoString inheritStyle;
|
||||||
|
mBinding->GetAttribute(kNameSpaceID_None, kInheritStyleAtom, inheritStyle);
|
||||||
|
if (inheritStyle == NS_LITERAL_STRING("false"))
|
||||||
|
mInheritStyle = PR_FALSE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBindingURI(nsCString& aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
|
GetXBLDocumentInfo(nsnull, getter_AddRefs(info));
|
||||||
|
|
||||||
|
info->GetDocumentURI(aResult);
|
||||||
|
aResult += "#";
|
||||||
|
aResult += mID;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetDocURI(nsCString& aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
|
GetXBLDocumentInfo(nsnull, getter_AddRefs(info));
|
||||||
|
|
||||||
|
info->GetDocumentURI(aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetID(nsCString& aResult)
|
||||||
|
{
|
||||||
|
aResult = mID;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetAllowScripts(PRBool* aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
|
GetXBLDocumentInfo(nsnull, getter_AddRefs(info));
|
||||||
|
return info->GetScriptAccess(aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::InheritsStyle(PRBool* aResult)
|
||||||
|
{
|
||||||
|
*aResult = mInheritStyle;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetXBLDocumentInfo(nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLDocumentInfo> info(do_QueryReferent(mXBLDocInfoWeak));
|
||||||
|
if (info) {
|
||||||
|
*aResult = info;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
else *aResult=nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::HasBasePrototype(PRBool* aResult)
|
||||||
|
{
|
||||||
|
*aResult = mHasBaseProto;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetHasBasePrototype(PRBool aHasBase)
|
||||||
|
{
|
||||||
|
mHasBaseProto = aHasBase;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetPrototypeHandler(nsIXBLPrototypeHandler** aResult)
|
||||||
|
{
|
||||||
|
*aResult = mPrototypeHandler;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler)
|
||||||
|
{
|
||||||
|
mPrototypeHandler = aHandler;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||||
|
nsIContent* aChangedElement, nsIContent* aAnonymousContent)
|
||||||
|
{
|
||||||
|
if (!mAttributeTable)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsISupportsKey key(aAttribute);
|
||||||
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||||
|
mAttributeTable->Get(&key)));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> xblAttr = do_QueryInterface(supports);
|
||||||
|
if (!xblAttr)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// Iterate over the elements in the array.
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(content));
|
||||||
|
while (xblAttr) {
|
||||||
|
nsCOMPtr<nsIContent> element;
|
||||||
|
nsCOMPtr<nsIAtom> dstAttr;
|
||||||
|
xblAttr->GetElement(getter_AddRefs(element));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> realElement;
|
||||||
|
LocateInstance(content, aAnonymousContent, element, getter_AddRefs(realElement));
|
||||||
|
|
||||||
|
xblAttr->GetDstAttribute(getter_AddRefs(dstAttr));
|
||||||
|
|
||||||
|
if (aRemoveFlag)
|
||||||
|
realElement->UnsetAttribute(aNameSpaceID, dstAttr, PR_TRUE);
|
||||||
|
else {
|
||||||
|
nsAutoString value;
|
||||||
|
nsresult result = aChangedElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
||||||
|
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||||
|
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||||
|
|
||||||
|
if (attrPresent)
|
||||||
|
realElement->SetAttribute(aNameSpaceID, dstAttr, value, PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if we're the <html> tag in XUL, and see if value is being
|
||||||
|
// set or unset on us.
|
||||||
|
nsCOMPtr<nsIAtom> tag;
|
||||||
|
realElement->GetTag(*getter_AddRefs(tag));
|
||||||
|
if ((tag.get() == kHTMLAtom) && (dstAttr.get() == kValueAtom)) {
|
||||||
|
// Flush out all our kids.
|
||||||
|
PRInt32 childCount;
|
||||||
|
realElement->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++)
|
||||||
|
realElement->RemoveChildAt(0, PR_TRUE);
|
||||||
|
|
||||||
|
if (!aRemoveFlag) {
|
||||||
|
// Construct a new text node and insert it.
|
||||||
|
nsAutoString value;
|
||||||
|
aChangedElement->GetAttribute(aNameSpaceID, aAttribute, value);
|
||||||
|
if (!value.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIDOMText> textNode;
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
aChangedElement->GetDocument(*getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
||||||
|
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
||||||
|
nsCOMPtr<nsIDOMNode> dummy;
|
||||||
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(realElement));
|
||||||
|
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = xblAttr;
|
||||||
|
tmpAttr->GetNext(getter_AddRefs(xblAttr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aChild, nsIContent** aResult)
|
||||||
|
{
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> realContent;
|
||||||
|
nsCOMPtr<nsIContent> templContent;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
|
||||||
|
LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent));
|
||||||
|
if (realContent)
|
||||||
|
*aResult = realContent;
|
||||||
|
else *aResult = aBoundElement;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetSingleInsertionPoint(nsIContent* aBoundElement,
|
||||||
|
nsIContent* aCopyRoot,
|
||||||
|
nsIContent** aResult, PRBool* aMultipleInsertionPoints)
|
||||||
|
{
|
||||||
|
if (mInsertionPointTable) {
|
||||||
|
if(mInsertionPointTable->Count() == 1) {
|
||||||
|
nsISupportsKey key(kChildrenAtom);
|
||||||
|
nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*,
|
||||||
|
mInsertionPointTable->Get(&key)));
|
||||||
|
nsCOMPtr<nsIContent> realContent;
|
||||||
|
nsCOMPtr<nsIContent> templContent;
|
||||||
|
GetImmediateChild(kContentAtom, getter_AddRefs(templContent));
|
||||||
|
LocateInstance(templContent, aCopyRoot, content, getter_AddRefs(realContent));
|
||||||
|
if (realContent)
|
||||||
|
*aResult = realContent;
|
||||||
|
else *aResult = aBoundElement;
|
||||||
|
NS_IF_ADDREF(*aResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*aMultipleInsertionPoints = PR_TRUE;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag)
|
||||||
|
{
|
||||||
|
mBaseNameSpaceID = aNamespaceID;
|
||||||
|
mBaseTag = aTag;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aResult)
|
||||||
|
{
|
||||||
|
if (mBaseTag) {
|
||||||
|
*aResult = mBaseTag;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
*aNamespaceID = mBaseNameSpaceID;
|
||||||
|
}
|
||||||
|
else *aResult = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helpers ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::GetImmediateChild(nsIAtom* aTag, nsIContent** aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
PRInt32 childCount;
|
||||||
|
mBinding->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
|
nsCOMPtr<nsIContent> child;
|
||||||
|
mBinding->ChildAt(i, *getter_AddRefs(child));
|
||||||
|
nsCOMPtr<nsIAtom> tag;
|
||||||
|
child->GetTag(*getter_AddRefs(tag));
|
||||||
|
if (aTag == tag.get()) {
|
||||||
|
*aResult = child;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::ConstructHandlers()
|
||||||
|
{
|
||||||
|
// See if this binding has a handler elt.
|
||||||
|
nsCOMPtr<nsIContent> handlers;
|
||||||
|
GetImmediateChild(kHandlersAtom, getter_AddRefs(handlers));
|
||||||
|
if (handlers) {
|
||||||
|
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
||||||
|
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(firstHandler));
|
||||||
|
SetPrototypeHandler(firstHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::LocateInstance(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) {
|
||||||
|
*aCopyResult = nsnull;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> templParent;
|
||||||
|
nsCOMPtr<nsIContent> copyParent;
|
||||||
|
|
||||||
|
aTemplChild->GetParent(*getter_AddRefs(templParent));
|
||||||
|
|
||||||
|
if (templParent.get() == aTemplRoot)
|
||||||
|
copyParent = aCopyRoot;
|
||||||
|
else
|
||||||
|
LocateInstance(aTemplRoot, aCopyRoot, templParent, getter_AddRefs(copyParent));
|
||||||
|
|
||||||
|
PRInt32 index;
|
||||||
|
templParent->IndexOf(aTemplChild, index);
|
||||||
|
copyParent->ChildAt(index, *aCopyResult); // Addref happens here.
|
||||||
|
}
|
||||||
|
|
||||||
|
struct nsXBLAttrChangeData
|
||||||
|
{
|
||||||
|
nsXBLPrototypeBinding* mProto;
|
||||||
|
nsIContent* mBoundElement;
|
||||||
|
nsIContent* mContent;
|
||||||
|
|
||||||
|
nsXBLAttrChangeData(nsXBLPrototypeBinding* aProto,
|
||||||
|
nsIContent* aElt, nsIContent* aContent)
|
||||||
|
:mProto(aProto), mBoundElement(aElt), mContent(aContent) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
|
{
|
||||||
|
// XXX How to deal with NAMESPACES!!!?
|
||||||
|
nsIXBLAttributeEntry* entry = (nsIXBLAttributeEntry*)aData;
|
||||||
|
nsXBLAttrChangeData* changeData = (nsXBLAttrChangeData*)aClosure;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIAtom> src;
|
||||||
|
entry->GetSrcAttribute(getter_AddRefs(src));
|
||||||
|
|
||||||
|
nsAutoString value;
|
||||||
|
nsresult result = changeData->mBoundElement->GetAttribute(kNameSpaceID_None, src, value);
|
||||||
|
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||||
|
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||||
|
if (attrPresent) {
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
changeData->mProto->GetImmediateChild(nsXBLPrototypeBinding::kContentAtom, getter_AddRefs(content));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> curr = entry;
|
||||||
|
while (curr) {
|
||||||
|
nsCOMPtr<nsIAtom> dst;
|
||||||
|
nsCOMPtr<nsIContent> element;
|
||||||
|
curr->GetDstAttribute(getter_AddRefs(dst));
|
||||||
|
curr->GetElement(getter_AddRefs(element));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> realElement;
|
||||||
|
changeData->mProto->LocateInstance(content, changeData->mContent, element, getter_AddRefs(realElement));
|
||||||
|
if (realElement) {
|
||||||
|
realElement->SetAttribute(kNameSpaceID_None, dst, value, PR_FALSE);
|
||||||
|
nsCOMPtr<nsIAtom> tag;
|
||||||
|
realElement->GetTag(*getter_AddRefs(tag));
|
||||||
|
if ((tag.get() == nsXBLPrototypeBinding::kHTMLAtom) && (dst.get() == nsXBLPrototypeBinding::kValueAtom) && !value.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIDOMText> textNode;
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
changeData->mBoundElement->GetDocument(*getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(doc));
|
||||||
|
domDoc->CreateTextNode(value, getter_AddRefs(textNode));
|
||||||
|
nsCOMPtr<nsIDOMNode> dummy;
|
||||||
|
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(realElement));
|
||||||
|
domElement->AppendChild(textNode, getter_AddRefs(dummy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> next = curr;
|
||||||
|
curr->GetNext(getter_AddRefs(next));
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)
|
||||||
|
{
|
||||||
|
if (mAttributeTable) {
|
||||||
|
nsXBLAttrChangeData data(this, aBoundElement, aAnonymousContent);
|
||||||
|
mAttributeTable->Enumerate(SetAttrs, (void*)&data);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||||
|
{
|
||||||
|
nsAutoString inherits;
|
||||||
|
aElement->GetAttribute(kNameSpaceID_None, kInheritsAtom, inherits);
|
||||||
|
if (!inherits.IsEmpty()) {
|
||||||
|
if (!mAttributeTable) {
|
||||||
|
mAttributeTable = new nsSupportsHashtable(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The user specified at least one attribute.
|
||||||
|
char* str = inherits.ToNewCString();
|
||||||
|
char* newStr;
|
||||||
|
// XXX We should use a strtok function that tokenizes PRUnichars
|
||||||
|
// 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 attribute.
|
||||||
|
nsCOMPtr<nsIAtom> atom;
|
||||||
|
nsCOMPtr<nsIAtom> attribute;
|
||||||
|
|
||||||
|
// Figure out if this token contains a :.
|
||||||
|
nsAutoString attrTok; attrTok.AssignWithConversion(token);
|
||||||
|
PRInt32 index = attrTok.Find("=", PR_TRUE);
|
||||||
|
if (index != -1) {
|
||||||
|
// This attribute maps to something different.
|
||||||
|
nsAutoString left, right;
|
||||||
|
attrTok.Left(left, index);
|
||||||
|
attrTok.Right(right, attrTok.Length()-index-1);
|
||||||
|
|
||||||
|
atom = getter_AddRefs(NS_NewAtom(right.GetUnicode()));
|
||||||
|
attribute = getter_AddRefs(NS_NewAtom(left.GetUnicode()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nsAutoString tok; tok.AssignWithConversion(token);
|
||||||
|
atom = getter_AddRefs(NS_NewAtom(tok.GetUnicode()));
|
||||||
|
attribute = atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an XBL attribute entry.
|
||||||
|
nsXBLAttributeEntry* xblAttr = new (kPool) nsXBLAttributeEntry(atom, attribute, aElement);
|
||||||
|
|
||||||
|
// Now we should see if some element within our anonymous
|
||||||
|
// content is already observing this attribute.
|
||||||
|
nsISupportsKey key(atom);
|
||||||
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(NS_STATIC_CAST(nsISupports*,
|
||||||
|
mAttributeTable->Get(&key)));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> entry = do_QueryInterface(supports);
|
||||||
|
if (!entry) {
|
||||||
|
// Put it in the table.
|
||||||
|
mAttributeTable->Put(&key, xblAttr);
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> attr = entry;
|
||||||
|
nsCOMPtr<nsIXBLAttributeEntry> tmpAttr = entry;
|
||||||
|
do {
|
||||||
|
attr = tmpAttr;
|
||||||
|
attr->GetNext(getter_AddRefs(tmpAttr));
|
||||||
|
} while (tmpAttr);
|
||||||
|
attr->SetNext(xblAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove the inherits attribute from the element so that it doesn't
|
||||||
|
// show up on clones of the element. It is used
|
||||||
|
// by the template only, and we don't need it anymore.
|
||||||
|
aElement->UnsetAttribute(kNameSpaceID_None, kInheritsAtom, PR_FALSE);
|
||||||
|
|
||||||
|
token = nsCRT::strtok( newStr, ", ", &newStr );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMemory::Free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recur into our children.
|
||||||
|
PRInt32 childCount;
|
||||||
|
aElement->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
|
nsCOMPtr<nsIContent> child;
|
||||||
|
aElement->ChildAt(i, *getter_AddRefs(child));
|
||||||
|
ConstructAttributeTable(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupportsArray> childrenElements;
|
||||||
|
GetNestedChildren(kChildrenAtom, aContent, getter_AddRefs(childrenElements));
|
||||||
|
|
||||||
|
if (!childrenElements)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mInsertionPointTable = new nsSupportsHashtable;
|
||||||
|
|
||||||
|
PRUint32 count;
|
||||||
|
childrenElements->Count(&count);
|
||||||
|
PRUint32 i;
|
||||||
|
for (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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMemory::Free(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove the <children> elements.
|
||||||
|
for (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));
|
||||||
|
PRInt32 index;
|
||||||
|
parent->IndexOf(child, index);
|
||||||
|
parent->RemoveChildAt(index, PR_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXBLPrototypeBinding::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()) {
|
||||||
|
if (!*aList)
|
||||||
|
NS_NewISupportsArray(aList); // Addref happens here.
|
||||||
|
(*aList)->AppendElement(child);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GetNestedChildren(aTag, child, aList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_NewXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement,
|
||||||
|
nsIXBLDocumentInfo* aInfo, nsIXBLPrototypeBinding** aResult)
|
||||||
|
{
|
||||||
|
*aResult = new nsXBLPrototypeBinding(aRef, aElement, aInfo);
|
||||||
|
if (!*aResult)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
NS_ADDREF(*aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS
|
||||||
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||||
|
* implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||||||
|
* Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
|
#include "nsIXBLPrototypeHandler.h"
|
||||||
|
|
||||||
|
class nsIContent;
|
||||||
|
class nsIAtom;
|
||||||
|
class nsIDocument;
|
||||||
|
class nsIScriptContext;
|
||||||
|
class nsISupportsArray;
|
||||||
|
class nsSupportsHashtable;
|
||||||
|
class nsIXBLService;
|
||||||
|
class nsFixedSizeAllocator;
|
||||||
|
|
||||||
|
// *********************************************************************/
|
||||||
|
// The XBLPrototypeBinding class
|
||||||
|
|
||||||
|
class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding
|
||||||
|
{
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIXBLPrototypeBinding
|
||||||
|
NS_IMETHOD GetBindingElement(nsIContent** aResult);
|
||||||
|
NS_IMETHOD SetBindingElement(nsIContent* aElement);
|
||||||
|
|
||||||
|
NS_IMETHOD GetBindingURI(nsCString& aResult);
|
||||||
|
NS_IMETHOD GetDocURI(nsCString& aResult);
|
||||||
|
NS_IMETHOD GetID(nsCString& aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetAllowScripts(PRBool* aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD InheritsStyle(PRBool* aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetPrototypeHandler(nsIXBLPrototypeHandler** aHandler);
|
||||||
|
NS_IMETHOD SetPrototypeHandler(nsIXBLPrototypeHandler* aHandler);
|
||||||
|
|
||||||
|
NS_IMETHOD AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag,
|
||||||
|
nsIContent* aChangedElement, nsIContent* aAnonymousContent);
|
||||||
|
|
||||||
|
NS_IMETHOD SetBasePrototype(nsIXBLPrototypeBinding* aBinding);
|
||||||
|
NS_IMETHOD GetBasePrototype(nsIXBLPrototypeBinding** aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetXBLDocumentInfo(nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD HasBasePrototype(PRBool* aResult);
|
||||||
|
NS_IMETHOD SetHasBasePrototype(PRBool aHasBase);
|
||||||
|
|
||||||
|
NS_IMETHOD SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
|
||||||
|
|
||||||
|
NS_IMETHOD HasInsertionPoints(PRBool* aResult) { *aResult = (mInsertionPointTable != nsnull); return NS_OK; };
|
||||||
|
|
||||||
|
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aChild, nsIContent** aResult);
|
||||||
|
|
||||||
|
NS_IMETHOD GetSingleInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,
|
||||||
|
nsIContent** aResult, PRBool* aMultiple);
|
||||||
|
|
||||||
|
NS_IMETHOD GetBaseTag(PRInt32* aNamespaceID, nsIAtom** aTag);
|
||||||
|
NS_IMETHOD SetBaseTag(PRInt32 aNamespaceID, nsIAtom* aTag);
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsXBLPrototypeBinding(const nsCString& aRef, nsIContent* aElement,
|
||||||
|
nsIXBLDocumentInfo* aInfo);
|
||||||
|
virtual ~nsXBLPrototypeBinding();
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
static PRUint32 gRefCnt;
|
||||||
|
static nsIXBLService* gXBLService;
|
||||||
|
static nsIAtom* kInheritStyleAtom;
|
||||||
|
static nsIAtom* kHandlersAtom;
|
||||||
|
static nsIAtom* kChildrenAtom;
|
||||||
|
static nsIAtom* kIncludesAtom;
|
||||||
|
static nsIAtom* kContentAtom;
|
||||||
|
static nsIAtom* kInheritsAtom;
|
||||||
|
static nsIAtom* kHTMLAtom;
|
||||||
|
static nsIAtom* kValueAtom;
|
||||||
|
|
||||||
|
static nsFixedSizeAllocator kPool;
|
||||||
|
|
||||||
|
// Internal member functions
|
||||||
|
public:
|
||||||
|
void GetImmediateChild(nsIAtom* aTag, nsIContent** aResult);
|
||||||
|
void LocateInstance(nsIContent* aTemplRoot, nsIContent* aCopyRoot,
|
||||||
|
nsIContent* aTemplChild, nsIContent** aCopyResult);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ConstructHandlers();
|
||||||
|
void ConstructAttributeTable(nsIContent* aElement);
|
||||||
|
void ConstructInsertionTable(nsIContent* aElement);
|
||||||
|
void GetNestedChildren(nsIAtom* aTag, nsIContent* aContent, nsISupportsArray** aList);
|
||||||
|
|
||||||
|
// MEMBER VARIABLES
|
||||||
|
protected:
|
||||||
|
nsCString mID;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
|
||||||
|
nsCOMPtr<nsIXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
|
||||||
|
nsCOMPtr<nsIXBLPrototypeBinding> mBaseBinding; // Strong. We own the base binding in our explicit inheritance chain.
|
||||||
|
PRPackedBool mInheritStyle;
|
||||||
|
PRPackedBool mHasBaseProto;
|
||||||
|
|
||||||
|
nsWeakPtr mXBLDocInfoWeak; // A pointer back to our doc info. Weak, since it owns us.
|
||||||
|
|
||||||
|
nsSupportsHashtable* mAttributeTable; // A table for attribute entries. Used to efficiently
|
||||||
|
// handle attribute changes.
|
||||||
|
|
||||||
|
nsSupportsHashtable* mInsertionPointTable; // A table of insertion points for placing explicit content
|
||||||
|
// underneath anonymous content.
|
||||||
|
|
||||||
|
PRInt32 mBaseNameSpaceID; // If we extend a tagname/namespace, then that information will
|
||||||
|
nsCOMPtr<nsIAtom> mBaseTag; // be stored in here.
|
||||||
|
};
|
|
@ -54,6 +54,7 @@
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
|
||||||
#include "nsIXBLBinding.h"
|
#include "nsIXBLBinding.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
#include "nsIXBLDocumentInfo.h"
|
#include "nsIXBLDocumentInfo.h"
|
||||||
|
|
||||||
#include "nsIXBLPrototypeHandler.h"
|
#include "nsIXBLPrototypeHandler.h"
|
||||||
|
@ -343,9 +344,6 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
|
||||||
nsCOMPtr<nsIXBLDocumentInfo> info;
|
nsCOMPtr<nsIXBLDocumentInfo> info;
|
||||||
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
|
NS_NewXBLDocumentInfo(mBindingDocument, getter_AddRefs(info));
|
||||||
|
|
||||||
// Construct our prototype handlers.
|
|
||||||
nsXBLService::ConstructPrototypeHandlers(info);
|
|
||||||
|
|
||||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||||
PRBool cached = PR_FALSE;
|
PRBool cached = PR_FALSE;
|
||||||
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
||||||
|
@ -486,7 +484,6 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
||||||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||||
|
|
||||||
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
nsIAtom* nsXBLService::kExtendsAtom = nsnull;
|
||||||
nsIAtom* nsXBLService::kHandlersAtom = nsnull;
|
|
||||||
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
nsIAtom* nsXBLService::kScrollbarAtom = nsnull;
|
||||||
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
nsIAtom* nsXBLService::kInputAtom = nsnull;
|
||||||
|
|
||||||
|
@ -526,7 +523,6 @@ nsXBLService::nsXBLService(void)
|
||||||
|
|
||||||
// Create our atoms
|
// Create our atoms
|
||||||
kExtendsAtom = NS_NewAtom("extends");
|
kExtendsAtom = NS_NewAtom("extends");
|
||||||
kHandlersAtom = NS_NewAtom("handlers");
|
|
||||||
kScrollbarAtom = NS_NewAtom("scrollbar");
|
kScrollbarAtom = NS_NewAtom("scrollbar");
|
||||||
kInputAtom = NS_NewAtom("input");
|
kInputAtom = NS_NewAtom("input");
|
||||||
|
|
||||||
|
@ -558,7 +554,6 @@ nsXBLService::~nsXBLService(void)
|
||||||
|
|
||||||
// Release our atoms
|
// Release our atoms
|
||||||
NS_RELEASE(kExtendsAtom);
|
NS_RELEASE(kExtendsAtom);
|
||||||
NS_RELEASE(kHandlersAtom);
|
|
||||||
NS_RELEASE(kScrollbarAtom);
|
NS_RELEASE(kScrollbarAtom);
|
||||||
NS_RELEASE(kInputAtom);
|
NS_RELEASE(kInputAtom);
|
||||||
|
|
||||||
|
@ -915,77 +910,114 @@ NS_IMETHODIMP nsXBLService::GetBindingInternal(nsIContent* aBoundElement,
|
||||||
PRBool allowScripts;
|
PRBool allowScripts;
|
||||||
docInfo->GetScriptAccess(&allowScripts);
|
docInfo->GetScriptAccess(&allowScripts);
|
||||||
|
|
||||||
// We have a doc. Obtain our specific binding element.
|
nsCOMPtr<nsIXBLPrototypeBinding> protoBinding;
|
||||||
// Walk the children looking for the binding that matches the ref
|
docInfo->GetPrototypeBinding(ref, getter_AddRefs(protoBinding));
|
||||||
// specified in the URL.
|
nsCOMPtr<nsIContent> child;
|
||||||
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
if (!protoBinding) {
|
||||||
if (!root)
|
// We have a doc. Obtain our specific binding element.
|
||||||
return NS_ERROR_FAILURE;
|
// Walk the children looking for the binding that matches the ref
|
||||||
|
// specified in the URL.
|
||||||
|
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||||
|
if (!root)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsAutoString bindingName; bindingName.AssignWithConversion( NS_STATIC_CAST(const char*, ref) );
|
nsAutoString bindingName; bindingName.AssignWithConversion( NS_STATIC_CAST(const char*, ref) );
|
||||||
|
|
||||||
PRInt32 count;
|
PRInt32 count;
|
||||||
root->ChildCount(count);
|
root->ChildCount(count);
|
||||||
|
|
||||||
for (PRInt32 i = 0; i < count; i++) {
|
for (PRInt32 i = 0; i < count; i++) {
|
||||||
nsCOMPtr<nsIContent> child;
|
root->ChildAt(i, *getter_AddRefs(child));
|
||||||
root->ChildAt(i, *getter_AddRefs(child));
|
|
||||||
|
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, value);
|
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, value);
|
||||||
|
|
||||||
// If no ref is specified just use this.
|
// If no ref is specified just use this.
|
||||||
if ((bindingName.IsEmpty()) || (bindingName == value)) {
|
if ((bindingName.IsEmpty()) || (bindingName == value)) {
|
||||||
// Check for the presence of an extends attribute
|
// Construct a prototype binding.
|
||||||
nsAutoString extends;
|
NS_NewXBLPrototypeBinding(ref, child, docInfo, getter_AddRefs(protoBinding));
|
||||||
nsCOMPtr<nsIXBLBinding> baseBinding;
|
docInfo->SetPrototypeBinding(ref, protoBinding);
|
||||||
child->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
break;
|
||||||
value = extends;
|
}
|
||||||
if (!extends.IsEmpty()) {
|
}
|
||||||
nsAutoString prefix;
|
}
|
||||||
PRInt32 offset = extends.FindChar(':');
|
else
|
||||||
if (-1 != offset) {
|
protoBinding->GetBindingElement(getter_AddRefs(child));
|
||||||
extends.Left(prefix, offset);
|
|
||||||
extends.Cut(0, offset+1);
|
// If our prototype already has a base, then don't check for an "extends" attribute.
|
||||||
}
|
nsCOMPtr<nsIXBLBinding> baseBinding;
|
||||||
if (prefix.Length() > 0) {
|
nsCOMPtr<nsIXBLPrototypeBinding> baseProto;
|
||||||
// Look up the prefix.
|
PRBool hasBase;
|
||||||
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
protoBinding->HasBasePrototype(&hasBase);
|
||||||
nsCOMPtr<nsINameSpace> nameSpace;
|
protoBinding->GetBasePrototype(getter_AddRefs(baseProto));
|
||||||
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(child));
|
if (baseProto) {
|
||||||
if (xmlContent) {
|
nsCAutoString url;
|
||||||
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
baseProto->GetBindingURI(url);
|
||||||
if (nameSpace) {
|
if (NS_FAILED(GetBindingInternal(aBoundElement, url, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
|
||||||
nsCOMPtr<nsINameSpace> tagSpace;
|
return NS_ERROR_FAILURE; // We aren't ready yet.
|
||||||
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
if (!aPeekOnly) {
|
||||||
if (!tagSpace) {
|
// Make sure to set the base prototype.
|
||||||
// We have a base class binding. Load it right now.
|
baseBinding->GetPrototypeBinding(getter_AddRefs(baseProto));
|
||||||
nsCAutoString urlCString; urlCString.AssignWithConversion(value);
|
protoBinding->SetBasePrototype(baseProto);
|
||||||
GetBindingInternal(aBoundElement, urlCString, aPeekOnly, aIsReady, getter_AddRefs(baseBinding));
|
}
|
||||||
if (!*aIsReady)
|
}
|
||||||
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
|
else if (hasBase) {
|
||||||
|
// Check for the presence of an extends attribute
|
||||||
|
nsAutoString extends;
|
||||||
|
child->GetAttribute(kNameSpaceID_None, kExtendsAtom, extends);
|
||||||
|
nsAutoString value(extends);
|
||||||
|
if (extends.IsEmpty())
|
||||||
|
protoBinding->SetHasBasePrototype(PR_FALSE);
|
||||||
|
else {
|
||||||
|
nsAutoString prefix;
|
||||||
|
PRInt32 offset = extends.FindChar(':');
|
||||||
|
if (-1 != offset) {
|
||||||
|
extends.Left(prefix, offset);
|
||||||
|
extends.Cut(0, offset+1);
|
||||||
|
}
|
||||||
|
if (prefix.Length() > 0) {
|
||||||
|
// Look up the prefix.
|
||||||
|
nsCOMPtr<nsIAtom> prefixAtom = getter_AddRefs(NS_NewAtom(prefix));
|
||||||
|
nsCOMPtr<nsINameSpace> nameSpace;
|
||||||
|
nsCOMPtr<nsIXMLContent> xmlContent(do_QueryInterface(child));
|
||||||
|
if (xmlContent) {
|
||||||
|
xmlContent->GetContainingNameSpace(*getter_AddRefs(nameSpace));
|
||||||
|
if (nameSpace) {
|
||||||
|
nsCOMPtr<nsINameSpace> tagSpace;
|
||||||
|
nameSpace->FindNameSpace(prefixAtom, *getter_AddRefs(tagSpace));
|
||||||
|
if (tagSpace) {
|
||||||
|
// We extend some widget/frame. We don't really have a base binding.
|
||||||
|
protoBinding->SetHasBasePrototype(PR_FALSE);
|
||||||
|
PRInt32 nameSpaceID;
|
||||||
|
tagSpace->GetNameSpaceID(nameSpaceID);
|
||||||
|
nsCOMPtr<nsIAtom> tagName = getter_AddRefs(NS_NewAtom(extends));
|
||||||
|
protoBinding->SetBaseTag(nameSpaceID, tagName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We have a base class binding. Load it right now.
|
||||||
|
nsCAutoString urlCString; urlCString.AssignWithConversion(value);
|
||||||
|
if (NS_FAILED(GetBindingInternal(aBoundElement, urlCString, aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
|
||||||
|
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
|
||||||
|
if (!aPeekOnly) {
|
||||||
|
// Make sure to set the base prototype.
|
||||||
|
baseBinding->GetPrototypeBinding(getter_AddRefs(baseProto));
|
||||||
|
protoBinding->SetBasePrototype(baseProto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*aIsReady = PR_TRUE;
|
|
||||||
if (!aPeekOnly) {
|
|
||||||
// Make a new binding
|
|
||||||
NS_NewXBLBinding(uri, ref, aResult);
|
|
||||||
|
|
||||||
// Initialize its bound element.
|
|
||||||
(*aResult)->SetBindingElement(child);
|
|
||||||
(*aResult)->SetAllowScripts(allowScripts);
|
|
||||||
|
|
||||||
if (baseBinding)
|
|
||||||
(*aResult)->SetBaseBinding(baseBinding);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*aIsReady = PR_TRUE;
|
||||||
|
if (!aPeekOnly) {
|
||||||
|
// Make a new binding
|
||||||
|
NS_NewXBLBinding(protoBinding, aResult);
|
||||||
|
if (baseBinding)
|
||||||
|
(*aResult)->SetBaseBinding(baseBinding);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,9 +1090,6 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aB
|
||||||
if (document) {
|
if (document) {
|
||||||
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
|
NS_NewXBLDocumentInfo(document, getter_AddRefs(info));
|
||||||
|
|
||||||
// Construct our prototype handlers.
|
|
||||||
ConstructPrototypeHandlers(info);
|
|
||||||
|
|
||||||
// If the doc is a chrome URI, then we put it into the XUL cache.
|
// If the doc is a chrome URI, then we put it into the XUL cache.
|
||||||
PRBool cached = PR_FALSE;
|
PRBool cached = PR_FALSE;
|
||||||
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
if (IsChromeURI(uri) && gXULUtils->UseXULCache()) {
|
||||||
|
@ -1288,40 +1317,6 @@ nsXBLService::BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** a
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsXBLService::ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDocument> doc;
|
|
||||||
aInfo->GetDocument(getter_AddRefs(doc));
|
|
||||||
nsCOMPtr<nsIContent> bindings = getter_AddRefs(doc->GetRootContent());
|
|
||||||
PRInt32 childCount;
|
|
||||||
bindings->ChildCount(childCount);
|
|
||||||
for (PRInt32 i = 0; i < childCount; i++) {
|
|
||||||
nsCOMPtr<nsIContent> binding;
|
|
||||||
bindings->ChildAt(i, *getter_AddRefs(binding));
|
|
||||||
|
|
||||||
// See if this binding has a handler elt.
|
|
||||||
nsCOMPtr<nsIContent> handlers;
|
|
||||||
GetImmediateChild(kHandlersAtom, binding, getter_AddRefs(handlers));
|
|
||||||
if (handlers) {
|
|
||||||
nsCOMPtr<nsIXBLPrototypeHandler> firstHandler;
|
|
||||||
nsXBLService::BuildHandlerChain(handlers, getter_AddRefs(firstHandler));
|
|
||||||
|
|
||||||
if (firstHandler) {
|
|
||||||
nsAutoString ref;
|
|
||||||
binding->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, ref);
|
|
||||||
|
|
||||||
nsCAutoString cref;
|
|
||||||
cref.AssignWithConversion(ref);
|
|
||||||
|
|
||||||
aInfo->SetPrototypeHandler(cref, firstHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -103,7 +103,6 @@ public:
|
||||||
// This method walks a binding document and removes any text nodes
|
// This method walks a binding document and removes any text nodes
|
||||||
// that contain only whitespace.
|
// that contain only whitespace.
|
||||||
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
static nsresult StripWhitespaceNodes(nsIContent* aContent);
|
||||||
static nsresult ConstructPrototypeHandlers(nsIXBLDocumentInfo* aInfo);
|
|
||||||
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
|
static nsresult BuildHandlerChain(nsIContent* aContent, nsIXBLPrototypeHandler** aResult);
|
||||||
|
|
||||||
// MEMBER VARIABLES
|
// MEMBER VARIABLES
|
||||||
|
@ -126,7 +125,6 @@ public:
|
||||||
|
|
||||||
// XBL Atoms
|
// XBL Atoms
|
||||||
static nsIAtom* kExtendsAtom;
|
static nsIAtom* kExtendsAtom;
|
||||||
static nsIAtom* kHandlersAtom;
|
|
||||||
static nsIAtom* kScrollbarAtom;
|
static nsIAtom* kScrollbarAtom;
|
||||||
static nsIAtom* kInputAtom;
|
static nsIAtom* kInputAtom;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIXBLPrototypeHandler.h"
|
#include "nsIXBLPrototypeHandler.h"
|
||||||
#include "nsXBLWindowKeyHandler.h"
|
#include "nsXBLWindowKeyHandler.h"
|
||||||
|
#include "nsIXBLPrototypeBinding.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIAtom.h"
|
#include "nsIAtom.h"
|
||||||
#include "nsIDOMNSUIEvent.h"
|
#include "nsIDOMNSUIEvent.h"
|
||||||
|
@ -41,6 +42,9 @@
|
||||||
#include "nsIDOMXULCommandDispatcher.h"
|
#include "nsIDOMXULCommandDispatcher.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
|
#include "nsIDOMDocument.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIDOMElement.h"
|
||||||
|
|
||||||
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
|
PRUint32 nsXBLWindowKeyHandler::gRefCnt = 0;
|
||||||
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
|
nsIAtom* nsXBLWindowKeyHandler::kKeyDownAtom = nsnull;
|
||||||
|
@ -115,6 +119,33 @@ nsXBLWindowKeyHandler::IsEditor()
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GetHandlers(nsIXBLDocumentInfo* aInfo, const nsCString& aDocURI,
|
||||||
|
const nsCString& aRef, nsIXBLPrototypeHandler** aResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIXBLPrototypeBinding> binding;
|
||||||
|
aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding));
|
||||||
|
if (!binding) {
|
||||||
|
nsCOMPtr<nsIDocument> doc;
|
||||||
|
aInfo->GetDocument(getter_AddRefs(doc));
|
||||||
|
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||||
|
PRInt32 childCount;
|
||||||
|
root->ChildCount(childCount);
|
||||||
|
for (PRInt32 i = 0; i < childCount; i++) {
|
||||||
|
nsCOMPtr<nsIContent> child;
|
||||||
|
root->ChildAt(i, *getter_AddRefs(child));
|
||||||
|
nsAutoString id;
|
||||||
|
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
|
||||||
|
if (id.EqualsWithConversion(aRef)) {
|
||||||
|
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
|
||||||
|
aInfo->SetPrototypeBinding(aRef, binding);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding->GetPrototypeHandler(aResult); // Addref happens here.
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXBLWindowKeyHandler::EnsureHandlers()
|
nsXBLWindowKeyHandler::EnsureHandlers()
|
||||||
{
|
{
|
||||||
|
@ -158,16 +189,24 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
||||||
|
|
||||||
// Now determine which handlers we should be using.
|
// Now determine which handlers we should be using.
|
||||||
if (IsEditor()) {
|
if (IsEditor()) {
|
||||||
mXBLSpecialDocInfo->mPlatformHTMLBindings->GetPrototypeHandler(nsCAutoString("editor"),
|
GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings,
|
||||||
getter_AddRefs(mPlatformHandler));
|
nsCAutoString("chrome://global/content/platformHTMLBindings.xml"),
|
||||||
mXBLSpecialDocInfo->mHTMLBindings->GetPrototypeHandler(nsCAutoString("editorBase"),
|
nsCAutoString("editor"),
|
||||||
getter_AddRefs(mHandler));
|
getter_AddRefs(mPlatformHandler));
|
||||||
|
GetHandlers(mXBLSpecialDocInfo->mHTMLBindings,
|
||||||
|
nsCAutoString("chrome://global/content/htmlBindings.xml"),
|
||||||
|
nsCAutoString("editorBase"),
|
||||||
|
getter_AddRefs(mHandler));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mXBLSpecialDocInfo->mPlatformHTMLBindings->GetPrototypeHandler(nsCAutoString("browser"),
|
GetHandlers(mXBLSpecialDocInfo->mPlatformHTMLBindings,
|
||||||
getter_AddRefs(mPlatformHandler));
|
nsCAutoString("chrome://global/content/platformHTMLBindings.xml"),
|
||||||
mXBLSpecialDocInfo->mHTMLBindings->GetPrototypeHandler(nsCAutoString("browserBase"),
|
nsCAutoString("browser"),
|
||||||
getter_AddRefs(mHandler));
|
getter_AddRefs(mPlatformHandler));
|
||||||
|
GetHandlers(mXBLSpecialDocInfo->mHTMLBindings,
|
||||||
|
nsCAutoString("chrome://global/content/htmlBindings.xml"),
|
||||||
|
nsCAutoString("browserBase"),
|
||||||
|
getter_AddRefs(mHandler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче