aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Gołębiowski <m.goleb@gmail.com>2015-06-01 23:25:38 +0200
committerMichał Gołębiowski <m.goleb@gmail.com>2015-06-13 23:14:36 +0200
commitbb026fc12c3c2ad37f47f0919e484bddcdc3d291 (patch)
tree7ba8975dcfd6c912f8ecb71761648ad4a38efe9b
parent9c8a3ecdc46156afd8f93aa44b6e6aea7c52c049 (diff)
downloadjquery-bb026fc12c3c2ad37f47f0919e484bddcdc3d291.tar.gz
jquery-bb026fc12c3c2ad37f47f0919e484bddcdc3d291.zip
Core: Make jQuery objects iterable
Make iterating over jQuery objects possible using ES 2015 for-of: for ( node of $( "<div id=narwhal>" ) ) { console.log( node.id ); // "narwhal" } Fixes gh-1693
-rw-r--r--.gitignore2
-rw-r--r--.jscsrc3
-rw-r--r--.jshintignore1
-rw-r--r--Gruntfile.js12
-rw-r--r--build/tasks/node_smoke_tests.js2
-rw-r--r--package.json2
-rw-r--r--src/core.js10
-rw-r--r--test/.jshintrc1
-rw-r--r--test/node_smoke_tests/iterable_with_native_symbol.js8
-rw-r--r--test/node_smoke_tests/iterable_with_symbol_polyfill.js13
-rw-r--r--test/node_smoke_tests/lib/ensure_iterability_es6.js25
-rw-r--r--test/unit/core.js20
12 files changed, 97 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 463dea426..eae5df6e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@
/dist
/node_modules
+
+/test/node_smoke_tests/lib/ensure_iterability.js
diff --git a/.jscsrc b/.jscsrc
index fa91a9d9e..14f349133 100644
--- a/.jscsrc
+++ b/.jscsrc
@@ -1,5 +1,6 @@
{
"preset": "jquery",
- "excludeFiles": [ "external", "src/intro.js", "src/outro.js" ]
+ "excludeFiles": [ "external", "src/intro.js", "src/outro.js",
+ "test/node_smoke_tests/lib/ensure_iterability.js" ]
}
diff --git a/.jshintignore b/.jshintignore
index 19f1b9c52..1ddafd635 100644
--- a/.jshintignore
+++ b/.jshintignore
@@ -9,3 +9,4 @@ test/data/readywaitasset.js
test/data/readywaitloader.js
test/data/support/csp.js
test/data/support/getComputedSupport.js
+test/node_smoke_tests/lib/ensure_iterability.js
diff --git a/Gruntfile.js b/Gruntfile.js
index d22807bf4..0bf20d454 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -30,6 +30,18 @@ module.exports = function( grunt ) {
cache: "build/.sizecache.json"
}
},
+ babel: {
+ options: {
+ sourceMap: "inline",
+ retainLines: true
+ },
+ nodeSmokeTests: {
+ files: {
+ "test/node_smoke_tests/lib/ensure_iterability.js":
+ "test/node_smoke_tests/lib/ensure_iterability_es6.js"
+ }
+ }
+ },
build: {
all: {
dest: "dist/jquery.js",
diff --git a/build/tasks/node_smoke_tests.js b/build/tasks/node_smoke_tests.js
index 5c23dae2b..9334516d9 100644
--- a/build/tasks/node_smoke_tests.js
+++ b/build/tasks/node_smoke_tests.js
@@ -5,7 +5,7 @@ module.exports = function( grunt ) {
var fs = require( "fs" ),
spawnTest = require( "./lib/spawn_test.js" ),
testsDir = "./test/node_smoke_tests/",
- nodeSmokeTests = [ "jsdom" ];
+ nodeSmokeTests = [ "jsdom", "babel:nodeSmokeTests" ];
// Fire up all tests defined in test/node_smoke_tests/*.js in spawned sub-processes.
// All the files under test/node_smoke_tests/*.js are supposed to exit with 0 code
diff --git a/package.json b/package.json
index c0ee70281..5d8299534 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,9 @@
"dependencies": {},
"devDependencies": {
"commitplease": "2.0.0",
+ "core-js": "0.9.17",
"grunt": "0.4.5",
+ "grunt-babel": "5.0.1",
"grunt-cli": "0.1.13",
"grunt-compare-size": "0.4.0",
"grunt-contrib-jshint": "0.11.2",
diff --git a/src/core.js b/src/core.js
index 88b9a3c5d..ba6eeceb8 100644
--- a/src/core.js
+++ b/src/core.js
@@ -425,6 +425,16 @@ jQuery.extend({
support: support
});
+// JSHint would error on this code due to the Symbol not being defined in ES5.
+// Defining this global in .jshintrc would create a danger of using the global
+// unguarded in another place, it seems safer to just disable JSHint for these
+// three lines.
+/* jshint ignore: start */
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+/* jshint ignore: end */
+
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),
function(i, name) {
diff --git a/test/.jshintrc b/test/.jshintrc
index b55594f4f..7aef665c6 100644
--- a/test/.jshintrc
+++ b/test/.jshintrc
@@ -22,6 +22,7 @@
"define": false,
"DOMParser": false,
"Promise": false,
+ "Symbol": false,
"QUnit": false,
"ok": false,
"equal": false,
diff --git a/test/node_smoke_tests/iterable_with_native_symbol.js b/test/node_smoke_tests/iterable_with_native_symbol.js
new file mode 100644
index 000000000..3376ebdc5
--- /dev/null
+++ b/test/node_smoke_tests/iterable_with_native_symbol.js
@@ -0,0 +1,8 @@
+"use strict";
+
+if ( typeof Symbol === "undefined" ) {
+ console.log( "Symbols not supported, skipping the test..." );
+ process.exit();
+}
+
+require( "./lib/ensure_iterability_es6" )();
diff --git a/test/node_smoke_tests/iterable_with_symbol_polyfill.js b/test/node_smoke_tests/iterable_with_symbol_polyfill.js
new file mode 100644
index 000000000..dd377f19c
--- /dev/null
+++ b/test/node_smoke_tests/iterable_with_symbol_polyfill.js
@@ -0,0 +1,13 @@
+/* jshint esnext: true */
+
+"use strict";
+
+var assert = require( "assert" );
+
+delete global.Symbol;
+require( "core-js" );
+
+assert.strictEqual( typeof Symbol, "function", "Expected Symbol to be a function" );
+assert.notEqual( typeof Symbol.iterator, "symbol", "Expected Symbol.iterator to be polyfilled" );
+
+require( "./lib/ensure_iterability" )();
diff --git a/test/node_smoke_tests/lib/ensure_iterability_es6.js b/test/node_smoke_tests/lib/ensure_iterability_es6.js
new file mode 100644
index 000000000..ebe68539e
--- /dev/null
+++ b/test/node_smoke_tests/lib/ensure_iterability_es6.js
@@ -0,0 +1,25 @@
+/* jshint esnext: true */
+
+"use strict";
+
+var assert = require( "assert" );
+
+module.exports = function ensureIterability() {
+ require( "jsdom" ).env( "", function( errors, window ) {
+ assert.ifError( errors );
+
+ var i,
+ ensureJQuery = require( "./ensure_jquery" ),
+ jQuery = require( "../../../dist/jquery.js" )( window ),
+ elem = jQuery( "<div></div><span></span><a></a>" ),
+ result = "";
+
+ ensureJQuery( jQuery );
+
+ for ( i of elem ) {
+ result += i.nodeName;
+ }
+
+ assert.strictEqual( result, "DIVSPANA", "for-of doesn't work on jQuery objects" );
+ } );
+};
diff --git a/test/unit/core.js b/test/unit/core.js
index 0a018dea4..d8370637b 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -1538,3 +1538,23 @@ testIframeWithCallback( "Don't call window.onready (#14802)", "core/onready.html
equal( error, false, "no call to user-defined onready" );
}
);
+
+test( "Iterability of jQuery objects (gh-1693)", function() {
+ /* jshint unused: false */
+ expect( 1 );
+
+ var i, elem, result;
+
+ if ( typeof Symbol === "function" ) {
+
+ elem = jQuery( "<div></div><span></span><a></a>" );
+ result = "";
+
+ try {
+ eval( "for ( i of elem ) { result += i.nodeName; }" );
+ } catch ( e ) {}
+ equal( result, "DIVSPANA", "for-of works on jQuery objects" );
+ } else {
+ ok( true, "The browser doesn't support Symbols" );
+ }
+} );