Final patch for bug 195350. Make XUL use new nsAttrAndChildren class. Kill nsXULAttributeValue and nsXULAttributes in favour of nsAttrValue resp. nsDOMAttributeMap. Should fix a few bugs, improve performance and reduce bloat.

r=bz sr=jst
This commit is contained in:
sicking%bigfoot.com 2004-02-10 09:08:06 +00:00
Родитель 9de01a1f92
Коммит 19ba87419f
30 изменённых файлов: 1234 добавлений и 1336 удалений

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

@ -144,12 +144,6 @@ public:
*/
virtual nsresult SetDocumentPrincipal(nsIPrincipal* aPrincipal) = 0;
/**
* Populate the given nsCOMArray with all of the nsINodeInfos
* managed by this manager.
*/
virtual nsresult GetNodeInfos(nsCOMArray<nsINodeInfo> *aArray) = 0;
protected:
nsIDocument *mDocument; // WEAK
};

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

@ -379,18 +379,17 @@ nsAttrAndChildArray::GetSafeAttrNameAt(PRUint32 aPos) const
}
const nsAttrName*
nsAttrAndChildArray::GetExistingAttrNameFromQName(const nsAString& aName) const
nsAttrAndChildArray::GetExistingAttrNameFromQName(const nsACString& aName) const
{
NS_ConvertUTF16toUTF8 name(aName);
PRUint32 i, slotCount = AttrSlotCount();
for (i = 0; i < slotCount && mImpl->mBuffer[i * ATTRSIZE]; ++i) {
if (ATTRS(mImpl)[i].mName.QualifiedNameEquals(name)) {
if (ATTRS(mImpl)[i].mName.QualifiedNameEquals(aName)) {
return &ATTRS(mImpl)[i].mName;
}
}
if (mImpl && mImpl->mMappedAttrs) {
return mImpl->mMappedAttrs->GetExistingAttrNameFromQName(name);
return mImpl->mMappedAttrs->GetExistingAttrNameFromQName(aName);
}
return nsnull;

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

@ -99,7 +99,8 @@ public:
nsresult SetAndTakeAttr(nsINodeInfo* aName, nsAttrValue& aValue);
nsresult RemoveAttrAt(PRUint32 aPos);
const nsAttrName* GetSafeAttrNameAt(PRUint32 aPos) const;
const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
// aName is UTF-8 encoded
const nsAttrName* GetExistingAttrNameFromQName(const nsACString& aName) const;
PRInt32 IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,

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

@ -96,6 +96,15 @@ public:
}
}
void SetTo(nsIAtom* aAtom)
{
NS_ASSERTION(aAtom, "null atom-name in nsAttrName");
ReleaseInternalName();
mBits = NS_REINTERPRET_CAST(PtrBits, aAtom);
NS_ADDREF(aAtom);
}
PRBool IsAtom() const
{
return !(mBits & NS_ATTRNAME_NODEINFO_BIT);

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

@ -58,7 +58,7 @@ nsAttrValue::nsAttrValue(const nsAString& aValue)
SetTo(aValue);
}
nsAttrValue::nsAttrValue(nsHTMLValue* aValue)
nsAttrValue::nsAttrValue(const nsHTMLValue& aValue)
: mBits(0)
{
SetTo(aValue);
@ -115,11 +115,7 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
}
case eHTMLValue:
{
nsHTMLValue* newVal =
new nsHTMLValue(*aOther.GetHTMLValue());
if (newVal) {
SetTo(newVal);
}
SetTo(*aOther.GetHTMLValue());
break;
}
case eAtom:
@ -155,11 +151,13 @@ nsAttrValue::SetTo(const nsAString& aValue)
}
void
nsAttrValue::SetTo(nsHTMLValue* aValue)
nsAttrValue::SetTo(const nsHTMLValue& aValue)
{
NS_ASSERTION(aValue, "null value in nsAttrValue::SetTo");
Reset();
SetValueAndType(aValue, eHTMLValue);
nsHTMLValue* htmlValue = new nsHTMLValue(aValue);
if (htmlValue) {
SetValueAndType(htmlValue, eHTMLValue);
}
}
void
@ -168,7 +166,24 @@ nsAttrValue::SetTo(nsIAtom* aValue)
NS_ASSERTION(aValue, "null value in nsAttrValue::SetTo");
Reset();
NS_ADDREF(aValue);
mBits = NS_REINTERPRET_CAST(PtrBits, aValue) | eAtom;
SetValueAndType(aValue, eAtom);
}
void
nsAttrValue::SetToStringOrAtom(const nsAString& aValue)
{
PRUint32 len = aValue.Length();
// Don't bother with atoms if it's an empty string since
// we can store those efficently anyway.
if (len && len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
nsCOMPtr<nsIAtom> atom = do_GetAtom(aValue);
if (atom) {
SetTo(atom);
}
}
else {
SetTo(aValue);
}
}
void

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

@ -47,6 +47,7 @@ class nsHTMLValue;
class nsAString;
class nsIAtom;
#define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12
#define NS_ATTRVALUE_TYPE_MASK (PtrBits(3))
#define NS_ATTRVALUE_VALUE_MASK (~NS_ATTRVALUE_TYPE_MASK)
@ -55,15 +56,16 @@ public:
nsAttrValue();
nsAttrValue(const nsAttrValue& aOther);
explicit nsAttrValue(const nsAString& aValue);
explicit nsAttrValue(nsHTMLValue* aValue);
explicit nsAttrValue(const nsHTMLValue& aValue);
explicit nsAttrValue(nsIAtom* aValue);
~nsAttrValue();
void Reset();
void SetTo(const nsAttrValue& aOther);
void SetTo(const nsAString& aValue);
void SetTo(nsHTMLValue* aValue);
void SetTo(const nsHTMLValue& aValue);
void SetTo(nsIAtom* aValue);
void SetToStringOrAtom(const nsAString& aValue);
void SwapValueWith(nsAttrValue& aOther);

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

@ -1281,6 +1281,11 @@ nsGenericElement::RemoveAttribute(const nsAString& aName)
return NS_OK;
}
// Hold a strong reference here so that the atom or nodeinfo doesn't go
// away during UnsetAttr. If it did UnsetAttr would be left with a
// dangling pointer as argument without knowing it.
nsAttrName tmp(*name);
return UnsetAttr(name->NamespaceID(), name->LocalName(), PR_TRUE);
}
@ -3174,7 +3179,8 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute,
const nsAttrName*
nsGenericContainerElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
{
return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
return mAttrsAndChildren.GetExistingAttrNameFromQName(
NS_ConvertUTF16toUTF8(aStr));
}
nsresult

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

@ -47,6 +47,8 @@
#include "nsIHTMLDocument.h"
#include "nsUnitConversion.h"
#include "prprf.h"
#include "nsICSSStyleRule.h"
#include "nsCSSDeclaration.h"
nsHTMLValue::nsHTMLValue(nsHTMLUnit aUnit)
: mUnit(aUnit)
@ -84,11 +86,11 @@ nsHTMLValue::nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit)
SetStringValueInternal(aValue, aUnit);
}
nsHTMLValue::nsHTMLValue(nsISupports* aValue)
: mUnit(eHTMLUnit_ISupports)
nsHTMLValue::nsHTMLValue(nsICSSStyleRule* aValue)
: mUnit(eHTMLUnit_CSSStyleRule)
{
mValue.mISupports = aValue;
NS_IF_ADDREF(mValue.mISupports);
mValue.mCSSStyleRule = aValue;
NS_IF_ADDREF(mValue.mCSSStyleRule);
}
nsHTMLValue::nsHTMLValue(nscolor aValue)
@ -145,8 +147,8 @@ PRBool nsHTMLValue::operator==(const nsHTMLValue& aOther) const
case HTMLUNIT_COLOR:
return mValue.mColor == aOther.mValue.mColor;
case HTMLUNIT_ISUPPORTS:
return mValue.mISupports == aOther.mValue.mISupports;
case HTMLUNIT_CSSSTYLERULE:
return mValue.mCSSStyleRule == aOther.mValue.mCSSStyleRule;
case HTMLUNIT_PERCENT:
return mValue.mFloat == aOther.mValue.mFloat;
@ -203,8 +205,8 @@ void nsHTMLValue::Reset(void)
nsCheapStringBufferUtils::Free(mValue.mString);
}
}
else if (mUnit == eHTMLUnit_ISupports) {
NS_IF_RELEASE(mValue.mISupports);
else if (mUnit == eHTMLUnit_CSSStyleRule) {
NS_IF_RELEASE(mValue.mCSSStyleRule);
}
else if (mUnit == eHTMLUnit_AtomArray) {
delete mValue.mAtomArray;
@ -265,12 +267,12 @@ void nsHTMLValue::SetStringValue(const nsAString& aValue,
SetStringValueInternal(aValue, aUnit);
}
void nsHTMLValue::SetISupportsValue(nsISupports* aValue)
void nsHTMLValue::SetCSSStyleRuleValue(nsICSSStyleRule* aValue)
{
Reset();
mUnit = eHTMLUnit_ISupports;
mValue.mISupports = aValue;
NS_IF_ADDREF(mValue.mISupports);
mUnit = eHTMLUnit_CSSStyleRule;
mValue.mCSSStyleRule = aValue;
NS_IF_ADDREF(mValue.mCSSStyleRule);
}
void nsHTMLValue::SetColorValue(nscolor aValue)
@ -312,9 +314,9 @@ nsHTMLValue::InitializeFrom(const nsHTMLValue& aCopy)
mValue.mColor = aCopy.mValue.mColor;
break;
case HTMLUNIT_ISUPPORTS:
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
case HTMLUNIT_CSSSTYLERULE:
mValue.mCSSStyleRule = aCopy.mValue.mCSSStyleRule;
NS_IF_ADDREF(mValue.mCSSStyleRule);
break;
case HTMLUNIT_PERCENT:
@ -486,6 +488,18 @@ nsHTMLValue::ToString(nsAString& aResult) const
}
return PR_TRUE;
}
case eHTMLUnit_CSSStyleRule:
{
if (mValue.mCSSStyleRule) {
nsCSSDeclaration* decl = mValue.mCSSStyleRule->GetDeclaration();
if (decl) {
decl->ToString(aResult);
}
}
return PR_TRUE;
}
default:
return PR_FALSE;
}

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

@ -41,7 +41,6 @@
#include "nscore.h"
#include "nsColor.h"
#include "nsString.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
@ -50,6 +49,7 @@
#include "nsIAtom.h"
class nsIDocument;
class nsICSSStyleRule;
class nsCheapStringBufferUtils {
public:
@ -148,15 +148,15 @@ public:
// between different things stored as the same type. Doing
// mUnit & HTMLUNIT_CLASS_MASK should give you the class of type.
//
#define HTMLUNIT_NOSTORE 0x0000
#define HTMLUNIT_STRING 0x0100
#define HTMLUNIT_INTEGER 0x0200
#define HTMLUNIT_PIXEL 0x0400
#define HTMLUNIT_COLOR 0x0800
#define HTMLUNIT_ISUPPORTS 0x1000
#define HTMLUNIT_PERCENT 0x2000
#define HTMLUNIT_ATOMARRAY 0x4000
#define HTMLUNIT_CLASS_MASK 0xff00
#define HTMLUNIT_NOSTORE 0x0000
#define HTMLUNIT_STRING 0x0100
#define HTMLUNIT_INTEGER 0x0200
#define HTMLUNIT_PIXEL 0x0400
#define HTMLUNIT_COLOR 0x0800
#define HTMLUNIT_CSSSTYLERULE 0x1000
#define HTMLUNIT_PERCENT 0x2000
#define HTMLUNIT_ATOMARRAY 0x4000
#define HTMLUNIT_CLASS_MASK 0xff00
enum nsHTMLUnit {
// null, value is not specified: 0x0000
@ -182,8 +182,8 @@ enum nsHTMLUnit {
// an RGBA value
eHTMLUnit_Color = HTMLUNIT_COLOR,
// (nsISupports*) a ref counted interface
eHTMLUnit_ISupports = HTMLUNIT_ISUPPORTS,
// a nsICSSStyleRule
eHTMLUnit_CSSStyleRule = HTMLUNIT_CSSSTYLERULE,
// (1.0 == 100%) value is percentage of something
eHTMLUnit_Percent = HTMLUNIT_PERCENT,
@ -204,7 +204,7 @@ public:
nsHTMLValue(PRInt32 aValue, nsHTMLUnit aUnit);
nsHTMLValue(float aValue);
nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit = eHTMLUnit_String);
nsHTMLValue(nsISupports* aValue);
nsHTMLValue(nsICSSStyleRule* aValue);
nsHTMLValue(nscolor aValue);
nsHTMLValue(nsCOMArray<nsIAtom>* aArray);
nsHTMLValue(const nsHTMLValue& aCopy);
@ -225,7 +225,7 @@ public:
PRInt32 GetPixelValue(void) const;
float GetPercentValue(void) const;
nsAString& GetStringValue(nsAString& aBuffer) const;
already_AddRefed<nsISupports> GetISupportsValue(void) const;
nsICSSStyleRule* GetCSSStyleRuleValue(void) const;
nscolor GetColorValue(void) const;
nsCOMArray<nsIAtom>* AtomArrayValue() const;
@ -237,7 +237,7 @@ public:
void SetPixelValue(PRInt32 aValue);
void SetPercentValue(float aValue);
void SetStringValue(const nsAString& aValue, nsHTMLUnit aUnit = eHTMLUnit_String);
void SetISupportsValue(nsISupports* aValue);
void SetCSSStyleRuleValue(nsICSSStyleRule* aValue);
void SetColorValue(nscolor aValue);
void SetEmptyValue(void);
@ -363,8 +363,8 @@ protected:
float mFloat;
/** String. First 4 bytes are the length, non-null-terminated. */
PRUnichar* mString;
/** ISupports. Strong reference. */
nsISupports* mISupports;
/** nsICSSStyleRule. Strong reference. */
nsICSSStyleRule* mCSSStyleRule;
/** Color. */
nscolor mColor;
/** Array if atoms */
@ -462,13 +462,11 @@ inline nsAString& nsHTMLValue::GetStringValue(nsAString& aBuffer) const
return aBuffer;
}
inline already_AddRefed<nsISupports> nsHTMLValue::GetISupportsValue(void) const
inline nsICSSStyleRule* nsHTMLValue::GetCSSStyleRuleValue(void) const
{
NS_ASSERTION(mUnit == eHTMLUnit_ISupports, "not an ISupports value");
if (mUnit == eHTMLUnit_ISupports) {
nsISupports *result = mValue.mISupports;
NS_IF_ADDREF(result);
return result;
NS_ASSERTION(mUnit == eHTMLUnit_CSSStyleRule, "not an CSSStyleRule value");
if (mUnit == eHTMLUnit_CSSStyleRule) {
return mValue.mCSSStyleRule;
}
return nsnull;
}

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

@ -295,33 +295,6 @@ nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
return NS_OK;
}
nsresult
nsNodeInfoManager::GetNodeInfos(nsCOMArray<nsINodeInfo> *aArray)
{
PL_HashTableEnumerateEntries(mNodeInfoHash,
GetNodeInfoArrayEnumerator,
aArray);
PRInt32 n = aArray->Count();
NS_ENSURE_TRUE((PRUint32)n == mNodeInfoHash->nentries, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
//static
PRIntn
nsNodeInfoManager::GetNodeInfoArrayEnumerator(PLHashEntry* he, PRIntn i,
void* arg)
{
NS_ASSERTION(arg, "missing array");
nsCOMArray<nsINodeInfo> *array = (nsCOMArray<nsINodeInfo> *) arg;
if (!array->AppendObject((nsINodeInfo*)he->value)) {
return HT_ENUMERATE_STOP;
}
return HT_ENUMERATE_NEXT;
}
void
nsNodeInfoManager::RemoveNodeInfo(nsNodeInfo *aNodeInfo)
{

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

@ -69,7 +69,6 @@ public:
virtual nsresult GetDocumentPrincipal(nsIPrincipal** aPrincipal);
virtual nsresult SetDocumentPrincipal(nsIPrincipal* aPrincipal);
virtual nsresult GetNodeInfos(nsCOMArray<nsINodeInfo> *aArray);
// nsNodeInfoManager
nsNodeInfoManager();
@ -82,10 +81,6 @@ private:
const void *key2);
static PLHashNumber PR_CALLBACK GetNodeInfoInnerHashValue(const void *key);
PR_STATIC_CALLBACK(PRIntn) GetNodeInfoArrayEnumerator(PLHashEntry* he,
PRIntn i,
void* arg);
PLHashTable *mNodeInfoHash;
nsCOMPtr<nsIPrincipal> mPrincipal;

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

@ -294,16 +294,18 @@ nsGenericHTMLElement::CopyInnerTo(nsIContent* aSrcContent,
nsHTMLValue val;
rv = GetHTMLAttribute(nsHTMLAtoms::style, val);
if (rv == NS_CONTENT_ATTR_HAS_VALUE &&
val.GetUnit() == eHTMLUnit_ISupports) {
nsCOMPtr<nsISupports> supports(val.GetISupportsValue());
nsCOMPtr<nsICSSStyleRule> rule(do_QueryInterface(supports));
val.GetUnit() == eHTMLUnit_CSSStyleRule) {
nsICSSStyleRule* rule = val.GetCSSStyleRuleValue();
if (rule) {
nsCOMPtr<nsICSSRule> ruleClone;
rv = rule->Clone(*getter_AddRefs(ruleClone));
NS_ENSURE_SUCCESS(rv, rv);
val.SetISupportsValue(ruleClone);
nsCOMPtr<nsICSSStyleRule> styleRule = do_QueryInterface(ruleClone);
NS_ENSURE_TRUE(styleRule, NS_ERROR_UNEXPECTED);
val.SetCSSStyleRuleValue(styleRule);
rv = aDst->SetHTMLAttribute(nsHTMLAtoms::style, val, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
@ -1540,8 +1542,9 @@ nsGenericHTMLElement::GetNameSpaceID(PRInt32* aID) const
*aID = kNameSpaceID_XHTML;
}
static nsresult
ParseClassAttribute(const nsAString& aStr, nsAttrValue& aValue)
// static
nsresult
nsGenericHTMLElement::ParseClassAttribute(const nsAString& aStr, nsAttrValue& aValue)
{
nsAString::const_iterator iter, end;
aStr.BeginReading(iter);
@ -1607,11 +1610,7 @@ ParseClassAttribute(const nsAString& aStr, nsAttrValue& aValue)
}
} while (iter != end);
nsHTMLValue* htmlVal = new nsHTMLValue(array);
NS_ENSURE_TRUE(htmlVal, NS_ERROR_OUT_OF_MEMORY);
array.forget();
aValue.SetTo(htmlVal);
aValue.SetTo(nsHTMLValue(array.forget()));
return NS_OK;
}
@ -1658,16 +1657,15 @@ nsGenericHTMLElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute,
nsAttrValue attrValue;
if (aNamespaceID == kNameSpaceID_None) {
nsHTMLValue htmlValue;
if ((aAttribute == nsHTMLAtoms::style &&
NS_SUCCEEDED(ParseStyleAttribute(aValue, htmlValue))) ||
(StringToAttribute(aAttribute, aValue, htmlValue) !=
if ((StringToAttribute(aAttribute, aValue, htmlValue) !=
NS_CONTENT_ATTR_NOT_THERE) ||
ParseCommonAttribute(aAttribute, aValue, htmlValue)) {
// string value was mapped to nsHTMLValue, set it that way
nsHTMLValue* tmp = new nsHTMLValue(htmlValue);
NS_ENSURE_TRUE(tmp, NS_ERROR_OUT_OF_MEMORY);
attrValue.SetTo(tmp);
attrValue.SetTo(htmlValue);
}
else if (aAttribute == nsHTMLAtoms::style) {
ParseStyleAttribute(this, mNodeInfo->NamespaceEquals(kNameSpaceID_XHTML),
aValue, attrValue);
}
else if (aAttribute == nsHTMLAtoms::id) {
nsCOMPtr<nsIAtom> idAtom = do_GetAtom(aValue);
@ -1682,10 +1680,7 @@ nsGenericHTMLElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute,
else if (aValue.IsEmpty()) {
// This is a bit evil but there's code out there that only looks for
// this datatype and not for empty-string.
nsHTMLValue* tmp = new nsHTMLValue(eHTMLUnit_Empty);
NS_ENSURE_TRUE(tmp, NS_ERROR_OUT_OF_MEMORY);
attrValue.SetTo(tmp);
attrValue.SetTo(nsHTMLValue(eHTMLUnit_Empty));
}
else {
attrValue.SetTo(aValue);
@ -1879,11 +1874,7 @@ nsGenericHTMLElement::SetHTMLAttribute(nsIAtom* aAttribute,
}
}
nsHTMLValue* htmlVal = new nsHTMLValue(aValue);
NS_ENSURE_TRUE(htmlVal, NS_ERROR_OUT_OF_MEMORY);
nsAttrValue attrValue(htmlVal);
nsAttrValue attrValue(aValue);
return SetAttrAndNotify(kNameSpaceID_None, aAttribute, nsnull, oldValueStr,
attrValue, modification, hasListeners, aNotify);
@ -1998,6 +1989,7 @@ nsGenericHTMLElement::GetAttr(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
case eHTMLUnit_Pixel:
case eHTMLUnit_Color:
case eHTMLUnit_Percent:
case eHTMLUnit_CSSStyleRule:
case eHTMLUnit_AtomArray:
value->ToString(aResult);
break;
@ -2191,19 +2183,16 @@ nsGenericHTMLElement::GetInlineStyleRule(nsICSSStyleRule** aStyleRule)
if (attrVal) {
if (attrVal->GetType() != nsAttrValue::eHTMLValue ||
attrVal->GetHTMLValue()->GetUnit() != eHTMLUnit_ISupports) {
attrVal->GetHTMLValue()->GetUnit() != eHTMLUnit_CSSStyleRule) {
ReparseStyleAttribute();
attrVal = mAttrsAndChildren.GetAttr(nsHTMLAtoms::style);
// hopefully value.GetUnit() is now eHTMLUnit_ISupports
// hopefully value.GetUnit() is now eHTMLUnit_CSSStyleRule
}
if (attrVal->GetType() == nsAttrValue::eHTMLValue &&
attrVal->GetHTMLValue()->GetUnit() == eHTMLUnit_ISupports) {
nsCOMPtr<nsISupports> supports =
attrVal->GetHTMLValue()->GetISupportsValue();
if (supports) {
return CallQueryInterface(supports, aStyleRule);
}
attrVal->GetHTMLValue()->GetUnit() == eHTMLUnit_CSSStyleRule) {
NS_IF_ADDREF(*aStyleRule =
attrVal->GetHTMLValue()->GetCSSStyleRuleValue());
}
}
@ -2389,24 +2378,7 @@ nsGenericHTMLElement::AttributeToString(nsIAtom* aAttribute,
const nsHTMLValue& aValue,
nsAString& aResult) const
{
if (nsHTMLAtoms::style == aAttribute) {
if (eHTMLUnit_ISupports == aValue.GetUnit()) {
nsCOMPtr<nsISupports> rule = aValue.GetISupportsValue();
nsCOMPtr<nsICSSStyleRule> cssRule = do_QueryInterface(rule);
if (cssRule) {
nsCSSDeclaration* decl = cssRule->GetDeclaration();
if (decl) {
decl->ToString(aResult);
} else {
aResult.Truncate();
}
}
else {
aResult.Assign(NS_LITERAL_STRING("Unknown rule type"));
}
return NS_CONTENT_ATTR_HAS_VALUE;
}
} else if (nsHTMLAtoms::dir == aAttribute) {
if (nsHTMLAtoms::dir == aAttribute) {
nsHTMLValue value;
nsresult result = GetHTMLAttribute(nsHTMLAtoms::dir, value);
@ -2957,37 +2929,38 @@ nsGenericHTMLElement::AttrToURI(nsIAtom* aAttrName, nsAString& aAbsoluteURI)
nsresult
nsGenericHTMLElement::ReparseStyleAttribute()
{
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsHTMLAtoms::style);
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsHTMLAtoms::style);
if (attrVal &&
(attrVal->GetType() != nsAttrValue::eHTMLValue ||
attrVal->GetHTMLValue()->GetUnit() == eHTMLUnit_String)) {
nsHTMLValue parsedValue;
if (oldVal &&
(oldVal->GetType() != nsAttrValue::eHTMLValue ||
oldVal->GetHTMLValue()->GetUnit() != eHTMLUnit_CSSStyleRule)) {
nsAttrValue attrValue;
nsAutoString stringValue;
attrVal->ToString(stringValue);
nsresult rv = ParseStyleAttribute(stringValue, parsedValue);
if (NS_SUCCEEDED(rv) && parsedValue.GetUnit() == eHTMLUnit_ISupports) {
nsHTMLValue* tmp = new nsHTMLValue(parsedValue);
NS_ENSURE_TRUE(tmp, NS_ERROR_OUT_OF_MEMORY);
// Don't bother going through SetHTMLAttribute, we don't want to fire off
// mutation events or document notifications anyway
nsAttrValue attrValue(tmp);
rv = mAttrsAndChildren.SetAndTakeAttr(nsHTMLAtoms::style, attrValue);
NS_ENSURE_SUCCESS(rv, rv);
}
oldVal->ToString(stringValue);
ParseStyleAttribute(this, mNodeInfo->NamespaceEquals(kNameSpaceID_XHTML),
stringValue, attrValue);
// Don't bother going through SetHTMLAttribute, we don't want to fire off
// mutation events or document notifications anyway
nsresult rv = mAttrsAndChildren.SetAndTakeAttr(nsHTMLAtoms::style, attrValue);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
nsGenericHTMLElement::ParseStyleAttribute(const nsAString& aValue, nsHTMLValue& aResult)
void
nsGenericHTMLElement::ParseStyleAttribute(nsIContent* aContent,
PRBool aCaseSensitive,
const nsAString& aValue,
nsAttrValue& aResult)
{
nsresult result = NS_OK;
NS_ASSERTION(mNodeInfo, "If we don't have a nodeinfo, we are very screwed");
NS_ASSERTION(aContent->GetNodeInfo(), "If we don't have a nodeinfo, we are very screwed");
nsIDocument* doc = GetOwnerDocument();
nsIDocument* doc = aContent->GetDocument();
if (!doc) {
doc = aContent->GetNodeInfo()->GetDocument();
}
if (doc) {
PRBool isCSS = PR_TRUE; // assume CSS until proven otherwise
@ -3010,11 +2983,11 @@ nsGenericHTMLElement::ParseStyleAttribute(const nsAString& aValue, nsHTMLValue&
if (cssParser) {
// look up our namespace. If we're XHTML, we need to be case-sensitive
// Otherwise, we should not be.
cssParser->SetCaseSensitive(mNodeInfo->NamespaceEquals(kNameSpaceID_XHTML));
cssParser->SetCaseSensitive(aCaseSensitive);
}
}
if (cssParser) {
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsCOMPtr<nsIURI> baseURI = aContent->GetBaseURI();
nsCOMPtr<nsICSSStyleRule> rule;
result = cssParser->ParseStyleAttribute(aValue, baseURI,
@ -3024,14 +2997,15 @@ nsGenericHTMLElement::ParseStyleAttribute(const nsAString& aValue, nsHTMLValue&
}
if (rule) {
aResult.SetISupportsValue(rule);
return NS_OK;
aResult.SetTo(nsHTMLValue(rule));
return;
}
}
}
}
return NS_ERROR_FAILURE;
aResult.SetTo(aValue);
}
/**
@ -4418,7 +4392,10 @@ nsGenericHTMLElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr
if (mNodeInfo->NamespaceEquals(kNameSpaceID_None)) {
nsAutoString lower;
ToLowerCase(aStr, lower);
return mAttrsAndChildren.GetExistingAttrNameFromQName(lower);
return mAttrsAndChildren.GetExistingAttrNameFromQName(
NS_ConvertUTF16toUTF8(lower));
}
return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
return mAttrsAndChildren.GetExistingAttrNameFromQName(
NS_ConvertUTF16toUTF8(aStr));
}

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

@ -490,13 +490,28 @@ public:
nsresult ReparseStyleAttribute(void);
/**
* Parse a style attr value into a CSS rulestruct (or, if there is no
* document, leave it as a string) and return as HTMLValue.
* document, leave it as a string) and return as nsAttrValue.
* Note: this function is used by other classes than nsGenericHTMLElement
*
* @param aValue the value to parse
* @param aResult the resulting HTMLValue [OUT]
*/
nsresult ParseStyleAttribute(const nsAString& aValue,
nsHTMLValue& aResult);
static void ParseStyleAttribute(nsIContent* aContent,
PRBool aCaseSensitive,
const nsAString& aValue,
nsAttrValue& aResult);
/**
* Parse a class attr value into a nsAttrValue. If there is only one class
* the resulting type will be an atom. If there are more then one the result
* will be an atom-array.
* Note: this function is used by other classes than nsGenericHTMLElement
*
* @param aStr The attributes string-value to parse.
* @param aValue The resulting nsAttrValue [OUT]
*/
static nsresult ParseClassAttribute(const nsAString& aStr,
nsAttrValue& aValue);
/*
* Attribute Mapping Helpers

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

@ -41,7 +41,6 @@
#include "nscore.h"
#include "nsColor.h"
#include "nsString.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
@ -50,6 +49,7 @@
#include "nsIAtom.h"
class nsIDocument;
class nsICSSStyleRule;
class nsCheapStringBufferUtils {
public:
@ -148,15 +148,15 @@ public:
// between different things stored as the same type. Doing
// mUnit & HTMLUNIT_CLASS_MASK should give you the class of type.
//
#define HTMLUNIT_NOSTORE 0x0000
#define HTMLUNIT_STRING 0x0100
#define HTMLUNIT_INTEGER 0x0200
#define HTMLUNIT_PIXEL 0x0400
#define HTMLUNIT_COLOR 0x0800
#define HTMLUNIT_ISUPPORTS 0x1000
#define HTMLUNIT_PERCENT 0x2000
#define HTMLUNIT_ATOMARRAY 0x4000
#define HTMLUNIT_CLASS_MASK 0xff00
#define HTMLUNIT_NOSTORE 0x0000
#define HTMLUNIT_STRING 0x0100
#define HTMLUNIT_INTEGER 0x0200
#define HTMLUNIT_PIXEL 0x0400
#define HTMLUNIT_COLOR 0x0800
#define HTMLUNIT_CSSSTYLERULE 0x1000
#define HTMLUNIT_PERCENT 0x2000
#define HTMLUNIT_ATOMARRAY 0x4000
#define HTMLUNIT_CLASS_MASK 0xff00
enum nsHTMLUnit {
// null, value is not specified: 0x0000
@ -182,8 +182,8 @@ enum nsHTMLUnit {
// an RGBA value
eHTMLUnit_Color = HTMLUNIT_COLOR,
// (nsISupports*) a ref counted interface
eHTMLUnit_ISupports = HTMLUNIT_ISUPPORTS,
// a nsICSSStyleRule
eHTMLUnit_CSSStyleRule = HTMLUNIT_CSSSTYLERULE,
// (1.0 == 100%) value is percentage of something
eHTMLUnit_Percent = HTMLUNIT_PERCENT,
@ -204,7 +204,7 @@ public:
nsHTMLValue(PRInt32 aValue, nsHTMLUnit aUnit);
nsHTMLValue(float aValue);
nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit = eHTMLUnit_String);
nsHTMLValue(nsISupports* aValue);
nsHTMLValue(nsICSSStyleRule* aValue);
nsHTMLValue(nscolor aValue);
nsHTMLValue(nsCOMArray<nsIAtom>* aArray);
nsHTMLValue(const nsHTMLValue& aCopy);
@ -225,7 +225,7 @@ public:
PRInt32 GetPixelValue(void) const;
float GetPercentValue(void) const;
nsAString& GetStringValue(nsAString& aBuffer) const;
already_AddRefed<nsISupports> GetISupportsValue(void) const;
nsICSSStyleRule* GetCSSStyleRuleValue(void) const;
nscolor GetColorValue(void) const;
nsCOMArray<nsIAtom>* AtomArrayValue() const;
@ -237,7 +237,7 @@ public:
void SetPixelValue(PRInt32 aValue);
void SetPercentValue(float aValue);
void SetStringValue(const nsAString& aValue, nsHTMLUnit aUnit = eHTMLUnit_String);
void SetISupportsValue(nsISupports* aValue);
void SetCSSStyleRuleValue(nsICSSStyleRule* aValue);
void SetColorValue(nscolor aValue);
void SetEmptyValue(void);
@ -363,8 +363,8 @@ protected:
float mFloat;
/** String. First 4 bytes are the length, non-null-terminated. */
PRUnichar* mString;
/** ISupports. Strong reference. */
nsISupports* mISupports;
/** nsICSSStyleRule. Strong reference. */
nsICSSStyleRule* mCSSStyleRule;
/** Color. */
nscolor mColor;
/** Array if atoms */
@ -462,13 +462,11 @@ inline nsAString& nsHTMLValue::GetStringValue(nsAString& aBuffer) const
return aBuffer;
}
inline already_AddRefed<nsISupports> nsHTMLValue::GetISupportsValue(void) const
inline nsICSSStyleRule* nsHTMLValue::GetCSSStyleRuleValue(void) const
{
NS_ASSERTION(mUnit == eHTMLUnit_ISupports, "not an ISupports value");
if (mUnit == eHTMLUnit_ISupports) {
nsISupports *result = mValue.mISupports;
NS_IF_ADDREF(result);
return result;
NS_ASSERTION(mUnit == eHTMLUnit_CSSStyleRule, "not an CSSStyleRule value");
if (mUnit == eHTMLUnit_CSSStyleRule) {
return mValue.mCSSStyleRule;
}
return nsnull;
}

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

@ -67,4 +67,8 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
INCLUDES += \
-I$(srcdir)/../../html/style/src \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT

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

@ -47,6 +47,8 @@
#include "nsIHTMLDocument.h"
#include "nsUnitConversion.h"
#include "prprf.h"
#include "nsICSSStyleRule.h"
#include "nsCSSDeclaration.h"
nsHTMLValue::nsHTMLValue(nsHTMLUnit aUnit)
: mUnit(aUnit)
@ -84,11 +86,11 @@ nsHTMLValue::nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit)
SetStringValueInternal(aValue, aUnit);
}
nsHTMLValue::nsHTMLValue(nsISupports* aValue)
: mUnit(eHTMLUnit_ISupports)
nsHTMLValue::nsHTMLValue(nsICSSStyleRule* aValue)
: mUnit(eHTMLUnit_CSSStyleRule)
{
mValue.mISupports = aValue;
NS_IF_ADDREF(mValue.mISupports);
mValue.mCSSStyleRule = aValue;
NS_IF_ADDREF(mValue.mCSSStyleRule);
}
nsHTMLValue::nsHTMLValue(nscolor aValue)
@ -145,8 +147,8 @@ PRBool nsHTMLValue::operator==(const nsHTMLValue& aOther) const
case HTMLUNIT_COLOR:
return mValue.mColor == aOther.mValue.mColor;
case HTMLUNIT_ISUPPORTS:
return mValue.mISupports == aOther.mValue.mISupports;
case HTMLUNIT_CSSSTYLERULE:
return mValue.mCSSStyleRule == aOther.mValue.mCSSStyleRule;
case HTMLUNIT_PERCENT:
return mValue.mFloat == aOther.mValue.mFloat;
@ -203,8 +205,8 @@ void nsHTMLValue::Reset(void)
nsCheapStringBufferUtils::Free(mValue.mString);
}
}
else if (mUnit == eHTMLUnit_ISupports) {
NS_IF_RELEASE(mValue.mISupports);
else if (mUnit == eHTMLUnit_CSSStyleRule) {
NS_IF_RELEASE(mValue.mCSSStyleRule);
}
else if (mUnit == eHTMLUnit_AtomArray) {
delete mValue.mAtomArray;
@ -265,12 +267,12 @@ void nsHTMLValue::SetStringValue(const nsAString& aValue,
SetStringValueInternal(aValue, aUnit);
}
void nsHTMLValue::SetISupportsValue(nsISupports* aValue)
void nsHTMLValue::SetCSSStyleRuleValue(nsICSSStyleRule* aValue)
{
Reset();
mUnit = eHTMLUnit_ISupports;
mValue.mISupports = aValue;
NS_IF_ADDREF(mValue.mISupports);
mUnit = eHTMLUnit_CSSStyleRule;
mValue.mCSSStyleRule = aValue;
NS_IF_ADDREF(mValue.mCSSStyleRule);
}
void nsHTMLValue::SetColorValue(nscolor aValue)
@ -312,9 +314,9 @@ nsHTMLValue::InitializeFrom(const nsHTMLValue& aCopy)
mValue.mColor = aCopy.mValue.mColor;
break;
case HTMLUNIT_ISUPPORTS:
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
case HTMLUNIT_CSSSTYLERULE:
mValue.mCSSStyleRule = aCopy.mValue.mCSSStyleRule;
NS_IF_ADDREF(mValue.mCSSStyleRule);
break;
case HTMLUNIT_PERCENT:
@ -486,6 +488,18 @@ nsHTMLValue::ToString(nsAString& aResult) const
}
return PR_TRUE;
}
case eHTMLUnit_CSSStyleRule:
{
if (mValue.mCSSStyleRule) {
nsCSSDeclaration* decl = mValue.mCSSStyleRule->GetDeclaration();
if (decl) {
decl->ToString(aResult);
}
}
return PR_TRUE;
}
default:
return PR_FALSE;
}

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

@ -915,9 +915,10 @@ nsXBLContentSink::AddAttributesToXULPrototype(const PRUnichar **aAtts,
// Copy the attributes into the prototype
nsCOMPtr<nsIAtom> nameSpacePrefix, nameAtom;
for (; *aAtts; aAtts += 2) {
const nsDependentString key(aAtts[0]);
PRUint32 i;
for (i = 0; i < aAttsCount; ++i) {
const nsDependentString key(aAtts[i * 2]);
SplitXMLName(key, getter_AddRefs(nameSpacePrefix),
getter_AddRefs(nameAtom));
@ -939,43 +940,19 @@ nsXBLContentSink::AddAttributesToXULPrototype(const PRUnichar **aAtts,
nameSpacePrefix = nsnull;
}
mNodeInfoManager->GetNodeInfo(nameAtom, nameSpacePrefix, nameSpaceID,
getter_AddRefs(attrs->mNodeInfo));
if (nameSpaceID == kNameSpaceID_None) {
attrs[i].mName.SetTo(nameAtom);
}
else {
nsCOMPtr<nsINodeInfo> ni;
mNodeInfoManager->GetNodeInfo(nameAtom, nameSpacePrefix, nameSpaceID,
getter_AddRefs(ni));
attrs[i].mName.SetTo(ni);
}
attrs->mValue.SetValue(nsDependentString(aAtts[1]));
++attrs;
}
// XUL elements may require some additional work to compute
// derived information.
if (aElement->mNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
nsAutoString value;
// Compute the element's class list if the element has a 'class' attribute.
rv = aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::clazz, value);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
rv = nsClassList::ParseClasses(&aElement->mClassList, value);
if (NS_FAILED(rv)) return rv;
}
// Parse the element's 'style' attribute
rv = aElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::style, value);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
if (!mCSSParser) {
mCSSParser = do_CreateInstance(kCSSParserCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mCSSParser->ParseStyleAttribute(value, mDocumentURI,
getter_AddRefs(aElement->mInlineStyleRule));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to parse style rule");
if (NS_FAILED(rv)) return rv;
}
rv = aElement->SetAttrAt(i, nsDependentString(aAtts[i * 2 + 1]),
mDocumentURI);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;

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

@ -156,8 +156,6 @@ protected:
nsIXBLDocumentInfo* mDocInfo;
PRBool mIsChromeOrResource; // For bug #45989
nsCOMPtr<nsICSSParser> mCSSParser; // [OWNER]
nsXBLPrototypeBinding* mBinding;
nsXBLPrototypeHandler* mHandler; // current handler, owned by its PrototypeBinding
nsXBLProtoImpl* mImplementation;

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

@ -51,8 +51,6 @@ REQUIRES = xpcom \
CPPSRCS = \
nsRDFDOMNodeList.cpp \
nsXULAttributeValue.cpp \
nsXULAttributes.cpp \
nsXULElement.cpp \
nsXULPopupListener.cpp \
$(NULL)
@ -70,6 +68,7 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../../../base/src \
-I$(srcdir)/../../../xml/document/src \
-I$(srcdir)/../../../html/style/src \
-I$(srcdir)/../../../html/content/src \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT

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

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

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

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -75,14 +75,13 @@
#include "nsIXULPrototypeCache.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIBoxObject.h"
#include "nsXULAttributes.h"
#include "nsIChromeEventHandler.h"
#include "nsXULAttributeValue.h"
#include "nsIXBLService.h"
#include "nsICSSOMFactory.h"
#include "nsLayoutCID.h"
#include "nsGenericElement.h" // for nsCheapVoidArray
#include "nsAttrAndChildArray.h"
#include "nsXULAtoms.h"
#include "nsAutoPtr.h"
class nsIDocument;
class nsIRDFService;
@ -91,9 +90,9 @@ class nsIXULContentUtils;
class nsIXULPrototypeDocument;
class nsRDFDOMNodeList;
class nsString;
class nsXULAttributes;
class nsVoidArray;
class nsIDocShell;
class nsDOMAttributeMap;
class nsIObjectInputStream;
class nsIObjectOutputStream;
@ -121,7 +120,8 @@ class nsXULPrototypeAttribute
{
public:
nsXULPrototypeAttribute()
: mEventHandler(nsnull)
: mEventHandler(nsnull),
mName(nsXULAtoms::id) // XXX this is a hack, but names have to have a value
{
XUL_PROTOTYPE_ATTRIBUTE_METER(gNumAttributes);
MOZ_COUNT_CTOR(nsXULPrototypeAttribute);
@ -129,9 +129,9 @@ public:
~nsXULPrototypeAttribute();
nsCOMPtr<nsINodeInfo> mNodeInfo;
nsXULAttributeValue mValue;
void* mEventHandler;
nsAttrName mName;
nsAttrValue mValue;
void* mEventHandler;
#ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
/**
@ -241,8 +241,7 @@ public:
mNumChildren(0),
mChildren(nsnull),
mNumAttributes(0),
mAttributes(nsnull),
mClassList(nsnull)
mAttributes(nsnull)
{
NS_LOG_ADDREF(this, 1, ClassName(), ClassSize());
}
@ -250,7 +249,6 @@ public:
virtual ~nsXULPrototypeElement()
{
delete[] mAttributes;
delete mClassList;
delete[] mChildren;
}
@ -280,6 +278,8 @@ public:
nsIURI* aDocumentURI,
const nsCOMArray<nsINodeInfo> *aNodeInfos);
nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI);
PRUint32 mNumChildren;
nsXULPrototypeNode** mChildren; // [OWNER]
@ -288,12 +288,6 @@ public:
PRUint32 mNumAttributes;
nsXULPrototypeAttribute* mAttributes; // [OWNER]
nsCOMPtr<nsICSSStyleRule> mInlineStyleRule; // [OWNER]
nsClassList* mClassList;
nsresult GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsAString& aValue);
static void ReleaseGlobals()
{
NS_IF_RELEASE(sCSSParser);
@ -590,7 +584,7 @@ protected:
protected:
// Required fields
nsXULPrototypeElement* mPrototype;
nsSmallVoidArray mChildren; // [OWNER]
nsAttrAndChildArray mAttrsAndChildren; // [OWNER]
nsCOMPtr<nsIEventListenerManager> mListenerManager; // [OWNER]
/**
@ -604,33 +598,35 @@ protected:
* lazily copied from the prototype when changed.
*/
struct Slots {
Slots(nsXULElement* mElement);
Slots();
~Slots();
nsCOMPtr<nsINodeInfo> mNodeInfo; // [OWNER]
nsCOMPtr<nsIControllers> mControllers; // [OWNER]
nsRefPtr<nsDOMCSSDeclaration> mDOMStyle; // [OWNER]
/**
* Contains the mLazyState in the low two bits, and a pointer
* to the nsXULAttributes structure in the high bits.
* to the nsDOMAttributeMap structure in the high bits.
*/
PRWord mBits;
#define LAZYSTATE_MASK ((PRWord(1) << LAZYSTATE_BITS) - 1)
#define ATTRIBUTES_MASK (~LAZYSTATE_MASK)
nsXULAttributes *
GetAttributes() const {
return NS_REINTERPRET_CAST(nsXULAttributes *, mBits & ATTRIBUTES_MASK);
nsDOMAttributeMap *
GetAttributeMap() const {
return NS_REINTERPRET_CAST(nsDOMAttributeMap *, mBits & ATTRIBUTES_MASK);
}
void
SetAttributes(nsXULAttributes *aAttributes) {
NS_ASSERTION((NS_REINTERPRET_CAST(PRWord, aAttributes) & ~ATTRIBUTES_MASK) == 0,
"nsXULAttributes pointer is unaligned");
SetAttributeMap(nsDOMAttributeMap *aAttributeMap) {
NS_ASSERTION((NS_REINTERPRET_CAST(PRWord, aAttributeMap) &
~ATTRIBUTES_MASK) == 0,
"nsDOMAttributeMap pointer is unaligned");
mBits &= ~ATTRIBUTES_MASK;
mBits |= NS_REINTERPRET_CAST(PRWord, aAttributes);
mBits |= NS_REINTERPRET_CAST(PRWord, aAttributeMap);
}
LazyState
@ -657,34 +653,14 @@ protected:
*/
nsresult EnsureSlots();
/**
* Ensure that our mSlots has an mAttributes, creating an
* nsXULAttributes object if necessary.
*/
nsresult EnsureAttributes();
/**
* Abandon our prototype linkage, and copy all attributes locally
*/
nsresult MakeHeavyweight();
/**
* Return our private copy of the attribute, if one exists.
*/
nsXULAttribute *FindLocalAttribute(nsINodeInfo *info) const;
/**
* Return our private copy of the attribute, if one exists.
*/
nsXULAttribute *FindLocalAttribute(PRInt32 aNameSpaceID,
nsIAtom *aName,
PRInt32 *aIndex = nsnull) const;
/**
* Return our prototype's attribute, if one exists.
*/
nsXULPrototypeAttribute *FindPrototypeAttribute(nsINodeInfo *info) const;
const nsAttrValue* FindLocalOrProtoAttr(PRInt32 aNameSpaceID,
nsIAtom *aName) const;
/**
* Return our prototype's attribute, if one exists.
*/
@ -693,15 +669,24 @@ protected:
/**
* Add a listener for the specified attribute, if appropriate.
*/
nsresult AddListenerFor(nsINodeInfo *aNodeInfo,
PRBool aCompileEventHandlers);
void AddListenerFor(const nsAttrName& aName,
PRBool aCompileEventHandlers);
void MaybeAddPopupListener(nsIAtom* aLocalName);
nsresult HideWindowChrome(PRBool aShouldHide);
void FinishSetAttr(PRInt32 aAttrNS, nsIAtom* aAttrName,
const nsAString& aOldValue, const nsAString& aNewValue,
PRInt32 aModHint, PRBool aNotify);
nsresult SetAttrAndNotify(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
nsIAtom* aPrefix,
const nsAString& aOldValue,
nsAttrValue& aParsedValue,
PRBool aModification,
PRBool aFireMutation,
PRBool aNotify);
const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
protected:
// Internal accessors. These shadow the 'Slots', and return
@ -709,7 +694,6 @@ protected:
// delegate.
nsINodeInfo *NodeInfo() const { return mSlots ? mSlots->mNodeInfo : mPrototype->mNodeInfo; }
nsIControllers *Controllers() const { return mSlots ? mSlots->mControllers.get() : nsnull; }
nsXULAttributes *Attributes() const { return mSlots ? mSlots->GetAttributes() : nsnull; }
void UnregisterAccessKey(const nsAString& aOldValue);
};

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

@ -104,6 +104,8 @@
#include "nsUnicharUtils.h"
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsContentUtils.h"
#include "nsAttrName.h"
static const char kNameSpaceSeparator = ':';
@ -187,7 +189,7 @@ protected:
nsresult NormalizeAttributeString(const nsAFlatString& aText,
nsINodeInfo** aNodeInfo);
nsAttrName& aName);
nsresult CreateElement(nsINodeInfo *aNodeInfo, nsXULPrototypeElement** aResult);
// Style sheets
@ -689,7 +691,7 @@ XULContentSinkImpl::FlushText(PRBool aCreateTextNode)
nsresult
XULContentSinkImpl::NormalizeAttributeString(const nsAFlatString& aText,
nsINodeInfo** aNodeInfo)
nsAttrName& aName)
{
PRInt32 nameSpaceID = kNameSpaceID_None;
@ -702,8 +704,15 @@ XULContentSinkImpl::NormalizeAttributeString(const nsAFlatString& aText,
nsCOMPtr<nsIAtom> prefix;
if (!FindCharInReadable(kNameSpaceSeparator, colon, end)) {
colon = start; // No ':' found, reset colon
} else if (start != colon) {
nsCOMPtr<nsIAtom> atom = do_GetAtom(aText);
NS_ENSURE_TRUE(atom, NS_ERROR_OUT_OF_MEMORY);
aName.SetTo(atom);
return NS_OK;
}
if (start != colon) {
prefix = do_GetAtom(Substring(start, colon));
nsCOMPtr<nsINameSpace> ns;
@ -724,8 +733,15 @@ XULContentSinkImpl::NormalizeAttributeString(const nsAFlatString& aText,
++colon; // Skip over the ':'
}
return mNodeInfoManager->GetNodeInfo(Substring(colon, end), prefix,
nameSpaceID, aNodeInfo);
nsCOMPtr<nsINodeInfo> ni;
nsresult rv = mNodeInfoManager->GetNodeInfo(Substring(colon, end), prefix,
nameSpaceID,
getter_AddRefs(ni));
NS_ENSURE_SUCCESS(rv, rv);
aName.SetTo(ni);
return NS_OK;
}
nsresult
@ -1491,25 +1507,15 @@ XULContentSinkImpl::AddAttributes(const PRUnichar** aAttributes,
aElement->mNumAttributes = aAttrLen;
// Copy the attributes into the prototype
for (; *aAttributes; aAttributes += 2) {
rv = NormalizeAttributeString(nsDependentString(aAttributes[0]),
getter_AddRefs(attrs->mNodeInfo));
PRUint32 i;
for (i = 0; i < aAttrLen; ++i) {
rv = NormalizeAttributeString(nsDependentString(aAttributes[i * 2]),
attrs[i].mName);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
nsAutoString qnameC;
qnameC.Assign(aAttributes[0]);
PR_LOG(gLog, PR_LOG_ALWAYS,
("xul: unable to parse attribute '%s' at line %d",
NS_ConvertUCS2toUTF8(qnameC).get(), -1)); // XXX pass in line number
#endif
// Bring it. We'll just fail to copy an attribute that we
// can't parse. And that's one less attribute to worry
// about.
--(aElement->mNumAttributes);
continue;
}
attrs->mValue.SetValue(nsDependentString(aAttributes[1]));
rv = aElement->SetAttrAt(i, nsDependentString(aAttributes[i * 2 + 1]),
mDocumentURL);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef PR_LOGGING
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
@ -1528,40 +1534,6 @@ XULContentSinkImpl::AddAttributes(const PRUnichar** aAttributes,
NS_ConvertUCS2toUTF8(valueC).get()));
}
#endif
++attrs;
}
// XUL elements may require some additional work to compute
// derived information.
if (aElement->mNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
nsAutoString value;
// Compute the element's class list if the element has a 'class' attribute.
rv = aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::clazz, value);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
rv = nsClassList::ParseClasses(&aElement->mClassList, value);
if (NS_FAILED(rv)) return rv;
}
// Parse the element's 'style' attribute
rv = aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::style, value);
if (NS_FAILED(rv)) return rv;
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
if (!mCSSParser) {
mCSSParser = do_CreateInstance(kCSSParserCID, &rv);
if (NS_FAILED(rv)) return rv;
}
rv = mCSSParser->ParseStyleAttribute(value, mDocumentURL,
getter_AddRefs(aElement->mInlineStyleRule));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to parse style rule");
if (NS_FAILED(rv)) return rv;
}
}
return NS_OK;

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

@ -115,6 +115,9 @@
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIScriptSecurityManager.h"
#include "nsContentUtils.h"
#include "nsIParser.h"
#include "nsICSSStyleSheet.h"
//----------------------------------------------------------------------
//
@ -3428,11 +3431,11 @@ nsXULDocument::AddAttributes(nsXULPrototypeElement* aPrototype,
for (PRUint32 i = 0; i < aPrototype->mNumAttributes; ++i) {
nsXULPrototypeAttribute* protoattr = &(aPrototype->mAttributes[i]);
nsAutoString valueStr;
protoattr->mValue.GetValue( valueStr );
protoattr->mValue.ToString(valueStr);
rv = aElement->SetAttr(protoattr->mNodeInfo->NamespaceID(),
protoattr->mNodeInfo->NameAtom(),
protoattr->mNodeInfo->GetPrefixAtom(),
rv = aElement->SetAttr(protoattr->mName.NamespaceID(),
protoattr->mName.LocalName(),
protoattr->mName.GetPrefix(),
valueStr,
PR_FALSE);
if (NS_FAILED(rv)) return rv;

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

@ -55,6 +55,7 @@
#include "nsIXULDocument.h"
#include "nsIXULPrototypeDocument.h"
#include "nsScriptLoader.h"
#include "nsIStreamListener.h"
class nsIRDFResource;
class nsIRDFService;

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

@ -69,6 +69,7 @@
#include "nsIDOMScriptObjectFactory.h"
#include "nsDOMCID.h"
#include "nsArray.h"
#include "nsContentUtils.h"
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
@ -438,6 +439,51 @@ nsXULPrototypeDocument::Read(nsIObjectInputStream* aStream)
return rv;
}
static nsresult
GetNodeInfos(nsXULPrototypeElement* aPrototype,
nsCOMArray<nsINodeInfo>& aArray)
{
nsresult rv;
if (aArray.IndexOf(aPrototype->mNodeInfo) < 0) {
if (!aArray.AppendObject(aPrototype->mNodeInfo)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
// Search attributes
PRUint32 i;
for (i = 0; i < aPrototype->mNumAttributes; ++i) {
nsCOMPtr<nsINodeInfo> ni;
nsAttrName* name = &aPrototype->mAttributes[i].mName;
if (name->IsAtom()) {
rv = aPrototype->mNodeInfo->NodeInfoManager()->
GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
getter_AddRefs(ni));
NS_ENSURE_SUCCESS(rv, rv);
}
else {
ni = name->NodeInfo();
}
if (aArray.IndexOf(ni) < 0) {
if (!aArray.AppendObject(ni)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
}
// Search children
for (i = 0; i < aPrototype->mNumChildren; ++i) {
nsXULPrototypeNode* child = aPrototype->mChildren[i];
if (child->mType == nsXULPrototypeNode::eType_Element) {
rv = GetNodeInfos(NS_STATIC_CAST(nsXULPrototypeElement*, child),
aArray);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsXULPrototypeDocument::Write(nsIObjectOutputStream* aStream)
@ -478,7 +524,7 @@ nsXULPrototypeDocument::Write(nsIObjectOutputStream* aStream)
// nsINodeInfo table
nsCOMArray<nsINodeInfo> nodeInfos;
rv |= mNodeInfoManager->GetNodeInfos(&nodeInfos);
rv |= GetNodeInfos(mRoot, nodeInfos);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 nodeInfoCount = nodeInfos.Count();

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

@ -70,6 +70,7 @@
#include "nsXULElement.h"
#include "nsXULTemplateBuilder.h"
#include "nsSupportsArray.h"
#include "nsContentUtils.h"
#include "jsapi.h"
#include "pldhash.h"