]> source.dussan.org Git - jquery.git/commitdiff
Core: Make jQuery objects iterable 2369/head
authorMichał Gołębiowski <m.goleb@gmail.com>
Mon, 1 Jun 2015 21:25:38 +0000 (23:25 +0200)
committerMichał Gołębiowski <m.goleb@gmail.com>
Sat, 13 Jun 2015 21:14:36 +0000 (23:14 +0200)
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

12 files changed:
.gitignore
.jscsrc
.jshintignore
Gruntfile.js
build/tasks/node_smoke_tests.js
package.json
src/core.js
test/.jshintrc
test/node_smoke_tests/iterable_with_native_symbol.js [new file with mode: 0644]
test/node_smoke_tests/iterable_with_symbol_polyfill.js [new file with mode: 0644]
test/node_smoke_tests/lib/ensure_iterability_es6.js [new file with mode: 0644]
test/unit/core.js

index 463dea426864dc850993402a7fea140736795a60..eae5df6e6cf9b6a6bc99c00a2869c61e92149b6a 100644 (file)
@@ -10,3 +10,5 @@
 
 /dist
 /node_modules
+
+/test/node_smoke_tests/lib/ensure_iterability.js
diff --git a/.jscsrc b/.jscsrc
index fa91a9d9e59354246fa0e0dba3e89a4517a397cb..14f3491337c3d39bd88b67f370b4294bbc643bf2 100644 (file)
--- 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" ]
 }
index 19f1b9c52320ceafe82100974a51d94f09e2ffe1..1ddafd635a18124198ef31a421424fb88b460b24 100644 (file)
@@ -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
index d22807bf480287f2b0ef3ba38be8e0249141ecc9..0bf20d45423f0a3498d2ae51355302341e97dba0 100644 (file)
@@ -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",
index 5c23dae2ba97a7e9ecb134e0927668279fdba7da..9334516d9ec516c3ba3d0c5347a27bba1f520ab0 100644 (file)
@@ -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
index c0ee7028110f08a301459ac58cb53ec24808f912..5d82995343ce76ee3a4da0b5de385bcafa4af7eb 100644 (file)
@@ -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",
index 88b9a3c5d86f812d546b295734bc068e10692edb..ba6eeceb8f7a73381459d89ab1b1ec19b7a31891 100644 (file)
@@ -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) {
index b55594f4f848dc0f342bb8d5ac98f2b6091b826c..7aef665c68b4c3c495075f9e8bcfab02b04cbfae 100644 (file)
@@ -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 (file)
index 0000000..3376ebd
--- /dev/null
@@ -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 (file)
index 0000000..dd377f1
--- /dev/null
@@ -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 (file)
index 0000000..ebe6853
--- /dev/null
@@ -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" );
+       } );
+};
index 0a018dea4eba1d43b4f80718bfa8b84494b3b383..d8370637bb1b690505343cbe96856b466a93e09f 100644 (file)
@@ -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" );
+       }
+} );