Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add .forEach method to iterable DOM collections, #329
Browse files Browse the repository at this point in the history
zloirock committed May 18, 2018
1 parent 7a1435f commit c908a46
Showing 21 changed files with 497 additions and 417 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1689,11 +1689,13 @@ Some DOM collections should have [iterable interface](https://heycam.github.io/w
#values() -> iterator
#keys() -> iterator
#entries() -> iterator
#forEach(fn(val, index, @), that) -> void
```
[*CommonJS entry points:*](#commonjs)
```js
core-js(/library)/web/dom-collections
core-js(/library)/fn/dom-collections/iterator
core-js/fn/dom-collections/for-each
```
[*Examples*](http://goo.gl/lfXVFl):
```js
@@ -1704,6 +1706,8 @@ for (let { id } of document.querySelectorAll('*')) {
for (let [index, { id }] of document.querySelectorAll('*').entries()) {
if (id) console.log(index, id);
}
document.querySelectorAll('*').forEach(it => console.log(it.id));
```
### Iteration helpers
Modules [`core.is-iterable`](https://github.com/zloirock/core-js/blob/v3/modules/core.is-iterable.js), [`core.get-iterator`](https://github.com/zloirock/core-js/blob/v3/modules/core.get-iterator.js), [`core.get-iterator-method`](https://github.com/zloirock/core-js/blob/v3/modules/core.get-iterator-method.js) - helpers for check iterability / get iterator in the `library` version or, for example, for `arguments` object:
2 changes: 2 additions & 0 deletions build/config.js
Original file line number Diff line number Diff line change
@@ -189,6 +189,7 @@ module.exports = {
'esnext.asap',
'esnext.observable',
'web.immediate',
'web.dom.for-each',
'web.dom.iterable',
'web.timers',
'core.get-iterator-method',
@@ -208,6 +209,7 @@ module.exports = {
'es.number.constructor',
'es.date.to-string',
'es.date.to-primitive',
'web.dom.for-each',
],

banner: '/**\n' +
739 changes: 386 additions & 353 deletions client/core.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions client/core.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/core.min.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions client/library.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/library.min.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions fn/dom-collections/for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require('../../modules/web.dom.for-each');
module.exports = require('../../modules/_array-for-each');
4 changes: 3 additions & 1 deletion fn/dom-collections/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
require('../../modules/web.dom.for-each');
require('../../modules/web.dom.iterable');
var $iterators = require('../../modules/es.array.iterator');
module.exports = {
keys: $iterators.keys,
values: $iterators.values,
entries: $iterators.entries,
iterator: $iterators.values
iterator: $iterators.values,
forEach: require('../../modules/_array-for-each')
};
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -188,5 +188,6 @@ require('./modules/esnext.asap');
require('./modules/esnext.observable');
require('./modules/web.timers');
require('./modules/web.immediate');
require('./modules/web.dom.for-each');
require('./modules/web.dom.iterable');
module.exports = require('./modules/_core');
8 changes: 8 additions & 0 deletions modules/_array-for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var nativeForEach = [].forEach;
var $forEach = require('./_array-methods')(0);
var STRICT = require('./_strict-method')(nativeForEach, true);

// 22.1.3.10 Array.prototype.forEach(callbackfn [, thisArg])
module.exports = STRICT ? nativeForEach : function forEach(callbackfn /* , thisArg */) {
return $forEach(this, callbackfn, arguments[1]);
};
35 changes: 35 additions & 0 deletions modules/_dom-iterables.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// iterable DOM collections
// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
module.exports = {
CSSRuleList: 0,
CSSStyleDeclaration: 0,
CSSValueList: 0,
ClientRectList: 0,
DOMRectList: 0,
DOMStringList: 0,
DOMTokenList: 1,
DataTransferItemList: 0,
FileList: 0,
HTMLAllCollection: 0,
HTMLCollection: 0,
HTMLFormElement: 0,
HTMLSelectElement: 0,
MediaList: 0,
MimeTypeArray: 0,
NamedNodeMap: 0,
NodeList: 1,
PaintRequestList: 0,
Plugin: 0,
PluginArray: 0,
SVGLengthList: 0,
SVGNumberList: 0,
SVGPathSegList: 0,
SVGPointList: 0,
SVGStringList: 0,
SVGTransformList: 0,
SourceBufferList: 0,
StyleSheetList: 0,
TextTrackCueList: 0,
TextTrackList: 0,
TouchList: 0
};
11 changes: 3 additions & 8 deletions modules/es.array.for-each.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
'use strict';
var $export = require('./_export');
var $forEach = require('./_array-methods')(0);
var STRICT = require('./_strict-method')([].forEach, true);
var forEach = require('./_array-for-each');

$export($export.P + $export.F * !STRICT, 'Array', {
// 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
forEach: function forEach(callbackfn /* , thisArg */) {
return $forEach(this, callbackfn, arguments[1]);
}
});
// 22.1.3.10 Array.prototype.forEach(callbackfn [, thisArg])
$export($export.P + $export.F * ([].forEach != forEach), 'Array', { forEach: forEach });
10 changes: 2 additions & 8 deletions modules/library/web.dom.iterable.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
require('./es.array.iterator');
var DOMIterables = require('./_dom-iterables');
var global = require('./_global');
var hide = require('./_hide');
var Iterators = require('./_iterators');
var TO_STRING_TAG = require('./_wks')('toStringTag');

var DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' +
'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' +
'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' +
'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' +
'TextTrackList,TouchList').split(',');

for (var i = 0; i < DOMIterables.length; i++) {
var NAME = DOMIterables[i];
for (var NAME in DOMIterables) {
var Collection = global[NAME];
var proto = Collection && Collection.prototype;
if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
10 changes: 10 additions & 0 deletions modules/web.dom.for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var DOMIterables = require('./_dom-iterables');
var forEach = require('./_array-for-each');
var redefine = require('./_redefine');
var global = require('./_global');

for (var NAME in DOMIterables) {
var Collection = global[NAME];
var proto = Collection && Collection.prototype;
if (proto && !proto.forEach) redefine(proto, 'forEach', forEach);
}
38 changes: 2 additions & 36 deletions modules/web.dom.iterable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var DOMIterables = require('./_dom-iterables');
var $iterators = require('./es.array.iterator');
var redefine = require('./_redefine');
var global = require('./_global');
@@ -8,48 +9,13 @@ var ITERATOR = wks('iterator');
var TO_STRING_TAG = wks('toStringTag');
var ArrayValues = Iterators.Array;

var DOMIterables = {
CSSRuleList: 0,
CSSStyleDeclaration: 0,
CSSValueList: 0,
ClientRectList: 0,
DOMRectList: 0,
DOMStringList: 0,
DOMTokenList: 1,
DataTransferItemList: 0,
FileList: 0,
HTMLAllCollection: 0,
HTMLCollection: 0,
HTMLFormElement: 0,
HTMLSelectElement: 0,
MediaList: 0,
MimeTypeArray: 0,
NamedNodeMap: 0,
NodeList: 1,
PaintRequestList: 0,
Plugin: 0,
PluginArray: 0,
SVGLengthList: 0,
SVGNumberList: 0,
SVGPathSegList: 0,
SVGPointList: 0,
SVGStringList: 0,
SVGTransformList: 0,
SourceBufferList: 0,
StyleSheetList: 0,
TextTrackCueList: 0,
TextTrackList: 0,
TouchList: 0
};

for (var NAME in DOMIterables) {
var Collection = global[NAME];
var proto = Collection && Collection.prototype;
var key;
if (proto) {
if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
Iterators[NAME] = ArrayValues;
if (DOMIterables[NAME]) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);
if (DOMIterables[NAME]) for (var key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);
}
}
1 change: 1 addition & 0 deletions tests/tests/index.js
Original file line number Diff line number Diff line change
@@ -217,6 +217,7 @@ import './esnext.weak-set.from';
import './esnext.weak-set.of';

QUnit.module('Web');
import './web.dom.for-each';
import './web.dom.iterable';
import './web.immediate';
import './web.timers';
22 changes: 22 additions & 0 deletions tests/tests/web.dom.for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GLOBAL } from '../helpers/constants';

QUnit.test('forEach method on iterable DOM collections', assert => {
let absent = true;
const collections = [
'NodeList',
'DOMTokenList'
];

for (const name of collections) {
const Collection = GLOBAL[name];
if (Collection) {
absent = false;
assert.isFunction(Collection.prototype.forEach, `${ name }::forEach is a function`);
assert.same(Collection.prototype.forEach, Array.prototype.forEach, `${ name }::forEach is equal of Array::forEach`);
}
}

if (absent) {
assert.ok(true, 'DOM collections are absent');
}
});
9 changes: 6 additions & 3 deletions tests/tests/web.dom.iterable.js
Original file line number Diff line number Diff line change
@@ -59,9 +59,12 @@ QUnit.test('Iterable DOM collections', assert => {
for (const name of collections) {
const Collection = GLOBAL[name];
if (Collection) {
assert.isFunction(Collection.prototype.values, `${ name }::@@values is function`);
assert.isFunction(Collection.prototype.keys, `${ name }::@@keys is function`);
assert.isFunction(Collection.prototype.entries, `${ name }::@@entries is function`);
assert.isFunction(Collection.prototype.values, `${ name }::values is function`);
assert.same(Collection.prototype.values, Array.prototype.values, `${ name }::values is equal of Array::values`);
assert.isFunction(Collection.prototype.keys, `${ name }::keys is function`);
assert.same(Collection.prototype.keys, Array.prototype.keys, `${ name }::keys is equal of Array::keys`);
assert.isFunction(Collection.prototype.entries, `${ name }::entries is function`);
assert.same(Collection.prototype.entries, Array.prototype.entries, `${ name }::entries is equal of Array::entries`);
}
}

1 change: 1 addition & 0 deletions web/dom-collections.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
require('../modules/web.dom.for-each');
require('../modules/web.dom.iterable');
module.exports = require('../modules/_core');
1 change: 1 addition & 0 deletions web/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require('../modules/web.timers');
require('../modules/web.immediate');
require('../modules/web.dom.for-each');
require('../modules/web.dom.iterable');
module.exports = require('../modules/_core');

0 comments on commit c908a46

Please sign in to comment.