diff --git a/mozilla/content/base/public/nsINode.h b/mozilla/content/base/public/nsINode.h index 87f7a3617f3..30f74fcbe0d 100644 --- a/mozilla/content/base/public/nsINode.h +++ b/mozilla/content/base/public/nsINode.h @@ -92,8 +92,14 @@ enum { NODE_IS_EDITABLE = 0x00000100U, + // Optimizations to quickly check whether element may have ID, class or style + // attributes. Not all element implementations may use these! + NODE_MAY_HAVE_ID = 0x00000200U, + NODE_MAY_HAVE_CLASS = 0x00000400U, + NODE_MAY_HAVE_STYLE = 0x00000800U, + // Four bits for the script-type ID - NODE_SCRIPT_TYPE_OFFSET = 9, + NODE_SCRIPT_TYPE_OFFSET = 12, NODE_SCRIPT_TYPE_SIZE = 4, diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index b7f8ec68b04..852d189a400 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -2265,6 +2265,10 @@ nsGenericElement::DispatchDOMEvent(nsEvent* aEvent, nsIAtom* nsGenericElement::GetID() const { + if (!HasFlag(NODE_MAY_HAVE_ID)) { + return nsnull; + } + nsIAtom* IDName = GetIDAttributeName(); if (IDName) { const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(IDName); @@ -2287,6 +2291,9 @@ nsGenericElement::GetID() const } } } + + nsINode* node = const_cast(static_cast(this)); + node->UnsetFlags(NODE_MAY_HAVE_ID); return nsnull; } @@ -3680,6 +3687,7 @@ nsGenericElement::ParseAttribute(PRInt32 aNamespaceID, { if (aNamespaceID == kNameSpaceID_None && aAttribute == GetIDAttributeName() && !aValue.IsEmpty()) { + SetFlags(NODE_MAY_HAVE_ID); // Store id as an atom. id="" means that the element has no id, // not that it has an emptystring as the id. aResult.ParseAtom(aValue); diff --git a/mozilla/content/base/src/nsStyledElement.cpp b/mozilla/content/base/src/nsStyledElement.cpp index 454fdbf7c9f..0967391c4f7 100644 --- a/mozilla/content/base/src/nsStyledElement.cpp +++ b/mozilla/content/base/src/nsStyledElement.cpp @@ -73,7 +73,15 @@ nsStyledElement::GetIDAttributeName() const const nsAttrValue* nsStyledElement::GetClasses() const { - return mAttrsAndChildren.GetAttr(nsGkAtoms::_class); + if (!HasFlag(NODE_MAY_HAVE_CLASS)) { + return nsnull; + } + const nsAttrValue* clazz = mAttrsAndChildren.GetAttr(nsGkAtoms::_class); + if (!clazz) { + nsINode* node = const_cast(static_cast(this)); + node->UnsetFlags(NODE_MAY_HAVE_CLASS); + } + return clazz; } PRBool @@ -82,10 +90,12 @@ nsStyledElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, { if (aNamespaceID == kNameSpaceID_None) { if (aAttribute == nsGkAtoms::style) { + SetFlags(NODE_MAY_HAVE_STYLE); ParseStyleAttribute(this, aValue, aResult); return PR_TRUE; } if (aAttribute == nsGkAtoms::_class) { + SetFlags(NODE_MAY_HAVE_CLASS); #ifdef MOZ_SVG NS_ASSERTION(!nsCOMPtr(do_QueryInterface(this)), "SVG code should have handled this 'class' attribute!"); @@ -102,6 +112,7 @@ nsStyledElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, NS_IMETHODIMP nsStyledElement::SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify) { + SetFlags(NODE_MAY_HAVE_STYLE); PRBool modification = PR_FALSE; nsAutoString oldValueStr; @@ -135,12 +146,16 @@ nsStyledElement::SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify) nsICSSStyleRule* nsStyledElement::GetInlineStyleRule() { + if (!HasFlag(NODE_MAY_HAVE_STYLE)) { + return nsnull; + } const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style); if (attrVal && attrVal->Type() == nsAttrValue::eCSSStyleRule) { return attrVal->GetCSSStyleRuleValue(); } + UnsetFlags(NODE_MAY_HAVE_STYLE); return nsnull; } @@ -196,6 +211,9 @@ nsStyledElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) nsresult nsStyledElement::ReparseStyleAttribute() { + if (!HasFlag(NODE_MAY_HAVE_STYLE)) { + return NS_OK; + } const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style); if (oldVal && oldVal->Type() != nsAttrValue::eCSSStyleRule) {