Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add [Symbol.iterator]() methods to HTMLCollection #37

Closed
tp opened this issue Feb 24, 2015 · 6 comments
Closed

Add [Symbol.iterator]() methods to HTMLCollection #37

tp opened this issue Feb 24, 2015 · 6 comments

Comments

@tp
Copy link

tp commented Feb 24, 2015

This is related to babel/babel#545 and was previously filed as babel/babel#884

I had this code (working in Firefox without Babel):

for (let contentGroupEl of xmlDocument.getElementsByTagName('contentGroups')) {
...
}

Where xmlDocument is defined as follows:

var xmlDocument = (new DOMParser).parseFromString(content, "application/xhtml+xml");

The above loop iterates over a HTMLCollection.

Babel + Browser Polyfill from babel-core npm package (v4.4.6) generates the following JS, which throws an exception in Chrome:

for (var _iterator = xmlDocument.getElementsByTagName("contentGroups")[Symbol.iterator](), _step; !(_step = _iterator.next()).done; ) {
                var contentGroupEl = _step.value;
}

TypeError: undefined is not a function: since xmlDocument.getElementsByTagName("contentGroups")[Symbol.iterator] equals undefined.

Is is possible to extend HTMLCollection with the iterator methods as well?

My current workaround looks like this:

for (let contentGroupEl of[].slice.call(xmlDocument.getElementsByTagName('contentGroups'))) {
...

Simply extending the HTMLCollection prototype does not seem to work. This code has no effect on the HTMLCollection instances.

if (!HTMLCollection.prototype[Symbol.iterator]) {
  HTMLCollection.prototype[Symbol.iterator] = [][Symbol.iterator]
}
@zloirock
Copy link
Owner

Show me how to implement it in all browsers :) In stable Chromium I see magic like in your example:

console.log(HTMLCollection.prototype[Symbol.iterator] = [][Symbol.iterator]) // => function ArrayValues() { [native code] }
console.log(HTMLCollection.prototype[Symbol.iterator] == [][Symbol.iterator]) // => true
console.log(Object.getPrototypeOf(document.getElementsByTagName('div')) == HTMLCollection.prototype) // => true
console.log(document.getElementsByTagName('div').hasOwnProperty(Symbol.iterator)) // => false
console.log(Symbol.iterator in document.getElementsByTagName('div')) // => true
console.log(document.getElementsByTagName('div')[Symbol.iterator]) // => undefined

In other browsers it works correct, in nightly it's fixed.

@tp
Copy link
Author

tp commented Feb 24, 2015

Uh, that looks bad :-/

So it's a Chrome stable bug. Hopefully not before long and it will be fixed for all users.

I myself have also not found a way to make it stick in Chrome.

Also I could not find a Chrome bug or code change relating to this.

@zloirock
Copy link
Owner

I see 2 way how to add it in Chromium, but they are too ugly. Write, if you find a simple way w/o side effect.

@SeanHayes
Copy link

SeanHayes commented Jan 26, 2017

I see this is marked as wontfix, but I see a linked commit that looks like it might fix this. Should iterating over HTMLCollections with for of work? It's broken for me in Safari.

@loganfsmyth
Copy link
Contributor

This is fixed in #249 but that has not been published yet. The next version of core-js, when it is released, should include iterable HTMLCollection.

@mrichard
Copy link

mrichard commented Feb 7, 2017

@loganfsmyth when is next version of core-js expected? Thanks

outoftime pushed a commit to outoftime/popcode that referenced this issue Mar 4, 2018
In Chrome 38, DOM collections have particularly buggy behavior with
respect to iteration—specifically, `Symbol.iterator in domCollection`
evaluates to `true`, but `domCollection[Symbol.iterator]` is undefined!
This bug is [mentioned in a `core-js` issue from around that
time](zloirock/core-js#37 (comment)).

Transpiled array destructuring uses iteration in its implementation, and
thus breaks when attempting to destructure a DOM collection in the
affected Chrome version(s). Because of the inconsistent feedback given
by the runtime, `core-js` isn’t able to effectively polyfill iteration
on this version.

So, just don’t destructure DOM collections—instead, do it the old
fashioned way.
@zloirock zloirock added v8 and removed wontfix labels Feb 28, 2021
zloirock added a commit that referenced this issue Feb 28, 2021
…it symbols (incl. well-known) from DOM collections prototypes to instances

#37
#406
This was referenced Mar 15, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

5 participants