diff --git a/Gruntfile.js b/Gruntfile.js index 81c3a2618..5d77e7393 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -77,10 +77,30 @@ var "dist/jquery-ui.min.js" ] }, - component = grunt.option( "component" ) || "**"; + component = grunt.option( "component" ) || "**", + + jscsBad = [ + "ui/button.js", + "ui/datepicker.js", + "ui/draggable.js", + "ui/droppable.js", + "ui/effect.js", + "ui/mouse.js", + "ui/resizable.js", + "ui/selectable.js", + "ui/slider.js", + "ui/sortable.js" + ], + + htmllintBad = [ + "demos/tabs/ajax/content*.html", + "demos/tooltip/ajax/content*.html", + "tests/unit/core/core.html", + "tests/unit/tabs/data/test.html" + ]; function mapMinFile( file ) { - return "dist/" + file.replace( /\.js$/, ".min.js" ).replace( /ui\//, "minified/" ); + return "dist/" + file.replace( /ui\//, "minified/" ); } function expandFiles( files ) { @@ -159,25 +179,54 @@ grunt.initConfig({ dest: "dist/jquery-ui.css" } }, + + // Remove the requireSpacesInsideParentheses override once everything is fixed jscs: { - // datepicker and sortable are getting rewritten, ignore until that's done - ui: [ "ui/*.js", "!ui/datepicker.js", "!ui/sortable.js" ], - // TODO enable this once we have a tool that can auto format files - // tests: "tests/unit/**/*.js", - grunt: [ "Gruntfile.js", "build/tasks/*.js" ] + "ui-good": [ "ui/*.js" ].concat( jscsBad.map( function( file ) { + return "!" + file; + } ) ), + "ui-bad": { + options: { + requireSpacesInsideParentheses: null + }, + src: jscsBad + }, + tests: { + options: { + requireSpacesInsideParentheses: null + }, + src: "tests/unit/**/*.js" + }, + grunt: { + options: { + requireSpacesInsideParentheses: null + }, + src: [ "Gruntfile.js", "build/tasks/*.js" ] + } }, uglify: minify, htmllint: { - // ignore files that contain invalid html, used only for ajax content testing - all: grunt.file.expand( [ "demos/**/*.html", "tests/**/*.html" ] ).filter(function( file ) { - return !/(?:ajax\/content\d\.html|tabs\/data\/test\.html|tests\/unit\/core\/core.*\.html)/.test( file ); - }) + good: [ "demos/**/*.html", "tests/**/*.html" ].concat( htmllintBad.map( function( file ) { + return "!" + file; + } ) ), + bad: { + options: { + ignore: [ + /Start tag seen without seeing a doctype first/, + /Element “head” is missing a required instance of child element “title”/, + /Element “object” is missing one or more of the following/, + /The “codebase” attribute on the “object” element is obsolete/ + ] + }, + src: htmllintBad + } }, qunit: { files: expandFiles( "tests/unit/" + component + "/*.html" ).filter(function( file ) { return !( /(all|index|test)\.html$/ ).test( file ); }), options: { + inject: false, page: { viewportSize: { width: 700, height: 500 } } @@ -191,7 +240,8 @@ grunt.initConfig({ "ui/*.js", "Gruntfile.js", "build/**/*.js", - "tests/unit/**/*.js" + "tests/unit/**/*.js", + "tests/lib/**/*.js" ] }, csslint: { @@ -228,7 +278,19 @@ grunt.initConfig({ files: { "qunit/qunit.js": "qunit/qunit/qunit.js", "qunit/qunit.css": "qunit/qunit/qunit.css", - "qunit/MIT-LICENSE.txt": "qunit/MIT-LICENSE.txt", + "qunit/LICENSE.txt": "qunit/LICENSE.txt", + + "qunit-assert-classes/qunit-assert-classes.js": "qunit-assert-classes/qunit-assert-classes.js", + "qunit-assert-classes/LICENSE.txt": "qunit-assert-classes/LICENSE", + + "qunit-assert-close/qunit-assert-close.js": "qunit-assert-close/qunit-assert-close.js", + "qunit-assert-close/MIT-LICENSE.txt": "qunit-assert-close/MIT-LICENSE.txt", + + "qunit-composite/qunit-composite.js": "qunit-composite/qunit-composite.js", + "qunit-composite/qunit-composite.css": "qunit-composite/qunit-composite.css", + "qunit-composite/LICENSE.txt": "qunit-composite/LICENSE.txt", + + "requirejs/require.js": "requirejs/require.js", "jquery-mousewheel/jquery.mousewheel.js": "jquery-mousewheel/jquery.mousewheel.js", "jquery-mousewheel/LICENSE.txt": "jquery-mousewheel/LICENSE.txt", @@ -239,7 +301,7 @@ grunt.initConfig({ "jshint/jshint.js": "jshint/dist/jshint.js", "jshint/LICENSE": "jshint/LICENSE", - "jquery/jquery.js": "jquery-1.x/jquery.js", + "jquery/jquery.js": "jquery-1.x/dist/jquery.js", "jquery/MIT-LICENSE.txt": "jquery-1.x/MIT-LICENSE.txt", "jquery-1.7.0/jquery.js": "jquery-1.7.0/jquery.js", @@ -278,6 +340,18 @@ grunt.initConfig({ "jquery-1.10.2/jquery.js": "jquery-1.10.2/jquery.js", "jquery-1.10.2/MIT-LICENSE.txt": "jquery-1.10.2/MIT-LICENSE.txt", + "jquery-1.11.0/jquery.js": "jquery-1.11.0/dist/jquery.js", + "jquery-1.11.0/MIT-LICENSE.txt": "jquery-1.11.0/MIT-LICENSE.txt", + + "jquery-1.11.1/jquery.js": "jquery-1.11.1/dist/jquery.js", + "jquery-1.11.1/MIT-LICENSE.txt": "jquery-1.11.1/MIT-LICENSE.txt", + + "jquery-1.11.2/jquery.js": "jquery-1.11.2/dist/jquery.js", + "jquery-1.11.2/MIT-LICENSE.txt": "jquery-1.11.2/MIT-LICENSE.txt", + + "jquery-1.11.3/jquery.js": "jquery-1.11.3/dist/jquery.js", + "jquery-1.11.3/MIT-LICENSE.txt": "jquery-1.11.3/MIT-LICENSE.txt", + "jquery-2.0.0/jquery.js": "jquery-2.0.0/jquery.js", "jquery-2.0.0/MIT-LICENSE.txt": "jquery-2.0.0/MIT-LICENSE.txt", @@ -288,7 +362,19 @@ grunt.initConfig({ "jquery-2.0.2/MIT-LICENSE.txt": "jquery-2.0.2/MIT-LICENSE.txt", "jquery-2.0.3/jquery.js": "jquery-2.0.3/jquery.js", - "jquery-2.0.3/MIT-LICENSE.txt": "jquery-2.0.3/MIT-LICENSE.txt" + "jquery-2.0.3/MIT-LICENSE.txt": "jquery-2.0.3/MIT-LICENSE.txt", + + "jquery-2.1.0/jquery.js": "jquery-2.1.0/dist/jquery.js", + "jquery-2.1.0/MIT-LICENSE.txt": "jquery-2.1.0/MIT-LICENSE.txt", + + "jquery-2.1.1/jquery.js": "jquery-2.1.1/dist/jquery.js", + "jquery-2.1.1/MIT-LICENSE.txt": "jquery-2.1.1/MIT-LICENSE.txt", + + "jquery-2.1.2/jquery.js": "jquery-2.1.2/dist/jquery.js", + "jquery-2.1.2/MIT-LICENSE.txt": "jquery-2.1.2/MIT-LICENSE.txt", + + "jquery-2.1.3/jquery.js": "jquery-2.1.3/dist/jquery.js", + "jquery-2.1.3/MIT-LICENSE.txt": "jquery-2.1.3/MIT-LICENSE.txt" } } }, diff --git a/README.md b/README.md index 998a3f24b..a1727c0c0 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ You can also run the unit tests inside phantomjs by [setting up your environment jQuery UI uses the [Grunt](http://gruntjs.com/) build system. -To build jQuery UI, [setup your environment]([setting up your environment](CONTRIBUTING.md#environment-minimum-required)) and then run the following commands: +To build jQuery UI, [setup your environment](CONTRIBUTING.md#environment-minimum-required) and then run the following commands: ```sh # Run the concat task to concatenate files diff --git a/bower.json b/bower.json index cab4b258e..2c8b5a6ba 100644 --- a/bower.json +++ b/bower.json @@ -14,7 +14,11 @@ "jquery-mousewheel": "3.1.12", "jquery-simulate": "1.0.0", "jshint": "2.4.4", - "qunit": "1.17.1", + "qunit": "1.18.0", + "qunit-assert-classes": "1.0.2", + "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", + "qunit-composite": "JamesMGreene/qunit-composite#v1.1.0", + "requirejs": "2.1.14", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", @@ -28,10 +32,18 @@ "jquery-1.10.0": "jquery#1.10.0", "jquery-1.10.1": "jquery#1.10.1", "jquery-1.10.2": "jquery#1.10.2", - "jquery-1.x": "jquery#1.10.2", + "jquery-1.11.0": "jquery#1.11.0", + "jquery-1.11.1": "jquery#1.11.1", + "jquery-1.11.2": "jquery#1.11.2", + "jquery-1.11.3": "jquery#1.11.3", + "jquery-1.x": "jquery#1.11.3", "jquery-2.0.0": "jquery#2.0.0", "jquery-2.0.1": "jquery#2.0.1", "jquery-2.0.2": "jquery#2.0.2", - "jquery-2.0.3": "jquery#2.0.3" + "jquery-2.0.3": "jquery#2.0.3", + "jquery-2.1.0": "jquery#2.1.0", + "jquery-2.1.1": "jquery#2.1.1", + "jquery-2.1.2": "jquery#2.1.2", + "jquery-2.1.3": "jquery#2.1.3" } } diff --git a/build/release.js b/build/release.js index a55f8002c..ce1425bb0 100644 --- a/build/release.js +++ b/build/release.js @@ -9,7 +9,7 @@ function replaceAtVersion() { var matches = []; function recurse( folder ) { - fs.readdirSync( folder ).forEach(function( fileName ) { + fs.readdirSync( folder ).forEach( function( fileName ) { var content, fullPath = folder + "/" + fileName; if ( fs.statSync( fullPath ).isDirectory() ) { @@ -18,13 +18,13 @@ function replaceAtVersion() { } content = fs.readFileSync( fullPath, { encoding: "utf-8" - }); + } ); if ( !/@VERSION/.test( content ) ) { return; } matches.push( fullPath ); fs.writeFileSync( fullPath, content.replace( /@VERSION/g, Release.newVersion ) ); - }); + } ); } [ "ui", "themes" ].forEach( recurse ); @@ -41,7 +41,7 @@ function buildCDNPackage( callback ) { builder = new downloadBuilder.Builder( jqueryUi, ":all:" ), packer = new downloadBuilder.ThemesPacker( builder, { includeJs: true - }), + } ), target = "../" + jqueryUi.pkg.name + "-" + jqueryUi.pkg.version + "-cdn.zip"; // Zip dir structure must be flat, override default base folder @@ -51,15 +51,15 @@ function buildCDNPackage( callback ) { Release.abort( "Failed to zip CDN package", error ); } callback(); - }); + } ); } -Release.define({ +Release.define( { issueTracker: "trac", contributorReportId: 22, changelogShell: function() { var monthNames = [ "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December" ], + "August", "September", "October", "November", "December" ], now = new Date(); return "\n\nReleased on " + monthNames[ now.getMonth() ] + " " + now.getDate() + ", " + now.getFullYear() + "\n\n"; @@ -67,14 +67,14 @@ Release.define({ generateArtifacts: function( fn ) { var files = replaceAtVersion(); - buildCDNPackage(function copyCdnFiles() { + buildCDNPackage( function copyCdnFiles() { var zipFile = shell.ls( "../jquery*-cdn.zip" )[ 0 ], tmpFolder = "../tmp-zip-output", unzipCommand = "unzip -o " + zipFile + " -d " + tmpFolder; console.log( "Unzipping for dist/cdn copies" ); shell.mkdir( "-p", tmpFolder ); - Release.exec({ + Release.exec( { command: unzipCommand, silent: true }, "Failed to unzip cdn files" ); @@ -83,9 +83,9 @@ Release.define({ shell.cp( tmpFolder + "/jquery-ui*.js", "dist/cdn" ); shell.cp( "-r", tmpFolder + "/themes", "dist/cdn" ); fn( files ); - }); + } ); } -}); +} ); }; diff --git a/build/tasks/build.js b/build/tasks/build.js index 13e6fad14..77ae2545d 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -4,12 +4,12 @@ module.exports = function( grunt ) { grunt.registerTask( "clean", function() { require( "rimraf" ).sync( "dist" ); -}); +} ); grunt.registerTask( "asciilint", function() { var valid = true, - files = grunt.file.expand({ filter: "isFile" }, "ui/*.js" ); - files.forEach(function( filename ) { + files = grunt.file.expand( { filter: "isFile" }, "ui/*.js" ); + files.forEach( function( filename ) { var i, c, text = grunt.file.read( filename ); @@ -32,11 +32,11 @@ grunt.registerTask( "asciilint", function() { } valid = false; } - }); + } ); if ( valid ) { grunt.log.ok( files.length + " files lint free." ); } return valid; -}); +} ); }; diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js index 957153777..b889c6c36 100644 --- a/build/tasks/testswarm.js +++ b/build/tasks/testswarm.js @@ -3,8 +3,9 @@ module.exports = function( grunt ) { "use strict"; var versions = { - "git": "git", - "1.10": "1.10.0 1.10.1 1.10.2", + "compat-git": "compat-git", + "1.11": "1.11.0 1.11.1 1.11.2 1.11.3", + "1.10": "1.10.0 1.10.2", "1.9": "1.9.0 1.9.1", "1.8": "1.8.0 1.8.1 1.8.2 1.8.3", "1.7": "1.7.0 1.7.1 1.7.2" @@ -48,26 +49,26 @@ function submit( commit, runs, configFile, extra, done ) { runs[ testName ] = config.testUrl + commit + "/tests/unit/" + runs[ testName ]; } - testswarm.createClient({ + testswarm.createClient( { url: config.swarmUrl - }) - .addReporter( testswarm.reporters.cli ) - .auth({ - id: config.authUsername, - token: config.authToken - }) - .addjob({ - name: "Commit " + commit.substr( 0, 10 ) + "" + extra, - runs: runs, - runMax: config.runMax, - browserSets: [ "popular-ui" ], - timeout: 1000 * 60 * 30 - }, function( error, passed ) { - if ( error ) { - grunt.log.error( error ); - } - done( passed ); - }); + } ) + .addReporter( testswarm.reporters.cli ) + .auth( { + id: config.authUsername, + token: config.authToken + } ) + .addjob( { + name: "Commit " + commit.substr( 0, 10 ) + "" + extra, + runs: runs, + runMax: config.runMax, + browserSets: config.browserSets, + timeout: 1000 * 60 * 30 + }, function( error, passed ) { + if ( error ) { + grunt.log.error( error ); + } + done( passed ); + } ); } grunt.registerTask( "testswarm", function( commit, configFile ) { @@ -77,16 +78,16 @@ grunt.registerTask( "testswarm", function( commit, configFile ) { latestTests[ test ] = tests[ test ] + "?nojshint=true"; } submit( commit, latestTests, configFile, "", this.async() ); -}); +} ); grunt.registerTask( "testswarm-multi-jquery", function( commit, configFile, minor ) { var allTests = {}; - versions[ minor ].split(" ").forEach(function( version ) { + versions[ minor ].split( " " ).forEach( function( version ) { for ( var test in tests ) { allTests[ test + "-" + version ] = tests[ test ] + "?nojshint=true&jquery=" + version; } - }); + } ); submit( commit, allTests, configFile, "core " + minor, this.async() ); -}); +} ); }; diff --git a/demos/accordion/custom-icons.html b/demos/accordion/custom-icons.html index 91ca4543a..9d43c3c8b 100644 --- a/demos/accordion/custom-icons.html +++ b/demos/accordion/custom-icons.html @@ -19,7 +19,7 @@ $( "#accordion" ).accordion({ icons: icons }); - $( "#toggle" ).button().click(function() { + $( "#toggle" ).button().on( "click", function() { if ( $( "#accordion" ).accordion( "option", "icons" ) ) { $( "#accordion" ).accordion( "option", "icons", null ); } else { diff --git a/demos/accordion/hoverintent.html b/demos/accordion/hoverintent.html index dce8a8f0c..ad15721f3 100644 --- a/demos/accordion/hoverintent.html +++ b/demos/accordion/hoverintent.html @@ -23,10 +23,10 @@ */ $.event.special.hoverintent = { setup: function() { - $( this ).bind( "mouseover", jQuery.event.special.hoverintent.handler ); + $( this ).on( "mouseover", jQuery.event.special.hoverintent.handler ); }, teardown: function() { - $( this ).unbind( "mouseover", jQuery.event.special.hoverintent.handler ); + $( this ).off( "mouseover", jQuery.event.special.hoverintent.handler ); }, handler: function( event ) { var currentX, currentY, timeout, @@ -42,8 +42,8 @@ function clear() { target - .unbind( "mousemove", track ) - .unbind( "mouseout", clear ); + .off( "mousemove", track ) + .off( "mouseout", clear ); clearTimeout( timeout ); } @@ -75,7 +75,7 @@ } timeout = setTimeout( handler, 100 ); - target.bind({ + target.on({ mousemove: track, mouseout: clear }); diff --git a/demos/autocomplete/combobox.html b/demos/autocomplete/combobox.html index 437e52ab1..76d792470 100644 --- a/demos/autocomplete/combobox.html +++ b/demos/autocomplete/combobox.html @@ -58,7 +58,9 @@ source: $.proxy( this, "_source" ) }) .tooltip({ - tooltipClass: "ui-state-highlight" + classes: { + "ui-tooltip": "ui-state-highlight" + } }); this._on( this.input, { @@ -90,11 +92,11 @@ }) .removeClass( "ui-corner-all" ) .addClass( "custom-combobox-toggle ui-corner-right" ) - .mousedown(function() { + .on( "mousedown", function() { wasOpen = input.autocomplete( "widget" ).is( ":visible" ); }) - .click(function() { - input.focus(); + .on( "click", function() { + input.trigger( "focus" ); // Close if already visible if ( wasOpen ) { @@ -163,7 +165,7 @@ $(function() { $( "#combobox" ).combobox(); - $( "#toggle" ).click(function() { + $( "#toggle" ).on( "click", function() { $( "#combobox" ).toggle(); }); }); diff --git a/demos/autocomplete/multiple-remote.html b/demos/autocomplete/multiple-remote.html index 72c001754..45f319865 100644 --- a/demos/autocomplete/multiple-remote.html +++ b/demos/autocomplete/multiple-remote.html @@ -27,7 +27,7 @@ $( "#birds" ) // don't navigate away from the field on tab when selecting an item - .bind( "keydown", function( event ) { + .on( "keydown", function( event ) { if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) { event.preventDefault(); diff --git a/demos/autocomplete/multiple.html b/demos/autocomplete/multiple.html index 63d379067..1bd70f228 100644 --- a/demos/autocomplete/multiple.html +++ b/demos/autocomplete/multiple.html @@ -46,7 +46,7 @@ $( "#tags" ) // don't navigate away from the field on tab when selecting an item - .bind( "keydown", function( event ) { + .on( "keydown", function( event ) { if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) { event.preventDefault(); diff --git a/demos/autocomplete/remote-jsonp.html b/demos/autocomplete/remote-jsonp.html index 84c6957e0..0d71dae9a 100644 --- a/demos/autocomplete/remote-jsonp.html +++ b/demos/autocomplete/remote-jsonp.html @@ -26,39 +26,33 @@ $( "#city" ).autocomplete({ source: function( request, response ) { - $.ajax({ + $.ajax( { url: "http://gd.geobytes.com/AutoCompleteCity", dataType: "jsonp", data: { q: request.term }, success: function( data ) { - response( data ); + + // Handle 'no match' indicated by [ "" ] response + response( data.length === 1 && data[ 0 ].length === 0 ? [] : data ); } - }); + } ); }, minLength: 3, select: function( event, ui ) { - log( ui.item ? - "Selected: " + ui.item.label : - "Nothing selected, input was " + this.value); - }, - open: function() { - $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" ); - }, - close: function() { - $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" ); + log( "Selected: " + ui.item.label ); } - }); - }); + } ); + } );
The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are cities, displayed when at least two characters are entered into the field.
-In this case, the datasource is the geonames.org webservice. While only the city name itself ends up in the input after selecting an element, more info is displayed in the suggestions to help find the right entry. That data is also available in callbacks, as illustrated by the Result area below the input.
+The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are cities, displayed when at least three characters are entered into the field. The datasource is the geobytes.com webservice. That data is also available in callbacks, as illustrated by the Result area below the input.