If you think a bug might affect users in the 57 release, please set the correct tracking and status flags for Release Management.

getElementsByAttribute returns an HTMLCollection, not a NodeList

UNCONFIRMED
Unassigned

Status

()

Core
DOM
UNCONFIRMED
5 years ago
5 years ago

People

(Reporter: Moisés Campos, Unassigned)

Tracking

17 Branch
x86
Linux
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

574 bytes, application/octet-stream
Details
(Reporter)

Description

5 years ago
User Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20100101 Firefox/17.0
Build ID: 20121128204232

Steps to reproduce:

if we run this code: 
<vbox id="list">
	<button id="one" source="source1" label="1"/>
	<button id="two" source="source2" label="2"/>
	<button id="three" label="3"/>
	<button id="four" source="source4" label="4"/>
</vbox>
<button label="Go!" oncommand="test()"/>
<script>
var ConsSrv = Components.classes['@mozilla.org/consoleservice;1'].getService(Components.interfaces.nsIConsoleService);
function test() {
	var list = document.getElementById('list').getElementsByAttribute('source', '*');
	for each(var obj in list) {
		ConsSrv.logStringMessage('|'+obj.tagName+'|'+obj.id+'|');
	}
}
</script>

Note: This code is loaded through document.loadOverlay invocation 



Actual results:

On Firefox v17.0.1 we get this result on console: 

|button|one|
 ----------
|button|two|
 ----------
|button|four|
 ----------
 ----------
Warning: ReferenceError: reference to undefined property obj.tagName
Source file: (...) 
Line: 29
 ----------
|undefined|undefined|
 ----------
|undefined|undefined|
 ----------
|undefined|undefined|
 ----------
|undefined|undefined|

On Aurora 19.0a2 we get this result: 
|button|one|
 ----------
|button|two|
 ----------
|button|four|
 ----------
|button|one|
 ----------
|button|two|
 ----------
|button|four|
 ----------
Warning: ReferenceError: reference to undefined property obj.tagName
Source file: (...)
Line: 29
 ----------
|undefined|undefined|
 ----------
|undefined|undefined|
 ----------
|undefined|undefined|
 ----------
|undefined|undefined|

The returned NodeList has duplicates obj's in it. 
This happens on Linux (Fedora 16) and also tested on MWindows 



Expected results:

I think that the correct result should be: 
|button|one|
 ----------
|button|two|
 ----------
|button|four|
Moisés, could you please attach a testcase that can reproduce this issue?

Updated

5 years ago
Flags: needinfo?(moises.campos)

Updated

5 years ago
Component: Untriaged → DOM
Product: Firefox → Core
(Reporter)

Comment 2

5 years ago
Created attachment 690913 [details]
XUL page with testcase

The output is sent to console.
Flags: needinfo?(moises.campos)
> for each(var obj in list) {

That's the wrong way to iterate over a list, and it's what's biting you...

In this case, GetElementsByAttribute returns an HTMLCollection, not a NodeList (which is perhaps a bug in its own right, but a preexisting one I suspect).  And what changed is that enumeration of an HTMLCollection now also enumerates the named properties, as the spec requires.  So when you enumerate all properties, as you do above, you get the following set of property names: { "0", "1", "2", "one", "two", "four" }.  Then you look them up on the list object, and get the result you get.

I don't know whether the compat hit from enumerating the names is worse than the compat hit from making GetElementsByAttribute return a NodeList and thus hiding the names completely, given that I believe we've exposed the names on it for a decade or so if you look for them...
Also note that you'd have similar problems if anyone added enumerable properties to HTMLCollection.prototype or Object.prototype...
Summary: getElementsByAttribute returns wrong NodeList → getElementsByAttribute returns an HTMLCollection, not a NodeList
Peter, thoughts?
(Reporter)

Comment 6

5 years ago
Well noticed! Wrong webpage reference... Iteration in the returned Array works fine in Aurora 19.0a2 and Firefox v17.0.1. 
Thanks for the inconvenience
|for (var obj of list)| works.
You need to log in before you can comment on or make changes to this bug.