зеркало из https://github.com/mozilla/pjs.git
Bug 51444 Make xbl:inherits work with namespaced attributes p=smaug@welho.com r+sr=bz
This commit is contained in:
Родитель
9030bead0f
Коммит
36fef2db76
|
@ -294,6 +294,14 @@ public:
|
||||||
static nsresult CheckQName(const nsAString& aQualifiedName,
|
static nsresult CheckQName(const nsAString& aQualifiedName,
|
||||||
PRBool aNamespaceAware = PR_TRUE);
|
PRBool aNamespaceAware = PR_TRUE);
|
||||||
|
|
||||||
|
static nsresult SplitQName(nsIContent* aNamespaceResolver,
|
||||||
|
const nsAFlatString& aQName,
|
||||||
|
PRInt32 *aNamespace, nsIAtom **aLocalName);
|
||||||
|
|
||||||
|
static nsresult LookupNamespaceURI(nsIContent* aNamespaceResolver,
|
||||||
|
const nsAString& aNamespacePrefix,
|
||||||
|
nsAString& aNamespaceURI);
|
||||||
|
|
||||||
static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
|
static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
|
||||||
const nsAString& aQualifiedName,
|
const nsAString& aQualifiedName,
|
||||||
nsNodeInfoManager* aNodeInfoManager,
|
nsNodeInfoManager* aNodeInfoManager,
|
||||||
|
|
|
@ -1627,6 +1627,66 @@ nsContentUtils::CheckQName(const nsAString& aQualifiedName,
|
||||||
aNamespaceAware, &colon);
|
aNamespaceAware, &colon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
nsresult
|
||||||
|
nsContentUtils::SplitQName(nsIContent* aNamespaceResolver,
|
||||||
|
const nsAFlatString& aQName,
|
||||||
|
PRInt32 *aNamespace, nsIAtom **aLocalName)
|
||||||
|
{
|
||||||
|
nsIParserService* parserService = GetParserServiceWeakRef();
|
||||||
|
NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
const PRUnichar* colon;
|
||||||
|
nsresult rv = parserService->CheckQName(aQName, PR_TRUE, &colon);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (colon) {
|
||||||
|
const PRUnichar* end;
|
||||||
|
aQName.EndReading(end);
|
||||||
|
nsAutoString nameSpace;
|
||||||
|
rv = LookupNamespaceURI(aNamespaceResolver, Substring(aQName.get(), colon),
|
||||||
|
nameSpace);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
GetNSManagerWeakRef()->GetNameSpaceID(nameSpace, aNamespace);
|
||||||
|
if (*aNamespace == kNameSpaceID_Unknown)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
*aLocalName = NS_NewAtom(Substring(colon + 1, end));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*aNamespace = kNameSpaceID_None;
|
||||||
|
*aLocalName = NS_NewAtom(aQName);
|
||||||
|
}
|
||||||
|
NS_ENSURE_TRUE(aLocalName, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
nsresult
|
||||||
|
nsContentUtils::LookupNamespaceURI(nsIContent* aNamespaceResolver,
|
||||||
|
const nsAString& aNamespacePrefix,
|
||||||
|
nsAString& aNamespaceURI)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIAtom> name;
|
||||||
|
if (!aNamespacePrefix.IsEmpty()) {
|
||||||
|
name = do_GetAtom(aNamespacePrefix);
|
||||||
|
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = nsLayoutAtoms::xmlnsNameSpace;
|
||||||
|
}
|
||||||
|
// Trace up the content parent chain looking for the namespace
|
||||||
|
// declaration that declares aNamespacePrefix.
|
||||||
|
for (nsIContent* content = aNamespaceResolver; content;
|
||||||
|
content = content->GetParent()) {
|
||||||
|
if (content->GetAttr(kNameSpaceID_XMLNS, name, aNamespaceURI) ==
|
||||||
|
NS_CONTENT_ATTR_HAS_VALUE)
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
nsresult
|
nsresult
|
||||||
nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
|
nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
|
||||||
|
|
|
@ -460,28 +460,11 @@ NS_IMETHODIMP
|
||||||
nsNode3Tearoff::LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
nsNode3Tearoff::LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
||||||
nsAString& aNamespaceURI)
|
nsAString& aNamespaceURI)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIAtom> name;
|
if (NS_FAILED(nsContentUtils::LookupNamespaceURI(mContent,
|
||||||
|
aNamespacePrefix,
|
||||||
if (!aNamespacePrefix.IsEmpty()) {
|
aNamespaceURI))) {
|
||||||
name = do_GetAtom(aNamespacePrefix);
|
SetDOMStringToNull(aNamespaceURI);
|
||||||
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
} else {
|
|
||||||
name = nsLayoutAtoms::xmlnsNameSpace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace up the content parent chain looking for the namespace
|
|
||||||
// declaration that declares aNamespacePrefix.
|
|
||||||
for (nsIContent* content = mContent; content;
|
|
||||||
content = content->GetParent()) {
|
|
||||||
nsresult rv = content->GetAttr(kNameSpaceID_XMLNS, name, aNamespaceURI);
|
|
||||||
|
|
||||||
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDOMStringToNull(aNamespaceURI);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@ XBL_ATOM(image, "image")
|
||||||
XBL_ATOM(stylesheet, "stylesheet")
|
XBL_ATOM(stylesheet, "stylesheet")
|
||||||
XBL_ATOM(implementation, "implementation")
|
XBL_ATOM(implementation, "implementation")
|
||||||
XBL_ATOM(implements, "implements")
|
XBL_ATOM(implements, "implements")
|
||||||
XBL_ATOM(xbltext, "xbl:text")
|
|
||||||
XBL_ATOM(method, "method")
|
XBL_ATOM(method, "method")
|
||||||
XBL_ATOM(property, "property")
|
XBL_ATOM(property, "property")
|
||||||
XBL_ATOM(field, "field")
|
XBL_ATOM(field, "field")
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
#include "nsXBLAtoms.h"
|
#include "nsXBLAtoms.h"
|
||||||
#include "nsXBLProtoImpl.h"
|
#include "nsXBLProtoImpl.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
|
|
||||||
|
@ -88,6 +89,7 @@ class nsXBLAttributeEntry {
|
||||||
public:
|
public:
|
||||||
nsIAtom* GetSrcAttribute() { return mSrcAttribute; }
|
nsIAtom* GetSrcAttribute() { return mSrcAttribute; }
|
||||||
nsIAtom* GetDstAttribute() { return mDstAttribute; }
|
nsIAtom* GetDstAttribute() { return mDstAttribute; }
|
||||||
|
PRInt32 GetDstNameSpace() { return mDstNameSpace; }
|
||||||
|
|
||||||
nsIContent* GetElement() { return mElement; }
|
nsIContent* GetElement() { return mElement; }
|
||||||
|
|
||||||
|
@ -95,9 +97,10 @@ public:
|
||||||
void SetNext(nsXBLAttributeEntry* aEntry) { mNext = aEntry; }
|
void SetNext(nsXBLAttributeEntry* aEntry) { mNext = aEntry; }
|
||||||
|
|
||||||
static nsXBLAttributeEntry*
|
static nsXBLAttributeEntry*
|
||||||
Create(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, nsIContent* aContent) {
|
Create(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, PRInt32 aDstNameSpace, nsIContent* aContent) {
|
||||||
void* place = nsXBLPrototypeBinding::kAttrPool->Alloc(sizeof(nsXBLAttributeEntry));
|
void* place = nsXBLPrototypeBinding::kAttrPool->Alloc(sizeof(nsXBLAttributeEntry));
|
||||||
return place ? ::new (place) nsXBLAttributeEntry(aSrcAtom, aDstAtom, aContent) : nsnull;
|
return place ? ::new (place) nsXBLAttributeEntry(aSrcAtom, aDstAtom, aDstNameSpace,
|
||||||
|
aContent) : nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -111,13 +114,15 @@ protected:
|
||||||
|
|
||||||
nsCOMPtr<nsIAtom> mSrcAttribute;
|
nsCOMPtr<nsIAtom> mSrcAttribute;
|
||||||
nsCOMPtr<nsIAtom> mDstAttribute;
|
nsCOMPtr<nsIAtom> mDstAttribute;
|
||||||
|
PRInt32 mDstNameSpace;
|
||||||
nsXBLAttributeEntry* mNext;
|
nsXBLAttributeEntry* mNext;
|
||||||
|
|
||||||
nsXBLAttributeEntry(nsIAtom* aSrcAtom, nsIAtom* aDstAtom,
|
nsXBLAttributeEntry(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, PRInt32 aDstNameSpace,
|
||||||
nsIContent* aContent)
|
nsIContent* aContent)
|
||||||
: mElement(aContent),
|
: mElement(aContent),
|
||||||
mSrcAttribute(aSrcAtom),
|
mSrcAttribute(aSrcAtom),
|
||||||
mDstAttribute(aDstAtom),
|
mDstAttribute(aDstAtom),
|
||||||
|
mDstNameSpace(aDstNameSpace),
|
||||||
mNext(nsnull) { }
|
mNext(nsnull) { }
|
||||||
|
|
||||||
~nsXBLAttributeEntry() { delete mNext; }
|
~nsXBLAttributeEntry() { delete mNext; }
|
||||||
|
@ -226,7 +231,7 @@ nsXBLPrototypeBinding::nsXBLPrototypeBinding()
|
||||||
mHasBaseProto(PR_TRUE),
|
mHasBaseProto(PR_TRUE),
|
||||||
mKeyHandlersRegistered(PR_FALSE),
|
mKeyHandlersRegistered(PR_FALSE),
|
||||||
mResources(nsnull),
|
mResources(nsnull),
|
||||||
mAttributeTable(nsnull),
|
mAttributeTable(nsnull),
|
||||||
mInsertionPointTable(nsnull),
|
mInsertionPointTable(nsnull),
|
||||||
mInterfaceTable(nsnull)
|
mInterfaceTable(nsnull)
|
||||||
{
|
{
|
||||||
|
@ -436,9 +441,15 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute,
|
||||||
{
|
{
|
||||||
if (!mAttributeTable)
|
if (!mAttributeTable)
|
||||||
return;
|
return;
|
||||||
|
nsPRUint32Key nskey(aNameSpaceID);
|
||||||
|
nsObjectHashtable *attributesNS = NS_STATIC_CAST(nsObjectHashtable*,
|
||||||
|
mAttributeTable->Get(&nskey));
|
||||||
|
if (!attributesNS)
|
||||||
|
return;
|
||||||
|
|
||||||
nsISupportsKey key(aAttribute);
|
nsISupportsKey key(aAttribute);
|
||||||
nsXBLAttributeEntry* xblAttr = NS_STATIC_CAST(nsXBLAttributeEntry*, mAttributeTable->Get(&key));
|
nsXBLAttributeEntry* xblAttr = NS_STATIC_CAST(nsXBLAttributeEntry*,
|
||||||
|
attributesNS->Get(&key));
|
||||||
if (!xblAttr)
|
if (!xblAttr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -453,15 +464,16 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute,
|
||||||
|
|
||||||
if (realElement) {
|
if (realElement) {
|
||||||
nsIAtom* dstAttr = xblAttr->GetDstAttribute();
|
nsIAtom* dstAttr = xblAttr->GetDstAttribute();
|
||||||
|
PRInt32 dstNs = xblAttr->GetDstNameSpace();
|
||||||
|
|
||||||
if (aRemoveFlag)
|
if (aRemoveFlag)
|
||||||
realElement->UnsetAttr(aNameSpaceID, dstAttr, aNotify);
|
realElement->UnsetAttr(dstNs, dstAttr, aNotify);
|
||||||
else {
|
else {
|
||||||
PRBool attrPresent = PR_TRUE;
|
PRBool attrPresent = PR_TRUE;
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
// Check to see if the src attribute is xbl:text. If so, then we need to obtain the
|
// Check to see if the src attribute is xbl:text. If so, then we need to obtain the
|
||||||
// children of the real element and get the text nodes' values.
|
// children of the real element and get the text nodes' values.
|
||||||
if (aAttribute == nsXBLAtoms::xbltext) {
|
if (aAttribute == nsHTMLAtoms::text && aNameSpaceID == kNameSpaceID_XBL) {
|
||||||
nsXBLBinding::GetTextData(aChangedElement, value);
|
nsXBLBinding::GetTextData(aChangedElement, value);
|
||||||
value.StripChar(PRUnichar('\n'));
|
value.StripChar(PRUnichar('\n'));
|
||||||
value.StripChar(PRUnichar('\r'));
|
value.StripChar(PRUnichar('\r'));
|
||||||
|
@ -477,14 +489,14 @@ nsXBLPrototypeBinding::AttributeChanged(nsIAtom* aAttribute,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrPresent)
|
if (attrPresent)
|
||||||
realElement->SetAttr(aNameSpaceID, dstAttr, value, aNotify);
|
realElement->SetAttr(dstNs, dstAttr, value, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we're the <html> tag in XUL, and see if value is being
|
// See if we're the <html> tag in XUL, and see if value is being
|
||||||
// set or unset on us. We may also be a tag that is having
|
// set or unset on us. We may also be a tag that is having
|
||||||
// xbl:text set on us.
|
// xbl:text set on us.
|
||||||
|
|
||||||
if (dstAttr == nsXBLAtoms::xbltext ||
|
if ((dstAttr == nsHTMLAtoms::text && dstNs == kNameSpaceID_XBL) ||
|
||||||
realElement->GetNodeInfo()->Equals(nsHTMLAtoms::html,
|
realElement->GetNodeInfo()->Equals(nsHTMLAtoms::html,
|
||||||
kNameSpaceID_XUL) &&
|
kNameSpaceID_XUL) &&
|
||||||
dstAttr == nsHTMLAtoms::value) {
|
dstAttr == nsHTMLAtoms::value) {
|
||||||
|
@ -833,6 +845,7 @@ struct nsXBLAttrChangeData
|
||||||
nsXBLPrototypeBinding* mProto;
|
nsXBLPrototypeBinding* mProto;
|
||||||
nsIContent* mBoundElement;
|
nsIContent* mBoundElement;
|
||||||
nsIContent* mContent;
|
nsIContent* mContent;
|
||||||
|
PRInt32 mSrcNamespace;
|
||||||
|
|
||||||
nsXBLAttrChangeData(nsXBLPrototypeBinding* aProto,
|
nsXBLAttrChangeData(nsXBLPrototypeBinding* aProto,
|
||||||
nsIContent* aElt, nsIContent* aContent)
|
nsIContent* aElt, nsIContent* aContent)
|
||||||
|
@ -841,15 +854,15 @@ struct nsXBLAttrChangeData
|
||||||
|
|
||||||
PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
{
|
{
|
||||||
// XXX How to deal with NAMESPACES!!!?
|
|
||||||
nsXBLAttributeEntry* entry = NS_STATIC_CAST(nsXBLAttributeEntry*, aData);
|
nsXBLAttributeEntry* entry = NS_STATIC_CAST(nsXBLAttributeEntry*, aData);
|
||||||
nsXBLAttrChangeData* changeData = NS_STATIC_CAST(nsXBLAttrChangeData*, aClosure);
|
nsXBLAttrChangeData* changeData = NS_STATIC_CAST(nsXBLAttrChangeData*, aClosure);
|
||||||
|
|
||||||
nsIAtom* src = entry->GetSrcAttribute();
|
nsIAtom* src = entry->GetSrcAttribute();
|
||||||
|
PRInt32 srcNs = changeData->mSrcNamespace;
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
PRBool attrPresent = PR_TRUE;
|
PRBool attrPresent = PR_TRUE;
|
||||||
|
|
||||||
if (src == nsXBLAtoms::xbltext) {
|
if (src == nsHTMLAtoms::text && srcNs == kNameSpaceID_XBL) {
|
||||||
nsXBLBinding::GetTextData(changeData->mBoundElement, value);
|
nsXBLBinding::GetTextData(changeData->mBoundElement, value);
|
||||||
value.StripChar(PRUnichar('\n'));
|
value.StripChar(PRUnichar('\n'));
|
||||||
value.StripChar(PRUnichar('\r'));
|
value.StripChar(PRUnichar('\r'));
|
||||||
|
@ -860,7 +873,7 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
attrPresent = PR_FALSE;
|
attrPresent = PR_FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nsresult result = changeData->mBoundElement->GetAttr(kNameSpaceID_None, src, value);
|
nsresult result = changeData->mBoundElement->GetAttr(srcNs, src, value);
|
||||||
attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||||
}
|
}
|
||||||
|
@ -872,6 +885,7 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
nsXBLAttributeEntry* curr = entry;
|
nsXBLAttributeEntry* curr = entry;
|
||||||
while (curr) {
|
while (curr) {
|
||||||
nsIAtom* dst = curr->GetDstAttribute();
|
nsIAtom* dst = curr->GetDstAttribute();
|
||||||
|
PRInt32 dstNs = curr->GetDstNameSpace();
|
||||||
nsIContent* element = curr->GetElement();
|
nsIContent* element = curr->GetElement();
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> realElement;
|
nsCOMPtr<nsIContent> realElement;
|
||||||
|
@ -880,9 +894,9 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
changeData->mContent,
|
changeData->mContent,
|
||||||
element);
|
element);
|
||||||
if (realElement) {
|
if (realElement) {
|
||||||
realElement->SetAttr(kNameSpaceID_None, dst, value, PR_FALSE);
|
realElement->SetAttr(dstNs, dst, value, PR_FALSE);
|
||||||
|
|
||||||
if (dst == nsXBLAtoms::xbltext ||
|
if ((dst == nsHTMLAtoms::text && dstNs == kNameSpaceID_XBL) ||
|
||||||
(realElement->GetNodeInfo()->Equals(nsHTMLAtoms::html,
|
(realElement->GetNodeInfo()->Equals(nsHTMLAtoms::html,
|
||||||
kNameSpaceID_XUL) &&
|
kNameSpaceID_XUL) &&
|
||||||
dst == nsHTMLAtoms::value && !value.IsEmpty())) {
|
dst == nsHTMLAtoms::value && !value.IsEmpty())) {
|
||||||
|
@ -904,12 +918,26 @@ PRBool PR_CALLBACK SetAttrs(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool PR_CALLBACK SetAttrsNS(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
|
{
|
||||||
|
if (aData && aClosure) {
|
||||||
|
nsPRUint32Key * key = NS_STATIC_CAST(nsPRUint32Key*, aKey);
|
||||||
|
nsObjectHashtable* xblAttributes =
|
||||||
|
NS_STATIC_CAST(nsObjectHashtable*, aData);
|
||||||
|
nsXBLAttrChangeData * changeData = NS_STATIC_CAST(nsXBLAttrChangeData *,
|
||||||
|
aClosure);
|
||||||
|
changeData->mSrcNamespace = key->GetValue();
|
||||||
|
xblAttributes->Enumerate(SetAttrs, (void*)changeData);
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)
|
nsXBLPrototypeBinding::SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent)
|
||||||
{
|
{
|
||||||
if (mAttributeTable) {
|
if (mAttributeTable) {
|
||||||
nsXBLAttrChangeData data(this, aBoundElement, aAnonymousContent);
|
nsXBLAttrChangeData data(this, aBoundElement, aAnonymousContent);
|
||||||
mAttributeTable->Enumerate(SetAttrs, (void*)&data);
|
mAttributeTable->Enumerate(SetAttrsNS, (void*)&data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,9 +964,14 @@ nsXBLPrototypeBinding::GetStyleSheets()
|
||||||
PRBool
|
PRBool
|
||||||
nsXBLPrototypeBinding::ShouldBuildChildFrames()
|
nsXBLPrototypeBinding::ShouldBuildChildFrames()
|
||||||
{
|
{
|
||||||
if (mAttributeTable) {
|
if (!mAttributeTable)
|
||||||
nsISupportsKey key(nsXBLAtoms::xbltext);
|
return PR_TRUE;
|
||||||
void* entry = mAttributeTable->Get(&key);
|
nsPRUint32Key nskey(kNameSpaceID_XBL);
|
||||||
|
nsObjectHashtable* xblAttributes =
|
||||||
|
NS_STATIC_CAST(nsObjectHashtable*, mAttributeTable->Get(&nskey));
|
||||||
|
if (xblAttributes) {
|
||||||
|
nsISupportsKey key(nsHTMLAtoms::text);
|
||||||
|
void* entry = xblAttributes->Get(&key);
|
||||||
return !entry;
|
return !entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,6 +985,13 @@ DeleteAttributeEntry(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool PR_CALLBACK
|
||||||
|
DeleteAttributeTable(nsHashKey* aKey, void* aData, void* aClosure)
|
||||||
|
{
|
||||||
|
delete NS_STATIC_CAST(nsObjectHashtable*, aData);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||||
{
|
{
|
||||||
|
@ -961,7 +1001,7 @@ nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||||
if (!inherits.IsEmpty()) {
|
if (!inherits.IsEmpty()) {
|
||||||
if (!mAttributeTable) {
|
if (!mAttributeTable) {
|
||||||
mAttributeTable = new nsObjectHashtable(nsnull, nsnull,
|
mAttributeTable = new nsObjectHashtable(nsnull, nsnull,
|
||||||
DeleteAttributeEntry, nsnull, 4);
|
DeleteAttributeTable, nsnull, 4);
|
||||||
if (!mAttributeTable)
|
if (!mAttributeTable)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -976,38 +1016,66 @@ nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent* aElement)
|
||||||
while( token != NULL ) {
|
while( token != NULL ) {
|
||||||
// Build an atom out of this attribute.
|
// Build an atom out of this attribute.
|
||||||
nsCOMPtr<nsIAtom> atom;
|
nsCOMPtr<nsIAtom> atom;
|
||||||
|
PRInt32 atomNsID = kNameSpaceID_None;
|
||||||
nsCOMPtr<nsIAtom> attribute;
|
nsCOMPtr<nsIAtom> attribute;
|
||||||
|
PRInt32 attributeNsID = kNameSpaceID_None;
|
||||||
|
|
||||||
// Figure out if this token contains a :.
|
// Figure out if this token contains a :.
|
||||||
nsAutoString attrTok; attrTok.AssignWithConversion(token);
|
nsAutoString attrTok; attrTok.AssignWithConversion(token);
|
||||||
PRInt32 index = attrTok.Find("=", PR_TRUE);
|
PRInt32 index = attrTok.Find("=", PR_TRUE);
|
||||||
|
nsresult rv;
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
// This attribute maps to something different.
|
// This attribute maps to something different.
|
||||||
nsAutoString left, right;
|
nsAutoString left, right;
|
||||||
attrTok.Left(left, index);
|
attrTok.Left(left, index);
|
||||||
attrTok.Right(right, attrTok.Length()-index-1);
|
attrTok.Right(right, attrTok.Length()-index-1);
|
||||||
|
|
||||||
atom = do_GetAtom(right);
|
rv = nsContentUtils::SplitQName(aElement, left, &attributeNsID,
|
||||||
attribute = do_GetAtom(left);
|
getter_AddRefs(attribute));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
rv = nsContentUtils::SplitQName(aElement, right, &atomNsID,
|
||||||
|
getter_AddRefs(atom));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nsAutoString tok;
|
nsAutoString tok;
|
||||||
tok.AssignWithConversion(token);
|
tok.AssignWithConversion(token);
|
||||||
atom = do_GetAtom(tok);
|
rv = nsContentUtils::SplitQName(aElement, tok, &atomNsID,
|
||||||
|
getter_AddRefs(atom));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return;
|
||||||
attribute = atom;
|
attribute = atom;
|
||||||
|
attributeNsID = atomNsID;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPRUint32Key nskey(atomNsID);
|
||||||
|
nsObjectHashtable* attributesNS =
|
||||||
|
NS_STATIC_CAST(nsObjectHashtable*, mAttributeTable->Get(&nskey));
|
||||||
|
if (!attributesNS) {
|
||||||
|
attributesNS = new nsObjectHashtable(nsnull, nsnull,
|
||||||
|
DeleteAttributeEntry, nsnull, 4);
|
||||||
|
if (!attributesNS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mAttributeTable->Put(&nskey, attributesNS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an XBL attribute entry.
|
// Create an XBL attribute entry.
|
||||||
nsXBLAttributeEntry* xblAttr = nsXBLAttributeEntry::Create(atom, attribute, aElement);
|
nsXBLAttributeEntry* xblAttr =
|
||||||
|
nsXBLAttributeEntry::Create(atom, attribute, attributeNsID, aElement);
|
||||||
|
|
||||||
// Now we should see if some element within our anonymous
|
// Now we should see if some element within our anonymous
|
||||||
// content is already observing this attribute.
|
// content is already observing this attribute.
|
||||||
nsISupportsKey key(atom);
|
nsISupportsKey key(atom);
|
||||||
nsXBLAttributeEntry* entry = NS_STATIC_CAST(nsXBLAttributeEntry*, mAttributeTable->Get(&key));
|
nsXBLAttributeEntry* entry = NS_STATIC_CAST(nsXBLAttributeEntry*,
|
||||||
|
attributesNS->Get(&key));
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
// Put it in the table.
|
// Put it in the table.
|
||||||
mAttributeTable->Put(&key, xblAttr);
|
attributesNS->Put(&key, xblAttr);
|
||||||
} else {
|
} else {
|
||||||
while (entry->GetNext())
|
while (entry->GetNext())
|
||||||
entry = entry->GetNext();
|
entry = entry->GetNext();
|
||||||
|
@ -1250,7 +1318,7 @@ nsXBLPrototypeBinding::CreateKeyHandlers()
|
||||||
|
|
||||||
PRInt32 count = mKeyHandlers.Count();
|
PRInt32 count = mKeyHandlers.Count();
|
||||||
PRInt32 i;
|
PRInt32 i;
|
||||||
nsXBLKeyEventHandler* handler;
|
nsXBLKeyEventHandler* handler = nsnull;
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
handler = mKeyHandlers[i];
|
handler = mKeyHandlers[i];
|
||||||
if (handler->Matches(eventAtom, phase, type))
|
if (handler->Matches(eventAtom, phase, type))
|
||||||
|
|
|
@ -236,8 +236,9 @@ protected:
|
||||||
|
|
||||||
nsIXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info. Weak, since it owns us.
|
nsIXBLDocumentInfo* mXBLDocInfoWeak; // A pointer back to our doc info. Weak, since it owns us.
|
||||||
|
|
||||||
nsObjectHashtable* mAttributeTable; // A table for attribute entries. Used to efficiently
|
nsObjectHashtable* mAttributeTable; // A table for attribute containers. Namespace IDs are used as
|
||||||
// handle attribute changes.
|
// keys in the table. Containers are nsObjectHashtables.
|
||||||
|
// This table is used to efficiently handle attribute changes.
|
||||||
|
|
||||||
nsObjectHashtable* mInsertionPointTable; // A table of insertion points for placing explicit content
|
nsObjectHashtable* mInsertionPointTable; // A table of insertion points for placing explicit content
|
||||||
// underneath anonymous content.
|
// underneath anonymous content.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче