зеркало из https://github.com/mozilla/pjs.git
Bug 394442, Optimize ID, class and style getters, r=bz+sicking, sr=sicking, a=jst
This commit is contained in:
Родитель
f0bad9d03b
Коммит
9b1f783188
|
@ -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,
|
||||
|
||||
|
|
|
@ -2268,6 +2268,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);
|
||||
|
@ -3683,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);
|
||||
|
|
|
@ -73,6 +73,9 @@ nsStyledElement::GetIDAttributeName() const
|
|||
const nsAttrValue*
|
||||
nsStyledElement::GetClasses() const
|
||||
{
|
||||
if (!HasFlag(NODE_MAY_HAVE_CLASS)) {
|
||||
return nsnull;
|
||||
}
|
||||
return mAttrsAndChildren.GetAttr(nsGkAtoms::_class);
|
||||
}
|
||||
|
||||
|
@ -82,10 +85,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<nsIDOMSVGStylable>(do_QueryInterface(this)),
|
||||
"SVG code should have handled this 'class' attribute!");
|
||||
|
@ -102,6 +107,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,6 +141,9 @@ 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) {
|
||||
|
@ -186,6 +195,7 @@ nsStyledElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
|
|||
rv = gCSSOMFactory->CreateDOMCSSAttributeDeclaration(this,
|
||||
getter_AddRefs(slots->mStyle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
SetFlags(NODE_MAY_HAVE_STYLE);
|
||||
}
|
||||
|
||||
// Why bother with QI?
|
||||
|
@ -196,6 +206,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) {
|
||||
|
|
|
@ -275,6 +275,15 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
|
|||
NS_ADDREF(element);
|
||||
|
||||
element->mPrototype = aPrototype;
|
||||
if (aPrototype->mHasIdAttribute) {
|
||||
element->SetFlags(NODE_MAY_HAVE_ID);
|
||||
}
|
||||
if (aPrototype->mHasClassAttribute) {
|
||||
element->SetFlags(NODE_MAY_HAVE_CLASS);
|
||||
}
|
||||
if (aPrototype->mHasStyleAttribute) {
|
||||
element->SetFlags(NODE_MAY_HAVE_STYLE);
|
||||
}
|
||||
|
||||
NS_ASSERTION(aPrototype->mScriptTypeID != nsIProgrammingLanguage::UNKNOWN,
|
||||
"Need to know the language!");
|
||||
|
@ -1069,11 +1078,13 @@ nsXULElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
// Any changes should be made to both functions.
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::style) {
|
||||
SetFlags(NODE_MAY_HAVE_STYLE);
|
||||
nsStyledElement::ParseStyleAttribute(this, aValue, aResult);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::_class) {
|
||||
SetFlags(NODE_MAY_HAVE_CLASS);
|
||||
aResult.ParseAtomArray(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -1632,6 +1643,10 @@ nsXULElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex, PRBool aNotify)
|
|||
nsIAtom*
|
||||
nsXULElement::GetID() const
|
||||
{
|
||||
if (!HasFlag(NODE_MAY_HAVE_ID)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
const nsAttrValue* attrVal = FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::id);
|
||||
|
||||
NS_ASSERTION(!attrVal ||
|
||||
|
@ -1649,6 +1664,9 @@ nsXULElement::GetID() const
|
|||
const nsAttrValue*
|
||||
nsXULElement::GetClasses() const
|
||||
{
|
||||
if (!HasFlag(NODE_MAY_HAVE_CLASS)) {
|
||||
return nsnull;
|
||||
}
|
||||
return FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::_class);
|
||||
}
|
||||
|
||||
|
@ -1661,6 +1679,9 @@ nsXULElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
|||
nsICSSStyleRule*
|
||||
nsXULElement::GetInlineStyleRule()
|
||||
{
|
||||
if (!HasFlag(NODE_MAY_HAVE_STYLE)) {
|
||||
return nsnull;
|
||||
}
|
||||
// Fetch the cached style rule from the attributes.
|
||||
const nsAttrValue* attrVal = FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::style);
|
||||
|
||||
|
@ -1674,6 +1695,7 @@ nsXULElement::GetInlineStyleRule()
|
|||
NS_IMETHODIMP
|
||||
nsXULElement::SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify)
|
||||
{
|
||||
SetFlags(NODE_MAY_HAVE_STYLE);
|
||||
PRBool modification = PR_FALSE;
|
||||
nsAutoString oldValueStr;
|
||||
|
||||
|
@ -1887,6 +1909,7 @@ nsXULElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
|
|||
rv = gCSSOMFactory->CreateDOMCSSAttributeDeclaration(this,
|
||||
getter_AddRefs(slots->mStyle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
SetFlags(NODE_MAY_HAVE_STYLE);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aStyle = slots->mStyle);
|
||||
|
@ -2470,7 +2493,10 @@ nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream,
|
|||
nsresult rv;
|
||||
|
||||
// Read script language
|
||||
rv = aStream->Read32(&mScriptTypeID);
|
||||
PRUint32 scriptId = 0;
|
||||
rv = aStream->Read32(&scriptId);
|
||||
mScriptTypeID = scriptId;
|
||||
|
||||
// Read Node Info
|
||||
PRUint32 number;
|
||||
rv |= aStream->Read32(&number);
|
||||
|
@ -2610,6 +2636,7 @@ nsXULPrototypeElement::SetAttrAt(PRUint32 aPos, const nsAString& aValue,
|
|||
|
||||
if (mAttributes[aPos].mName.Equals(nsGkAtoms::id) &&
|
||||
!aValue.IsEmpty()) {
|
||||
mHasIdAttribute = PR_TRUE;
|
||||
// Store id as atom.
|
||||
// id="" means that the element has no id. Not that it has
|
||||
// emptystring as id.
|
||||
|
@ -2618,12 +2645,14 @@ nsXULPrototypeElement::SetAttrAt(PRUint32 aPos, const nsAString& aValue,
|
|||
return NS_OK;
|
||||
}
|
||||
else if (mAttributes[aPos].mName.Equals(nsGkAtoms::_class)) {
|
||||
mHasClassAttribute = PR_TRUE;
|
||||
// Compute the element's class list
|
||||
mAttributes[aPos].mValue.ParseAtomArray(aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
else if (mAttributes[aPos].mName.Equals(nsGkAtoms::style)) {
|
||||
mHasStyleAttribute = PR_TRUE;
|
||||
// Parse the element's 'style' attribute
|
||||
nsCOMPtr<nsICSSStyleRule> rule;
|
||||
nsICSSParser* parser = GetCSSParser();
|
||||
|
|
|
@ -246,6 +246,9 @@ public:
|
|||
mChildren(nsnull),
|
||||
mNumAttributes(0),
|
||||
mAttributes(nsnull),
|
||||
mHasIdAttribute(PR_FALSE),
|
||||
mHasClassAttribute(PR_FALSE),
|
||||
mHasStyleAttribute(PR_FALSE),
|
||||
mScriptTypeID(nsIProgrammingLanguage::UNKNOWN)
|
||||
{
|
||||
NS_LOG_ADDREF(this, 1, ClassName(), ClassSize());
|
||||
|
@ -298,12 +301,16 @@ public:
|
|||
|
||||
PRUint32 mNumAttributes;
|
||||
nsXULPrototypeAttribute* mAttributes; // [OWNER]
|
||||
|
||||
PRPackedBool mHasIdAttribute:1;
|
||||
PRPackedBool mHasClassAttribute:1;
|
||||
PRPackedBool mHasStyleAttribute:1;
|
||||
|
||||
// The language ID can not be set on a per-node basis, but is tracked
|
||||
// so that the language ID from the originating root can be used
|
||||
// (eg, when a node from an overlay ends up in our document, that node
|
||||
// must use its original script language, not our document's default.
|
||||
PRUint32 mScriptTypeID;
|
||||
PRUint16 mScriptTypeID;
|
||||
static void ReleaseGlobals()
|
||||
{
|
||||
NS_IF_RELEASE(sCSSParser);
|
||||
|
|
|
@ -855,7 +855,9 @@ XULContentSinkImpl::SetElementScriptType(nsXULPrototypeElement* element,
|
|||
// Ask the top-node for its script type (which has already
|
||||
// had this function called for it - so no need to recurse
|
||||
// until we find it)
|
||||
rv = mContextStack.GetTopNodeScriptType(&element->mScriptTypeID);
|
||||
PRUint32 scriptId = 0;
|
||||
rv = mContextStack.GetTopNodeScriptType(&scriptId);
|
||||
element->mScriptTypeID = scriptId;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче