| 'use strict'; |
| |
| /* eslint global-require: 0 */ |
| // the code is structured this way so that bundlers can |
| // alias out `has-symbols` to `() => true` or `() => false` if your target |
| // environments' Symbol capabilities are known, and then use |
| // dead code elimination on the rest of this module. |
| // |
| // Similarly, `isarray` can be aliased to `Array.isArray` if |
| // available in all target environments. |
| |
| var isArguments = require('is-arguments'); |
| var getStopIterationIterator = require('stop-iteration-iterator'); |
| |
| if (require('has-symbols')() || require('has-symbols/shams')()) { |
| var $iterator = Symbol.iterator; |
| // Symbol is available natively or shammed |
| // natively: |
| // - Chrome >= 38 |
| // - Edge 12-14?, Edge >= 15 for sure |
| // - FF >= 36 |
| // - Safari >= 9 |
| // - node >= 0.12 |
| module.exports = function getIterator(iterable) { |
| // alternatively, `iterable[$iterator]?.()` |
| if (iterable != null && typeof iterable[$iterator] !== 'undefined') { |
| return iterable[$iterator](); |
| } |
| if (isArguments(iterable)) { |
| // arguments objects lack Symbol.iterator |
| // - node 0.12 |
| return Array.prototype[$iterator].call(iterable); |
| } |
| }; |
| } else { |
| // Symbol is not available, native or shammed |
| var isArray = require('isarray'); |
| var isString = require('is-string'); |
| var GetIntrinsic = require('get-intrinsic'); |
| var $Map = GetIntrinsic('%Map%', true); |
| var $Set = GetIntrinsic('%Set%', true); |
| var callBound = require('call-bind/callBound'); |
| var $arrayPush = callBound('Array.prototype.push'); |
| var $charCodeAt = callBound('String.prototype.charCodeAt'); |
| var $stringSlice = callBound('String.prototype.slice'); |
| |
| var advanceStringIndex = function advanceStringIndex(S, index) { |
| var length = S.length; |
| if ((index + 1) >= length) { |
| return index + 1; |
| } |
| |
| var first = $charCodeAt(S, index); |
| if (first < 0xD800 || first > 0xDBFF) { |
| return index + 1; |
| } |
| |
| var second = $charCodeAt(S, index + 1); |
| if (second < 0xDC00 || second > 0xDFFF) { |
| return index + 1; |
| } |
| |
| return index + 2; |
| }; |
| |
| var getArrayIterator = function getArrayIterator(arraylike) { |
| var i = 0; |
| return { |
| next: function next() { |
| var done = i >= arraylike.length; |
| var value; |
| if (!done) { |
| value = arraylike[i]; |
| i += 1; |
| } |
| return { |
| done: done, |
| value: value |
| }; |
| } |
| }; |
| }; |
| |
| var getNonCollectionIterator = function getNonCollectionIterator(iterable, noPrimordialCollections) { |
| if (isArray(iterable) || isArguments(iterable)) { |
| return getArrayIterator(iterable); |
| } |
| if (isString(iterable)) { |
| var i = 0; |
| return { |
| next: function next() { |
| var nextIndex = advanceStringIndex(iterable, i); |
| var value = $stringSlice(iterable, i, nextIndex); |
| i = nextIndex; |
| return { |
| done: nextIndex > iterable.length, |
| value: value |
| }; |
| } |
| }; |
| } |
| |
| // es6-shim and es-shims' es-map use a string "_es6-shim iterator_" property on different iterables, such as MapIterator. |
| if (noPrimordialCollections && typeof iterable['_es6-shim iterator_'] !== 'undefined') { |
| return iterable['_es6-shim iterator_'](); |
| } |
| }; |
| |
| if (!$Map && !$Set) { |
| // the only language iterables are Array, String, arguments |
| // - Safari <= 6.0 |
| // - Chrome < 38 |
| // - node < 0.12 |
| // - FF < 13 |
| // - IE < 11 |
| // - Edge < 11 |
| |
| module.exports = function getIterator(iterable) { |
| if (iterable != null) { |
| return getNonCollectionIterator(iterable, true); |
| } |
| }; |
| } else { |
| // either Map or Set are available, but Symbol is not |
| // - es6-shim on an ES5 browser |
| // - Safari 6.2 (maybe 6.1?) |
| // - FF v[13, 36) |
| // - IE 11 |
| // - Edge 11 |
| // - Safari v[6, 9) |
| |
| var isMap = require('is-map'); |
| var isSet = require('is-set'); |
| |
| // Firefox >= 27, IE 11, Safari 6.2 - 9, Edge 11, es6-shim in older envs, all have forEach |
| var $mapForEach = callBound('Map.prototype.forEach', true); |
| var $setForEach = callBound('Set.prototype.forEach', true); |
| if (typeof process === 'undefined' || !process.versions || !process.versions.node) { // "if is not node" |
| |
| // Firefox 17 - 26 has `.iterator()`, whose iterator `.next()` either |
| // returns a value, or throws a StopIteration object. These browsers |
| // do not have any other mechanism for iteration. |
| var $mapIterator = callBound('Map.prototype.iterator', true); |
| var $setIterator = callBound('Set.prototype.iterator', true); |
| } |
| // Firefox 27-35, and some older es6-shim versions, use a string "@@iterator" property |
| // this returns a proper iterator object, so we should use it instead of forEach. |
| // newer es6-shim versions use a string "_es6-shim iterator_" property. |
| var $mapAtAtIterator = callBound('Map.prototype.@@iterator', true) || callBound('Map.prototype._es6-shim iterator_', true); |
| var $setAtAtIterator = callBound('Set.prototype.@@iterator', true) || callBound('Set.prototype._es6-shim iterator_', true); |
| |
| var getCollectionIterator = function getCollectionIterator(iterable) { |
| if (isMap(iterable)) { |
| if ($mapIterator) { |
| return getStopIterationIterator($mapIterator(iterable)); |
| } |
| if ($mapAtAtIterator) { |
| return $mapAtAtIterator(iterable); |
| } |
| if ($mapForEach) { |
| var entries = []; |
| $mapForEach(iterable, function (v, k) { |
| $arrayPush(entries, [k, v]); |
| }); |
| return getArrayIterator(entries); |
| } |
| } |
| if (isSet(iterable)) { |
| if ($setIterator) { |
| return getStopIterationIterator($setIterator(iterable)); |
| } |
| if ($setAtAtIterator) { |
| return $setAtAtIterator(iterable); |
| } |
| if ($setForEach) { |
| var values = []; |
| $setForEach(iterable, function (v) { |
| $arrayPush(values, v); |
| }); |
| return getArrayIterator(values); |
| } |
| } |
| }; |
| |
| module.exports = function getIterator(iterable) { |
| return getCollectionIterator(iterable) || getNonCollectionIterator(iterable); |
| }; |
| } |
| } |