Skip to content

Commit

Permalink
Core: Make jQuery objects iterable
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mgol committed Jun 13, 2015
1 parent 9c8a3ec commit bb026fc
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@

/dist
/node_modules

/test/node_smoke_tests/lib/ensure_iterability.js
3 changes: 2 additions & 1 deletion .jscsrc
Original file line number Diff line number Diff line change
@@ -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" ]
}
1 change: 1 addition & 0 deletions .jshintignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 12 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion build/tasks/node_smoke_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 10 additions & 0 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions test/.jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"define": false,
"DOMParser": false,
"Promise": false,
"Symbol": false,
"QUnit": false,
"ok": false,
"equal": false,
Expand Down
8 changes: 8 additions & 0 deletions test/node_smoke_tests/iterable_with_native_symbol.js
Original file line number Diff line number Diff line change
@@ -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" )();
13 changes: 13 additions & 0 deletions test/node_smoke_tests/iterable_with_symbol_polyfill.js
Original file line number Diff line number Diff line change
@@ -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" )();
25 changes: 25 additions & 0 deletions test/node_smoke_tests/lib/ensure_iterability_es6.js
Original file line number Diff line number Diff line change
@@ -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" );

This comment has been minimized.

Copy link
@Krinkle

Krinkle Mar 20, 2017

Member

Typo! Fixed in #3584

} );
};
20 changes: 20 additions & 0 deletions test/unit/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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" );
}
} );

0 comments on commit bb026fc

Please sign in to comment.