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 iterator support #27

Merged
merged 1 commit into from
Sep 15, 2016
Merged

Add iterator support #27

merged 1 commit into from
Sep 15, 2016

Conversation

JakeChampion
Copy link
Contributor

@JakeChampion JakeChampion commented Jun 22, 2016

Should solve #4

while (!done) {
iterableResponse = arrayLike.next();
if (
iterableResponse.hasOwnProperty('value')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use the "has" module rather than trusting Object#hasOwnProperty

@JakeChampion
Copy link
Contributor Author

@ljharb Addressed all comments raised.

@@ -1,9 +1,88 @@
'use strict';
var ES = require('es-abstract/es6');
var supportsDescriptors = require('define-properties').supportsDescriptors;
var has = require('has');
var global = require('global-object');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an alternative to this module would be https://www.npmjs.com/package/system.global which follows the official language spec proposal.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to using system.global instead.

@mathiasbynens
Copy link
Owner

What’s with the failing builds?

@ljharb
Copy link
Collaborator

ljharb commented Aug 11, 2016

Most of the new tests in this PR are missing explicit end or plan calls.

@JakeChampion
Copy link
Contributor Author

All passing now :-)

@JakeChampion
Copy link
Contributor Author

@ljharb This is ready for another review when you have the time. Thanks for helping with this feature by the way, I really appreciate the feedback you have given :-)

}());

if (supportsStrIterator) {
iteratorSymbol = '@@iterator';
Copy link
Collaborator

@ljharb ljharb Aug 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit: now fixed I don't think that the above check actually indicates that it supports a string iterator - that can only be tested by setting one, and asserting that for..of invokes it.

if (iteratorSymbol && isCallable(items[iteratorSymbol])) {
return items[iteratorSymbol]();
} else if ('Set' in global && 'Map' in global && isCallable(items.entries) && isCallable(items.values)) {
if (items.constructor === Set) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anything with === won't work cross-realm (like iframes, or web workers, etc) - to be robust, I think you'd need to stash a copy of the Set.prototype.size getter (and Map) and assert that .calling on items did not throw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a JSBin to test this out, it seems Sets and Maps are detectable across realms (I tested web workers) via instanceof. Is this what you expected?

http://jsbin.com/kiguqunoxi/edit?js,console

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another, the following test will work on many more browsers.

var iframe = document.createElement('iframe');
iframe.src = 'about:blank';
document.body.appendChild(iframe);
console.log(isMap(new iframe.contentWindow.Map()));

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's the case with instanceof, it's a violation of the spec - the .call you're using is the correct way to make it work across realms.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is assumed to use .call.

@JakeChampion
Copy link
Contributor Author

Addressed all comments, all passing on CI except for 3 allowed failures -- node 0.9, node 0.6, node 0.4

I'm currently running this test suite against a multitude of browsers, this usually takes a very long time. I will add a comment Wednesday morning (UK time). So far, it looks like there are errors on ios 8.2 :-/

if (has(items, iteratorSymbol)) {
return items[iteratorSymbol]();
} else if ('Set' in global && 'Map' in global && isCallable(items.entries) && isCallable(items.values)) {
if (items.constructor === Set) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't work cross realm, need to resolve this.

@JakeChampion
Copy link
Contributor Author

All browsers not finished running yet, results so far for browsers which failed:

- failed: <iphone 7.0 on Mac 10.9> (4 failed, 96 passed)
- failed: <iphone 7.1 on Mac 10.10> (4 failed, 96 passed)
- failed: <iphone 8.1 on Mac 10.10> (12 failed, 88 passed)
- failed: <iphone 8.2 on Mac 10.10> (12 failed, 88 passed)
- failed: <iphone 8.4 on Mac 10.10> (12 failed, 88 passed)
- failed: <iphone 9.1 on Mac 10.10> (4 failed, 96 passed)
- failed: <iphone 9.2 on Mac 10.10> (4 failed, 96 passed)
- failed: <iphone 9.0 on Mac 10.10> (4 failed, 96 passed)
- failed: <ipad 7.0 on Mac 10.9> (4 failed, 96 passed)
- failed: <ipad 7.1 on Mac 10.10> (4 failed, 96 passed)
- failed: <iphone 9.3 on Mac 10.11> (4 failed, 96 passed)
- failed: <ipad 8.2 on Mac 10.10> (12 failed, 88 passed)
- failed: <ipad 8.1 on Mac 10.10> (12 failed, 88 passed)
- failed: <ipad 8.3 on Mac 10.10> (12 failed, 88 passed)
- failed: <ipad 8.4 on Mac 10.10> (12 failed, 88 passed)
- failed: <ipad 9.0 on Mac 10.10> (4 failed, 96 passed)
- failed: <ipad 9.1 on Mac 10.10> (4 failed, 96 passed)
- failed: <ipad 9.2 on Mac 10.10> (4 failed, 96 passed)
- failed: <firefox 20 on Windows 2008> (4 failed, 96 passed)
- failed: <ipad 9.3 on Mac 10.11> (4 failed, 96 passed)
- failed: <firefox 22 on Windows 2012 R2> (4 failed, 96 passed)
- failed: <firefox 21 on Mac 10.9> (4 failed, 96 passed)
- failed: <firefox 25 on Windows 2008> (8 failed, 92 passed)
- failed: <firefox 24 on Windows 2012> (8 failed, 92 passed)
- failed: <firefox 26 on Windows 10> (8 failed, 92 passed)
- failed: <firefox 23 on Mac 10.11> (4 failed, 96 passed)
- failed: <safari 6 on Mac 10.8> (12 failed, 88 passed)
- failed: <safari 8 on Mac 10.10> (12 failed, 88 passed)
- failed: <safari 7 on Mac 10.9> (4 failed, 96 passed)
- failed: <safari 9 on Mac 10.11> (4 failed, 96 passed)
- failed: <opera 11 on Windows 2003> (4 failed, 96 passed)
- failed: <opera 12 on Windows 2003> (4 failed, 96 passed)

return done ? tempArray : false;
};

var hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof Symbol.iterator === 'symbol' doesn't work with Symbol polyfills.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because Symbol isn't truly polyfillable - it's a native-only feature. We should be supporting shims, but not go out of our way to support shams.

@falsandtru
Copy link
Contributor

I refined this support in #30. It would work better. Could you review it?

@ljharb ljharb mentioned this pull request Aug 18, 2016
@JakeChampion
Copy link
Contributor Author

I ran the tests against the master using my list of browsers, it seems to have the same 4 failing tests.

@JakeChampion
Copy link
Contributor Author

   - failed: <iphone 7.0 on Mac 10.9> (4 failed, 80 passed)
    1 browser(s) failed
  Failed Tests: There were 4 failures
    no setters are called for indexes
      ✖ should throw
    no setters are called for indexes
      ✖ should throw
    no setters are called for indexes
      ✖ should throw
    no setters are called for indexes
      ✖ should throw
  total:     261
  passing:   257
  failing:   4
  duration:  1m 15.1s
~/Code/oss/Array.from master 1m 15s

@JakeChampion
Copy link
Contributor Author

I've commented out the test which is failing on master and am now rerunning against all the browsers on SauceLabs. I have high hopes it will work :-)

@ljharb
Copy link
Collaborator

ljharb commented Aug 19, 2016

Hmm - I'd like to fix those tests on master before merging this.

@JakeChampion
Copy link
Contributor Author

🎉 🎉 🎉 🎉 🎉 🎉 🎉

- passed: <iphone 7.0 on Mac 10.9>
- passed: <iphone 7.1 on Mac 10.10>
- passed: <iphone 9.0 on Mac 10.10>
- passed: <iphone 9.1 on Mac 10.10>
- passed: <iphone 9.2 on Mac 10.10>
- passed: <iphone 9.3 on Mac 10.11>
- passed: <ipad 7.0 on Mac 10.9>
- passed: <ipad 7.1 on Mac 10.10>
- passed: <ipad 9.0 on Mac 10.10>
- passed: <ipad 9.1 on Mac 10.10>
- passed: <ipad 9.2 on Mac 10.10>
- passed: <ipad 9.3 on Mac 10.11>
- passed: <firefox 4 on Windows 10>
- passed: <firefox 5 on Windows 2008>
- passed: <firefox 6 on Mac 10.8>
- passed: <firefox 7 on Windows 10>
- passed: <firefox 8 on Mac 10.11>
- passed: <firefox 9 on Windows 2012 R2>
- passed: <firefox 10 on Mac 10.8>
- passed: <firefox 11 on Windows 2008>
- passed: <firefox 12 on Windows 2012>
- passed: <firefox 45 on Windows 10>
- passed: <firefox 46 on Mac 10.11>
- passed: <firefox 47 on Mac 10.11>
- passed: <firefox 48 on Windows 2012>
- passed: <safari 5 on Windows 2008>
- passed: <safari 7 on Mac 10.9>
- passed: <safari 9 on Mac 10.11>
- passed: <chrome 26 on Windows 10>
- passed: <chrome 27 on Linux>
- passed: <chrome 28 on Windows 2003>
- passed: <chrome 29 on Windows 10>
- passed: <chrome 50 on Mac 10.9>
- passed: <chrome 51 on Mac 10.10>
- passed: <chrome 52 on Mac 10.10>
- passed: <internet explorer 9 on Windows 2008>
- passed: <internet explorer 10 on Windows 2012>
- passed: <microsoftedge 13 on Windows 10>
- passed: <opera 11 on Windows 2003>
- passed: <opera 12 on Windows 2003>
- passed: <android 4.0 on Linux>
- passed: <android 4.1 on Linux>
- passed: <android 4.3 on Linux>
- passed: <android 4.2 on Linux>
- passed: <android 4.4 on Linux>
- passed: <android 5.0 on Linux>
- passed: <android 5.1 on Linux>

@JakeChampion
Copy link
Contributor Author

@mathiasbynens @ljharb I believe this is ready for it's final review :-)

@ljharb
Copy link
Collaborator

ljharb commented Sep 15, 2016

@mathiasbynens btw would you mind enabling required PR approvals on this repo, in settings? :-)

@JakeChampion thanks! I'll take a final look and merge tonight.

@ljharb ljharb merged commit 0322091 into mathiasbynens:master Sep 15, 2016
@ljharb
Copy link
Collaborator

ljharb commented Sep 15, 2016

Thanks! I'm going to give this a couple days to bake, and for me to test and play around, before releasing it.

@ljharb ljharb mentioned this pull request Sep 15, 2016
@JakeChampion JakeChampion deleted the iteration branch September 15, 2016 07:55
@le0nik
Copy link

le0nik commented Feb 6, 2018

Iterators still don't work in latest as it is 1.0.3. Should users just install master until this is released?

@mroderick
Copy link

Or use https://github.com/studio-b12/array-from until a new version is published to NPM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants