Bug 581177 part 4. Make 'has id' into a boolean flag. r=sicking

This commit is contained in:
Boris Zbarsky 2011-04-07 19:29:50 -07:00
parent a5e45be39c
commit 0d7dcf77b8
6 changed files with 32 additions and 28 deletions

View File

@ -800,7 +800,7 @@ public:
* GetIDAttributeName(). This may be null if there is no ID.
*/
nsIAtom* GetID() const {
if (HasFlag(NODE_HAS_ID)) {
if (HasID()) {
return DoGetID();
}
return nsnull;
@ -960,7 +960,7 @@ public:
protected:
/**
* Hook for implementing GetID. This is guaranteed to only be
* called if the NODE_HAS_ID flag is set.
* called if HasID() is true.
*/
virtual nsIAtom* DoGetID() const = 0;

View File

@ -117,10 +117,7 @@ enum {
NODE_IS_EDITABLE = 0x00000100U,
// Set to true if the element has a non-empty id attribute. This can in rare
// cases lie for nsXMLElement, such as when the node has been moved between
// documents with different id mappings.
NODE_HAS_ID = 0x00000200U,
UNUSED3 = 0x00000200U,
// For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
// node in fact has a class, but may be set even if it doesn't.
NODE_MAY_HAVE_CLASS = 0x00000400U,
@ -1147,6 +1144,11 @@ private:
ParentIsContent,
// Set if this node is an Element
NodeIsElement,
// Set if the element has a non-empty id attribute. This can in rare
// cases lie for nsXMLElement, such as when the node has been moved between
// documents with different id mappings.
ElementHasID,
// Guard value
BooleanFlagCount
};
@ -1175,6 +1177,7 @@ public:
{ return GetBoolFlag(NodeHasRenderingObservers); }
void SetHasRenderingObservers(bool aValue)
{ SetBoolFlag(NodeHasRenderingObservers, aValue); }
bool HasID() const { return GetBoolFlag(ElementHasID); }
protected:
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
@ -1182,9 +1185,10 @@ protected:
void ClearInDocument() { ClearBoolFlag(IsInDocument); }
void SetIsElement() { SetBoolFlag(NodeIsElement); }
void ClearIsElement() { ClearBoolFlag(NodeIsElement); }
void SetHasID() { SetBoolFlag(ElementHasID); }
void ClearHasID() { ClearBoolFlag(ElementHasID); }
public:
// Optimized way to get classinfo.
virtual nsXPCClassInfo* GetClassInfo() = 0;
protected:

View File

@ -1024,14 +1024,14 @@ protected:
* Add/remove this element to the documents id cache
*/
void AddToIdTable(nsIAtom* aId) {
NS_ASSERTION(HasFlag(NODE_HAS_ID), "Node lacking NODE_HAS_ID flag");
NS_ASSERTION(HasID(), "Node doesn't have an ID?");
nsIDocument* doc = GetCurrentDoc();
if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
doc->AddToIdTable(this, aId);
}
}
void RemoveFromIdTable() {
if (HasFlag(NODE_HAS_ID)) {
if (HasID()) {
nsIDocument* doc = GetCurrentDoc();
if (doc) {
nsIAtom* id = DoGetID();

View File

@ -77,11 +77,11 @@ nsStyledElement::GetIDAttributeName() const
nsIAtom*
nsStyledElement::DoGetID() const
{
NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
NS_ASSERTION(HasID(), "Unexpected call");
// The nullcheck here is needed because nsGenericElement::UnsetAttr calls
// out to various code between removing the attribute and we get a chance to
// clear the NODE_HAS_ID flag.
// ClearHasID().
const nsAttrValue* attr = mAttrsAndChildren.GetAttr(nsGkAtoms::id);
@ -115,11 +115,11 @@ nsStyledElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
// not that it has an emptystring as the id.
RemoveFromIdTable();
if (aValue.IsEmpty()) {
UnsetFlags(NODE_HAS_ID);
ClearHasID();
return PR_FALSE;
}
aResult.ParseAtom(aValue);
SetFlags(NODE_HAS_ID);
SetHasID();
AddToIdTable(aResult.GetAtomValue());
return PR_TRUE;
}
@ -151,7 +151,7 @@ nsStyledElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute,
// The id has been removed when calling UnsetAttr but we kept it because
// the id is used for some layout stuff between UnsetAttr and AfterSetAttr.
// Now. the id is really removed so it would not be safe to keep this flag.
UnsetFlags(NODE_HAS_ID);
ClearHasID();
}
return nsGenericElement::AfterSetAttr(aNamespaceID, aAttribute, aValue,
@ -222,7 +222,7 @@ nsStyledElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument && HasFlag(NODE_HAS_ID) && !GetBindingParent()) {
if (aDocument && HasID() && !GetBindingParent()) {
aDocument->AddToIdTable(this, DoGetID());
}

View File

@ -89,7 +89,7 @@ nsXMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
(!guard.Mutated(0) ||
!mNodeInfo->GetIDAttributeAtom() ||
!HasAttr(kNameSpaceID_None, GetIDAttributeName()))) {
UnsetFlags(NODE_HAS_ID);
ClearHasID();
}
return rv;
@ -104,7 +104,7 @@ nsXMLElement::GetIDAttributeName() const
nsIAtom*
nsXMLElement::DoGetID() const
{
NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
NS_ASSERTION(HasID(), "Unexpected call");
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(GetIDAttributeName());
return attrVal ? attrVal->GetAtomValue() : nsnull;
@ -118,7 +118,7 @@ nsXMLElement::NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
"Can only change document if we're not inside one");
nsIDocument* doc = GetCurrentDoc();
if (HasFlag(NODE_HAS_ID) && doc) {
if (HasID() && doc) {
const nsAttrValue* attrVal =
mAttrsAndChildren.GetAttr(aOldNodeInfo->GetIDAttributeAtom());
if (attrVal) {
@ -126,13 +126,13 @@ nsXMLElement::NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
}
}
UnsetFlags(NODE_HAS_ID);
ClearHasID();
nsIAtom* IDName = GetIDAttributeName();
if (IDName) {
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(IDName);
if (attrVal) {
SetFlags(NODE_HAS_ID);
SetHasID();
if (attrVal->Type() == nsAttrValue::eString) {
nsString idVal(attrVal->GetStringValue());
@ -160,11 +160,11 @@ nsXMLElement::ParseAttribute(PRInt32 aNamespaceID,
// not that it has an emptystring as the id.
RemoveFromIdTable();
if (aValue.IsEmpty()) {
UnsetFlags(NODE_HAS_ID);
ClearHasID();
return PR_FALSE;
}
aResult.ParseAtom(aValue);
SetFlags(NODE_HAS_ID);
SetHasID();
AddToIdTable(aResult.GetAtomValue());
return PR_TRUE;
}
@ -182,7 +182,7 @@ nsXMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument && HasFlag(NODE_HAS_ID) && !GetBindingParent()) {
if (aDocument && HasID() && !GetBindingParent()) {
aDocument->AddToIdTable(this, DoGetID());
}

View File

@ -279,7 +279,7 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
element->mPrototype = aPrototype;
if (aPrototype->mHasIdAttribute) {
element->SetFlags(NODE_HAS_ID);
element->SetHasID();
}
if (aPrototype->mHasClassAttribute) {
element->SetFlags(NODE_MAY_HAVE_CLASS);
@ -1408,7 +1408,7 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify)
// XXX Know how to remove POPUP event listeners when an attribute is unset?
if (isId) {
UnsetFlags(NODE_HAS_ID);
ClearHasID();
}
if (aNameSpaceID == kNameSpaceID_None) {
@ -1778,15 +1778,15 @@ nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
nsIAtom*
nsXULElement::DoGetID() const
{
NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
NS_ASSERTION(HasID(), "Unexpected call");
const nsAttrValue* attr =
FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::id);
// We need the nullcheck here because during unlink the prototype looses
// We need the nullcheck here because during unlink the prototype loses
// all of its attributes. We might want to change that.
// The nullcheck would also be needed if we make UnsetAttr use
// nsGenericElement::UnsetAttr as that calls out to various code between
// removing the attribute and clearing the NODE_HAS_ID flag.
// removing the attribute and calling ClearHasID().
return attr ? attr->GetAtomValue() : nsnull;
}