Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants