Closed Bug 208744 Opened 21 years ago Closed 21 years ago

[FIX]Any attribute 'id' in an XHTML document acts as an id

Categories

(Core :: DOM: Core & HTML, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.6alpha

People

(Reporter: ian, Assigned: bzbarsky)

References

()

Details

Attachments

(1 file, 2 obsolete files)

I was stepping through Gecko in the debugger when I came across: NS_IMETHODIMP nsHTMLDocument::AttributeChanged(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType, nsChangeHint aHint) { ... } else if (aAttribute == nsHTMLAtoms::id && aNameSpaceID == kNameSpaceID_None) { ... nsresult rv = AddToIdTable(value, aContent); This is rather wrong, as shown by: http://www.hixie.ch/tests/adhoc/xml/dynamic/001.xhtml Namely, an element in the "" namespace is added an attribute "id" and somehow getElementById() begins to find it. (CSS selectors, however, correctly do not.) What is an ID attribute should be much more carefully examined for non-HTML documents. I would hope that in fact we could use the same code for both XHTML and generic XML documents.
See nsINodeInfo::GetIDAttributeAtom. Personally, I would prefer to hoist up GetID from nsIXMLContent to nsIContent (or something similar to that) and create a GetIDAttributeAtom or something like that to parallel it.... (which would internally just calle GetIDAttributeAtom for generic XML and would return an "id" atom for classes that know their ID -- nsXULElement, nsSVGElement, nsGenericHTMLElement, etc). For that matter, if we do that we could maybe combine all the GetElementById code from nsHTMLDocument and nsXMLDocument into nsDocument (using proper ID checking per the XML code and the hashtable per the HTML code). See the XXX perf comment on GetElementById in nsXMLDocument.
I would think this a good idea to fix if we implement Element.setIdAttribute(), Element.setIdAttributeNS(), and Element.setIdAttributeNode() first. (Reference DOM Core 3 Last Call WD for details.) Personally, I thought Hixie's report was correct behavior, as the DOM developer otherwise has no way of setting an ID-type attribute before DOM 3 Core is implemented.
Sure you can. Just use the same attribute as you would have using raw XML, e.g. the ID attribute on XHTML elements, or the id attribute set in the internal DTD subset, or whatever.
Ah, and your testcase has *no* DTD...
Indeed. (It doesn't need one, it's XML, the semantics are given by the namespace.)
Attached patch Patch (obsolete) — Splinter Review
Taking.
Assignee: dom_bugs → bzbarsky
OS: Windows 2000 → All
Priority: -- → P1
Hardware: PC → All
Summary: Any attribute 'id' in an XHTML document acts as an id → [FIX]Any attribute 'id' in an XHTML document acts as an id
Target Milestone: --- → mozilla1.6alpha
Comment on attachment 133396 [details] [diff] [review] Patch caillon, I hate to do this to you, but I can't think of anyone except you, peterv, jst, sicking, and maybe dbaron to review this... and jst/sicking are pretty laggy recently. :(
Attachment #133396 - Flags: superreview?(peterv)
Attachment #133396 - Flags: review?(caillon)
Attached patch Forgot a few files... (obsolete) — Splinter Review
Attachment #133396 - Attachment is obsolete: true
Attachment #133398 - Flags: superreview?(peterv)
Attachment #133398 - Flags: review?(caillon)
Attachment #133396 - Flags: superreview?(peterv)
Attachment #133396 - Flags: review?(caillon)
Comment on attachment 133398 [details] [diff] [review] Forgot a few files... +nsIAtom* +nsGenericHTMLElement::GetIDAttributeName() const shouldn't the nsIAtom* be NS_IMETHODIMP_(nsIAtom*)?
Tough to tell.. the NS_IMETHODs in the header become "nsresult" in the cpp in this file. I'm not sure whether this is done for a reason, or just because.
hm, but your patch does show NS_IMETHODIMP_(PRBool) nsGenericHTMLElement::HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const in that file
Yeah, this file has never made sense to me that way. I'm perfectly happy to do NS_IMETHODIMP_(nsIAtom*), of course.
Comment on attachment 133398 [details] [diff] [review] Forgot a few files... >Index: content/html/content/src/nsGenericHTMLElement.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/content/src/nsGenericHTMLElement.cpp,v >retrieving revision 1.443 >diff -p -u -1 -0 -r1.443 nsGenericHTMLElement.cpp >--- content/html/content/src/nsGenericHTMLElement.cpp 2 Oct 2003 21:29:32 -0000 1.443 >+++ content/html/content/src/nsGenericHTMLElement.cpp 16 Oct 2003 08:57:03 -0000 >@@ -2271,20 +2271,32 @@ nsGenericHTMLElement::GetID(nsIAtom** aR > > nsresult > nsGenericHTMLElement::GetClasses(nsVoidArray& aArray) const > { > if (nsnull != mAttributes) { > return mAttributes->GetClasses(aArray); > } > return NS_OK; > } > >+nsIAtom* >+nsGenericHTMLElement::GetIDAttributeName() const NS_IMETHODIMP_(nsIAtom*) >+{ >+ return nsHTMLAtoms::id; >+} >+ >+nsIAtom* >+nsGenericHTMLElement::GetClassAttributeName() const Ditto. >+{ >+ return nsHTMLAtoms::kClass; >+} >+ > NS_IMETHODIMP_(PRBool) > nsGenericHTMLElement::HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const > { > if (mAttributes) { > return mAttributes->HasClass(aClass, aCaseSensitive); > } > return PR_FALSE; > } > > nsresult >Index: content/html/document/src/nsHTMLDocument.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/document/src/nsHTMLDocument.cpp,v >retrieving revision 3.509 >diff -p -u -1 -0 -r3.509 nsHTMLDocument.cpp >--- content/html/document/src/nsHTMLDocument.cpp 7 Oct 2003 23:21:50 -0000 3.509 >+++ content/html/document/src/nsHTMLDocument.cpp 16 Oct 2003 08:57:12 -0000 >@@ -1443,21 +1443,21 @@ nsHTMLDocument::AttributeWillChange(nsIC > > aContent->GetTag(getter_AddRefs(tag)); > > if (IsNamedItem(aContent, tag, value)) { > nsresult rv = RemoveFromNameTable(value, aContent); > > if (NS_FAILED(rv)) { > return rv; > } > } >- } else if (aAttribute == nsHTMLAtoms::id && >+ } else if (aAttribute == aContent->GetIDAttributeName() && > aNameSpaceID == kNameSpaceID_None) { There probably should be an assert for aAttribute not being null somewhere. > nsresult rv = RemoveFromIdTable(aContent); > > if (NS_FAILED(rv)) { > return rv; > } > } > > return nsDocument::AttributeWillChange(aContent, aNameSpaceID, aAttribute); > } >@@ -1475,25 +1475,27 @@ nsHTMLDocument::AttributeChanged(nsICont > > aContent->GetTag(getter_AddRefs(tag)); > > if (IsNamedItem(aContent, tag, value)) { > nsresult rv = UpdateNameTableEntry(value, aContent); > > if (NS_FAILED(rv)) { > return rv; > } > } >- } else if (aAttribute == nsHTMLAtoms::id && >+ } else if (aAttribute == aContent->GetIDAttributeName() && > aNameSpaceID == kNameSpaceID_None) { Same here about the assert, though it probably doesn't matter since you likely will hit asserts in GetAttr(). > nsAutoString value; > >- aContent->GetAttr(aNameSpaceID, nsHTMLAtoms::id, value); >+ aContent->GetAttr(aNameSpaceID, >+ aContent->GetIDAttributeName(), >+ value); > > if (!value.IsEmpty()) { > nsresult rv = AddToIdTable(value, aContent); > > if (NS_FAILED(rv)) { > return rv; > } > } > } > >Index: content/html/style/src/nsCSSStyleSheet.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/style/src/nsCSSStyleSheet.cpp,v >retrieving revision 3.281 >diff -p -u -1 -0 -r3.281 nsCSSStyleSheet.cpp >--- content/html/style/src/nsCSSStyleSheet.cpp 14 Oct 2003 21:06:58 -0000 3.281 >+++ content/html/style/src/nsCSSStyleSheet.cpp 16 Oct 2003 08:57:20 -0000 >@@ -3795,21 +3795,22 @@ static PRBool SelectorMatches(RuleProces > } while (attr && result); > } > } > if (result && (aSelector->mIDList || aSelector->mClassList)) { > // test for ID & class match > result = localFalse; > if (data.mStyledContent) { > // case sensitivity: bug 93371 > PRBool isCaseSensitive = data.mCompatMode != eCompatibility_NavQuirks; > nsAtomList* IDList = aSelector->mIDList; >- if (nsnull == IDList || aAttribute == nsHTMLAtoms::id) { >+ if (nsnull == IDList || >+ aAttribute == data.mContent->GetIDAttributeName()) { This needs to check that aAttribute is not null. > result = PR_TRUE; > } > else if (nsnull != data.mContentID) { > result = PR_TRUE; > if (isCaseSensitive) { > do { > if (localTrue == (IDList->mAtom != data.mContentID)) { > result = PR_FALSE; > break; > } >@@ -3826,21 +3827,21 @@ static PRBool SelectorMatches(RuleProces > if (localTrue != > id1.Equals(id2, nsCaseInsensitiveCStringComparator())) { > result = PR_FALSE; > break; > } > IDList = IDList->mNext; > } while (IDList); > } > } > >- if (result && aAttribute != nsHTMLAtoms::kClass) { >+ if (result && aAttribute != data.mContent->GetClassAttributeName()) { Same as above. > nsAtomList* classList = aSelector->mClassList; > while (nsnull != classList) { > if (localTrue == (!data.mStyledContent->HasClass(classList->mAtom, isCaseSensitive))) { > result = PR_FALSE; > break; > } > classList = classList->mNext; > } > } > } r=caillon with comments dealt with, yadda yadda. ;-)
Attachment #133398 - Flags: review?(caillon) → review+
Attachment #133398 - Attachment is obsolete: true
Attachment #133398 - Flags: superreview?(peterv)
Attachment #133558 - Flags: superreview?(peterv)
Comment on attachment 133558 [details] [diff] [review] updated to caillon's comments So do you want to do the GetID change too? And is the comment at http://lxr.mozilla.org/seamonkey/source/content/base/public/nsIStyledContent.h# 59 still correct?
Attachment #133558 - Flags: superreview?(peterv) → superreview+
I was going to do GetID as a part of a separate deCOM patch at some point... this patch had gotten big enough. And yes, that comment is still correct for now. Checked in.
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Not sure how relevant this is, but.. the ID-ness of attributes in XML (in the absence of a DTD) is part of an open W3C TAG issue, xmlIDSemantics-32. see http://www.w3.org/2001/tag/ilist#xmlIDSemantics-32 and http://www.w3.org/2001/tag/doc/xmlIDsemantics-32.html
Right. When they decide on something, we'll look into implementing it... Far more worrisome is the suggestion in DOM3 Core that elements of the same type can have different ID attributes.. ;)
Component: DOM: Core → DOM: Core & HTML
QA Contact: desale → general
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: