diff --git a/.csslintrc b/.csslintrc new file mode 100644 index 000000000..5d9db072c --- /dev/null +++ b/.csslintrc @@ -0,0 +1,11 @@ +{ + "adjoining-classes": false, + "box-model": false, + "compatible-vendor-prefixes": false, + "duplicate-background-images": false, + "import": false, + "important": false, + "outline-none": false, + "overqualified-elements": false, + "text-indent": false +} diff --git a/.gitignore b/.gitignore index 23d9dd000..a8b8bc7ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,3 @@ dist node_modules -docs -.project -*~ -*.diff -*.patch -.DS_Store -.settings +.sizecache.json \ No newline at end of file diff --git a/.jscs.json b/.jscs.json new file mode 100644 index 000000000..f5387e9af --- /dev/null +++ b/.jscs.json @@ -0,0 +1,3 @@ +{ + "preset": "jquery" +} diff --git a/.jshintrc b/.jshintrc index d6966c51d..d34c42da5 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,12 +1,17 @@ { + "boss": true, "curly": true, - "eqnull": true, "eqeqeq": true, + "eqnull": true, "expr": true, + "immed": true, "noarg": true, - "node": true, "onevar": true, + "quotmark": "double", + "smarttabs": true, "trailing": true, "undef": true, - "unused": true + "unused": true, + + "node": true } diff --git a/.mailmap b/.mailmap index e130cc4bb..e0dd92c78 100644 --- a/.mailmap +++ b/.mailmap @@ -1,6 +1,114 @@ +Aaron Peterson +Adam Baratz +Adam Sontag +Alexander Polomoshnov +Aliaksandr Rahalevich +Andrew Couch +Andrew Newcomb +Andrew Powell +Andrew Powell +Andrey Kapitcyn +Ben Hollis +Benjamin Scott Boyle +Bert ter Heide +Bjørn Johansen +Chairat Sunthornwiphat +Christoph Rönsch +Corey Frang +Courtland Allen +Dan Streetman +Danny Trunk +David De Sloovere +David Murdoch +Diego Tres +Dominique Vincent +Doug Blood +Douglas Cerna +Douglas Neiner +Douglas Neiner +Dylan Just +Eddie Monge +Edward A Faulkner +Eric Hynds +Ethan Romba +EungJun Yi +Eyal Kobrigo +Filippo Cavallarin +Florian Gutmann +Genie <386@mail.com> +Guntupalli Karunakar +Heiko Henning +Hiroshi Tomita +Ian Simpson +Igor Milla +Israel Tsadok +Jacek Jędrzejewski +Jamie Gegerson +Jason Oster +Jay Merrifield +Jean-Francois Remy +Jyoti Deka +John Enters +Jonathan Vingiano +Josh Varner +Justin Domnitz +Justin MacCarthy +Jörn Zaefferer +Karl Kirch +Keith Wood +Kevin Dalman +Klaus Hartl +Klaus Hartl Kris Borchers Kris Borchers -Corey Frang -Maggie Costello Wachs maggiewachs +Krzysztof Rosiński +Lev Kitsis +Maciej Mroziński +Maggie Wachs +Maggie Wachs +Marc Neuwirth +Marcos Sousa +Martin Frost +Mathias Stenbom +Matt Hoskins +Matthew Edward Hutton +Max Schnur +Michael Hollis +Michael Stay +Michael Wu +Mike Alsup +Milan Broum +Mohamed Cherif Bouchelaghem +Monika Piotrowicz +Nick Pierpoint +Ondrej Novy +Paul Bakaus +Paul Irish +Pavol Hluchý +Peter Heiberg +Petr Hromadko +Phillip Barnes +Pierre-Henri Ausseil +Raymond Schwartz Richard Worth -Jörn Zaefferer +Rick Waldron +Ryan Neufeld +Ryan Olton +Saji Nediyanchath Saji +Scott Jehl +Sebastian Sauer +Sergey Kartashov +Shahyar Ghobadpour +Shane Whittet +Shannon Pekary +Simon Sattes +Stojce Slavkovski +Tarafder Ashek-E-Elahi +Thibault Duplessis +Thomas Jaggi +Ting Kuei +Todd Parker +Wesley Walser +Xavi Ramirez +Yuriy Khabarov <13real008@gmail.com> +Ziling Zhao diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..60bbd484c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.8" +before_script: + - npm install -g grunt-cli \ No newline at end of file diff --git a/AUTHORS.txt b/AUTHORS.txt index 2a7a396c8..01f77d5c7 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,20 +1,20 @@ Authors ordered by first contribution A list of current team members is available at http://jqueryui.com/about -Paul Bakaus +Paul Bakaus Richard Worth Yehuda Katz Sean Catchpole John Resig Tane Piper Dmitri Gaskin -Klaus Hartl +Klaus Hartl Stefan Petre Gilles van den Hoven Micheil Bryan Smith Jörn Zaefferer Marc Grabanski -Keith Wood +Keith Wood Brandon Aaron Scott González Eduardo Lundgren @@ -27,12 +27,12 @@ David Bolter Chi Cheng Ca-Phun Ung Ariel Flesler -Maggie Costello Wachs +Maggie Wachs Scott Jehl -Todd Parker -Andrew Powell +Todd Parker +Andrew Powell Brant Burnett -Douglas Neiner +Douglas Neiner Paul Irish Ralph Whitbeck Thibault Duplessis @@ -79,16 +79,16 @@ Phillip Barnes Kyle Wilkinson Khaled AlHourani Marian Rudzynski -Jean-Francois Remy -Doug Blood +Jean-Francois Remy +Doug Blood Filippo Cavallarin -Heiko Henning +Heiko Henning Aliaksandr Rahalevich Mario Visic Xavi Ramirez Max Schnur Saji Nediyanchath -Corey Frang +Corey Frang Aaron Peterson Ivan Peters Mohamed Cherif Bouchelaghem @@ -106,7 +106,7 @@ Adam Parod Guillaume Gautreau Marcel Toele Dan Streetman -Matt Hoskins +Matt Hoskins Giovanni Giacobbi Kyle Florence Pavol Hluchý @@ -124,7 +124,7 @@ Israel Tsadok Carson McDonald Jason Davies Garrison Locke -David Murdoch +David Murdoch Benjamin Scott Boyle Jesse Baird Jonathan Vingiano @@ -150,11 +150,10 @@ Marwan Al Jubeh Milan Broum Sebastian Sauer Gaëtan Muller -Michel Weimerskirch William Griffiths Stojce Slavkovski David Soms -David De Sloovere +David De Sloovere Michael P. Jung Shannon Pekary Matthew Edward Hutton @@ -168,12 +167,12 @@ Genie <386@mail.com> Rick Waldron Ian Simpson Lev Kitsis -Ted VanToll +TJ VanToll Justin Domnitz Douglas Cerna Bert ter Heide Jasvir Nagra -Petr Hromadko +Yuriy Khabarov <13real008@gmail.com> Harri Kilpiö Lado Lomidze Amir E. Aharoni @@ -198,7 +197,7 @@ Lee Rowlands Timmy Willison Karl Swedberg Baoju Yuan -Maciej Mroziński +Maciej Mroziński Luis Dalmolin Mark Aaron Shirley Martin Hoch @@ -216,8 +215,8 @@ Marc-Andre Lafortune Nate Eagle David Souther Mathias Stenbom -Avinash R Sergey Kartashov +Avinash R Ethan Romba Cory Gackenheimer Juan Pablo Kaniefsky @@ -226,13 +225,41 @@ Anika Henke Samuel Bovée Fabrício Matté Viktor Kojouharov -Pawel Maruszczyk +Pawel Maruszczyk (http://hrabstwo.net) Pavel Selitskas -Bjørn Johansen +Bjørn Johansen Matthieu Penant Dominic Barnes David Sullivan -Thomas Jaggi +Thomas Jaggi Vahid Sohrabloo Travis Carden Bruno M. Custódio +Nathanael Silverman +Christian Wenz +Steve Urmston +Zaven Muradyan +Woody Gilk +Zbigniew Motyka +Suhail Alkowaileet +Toshi MARUYAMA +David Hansen +Brian Grinstead +Christian Klammer +Steven Luscher +Gan Eng Chin +Gabriel Schulhof +Alexander Schmitz +Vilhjálmur Skúlason +Siebrand Mazeland +Mohsen Ekhtiari +Pere Orga +Jasper de Groot +Stephane Deschamps +Jyoti Deka +Andrei Picus +Ondrej Novy +Jacob McCutcheon +Monika Piotrowicz +Imants Horsts +Eric Dahl diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7b92529f4..1be96bf17 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,89 +1,36 @@ # Contributing to jQuery UI -1. [Getting Involved](#getting-involved) -2. [Discussion](#discussion) -3. [How To Report Bugs](#how-to-report-bugs) -4. [jQuery UI Coding Standards](#jquery-ui-coding-standards) -5. [Tips For Bug Patching](#tips-for-bug-patching) +Welcome! Thanks for your interest in contributing to jQuery UI. Most of our information on how to contribute to this and all other jQuery Foundation projects is over at [contribute.jquery.org](http://contribute.jquery.org). You'll definitely want to take a look at the articles on contributing [code](http://contribute.jquery.org/code). +You may also want to take a look at our [commit & pull request guide](http://contribute.jquery.org/commits-and-pull-requests/) and [style guides](http://contribute.jquery.org/style-guide/) for instructions on how to maintain your fork and submit your code. Before we can merge any pull request, we'll also need you to sign our [contributor license agreement](http://contribute.jquery.org/cla). +You can find us on [IRC](http://irc.jquery.org), specifically in #jqueryui-dev should you have any questions. If you've never contributed to open source before, we've put together [a short guide with tips, tricks, and ideas on getting started](http://contribute.jquery.org/open-source/). For other forms of discussion and support, please see the [jQuery UI support center](http://jqueryui.com/support/). ## Getting Involved There are a number of ways to get involved with the development of jQuery UI. Even if you've never contributed code to an Open Source project before, we're always looking for help identifying bugs, writing and reducing test cases and documentation. -This is the best way to contribute to jQuery UI. Please read through the full guide detailing [How to Report Bugs](#how-to-report-bugs). +This is the best way to contribute to jQuery UI. Please read through the full guide detailing [How to Report Bugs](http://contribute.jquery.org/bug-reports/). -## Discussion +### Weekly Meetings -### Forum and IRC - -The jQuery UI development team frequently tracks posts on the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui). If you have longer posts or questions please feel free to post them there. If you think you've found a bug please [file it in the bug tracker](#how-to-report-bugs). - -Additionally most of the jQuery UI development team can be found in the [#jqueryui-dev](http://webchat.freenode.net/?channels=jqueryui-dev) IRC channel on irc.freenode.net. - -### Weekly Status Meetings - -Every week (unless otherwise noted) the jQuery UI dev team has a meeting to discuss the progress of current work and to bring forward possible new blocker bugs for discussion. - -The meeting is held in the [#jquery-meeting](http://webchat.freenode.net/?channels=jquery-meeting) IRC channel on irc.freenode.net at [Noon EST](http://www.timeanddate.com/worldclock/fixedtime.html?month=1&day=17&year=2011&hour=12&min=0&sec=0&p1=43) on Wednesdays. - -Past Meeting Notes: -[2008 - 2011](https://docs.google.com/spreadsheet/ccc?key=0AusvKVL7jmFUcHVBQk9tMUxkRGl0emVwZGdLd0QtUlE), -[2012 - current](https://docs.google.com/spreadsheet/ccc?key=0ArIM4UVbwE-3dFg1T0k4VlE1bF82Nm9tbW90cVNxN0E) - - -## How to Report Bugs - -### Make sure it is a jQuery UI bug - -Many bugs reported to our bug tracker are actually bugs in user code, not in jQuery UI code. Keep in mind that just because your code throws an error and the console points to a line number inside of jQuery or jQuery UI, this does *not* mean the bug is a jQuery UI bug. - -If you are new to jQuery and/or jQuery UI, it is usually a much better idea to ask for help first in the [Using jQuery Forum](http://forum.jquery.com/using-jquery), the [Using jQuery UI Forum](http://forum.jquery.com/using-jquery-ui) or the [jQuery IRC channel](http://webchat.freenode.net/?channels=%23jquery). You will get much quicker support, and you will help avoid tying up the jQuery UI team with invalid bug reports. These same resources can also be useful if you want to confirm that your bug is indeed a bug in jQuery UI before filing any tickets. - - -### Disable any browser extensions - -Make sure you have reproduced the bug with all browser extensions and add-ons disabled, as these can sometimes cause things to break in interesting and unpredictable ways. Try using incognito, stealth or anonymous browsing modes. - - -### Try the latest version of jQuery UI - -Bugs in old versions of jQuery UI may have already been fixed. In order to avoid reporting known issues, make sure you are always testing against the latest stable release. - -### Try an older version of jQuery UI - -Sometimes, bugs are introduced in newer versions of jQuery UI that do not exist in previous versions. When possible, it can be useful to try testing with an older release. - -### Reduce, reduce, reduce! - -When you are experiencing a problem, the most useful thing you can possibly do is to [reduce your code](http://webkit.org/quality/reduction.html) to the bare minimum required to reproduce the issue. This makes it *much* easier to isolate and fix the offending code. Bugs that are reported without reduced test cases generally take much longer to fix than bugs that are submitted with them, so you really should try to do this if at all possible. - -## jQuery UI Coding Standards - -See: [jQuery UI Coding Standards](http://wiki.jqueryui.com/w/page/12137737/Coding%20standards) +Every week (unless otherwise noted) the jQuery UI team has a meeting to discuss the progress of current work and to bring forward possible new blockers for discussion. The meeting is held on [IRC](http://irc.jquery.org) in the #jquery-meeting channel at [Noon EST](http://www.timeanddate.com/worldclock/fixedtime.html?month=1&day=17&year=2011&hour=12&min=0&sec=0&p1=43) on Wednesdays. Meeting notes are posted on http://meetings.jquery.org/category/ui/ after each meeting. ## Tips For Bug Patching +### Environment: localhost w/ PHP, Node.js & Grunt -### Environment: localhost w/ PHP, Node & Grunt - -jQuery UI uses node & gruntjs to automate the building and validation of source code. +jQuery UI uses Node.js & Grunt to automate the building and validation of source code. Some tests depend on PHP running locally, so make sure you have the following installed: -* Some kind of localhost server program that supports PHP (any will do) -* Node.js -* NPM (comes with the latest version of Node.js) -* Grunt (install with: `npm install grunt -g` - - -Maintaining a list of platform specific instructions is outside of the scope of this document and there is plenty of existing documentation for the above technologies. - +* A web server with PHP support (any will do, such as [XAMPP](http://www.apachefriends.org/en/xampp.html) or [MAMP](http://www.mamp.info/en/index.html)) +* [Node.js](http://nodejs.org/) (includes NPM, necessary for the next step) +* Grunt (install with: `npm install -g grunt` ### Build a Local Copy of jQuery UI -Create a fork of the jQuery UI repo on github at http://github.com/jquery/jquery-ui +Create a fork of the jQuery UI repo on GitHub at http://github.com/jquery/jquery-ui. Change directory to your web root directory, whatever that might be: @@ -91,115 +38,46 @@ Change directory to your web root directory, whatever that might be: $ cd /path/to/your/www/root/ ``` -Clone your jQuery UI fork to work locally +Clone your jQuery UI fork to work locally. + +*Note: be sure to replace `[USERNAME]` with your GitHub username.* ```bash -$ git clone git@github.com:username/jquery-ui.git +$ git clone git@github.com:[USERNAME]/jquery-ui.git ``` -Change directory to the newly created dir jquery-ui/ +Change to the newly created directory. ```bash $ cd jquery-ui ``` -Add the jQuery master as a remote. I label mine "upstream" +Add the official jQuery repository as a remote. We recommend naming it "upstream". ```bash $ git remote add upstream git://github.com/jquery/jquery-ui.git ``` -Get in the habit of pulling in the "upstream" master to stay up to date as jQuery UI receives new commits +Get in the habit of pulling in the "upstream" master to stay up to date as jQuery UI receives new commits. ```bash $ git pull upstream master ``` +Install the dependencies. + +```bash +npm install +``` + To lint the JavaScript, HTML, and CSS, as well as run a smoke test in PhantomJS, run grunt: ```bash $ grunt ``` -To run the tests for a specific plugin in your browser, open the approriate file from the /tests/unit/ directory, for example: http://localhost/tests/unit/accordion/accordion.html. The domain will be dependent on your local server configuation; if there is a port, be sure to include it. +To run the tests for a specific plugin in your browser, open the approriate file from the `/tests/unit/` directory, for example: `http://localhost/tests/unit/accordion/accordion.html`. The domain will be dependent on your local server configuation; if there is a port, be sure to include it. -Success! You just tested jQuery UI! +Ideally you would test in all of our [supported browsers](http://jqueryui.com/browser-support/), but if you don't have all of these browsers available, that's ok. - -### Fix a bug from a ticket filed at bugs.jqueryui.com: - -**NEVER write your patches to the master branch** - it gets messy (I say this from experience!) - -**ALWAYS USE A "TOPIC" BRANCH!** Like so (#### = the ticket #)... - -Make sure you start with your up-to-date master: - -```bash -$ git checkout master -``` - -Create and checkout a new branch that includes the ticket # - -```bash -$ git checkout -b bug_#### - -# ( Explanation: this useful command will: -# "checkout" a "-b" (branch) by the name of "bug_####" -# or create it if it doesn't exist ) -``` - -Now you're on branch: bug_#### - -Determine the file you'll be working in... - -Open up the corresponding /tests/unit/?????.js and add the initial failing unit tests. This may seem awkward at first, but in the long run it will make sense. To truly and efficiently patch a bug, you need to be working against that bug. - -Next, open the source files and make your changes - -Run http://localhost/tests/unit/???? --> **ALL TESTS MUST PASS** - -Once you're satisfied with your patch... - -Stage the files to be tracked: - -```bash -$ git add filename -# (you can use "git status" to list the files you've changed) -``` - - -( I recommend NEVER, EVER using "git add . " ) - -Once you've staged all of your changed files, go ahead and commit them - -```bash -$ git commit -m "Component: Brief description of fix. Fixes #0000 - Ticket description." -``` - -See the [commit message style guide](http://wiki.jqueryui.com/w/page/25941597/Commit%20Message%20Style%20Guide) for more details on how to format your commit message. - -For a multiple line commit message, leave off the `-m "description"`. - -You will then be led into vi (or the text editor that you have set up) to complete your commit message. - -Then, push your branch with the bug fix commits to your github fork - -```bash -$ git push origin -u bug_#### -``` - -Before you tackle your next bug patch, return to the master: - -```bash -$ git checkout master -``` - - - -### jQuery UI supports the following browsers: - -* Chrome Current-1 -* Safari Current-1 -* Firefox Current-1 -* Opera Current-1 -* IE 7+ +Make sure to read our [commits and pull requests documentation](http://dev.contribute.jquery.org/commits-and-pull-requests/) for full details on working with branches and forks, as well as our commit guidelines. diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 000000000..ac9fa9cb8 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,231 @@ +module.exports = function( grunt ) { + +"use strict"; + +var + // files + coreFiles = [ + "core.js", + "widget.js", + "mouse.js", + "interaction.js", + "draggable.js", + "droppable.js", + "resizable.js", + "selectable.js", + "sortable.js", + "effect.js" + ], + + uiFiles = coreFiles.map(function( file ) { + return "ui/" + file; + }).concat( expandFiles( "ui/*.js" ).filter(function( file ) { + return coreFiles.indexOf( file.substring( 3 ) ) === -1; + }) ), + + allI18nFiles = expandFiles( "ui/i18n/*.js" ), + + cssFiles = [ + "core", + "accordion", + "autocomplete", + "button", + "datepicker", + "dialog", + "menu", + "progressbar", + "resizable", + "selectable", + "selectmenu", + "slider", + "spinner", + "tabs", + "tooltip", + "theme" + ].map(function( component ) { + return "themes/base/" + component + ".css"; + }), + + // minified files + minify = { + options: { + preserveComments: false + }, + main: { + options: { + banner: createBanner( uiFiles ) + }, + files: { + "dist/jquery-ui.min.js": "dist/jquery-ui.js" + } + }, + i18n: { + options: { + banner: createBanner( allI18nFiles ) + }, + files: { + "dist/i18n/jquery-ui-i18n.min.js": "dist/i18n/jquery-ui-i18n.js" + } + } + }, + + compareFiles = { + all: [ + "dist/jquery-ui.js", + "dist/jquery-ui.min.js" + ] + }; + +function mapMinFile( file ) { + return "dist/" + file.replace( /\.js$/, ".min.js" ).replace( /ui\//, "minified/" ); +} + +function expandFiles( files ) { + return grunt.util._.pluck( grunt.file.expandMapping( files ), "src" ).map(function( values ) { + return values[ 0 ]; + }); +} + +uiFiles.concat( allI18nFiles ).forEach(function( file ) { + minify[ file ] = { + options: { + banner: createBanner() + }, + files: {} + }; + minify[ file ].files[ mapMinFile( file ) ] = file; +}); + +uiFiles.forEach(function( file ) { + // TODO this doesn't do anything until https://github.com/rwldrn/grunt-compare-size/issues/13 + compareFiles[ file ] = [ file, mapMinFile( file ) ]; +}); + +// grunt plugins +grunt.loadNpmTasks( "grunt-contrib-jshint" ); +grunt.loadNpmTasks( "grunt-contrib-uglify" ); +grunt.loadNpmTasks( "grunt-contrib-concat" ); +grunt.loadNpmTasks( "grunt-contrib-qunit" ); +grunt.loadNpmTasks( "grunt-contrib-csslint" ); +grunt.loadNpmTasks( "grunt-jscs-checker" ); +grunt.loadNpmTasks( "grunt-html" ); +grunt.loadNpmTasks( "grunt-compare-size" ); +grunt.loadNpmTasks( "grunt-git-authors" ); +grunt.loadNpmTasks( "grunt-esformatter" ); +// local testswarm and build tasks +grunt.loadTasks( "build/tasks" ); + +function stripDirectory( file ) { + return file.replace( /.+\/(.+?)>?$/, "$1" ); +} + +function createBanner( files ) { + // strip folders + var fileNames = files && files.map( stripDirectory ); + return "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " + + "<%= grunt.template.today('isoDate') %>\n" + + "<%= pkg.homepage ? '* ' + pkg.homepage + '\\n' : '' %>" + + (files ? "* Includes: " + fileNames.join(", ") + "\n" : "") + + "* Copyright <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;" + + " Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> */\n"; +} + +grunt.initConfig({ + pkg: grunt.file.readJSON( "package.json" ), + files: { + dist: "<%= pkg.name %>-<%= pkg.version %>" + }, + compare_size: compareFiles, + concat: { + ui: { + options: { + banner: createBanner( uiFiles ), + stripBanners: { + block: true + } + }, + src: uiFiles, + dest: "dist/jquery-ui.js" + }, + i18n: { + options: { + banner: createBanner( allI18nFiles ) + }, + src: allI18nFiles, + dest: "dist/i18n/jquery-ui-i18n.js" + }, + css: { + options: { + banner: createBanner( cssFiles ), + stripBanners: { + block: true + } + }, + src: cssFiles, + dest: "dist/jquery-ui.css" + } + }, + jscs: { + // datepicker, sortable, resizable and draggable are getting rewritten, ignore until that's done + ui: [ "ui/*.js", "!ui/datepicker.js", "!ui/sortable.js", "!ui/resizable.js", "!ui/draggable.js" ], + // TODO enable this once we have a tool that can help with fixing formatting of existing files + // tests: "tests/unit/**/*.js", + grunt: "Gruntfile.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 ); + }) + }, + qunit: { + files: expandFiles( "tests/unit/**/*.html" ).filter(function( file ) { + // disabling everything that doesn't (quite) work with PhantomJS for now + // TODO except for all|index|test, try to include more as we go + return !( /(all|index|test|dialog|tooltip)\.html$/ ).test( file ); + }) + }, + jshint: { + options: { + jshintrc: true + }, + all: [ + "ui/*.js", + "Gruntfile.js", + "build/**/*.js", + "tests/unit/**/*.js" + ] + }, + csslint: { + base_theme: { + src: "themes/base/*.css", + options: { + csslintrc: ".csslintrc" + } + } + }, + + esformatter: { + options: { + preset: "jquery" + }, + ui: "ui/*.js", + tests: "tests/unit/**/*.js", + build: { + options: { + skipHashbang: true + }, + src: "build/**/*.js" + }, + grunt: "Gruntfile.js" + } +}); + +grunt.registerTask( "default", [ "lint", "test" ]); +grunt.registerTask( "lint", [ "asciilint", "jshint", "jscs", "csslint", "htmllint" ]); +grunt.registerTask( "test", [ "qunit" ]); +grunt.registerTask( "sizer", [ "concat:ui", "uglify:main", "compare_size:all" ]); +grunt.registerTask( "sizer_all", [ "concat:ui", "uglify", "compare_size" ]); + +}; diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt index 1c693e3d4..fc96cbd32 100644 --- a/MIT-LICENSE.txt +++ b/MIT-LICENSE.txt @@ -1,4 +1,4 @@ -Copyright 2013 jQuery Foundation and other contributors, +Copyright 2014 jQuery Foundation and other contributors, http://jqueryui.com/ This software consists of voluntary contributions made by many diff --git a/README.md b/README.md index e7ae90e8a..7c730cefe 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -[jQuery UI](http://jqueryui.com/) - Interactions and Widgets for the web -================================ +# [jQuery UI](http://jqueryui.com/) - Interactions and Widgets for the web -jQuery UI provides interactions like Drag and Drop and widgets like Autocomplete, Tabs and Slider and makes these as easy to use as jQuery itself. +jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of jQuery. Whether you're building highly interactive web applications, or you just need to add a date picker to a form control, jQuery UI is the perfect choice. -If you want to use jQuery UI, go to [jqueryui.com](http://jqueryui.com) to get started. Or visit the [Using jQuery UI Forum](http://forum.jquery.com/using-jquery-ui) for discussions and questions. +If you want to use jQuery UI, go to [jqueryui.com](http://jqueryui.com) to get started, [jqueryui.com/demos/](http://jqueryui.com/demos/) for demos, [api.jqueryui.com](http://api.jqueryui.com/) for API documentation, or the [Using jQuery UI Forum](http://forum.jquery.com/using-jquery-ui) for discussions and questions. + +If you want to report a bug/issue, please visit [bugs.jqueryui.com](http://bugs.jqueryui.com). If you are interested in helping develop jQuery UI, you are in the right place. -To discuss development with team members and the community, visit the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui) or in #jquery on irc.freednode.net. +To discuss development with team members and the community, visit the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui) or [#jqueryui-dev on irc.freenode.net](http://irc.jquery.org/). -For contributors ---- +## For contributors If you want to help and provide a patch for a bugfix or new feature, please take a few minutes and look at [our Getting Involved guide](http://wiki.jqueryui.com/w/page/35263114/Getting-Involved). @@ -22,8 +22,7 @@ pull request for that branch. Don't mix unrelated changes. You can use the commi message as the description for the pull request. -Running the Unit Tests ---- +## Running the Unit Tests Run the unit tests with a local server that supports PHP. No database is required. Pre-configured php local servers are available for Windows and Mac. Here are some options: @@ -33,36 +32,34 @@ Run the unit tests with a local server that supports PHP. No database is require - [Mongoose (most platforms)](http://code.google.com/p/mongoose/) -Building jQuery UI ---- +## Building jQuery UI -jQuery UI uses the [grunt](http://github.com/cowboy/grunt) build system. Building jQuery UI requires node.js and a command line zip program. +jQuery UI uses the [Grunt](http://github.com/gruntjs/grunt) build system. -Install grunt. +To build jQuery UI, you must have [node.js](http://nodejs.org/) installed and then run the following commands: -`npm install grunt -g` +```sh -Clone the jQuery UI git repo. +# Install the Grunt CLI +npm install -g grunt-cli -`git clone git://github.com/jquery/jquery-ui.git` +# Clone the jQuery UI git repo +git clone git://github.com/jquery/jquery-ui.git +cd jquery-ui -`cd jquery-ui` +# Install the node module dependencies +npm install -Install node modules. +# Run the concat task to concatenate files +grunt concat -`npm install` - -Run grunt. - -`grunt build` - -There are many other tasks that can be run through grunt. For a list of all tasks: - -`grunt --help` +# There are many other tasks that can be run through Grunt. +# For a list of all tasks: +grunt --help +``` -For committers ---- +## For committers When looking at pull requests, first check for [proper commit messages](http://wiki.jqueryui.com/w/page/12137724/Bug-Fixing-Guide). @@ -75,7 +72,7 @@ These should be squashed before landing in master. Fetch the remote first: - git fetch [their-fork.git] [their-branch] + git fetch [their-fork.git] [their-branch] Then cherry-pick the commit(s): @@ -83,7 +80,7 @@ Then cherry-pick the commit(s): If you need to edit the commit message: - git cherry-pick -e [sha-of-commit] + git cherry-pick -e [sha-of-commit] If you need to edit the changes: @@ -91,9 +88,9 @@ If you need to edit the changes: # make changes git commit --author="[author-name-and-email]" -If it should go to the stable brach, cherry-pick it to stable: +If it should go to the stable branch, cherry-pick it to stable: - git checkout 1-8-stable - git cherry-pick -x [sha-of-commit-from-master] + git checkout 1-10-stable + git cherry-pick -x [sha-of-commit-from-master] -*NOTE: Do not cherry-pick into 1-8-stable until you have pushed the commit from master upstream.* +*NOTE: Do not cherry-pick into 1-10-stable until you have pushed the commit from master upstream.* diff --git a/build/core.json b/build/core.json index a9cac173a..903230c87 100644 --- a/build/core.json +++ b/build/core.json @@ -30,7 +30,7 @@ ], "category": "effect", "homepage": "http://jqueryui.com/", - "demo": "http://jqueryui.com/effects/", + "demo": "http://jqueryui.com/effect/", "docs": "http://api.jqueryui.com/category/effects-core/" }, "position": { diff --git a/build/effect.json b/build/effect.json index 7119f85bc..3963bced3 100644 --- a/build/effect.json +++ b/build/effect.json @@ -23,15 +23,23 @@ "highlight": { "description": "Highlights the background of an element in a defined color for a custom duration." }, + "puff": { + "dependencies": [ "effect-scale" ], + "description": "Creates a puff effect by scaling the element up and hiding it at the same time." + }, "pulsate": { "description": "Pulsates an element n times by changing the opacity to zero and back." }, "scale": { - "description": "Grows or shrinks an element and its content. Restores an elemnt to its original size." + "dependencies": [ "effect-size" ], + "description": "Grows or shrinks an element and its content. Restores an element to its original size." }, "shake": { "description": "Shakes an element horizontally or vertically n times." }, + "size": { + "description": "Resize an element to a specified width and height." + }, "slide": { "description": "Slides an element in and out of the viewport." } diff --git a/build/release/release.js b/build/release/release.js index 2eab5283f..1567390f0 100644 --- a/build/release/release.js +++ b/build/release/release.js @@ -1,16 +1,18 @@ #!/usr/bin/env node -/*global cat:true cd:true echo:true exec:true exit:true*/ +/* global cat:true, cd:true, echo:true, exec:true, exit:true */ // Usage: // stable release: node release.js // pre-release: node release.js --pre-release {version} +// test run: node release.js --remote={repo} +// - repo: "/tmp/repo" (filesystem), "user/repo" (github), "http://mydomain/repo.git" (another domain) "use strict"; -var baseDir, repoDir, prevVersion, newVersion, nextVersion, tagTime, preRelease, +var baseDir, downloadBuilder, repoDir, prevVersion, newVersion, nextVersion, tagTime, preRelease, repo, fs = require( "fs" ), + path = require( "path" ), rnewline = /\r?\n/, - repo = "git@github.com:jquery/jquery-ui.git", branch = "master"; walk([ @@ -25,7 +27,8 @@ walk([ confirm, section( "building release" ), - buildRelease, + buildReleaseBranch, + buildPackage, section( "pushing tag" ), confirmReview, @@ -66,13 +69,6 @@ function cloneRepo() { if ( exec( "npm install" ).code !== 0 ) { abort( "Error installing dependencies." ); } - // We need download.jqueryui.com in order to generate themes. - // We only generate themes for stable releases. - if ( !preRelease ) { - if ( exec( "npm install download.jqueryui.com" ).code !== 0 ) { - abort( "Error installing dependencies." ); - } - } echo(); } @@ -109,8 +105,7 @@ function getVersions() { if ( preRelease ) { newVersion = preRelease; - // Note: prevVersion is not currently used for pre-releases. The TODO - // below about 1.10.0 applies here as well. + // Note: prevVersion is not currently used for pre-releases. prevVersion = nextVersion = currentVersion; } else { newVersion = currentVersion.substr( 0, currentVersion.length - 3 ); @@ -119,15 +114,14 @@ function getVersions() { minor = parseInt( parts[ 1 ], 10 ); patch = parseInt( parts[ 2 ], 10 ); - // TODO: handle 1.10.0 - // Also see comment above about pre-releases - if ( patch === 0 ) { - abort( "This script is not smart enough to handle the 1.10.0 release." ); + if ( minor === 0 && patch === 0 ) { + abort( "This script is not smart enough to handle major release (eg. 2.0.0)." ); + } else if ( patch === 0 ) { + prevVersion = git( "for-each-ref --count=1 --sort=-authordate --format='%(refname:short)' refs/tags/" + [ major, minor - 1 ].join( "." ) + "*" ).trim(); + } else { + prevVersion = [ major, minor, patch - 1 ].join( "." ); } - prevVersion = patch === 0 ? - [ major, minor - 1, 0 ].join( "." ) : - [ major, minor, patch - 1 ].join( "." ); nextVersion = [ major, minor, patch + 1 ].join( "." ) + "pre"; } @@ -135,9 +129,8 @@ function getVersions() { echo( "After the release, the version will be " + nextVersion.cyan + "." ); } -function buildRelease() { - var pkg, - releaseTask = preRelease ? "release" : "release_cdn"; +function buildReleaseBranch() { + var pkg; echo( "Creating " + "release".cyan + " branch..." ); git( "checkout -b release", "Error creating release branch." ); @@ -158,12 +151,6 @@ function buildRelease() { } echo(); - echo( "Building release..." ); - if ( exec( "grunt " + releaseTask ).code !== 0 ) { - abort( "Error building release." ); - } - echo(); - echo( "Committing release artifacts..." ); git( "add *.jquery.json", "Error adding manifest files to git." ); git( "commit -am 'Tagging the " + newVersion + " release.'", @@ -175,6 +162,173 @@ function buildRelease() { tagTime = git( "log -1 --format='%ad'", "Error getting tag timestamp." ).trim(); } +function buildPackage( callback ) { + if( preRelease ) { + return buildPreReleasePackage( callback ); + } else { + return buildCDNPackage( callback ); + } +} + +function buildPreReleasePackage( callback ) { + var build, files, jqueryUi, packer, target, targetZip; + + echo( "Build pre-release Package" ); + + jqueryUi = new downloadBuilder.JqueryUi( path.resolve( "." ) ); + build = new downloadBuilder.Builder( jqueryUi, ":all:" ); + packer = new downloadBuilder.Packer( build, null, { + addTests: true, + bundleSuffix: "", + skipDocs: true, + skipTheme: true + }); + target = "../" + jqueryUi.pkg.name + "-" + jqueryUi.pkg.version; + targetZip = target + ".zip"; + + return walk([ + function( callback ) { + echo( "Building release files" ); + packer.pack(function( error, _files ) { + if( error ) { + abort( error.stack ); + } + files = _files.map(function( file ) { + + // Strip first path + file.path = file.path.replace( /^[^\/]*\//, "" ); + return file; + + }).filter(function( file ) { + + // Filter development-bundle content only + return (/^development-bundle/).test( file.path ); + }).map(function( file ) { + + // Strip development-bundle + file.path = file.path.replace( /^development-bundle\//, "" ); + return file; + + }); + return callback(); + }); + }, + function() { + downloadBuilder.util.createZip( files, targetZip, function( error ) { + if ( error ) { + abort( error.stack ); + } + echo( "Built zip package at " + path.relative( "../..", targetZip ).cyan ); + return callback(); + }); + } + ]); +} + +function buildCDNPackage( callback ) { + var build, output, target, targetZip, + add = function( file ) { + output.push( file ); + }, + jqueryUi = new downloadBuilder.JqueryUi( path.resolve( "." ) ), + themeGallery = downloadBuilder.themeGallery( jqueryUi ); + + echo( "Build CDN Package" ); + + build = new downloadBuilder.Builder( jqueryUi, ":all:" ); + output = []; + target = "../" + jqueryUi.pkg.name + "-" + jqueryUi.pkg.version + "-cdn"; + targetZip = target + ".zip"; + + [ "AUTHORS.txt", "MIT-LICENSE.txt", "package.json" ].map(function( name ) { + return build.get( name ); + }).forEach( add ); + + // "ui/*.js" + build.componentFiles.filter(function( file ) { + return (/^ui\//).test( file.path ); + }).forEach( add ); + + // "ui/*.min.js" + build.componentMinFiles.filter(function( file ) { + return (/^ui\//).test( file.path ); + }).forEach( add ); + + // "i18n/*.js" + build.i18nFiles.rename( /^ui\//, "" ).forEach( add ); + build.i18nMinFiles.rename( /^ui\//, "" ).forEach( add ); + build.bundleI18n.into( "i18n/" ).forEach( add ); + build.bundleI18nMin.into( "i18n/" ).forEach( add ); + + build.bundleJs.forEach( add ); + build.bundleJsMin.forEach( add ); + + walk( themeGallery.map(function( theme ) { + return function( callback ) { + var themeCssOnlyRe, themeDirRe, + folderName = theme.folderName(), + packer = new downloadBuilder.Packer( build, theme, { + skipDocs: true + }); + // TODO improve code by using custom packer instead of download packer (Packer) + themeCssOnlyRe = new RegExp( "development-bundle/themes/" + folderName + "/jquery.ui.theme.css" ); + themeDirRe = new RegExp( "css/" + folderName ); + packer.pack(function( error, files ) { + if ( error ) { + abort( error.stack ); + } + // Add theme files. + files + // Pick only theme files we need on the bundle. + .filter(function( file ) { + if ( themeCssOnlyRe.test( file.path ) || themeDirRe.test( file.path ) ) { + return true; + } + return false; + }) + // Convert paths the way bundle needs + .map(function( file ) { + file.path = file.path + + // Remove initial package name eg. "jquery-ui-1.10.0.custom" + .split( "/" ).slice( 1 ).join( "/" ) + + .replace( /development-bundle\/themes/, "css" ) + .replace( /css/, "themes" ) + + // Make jquery-ui-1.10.0.custom.css into jquery-ui.css, or jquery-ui-1.10.0.custom.min.css into jquery-ui.min.css + .replace( /jquery-ui-.*?(\.min)*\.css/, "jquery-ui$1.css" ); + + return file; + }).forEach( add ); + return callback(); + }); + }; + }).concat([function() { + var crypto = require( "crypto" ); + + // Create MD5 manifest + output.push({ + path: "MANIFEST", + data: output.sort(function( a, b ) { + return a.path.localeCompare( b.path ); + }).map(function( file ) { + var md5 = crypto.createHash( "md5" ); + md5.update( file.data ); + return file.path + " " + md5.digest( "hex" ); + }).join( "\n" ) + }); + + downloadBuilder.util.createZip( output, targetZip, function( error ) { + if ( error ) { + abort( error.stack ); + } + echo( "Built zip CDN package at " + path.relative( "../..", targetZip ).cyan ); + return callback(); + }); + }])); +} + function pushRelease() { echo( "Pushing release to GitHub..." ); git( "push --tags", "Error pushing tags to GitHub." ); @@ -357,6 +511,48 @@ function writePackage( pkg ) { } function bootstrap( fn ) { + getRemote(function( remote ) { + if ( (/:/).test( remote ) || fs.existsSync( remote ) ) { + repo = remote; + } else { + repo = "git@github.com:" + remote + ".git"; + } + _bootstrap( fn ); + }); +} + +function getRemote( fn ) { + var matches, remote; + + console.log( "Determining remote repo..." ); + process.argv.forEach(function( arg ) { + matches = /--remote=(.+)/.exec( arg ); + if ( matches ) { + remote = matches[ 1 ]; + } + }); + + if ( remote ) { + fn( remote ); + return; + } + + console.log(); + console.log( " !!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); + console.log( " !!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); + console.log( " !! !!" ); + console.log( " !! Using jquery/jquery-ui !!" ); + console.log( " !! !!" ); + console.log( " !!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); + console.log( " !!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); + console.log(); + console.log( "Press enter to continue, or ctrl+c to cancel." ); + prompt(function() { + fn( "jquery/jquery-ui" ); + }); +} + +function _bootstrap( fn ) { console.log( "Determining release type..." ); preRelease = process.argv.indexOf( "--pre-release" ); if ( preRelease !== -1 ) { @@ -381,7 +577,7 @@ function bootstrap( fn ) { fs.mkdirSync( baseDir ); console.log( "Installing dependencies..." ); - require( "child_process" ).exec( "npm install shelljs colors", function( error ) { + require( "child_process" ).exec( "npm install shelljs colors download.jqueryui.com@1.10.8", function( error ) { if ( error ) { console.log( error ); return process.exit( 1 ); @@ -389,6 +585,7 @@ function bootstrap( fn ) { require( "shelljs/global" ); require( "colors" ); + downloadBuilder = require( "download.jqueryui.com" ); fn(); }); diff --git a/build/tasks/build.js b/build/tasks/build.js index a8f25f98f..cdc03bd60 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -2,9 +2,6 @@ module.exports = function( grunt ) { "use strict"; -var path = require( "path" ), - fs = require( "fs" ); - grunt.registerTask( "manifest", "Generate jquery.json manifest files", function() { var pkg = grunt.config( "pkg" ), base = { @@ -26,8 +23,8 @@ grunt.registerTask( "manifest", "Generate jquery.json manifest files", function( name: "ui.effect-{plugin}", title: "jQuery UI {Plugin} Effect", keywords: [ "effect", "show", "hide" ], - homepage: "http://jqueryui.com/{plugin}-effect/", - demo: "http://jqueryui.com/{plugin}-effect/", + homepage: "http://jqueryui.com/effect/", + demo: "http://jqueryui.com/effect/", docs: "http://api.jqueryui.com/{plugin}-effect/", dependencies: [ "effect" ] } @@ -84,139 +81,41 @@ grunt.registerTask( "manifest", "Generate jquery.json manifest files", function( }); }); -grunt.registerMultiTask( "copy", "Copy files to destination folder and replace @VERSION with pkg.version", function() { - function replaceVersion( source ) { - return source.replace( /@VERSION/g, grunt.config( "pkg.version" ) ); - } - function copyFile( src, dest ) { - if ( /(js|css)$/.test( src ) ) { - grunt.file.copy( src, dest, { - process: replaceVersion - }); - } else { - grunt.file.copy( src, dest ); - } - } - var files = grunt.file.expandFiles( this.file.src ), - target = this.file.dest + "/", - strip = this.data.strip, - renameCount = 0, - fileName; - if ( typeof strip === "string" ) { - strip = new RegExp( "^" + grunt.template.process( strip, grunt.config() ).replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ) ); - } - files.forEach(function( fileName ) { - var targetFile = strip ? fileName.replace( strip, "" ) : fileName; - copyFile( fileName, target + targetFile ); - }); - grunt.log.writeln( "Copied " + files.length + " files." ); - for ( fileName in this.data.renames ) { - renameCount += 1; - copyFile( fileName, target + grunt.template.process( this.data.renames[ fileName ], grunt.config() ) ); - } - if ( renameCount ) { - grunt.log.writeln( "Renamed " + renameCount + " files." ); - } -}); - - -grunt.registerMultiTask( "zip", "Create a zip file for release", function() { - // TODO switch back to adm-zip for better cross-platform compability once it actually works - // 0.1.3 works, but result can't be unzipped - // its also a lot slower then zip program, probably due to how its used... - // var files = grunt.file.expandFiles( "dist/" + this.file.src + "/**/*" ); - // grunt.log.writeln( "Creating zip file " + this.file.dest ); - - //var AdmZip = require( "adm-zip" ); - //var zip = new AdmZip(); - //files.forEach(function( file ) { - // grunt.verbose.writeln( "Zipping " + file ); - // // rewrite file names from dist folder (created by build), drop the /dist part - // zip.addFile(file.replace(/^dist/, "" ), fs.readFileSync( file ) ); - //}); - //zip.writeZip( "dist/" + this.file.dest ); - //grunt.log.writeln( "Wrote " + files.length + " files to " + this.file.dest ); - - var done = this.async(), - dest = this.file.dest, - src = grunt.template.process( this.file.src, grunt.config() ); - grunt.utils.spawn({ - cmd: "zip", - args: [ "-r", dest, src ], - opts: { - cwd: 'dist' - } - }, function( err ) { - if ( err ) { - grunt.log.error( err ); - done(); - return; - } - grunt.log.writeln( "Zipped " + dest ); - done(); - }); -}); - -grunt.registerMultiTask( "md5", "Create list of md5 hashes for CDN uploads", function() { - // remove dest file before creating it, to make sure itself is not included - if ( fs.existsSync( this.file.dest ) ) { - fs.unlinkSync( this.file.dest ); - } - var crypto = require( "crypto" ), - dir = this.file.src + "/", - hashes = []; - grunt.file.expandFiles( dir + "**/*" ).forEach(function( fileName ) { - var hash = crypto.createHash( "md5" ); - hash.update( grunt.file.read( fileName, "ascii" ) ); - hashes.push( fileName.replace( dir, "" ) + " " + hash.digest( "hex" ) ); - }); - grunt.file.write( this.file.dest, hashes.join( "\n" ) + "\n" ); - grunt.log.writeln( "Wrote " + this.file.dest + " with " + hashes.length + " hashes" ); -}); - -grunt.registerTask( "generate_themes", function() { - var download, done, - distFolder = "dist/" + grunt.template.process( grunt.config( "files.dist" ), grunt.config() ), - target = "dist/" + grunt.template.process( grunt.config( "files.themes" ), grunt.config() ) + "/"; - - try { - require.resolve( "download.jqueryui.com" ); - } catch( error ) { - throw new Error( "You need to manually install download.jqueryui.com for this task to work" ); - } - - download = require( "download.jqueryui.com" )({ - config: { - "jqueryUi": { - "stable": { "path": path.resolve( __dirname + "/../../" + distFolder ) } - }, - "jquery": "skip" - } - }); - - done = this.async(); - download.buildThemesBundle(function( error, files ) { - if ( error ) { - grunt.log.error( error ); - return done( false ); - } - - done( - files.every(function( file ) { - try { - grunt.file.write( target + file.path, file.data ); - } catch( err ) { - grunt.log.error( err ); - return false; - } - return true; - }) && grunt.log.writeln( "Generated at " + target ) - ); - }); -}); - 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 ) { + var i, c, + text = grunt.file.read( filename ); + + // Ensure files use only \n for line endings, not \r\n + if ( /\x0d\x0a/.test( text ) ) { + grunt.log.error( filename + ": Incorrect line endings (\\r\\n)" ); + valid = false; + } + + // Ensure only ASCII chars so script tags don't need a charset attribute + if ( text.length !== Buffer.byteLength( text, "utf8" ) ) { + grunt.log.error( filename + ": Non-ASCII characters detected:" ); + for ( i = 0; i < text.length; i++ ) { + c = text.charCodeAt( i ); + if ( c > 127 ) { + grunt.log.error( "- position " + i + ": " + c ); + grunt.log.error( "-- " + text.substring( i - 20, i + 20 ) ); + break; + } + } + 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 3361b7fa9..c2c14167b 100644 --- a/build/tasks/testswarm.js +++ b/build/tasks/testswarm.js @@ -4,6 +4,7 @@ module.exports = function( grunt ) { var versions = { "git": "git", + "1.10": "1.10.0 1.10.1 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 1.7.1 1.7.2", @@ -14,9 +15,9 @@ var versions = { "Autocomplete": "autocomplete/autocomplete.html", "Button": "button/button.html", "Core": "core/core.html", + "Core_deprecated": "core/core_deprecated.html", "Datepicker": "datepicker/datepicker.html", "Dialog": "dialog/dialog.html", - "Dialog_deprecated": "dialog/dialog_deprecated.html", "Draggable": "draggable/draggable.html", "Droppable": "droppable/droppable.html", "Effects": "effects/effects.html", @@ -25,6 +26,7 @@ var versions = { "Progressbar": "progressbar/progressbar.html", "Resizable": "resizable/resizable.html", "Selectable": "selectable/selectable.html", + "Selectmenu": "selectmenu/selectmenu.html", "Slider": "slider/slider.html", "Sortable": "sortable/sortable.html", "Spinner": "spinner/spinner.html", @@ -33,37 +35,41 @@ var versions = { "Widget": "widget/widget.html" }; -function submit( commit, runs, configFile, version, done ) { +function submit( commit, runs, configFile, extra, done ) { var testName, testswarm = require( "testswarm" ), - config = grunt.file.readJSON( configFile ).jqueryui; - version = version ? ( version + " " ) : ""; - for ( testName in runs ) { - runs[ testName] = config.testUrl + commit + "/tests/unit/" + runs[ testName ]; + config = grunt.file.readJSON( configFile ).jqueryui, + commitUrl = "https://github.com/jquery/jquery-ui/commit/" + commit; + + if ( extra ) { + extra = " (" + extra + ")"; } - testswarm.createClient( { + + for ( testName in runs ) { + runs[ testName ] = config.testUrl + commit + "/tests/unit/" + runs[ testName ]; + } + + testswarm.createClient({ url: config.swarmUrl, pollInterval: 10000, timeout: 1000 * 60 * 45 - } ) + }) .addReporter( testswarm.reporters.cli ) - .auth( { + .auth({ id: config.authUsername, token: config.authToken - } ) - .addjob( - { - name: 'jQuery UI ' + version + '#' + commit.substr( 0, 10 ) + '', - runs: runs, - runMax: config.runMax, - browserSets: config.browserSets - }, function( err, passed ) { - if ( err ) { - grunt.log.error( err ); - } - done( passed ); + }) + .addjob({ + name: "Commit " + commit.substr( 0, 10 ) + "" + extra, + runs: runs, + runMax: config.runMax, + browserSets: ["popular-no-ie6"] + }, function( error, passed ) { + if ( error ) { + grunt.log.error( error ); } - ); + done( passed ); + }); } grunt.registerTask( "testswarm", function( commit, configFile ) { @@ -82,7 +88,7 @@ grunt.registerTask( "testswarm-multi-jquery", function( commit, configFile, mino allTests[ test + "-" + version ] = tests[ test ] + "?nojshint=true&jquery=" + version; } }); - submit( commit, allTests, configFile, minor + " core", this.async() ); + submit( commit, allTests, configFile, "core " + minor, this.async() ); }); }; diff --git a/build/widget.json b/build/widget.json index 6adddb121..4a0f128a3 100644 --- a/build/widget.json +++ b/build/widget.json @@ -21,7 +21,7 @@ }, "button": { "dependencies": [], - "description": "Enhances a form with themable buttons.", + "description": "Enhances a form with themeable buttons.", "keywords": [ "form", "radio", diff --git a/demos/accordion/collapsible.html b/demos/accordion/collapsible.html index 659dfa744..864be026b 100644 --- a/demos/accordion/collapsible.html +++ b/demos/accordion/collapsible.html @@ -3,11 +3,11 @@ jQuery UI Accordion - Collapse content - - - - - + + + + + - - - - + + + + + + - - - + + + + + - - - - - + + + + + + + - - - - - - - + + + + + + + + + - - - - - + + + + + + + - - - - - + + + + + + + - - - - - + + + + + + + @@ -27,21 +27,13 @@ $( "#city" ).autocomplete({ source: function( request, response ) { $.ajax({ - url: "http://ws.geonames.org/searchJSON", + url: "http://gd.geobytes.com/AutoCompleteCity", dataType: "jsonp", data: { - featureClass: "P", - style: "full", - maxRows: 12, - name_startsWith: request.term + q: request.term }, success: function( data ) { - response( $.map( data.geonames, function( item ) { - return { - label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName, - value: item.name - } - })); + response( data ); } }); }, diff --git a/demos/autocomplete/remote-with-cache.html b/demos/autocomplete/remote-with-cache.html index b47608d39..200949bb8 100644 --- a/demos/autocomplete/remote-with-cache.html +++ b/demos/autocomplete/remote-with-cache.html @@ -3,17 +3,17 @@ jQuery UI Autocomplete - Remote with caching - - - - - - - + + + + + + + - - - - - + + + + + + + - - - - - + + + + + + + - - - + + + + + - - - + + + + + - - - + + + + + - - - + + + + + - - - - - + + + + + + + + + + +
+
Starting download...
+
+
+ + +
+

Download dialog progressbar demo.

+
+ + diff --git a/demos/progressbar/images/pbar-ani.gif b/demos/progressbar/images/pbar-ani.gif index cb59a04f9..c22469afd 100644 Binary files a/demos/progressbar/images/pbar-ani.gif and b/demos/progressbar/images/pbar-ani.gif differ diff --git a/demos/progressbar/indeterminate.html b/demos/progressbar/indeterminate.html index 54e7c43ef..2993a0163 100644 --- a/demos/progressbar/indeterminate.html +++ b/demos/progressbar/indeterminate.html @@ -3,11 +3,11 @@ jQuery UI Progressbar - Indeterminate Value - - - - - + + + + + - - - + + + + + + + + +
+ +
+ +

Selectmenu with framework icons

+
+ + +
+ +

Selectmenu with custom icon images

+
+ + +
+ +

Selectmenu with custom avatar 16x16 images as CSS background

+
+ + +
+ +
+ +
+ +
+

The whole rendering process is extendable to make custom styling as easy as possible.

+
+ + diff --git a/demos/selectmenu/default.html b/demos/selectmenu/default.html new file mode 100644 index 000000000..0c1101e6d --- /dev/null +++ b/demos/selectmenu/default.html @@ -0,0 +1,104 @@ + + + + + + jQuery UI Selectmenu - Default functionality + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + +
+ +
+ +
+ +
+

The Selectmenu widgets provides a styleable select element replacement. It will act as a proxy back to the original select element, controlling its state for form submission or serialization

+

The datasource is a native select element. Supports optgroups.

+
+ + diff --git a/demos/selectmenu/images/24-podcast-square.png b/demos/selectmenu/images/24-podcast-square.png new file mode 100644 index 000000000..3c3e38f3f Binary files /dev/null and b/demos/selectmenu/images/24-podcast-square.png differ diff --git a/demos/selectmenu/images/24-rss-square.png b/demos/selectmenu/images/24-rss-square.png new file mode 100644 index 000000000..f59b69ed3 Binary files /dev/null and b/demos/selectmenu/images/24-rss-square.png differ diff --git a/demos/selectmenu/images/24-video-square.png b/demos/selectmenu/images/24-video-square.png new file mode 100644 index 000000000..ce50ccfde Binary files /dev/null and b/demos/selectmenu/images/24-video-square.png differ diff --git a/demos/selectmenu/index.html b/demos/selectmenu/index.html new file mode 100644 index 000000000..3b035f5fb --- /dev/null +++ b/demos/selectmenu/index.html @@ -0,0 +1,16 @@ + + + + + + jQuery UI Selectmenu Demos + + + + + + + diff --git a/demos/show/index.html b/demos/show/index.html deleted file mode 100644 index 3620fd7c5..000000000 --- a/demos/show/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - jQuery UI Effects Demos - - - - - - - diff --git a/demos/slider/colorpicker.html b/demos/slider/colorpicker.html index e579b0e8b..d92bcc181 100644 --- a/demos/slider/colorpicker.html +++ b/demos/slider/colorpicker.html @@ -3,12 +3,12 @@ jQuery UI Slider - Colorpicker - - - - - - + + + + + + diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html index 0686d3700..34e32c296 100644 --- a/demos/spinner/currency.html +++ b/demos/spinner/currency.html @@ -3,16 +3,16 @@ jQuery UI Spinner - Currency - - + + - - - - + + + + + + - - - - + + + + + + - - - - + + + + - + - - - - + + + + + + - - - - + + + + + + - - - - + + + + - - - + + + + + - - - + + + + + - - - + + + + + - - - + + + + + - - - - - - + + + + + + + + + + + +

jQuery UI Core Test Suite

+

+
+

+
    +
    + + + + + + + + + + +
    +
    + +
    + + + + + + + + + + xxx + anchor + anchor + x +
    x
    + x +
    x
    +
    + +
    + + + + + + + + + +
    + +
    + + + + + + + + + +
    + +
    + + + + + + . + . + . + . +
    + +
    + + +
    + +
    +
    .
    +
    +
    +
    .
    +
    +
    +
    .
    +
    +
    + +
    + +
    + + diff --git a/tests/unit/core/core_deprecated.js b/tests/unit/core/core_deprecated.js new file mode 100644 index 000000000..bb06f77b2 --- /dev/null +++ b/tests/unit/core/core_deprecated.js @@ -0,0 +1,24 @@ +(function( $ ) { + +module( "core - deprecated" ); + +test( "zIndex", function() { + expect( 7 ); + var el = $( "#zIndexAutoWithParent" ), + parent = el.parent(); + equal( el.zIndex(), 100, "zIndex traverses up to find value" ); + equal( parent.zIndex(200 ), parent, "zIndex setter is chainable" ); + equal( el.zIndex(), 200, "zIndex setter changed zIndex" ); + + el = $( "#zIndexAutoWithParentViaCSS" ); + equal( el.zIndex(), 0, "zIndex traverses up to find CSS value, not found because not positioned" ); + + el = $( "#zIndexAutoWithParentViaCSSPositioned" ); + equal( el.zIndex(), 100, "zIndex traverses up to find CSS value" ); + el.parent().zIndex( 200 ); + equal( el.zIndex(), 200, "zIndex setter changed zIndex, overriding CSS" ); + + equal( $( "#zIndexAutoNoParent" ).zIndex(), 0, "zIndex never explicitly set in hierarchy" ); +}); + +})( jQuery ); diff --git a/tests/unit/datepicker/all.html b/tests/unit/datepicker/all.html index c6854ef9c..a5b68ed8d 100644 --- a/tests/unit/datepicker/all.html +++ b/tests/unit/datepicker/all.html @@ -4,7 +4,7 @@ jQuery UI Datepicker Test Suite - + diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 8ef2de5a4..37f949ae6 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -11,13 +11,13 @@ diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index befda3b2a..65b07e2f6 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -4,7 +4,11 @@ (function($) { -module("datepicker: core"); +module( "datepicker: core", { + setup: function() { + $( "body" ).focus(); + } +}); TestHelpers.testJshint( "datepicker" ); @@ -30,154 +34,173 @@ test("widget method", function() { deepEqual($("body > #ui-datepicker-div:last-child")[0], actual); }); -asyncTest("baseStructure", function() { +asyncTest( "baseStructure", function() { expect( 58 ); var header, title, table, thead, week, panel, inl, child, - inp = TestHelpers.datepicker.init("#inp"), - dp = $("#ui-datepicker-div"); + inp = TestHelpers.datepicker.initNewInput(), + dp = $( "#ui-datepicker-div" ); function step1() { - inp[0].focus(); - setTimeout(function() { - ok(dp.is(":visible"), "Structure - datepicker visible"); - ok(!dp.is(".ui-datepicker-rtl"), "Structure - not right-to-left"); - ok(!dp.is(".ui-datepicker-multi"), "Structure - not multi-month"); - equal(dp.children().length, 2, "Structure - child count"); + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Structure - datepicker visible" ); + ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" ); + ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" ); + equal( dp.children().length, 2, "Structure - child count" ); - header = dp.children(":first"); - ok(header.is("div.ui-datepicker-header"), "Structure - header division"); - equal(header.children().length, 3, "Structure - header child count"); - ok(header.children(":first").is("a.ui-datepicker-prev") && header.children(":first").html() !== "", "Structure - prev link"); - ok(header.children(":eq(1)").is("a.ui-datepicker-next") && header.children(":eq(1)").html() !== "", "Structure - next link"); + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" ); + equal( header.children().length, 3, "Structure - header child count" ); + ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); + ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); - title = header.children(":last"); - ok(title.is("div.ui-datepicker-title") && title.html() !== "","Structure - title division"); - equal(title.children().length, 2, "Structure - title child count"); - ok(title.children(":first").is("span.ui-datepicker-month") && title.children(":first").text() !== "", "Structure - month text"); - ok(title.children(":last").is("span.ui-datepicker-year") && title.children(":last").text() !== "", "Structure - year text"); + title = header.children( ":last" ); + ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "","Structure - title division" ); + equal( title.children().length, 2, "Structure - title child count" ); + ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); + ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); - table = dp.children(":eq(1)"); - ok(table.is("table.ui-datepicker-calendar"), "Structure - month table"); - ok(table.children(":first").is("thead"), "Structure - month table thead"); - thead = table.children(":first").children(":first"); - ok(thead.is("tr"), "Structure - month table title row"); - equal(thead.find("th").length, 7, "Structure - month table title cells"); - ok(table.children(":eq(1)").is("tbody"), "Structure - month table body"); - ok(table.children(":eq(1)").children("tr").length >= 4, "Structure - month table week count"); - week = table.children(":eq(1)").children(":first"); - ok(week.is("tr"), "Structure - month table week row"); - equal(week.children().length, 7, "Structure - week child count"); - ok(week.children(":first").is("td.ui-datepicker-week-end"), "Structure - month table first day cell"); - ok(week.children(":last").is("td.ui-datepicker-week-end"), "Structure - month table second day cell"); - inp.datepicker("hide").datepicker("destroy"); + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); + thead = table.children( ":first" ).children( ":first" ); + ok( thead.is( "tr" ), "Structure - month table title row" ); + equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); + ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); + + week = table.children( ":eq(1)" ).children( ":first" ); + ok( week.is( "tr" ), "Structure - month table week row" ); + equal( week.children().length, 7, "Structure - week child count" ); + ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); + ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); step2(); }); } function step2() { // Editable month/year and button panel - inp = TestHelpers.datepicker.init("#inp", {changeMonth: true, changeYear: true, showButtonPanel: true}); - inp.focus(); - setTimeout(function() { - title = dp.find("div.ui-datepicker-title"); - ok(title.children(":first").is("select.ui-datepicker-month"), "Structure - month selector"); - ok(title.children(":last").is("select.ui-datepicker-year"), "Structure - year selector"); + inp = TestHelpers.datepicker.initNewInput({ + changeMonth: true, + changeYear: true, + showButtonPanel: true + }); + TestHelpers.datepicker.onFocus( inp, function() { + title = dp.find( "div.ui-datepicker-title" ); + ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); + ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); - panel = dp.children(":last"); - ok(panel.is("div.ui-datepicker-buttonpane"), "Structure - button panel division"); - equal(panel.children().length, 2, "Structure - button panel child count"); - ok(panel.children(":first").is("button.ui-datepicker-current"), "Structure - today button"); - ok(panel.children(":last").is("button.ui-datepicker-close"), "Structure - close button"); - inp.datepicker("hide").datepicker("destroy"); + panel = dp.children( ":last" ); + ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" ); + equal( panel.children().length, 2, "Structure - button panel child count" ); + ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" ); + ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); step3(); }); } function step3() { // Multi-month 2 - inp = TestHelpers.datepicker.init("#inp", {numberOfMonths: 2}); - inp.focus(); - setTimeout(function() { - ok(dp.is(".ui-datepicker-multi"), "Structure multi [2] - multi-month"); - equal(dp.children().length, 3, "Structure multi [2] - child count"); - child = dp.children(":first"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-first"), "Structure multi [2] - first month division"); - child = dp.children(":eq(1)"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-last"), "Structure multi [2] - second month division"); - child = dp.children(":eq(2)"); - ok(child.is("div.ui-datepicker-row-break"), "Structure multi [2] - row break"); - ok(dp.is(".ui-datepicker-multi-2"), "Structure multi [2] - multi-2"); - inp.datepicker("hide").datepicker("destroy"); + inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 }); + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); + equal( dp.children().length, 3, "Structure multi [2] - child count" ); + child = dp.children( ":first" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); + ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); step4(); }); } function step4() { // Multi-month 3 - inp = TestHelpers.datepicker.init("#inp", {numberOfMonths: 3}); - inp.focus(); - setTimeout(function() { - ok(dp.is(".ui-datepicker-multi-3"), "Structure multi [3] - multi-3"); - ok(! dp.is(".ui-datepicker-multi-2"), "Structure multi [3] - Trac #6704"); - inp.datepicker("hide").datepicker("destroy"); + inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 }); + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); + ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); step5(); }); } function step5() { // Multi-month [2, 2] - inp = TestHelpers.datepicker.init("#inp", {numberOfMonths: [2, 2]}); - inp.focus(); - setTimeout(function() { - ok(dp.is(".ui-datepicker-multi"), "Structure multi - multi-month"); - equal(dp.children().length, 6, "Structure multi [2,2] - child count"); - child = dp.children(":first"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-first"), "Structure multi [2,2] - first month division"); - child = dp.children(":eq(1)"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-last"), "Structure multi [2,2] - second month division"); - child = dp.children(":eq(2)"); - ok(child.is("div.ui-datepicker-row-break"), "Structure multi [2,2] - row break"); - child = dp.children(":eq(3)"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-first"), "Structure multi [2,2] - third month division"); - child = dp.children(":eq(4)"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-last"), "Structure multi [2,2] - fourth month division"); - child = dp.children(":eq(5)"); - ok(child.is("div.ui-datepicker-row-break"), "Structure multi [2,2] - row break"); - inp.datepicker("hide").datepicker("destroy"); + inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] }); + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); + equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); + + child = dp.children( ":first" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); + + child = dp.children( ":eq(3)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" ); + + child = dp.children( ":eq(4)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" ); + + child = dp.children( ":eq(5)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); // Inline - inl = TestHelpers.datepicker.init("#inl"); + inl = TestHelpers.datepicker.init( "#inl" ); dp = inl.children(); - ok(dp.is(".ui-datepicker-inline"), "Structure inline - main div"); - ok(!dp.is(".ui-datepicker-rtl"), "Structure inline - not right-to-left"); - ok(!dp.is(".ui-datepicker-multi"), "Structure inline - not multi-month"); - equal(dp.children().length, 2, "Structure inline - child count"); - header = dp.children(":first"); - ok(header.is("div.ui-datepicker-header"), "Structure inline - header division"); - equal(header.children().length, 3, "Structure inline - header child count"); - table = dp.children(":eq(1)"); - ok(table.is("table.ui-datepicker-calendar"), "Structure inline - month table"); - ok(table.children(":first").is("thead"), "Structure inline - month table thead"); - ok(table.children(":eq(1)").is("tbody"), "Structure inline - month table body"); - inl.datepicker("destroy"); + + ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); + ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); + ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); + equal( dp.children().length, 2, "Structure inline - child count" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); + equal( header.children().length, 3, "Structure inline - header child count" ); + + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); + + inl.datepicker( "destroy" ); // Inline multi-month - inl = TestHelpers.datepicker.init("#inl", {numberOfMonths: 2}); + inl = TestHelpers.datepicker.init( "#inl", { numberOfMonths: 2 } ); dp = inl.children(); - ok(dp.is(".ui-datepicker-inline") && dp.is(".ui-datepicker-multi"), "Structure inline multi - main div"); - equal(dp.children().length, 3, "Structure inline multi - child count"); - child = dp.children(":first"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-first"), "Structure inline multi - first month division"); - child = dp.children(":eq(1)"); - ok(child.is("div.ui-datepicker-group") && child.is("div.ui-datepicker-group-last"), "Structure inline multi - second month division"); - child = dp.children(":eq(2)"); - ok(child.is("div.ui-datepicker-row-break"), "Structure inline multi - row break"); - inl.datepicker("destroy"); + ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); + equal( dp.children().length, 3, "Structure inline multi - child count" ); + + child = dp.children( ":first" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); + + inl.datepicker( "destroy" ); start(); }); } @@ -185,61 +208,103 @@ asyncTest("baseStructure", function() { step1(); }); -test("customStructure", function() { +asyncTest( "customStructure", function() { expect( 20 ); var header, panel, title, thead, - dp = $("#ui-datepicker-div"), - // Check right-to-left localisation - inp = TestHelpers.datepicker.init("#inp", $.datepicker.regional.he); - inp.datepicker( "option", "showButtonPanel", true); - inp.focus(); - ok(dp.is(".ui-datepicker-rtl"), "Structure RTL - right-to-left"); - header = dp.children(":first"); - ok(header.is("div.ui-datepicker-header"), "Structure RTL - header division"); - equal(header.children().length, 3, "Structure RTL - header child count"); - ok(header.children(":first").is("a.ui-datepicker-next"), "Structure RTL - prev link"); - ok(header.children(":eq(1)").is("a.ui-datepicker-prev"), "Structure RTL - next link"); - panel = dp.children(":last"); - ok(panel.is("div.ui-datepicker-buttonpane"), "Structure RTL - button division"); - equal(panel.children().length, 2, "Structure RTL - button panel child count"); - ok(panel.children(":first").is("button.ui-datepicker-close"), "Structure RTL - close button"); - ok(panel.children(":last").is("button.ui-datepicker-current"), "Structure RTL - today button"); - inp.datepicker("hide").datepicker("destroy"); + inp = TestHelpers.datepicker.initNewInput( $.datepicker.regional.he ), + dp = $( "#ui-datepicker-div" ); + + function step1() { + inp.datepicker( "option", "showButtonPanel", true ); + + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" ); + equal( header.children().length, 3, "Structure RTL - header child count" ); + ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" ); + ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" ); + + panel = dp.children( ":last" ); + ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" ); + equal( panel.children().length, 2, "Structure RTL - button panel child count" ); + ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" ); + ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step2(); + }); + } // Hide prev/next - inp = TestHelpers.datepicker.init("#inp", {hideIfNoPrevNext: true, minDate: new Date(2008, 2 - 1, 4), maxDate: new Date(2008, 2 - 1, 14)}); - inp.val("02/10/2008").focus(); - header = dp.children(":first"); - ok(header.is("div.ui-datepicker-header"), "Structure hide prev/next - header division"); - equal(header.children().length, 1, "Structure hide prev/next - links child count"); - ok(header.children(":first").is("div.ui-datepicker-title"), "Structure hide prev/next - title division"); - inp.datepicker("hide").datepicker("destroy"); + function step2() { + inp = TestHelpers.datepicker.initNewInput({ + hideIfNoPrevNext: true, + minDate: new Date( 2008, 2 - 1, 4 ), + maxDate: new Date( 2008, 2 - 1, 14 ) + }); + inp.val( "02/10/2008" ); + + TestHelpers.datepicker.onFocus( inp, function() { + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" ); + equal( header.children().length, 1, "Structure hide prev/next - links child count" ); + ok( header.children( ":first" ).is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step3(); + }); + } // Changeable Month with read-only year - inp = TestHelpers.datepicker.init("#inp", {changeMonth: true}); - inp.focus(); - title = dp.children(":first").children(":last"); - equal(title.children().length, 2, "Structure changeable month - title child count"); - ok(title.children(":first").is("select.ui-datepicker-month"), "Structure changeable month - month selector"); - ok(title.children(":last").is("span.ui-datepicker-year"), "Structure changeable month - read-only year"); - inp.datepicker("hide").datepicker("destroy"); + function step3() { + inp = TestHelpers.datepicker.initNewInput({ changeMonth: true }); + + TestHelpers.datepicker.onFocus( inp, function() { + title = dp.children( ":first" ).children( ":last" ); + equal( title.children().length, 2, "Structure changeable month - title child count" ); + ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); + ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step4(); + }); + } // Changeable year with read-only month - inp = TestHelpers.datepicker.init("#inp", {changeYear: true}); - inp.focus(); - title = dp.children(":first").children(":last"); - equal(title.children().length, 2, "Structure changeable year - title child count"); - ok(title.children(":first").is("span.ui-datepicker-month"), "Structure changeable year - read-only month"); - ok(title.children(":last").is("select.ui-datepicker-year"), "Structure changeable year - year selector"); - inp.datepicker("hide").datepicker("destroy"); + function step4() { + inp = TestHelpers.datepicker.initNewInput({ changeYear: true }); + + TestHelpers.datepicker.onFocus( inp, function() { + title = dp.children( ":first" ).children( ":last" ); + equal( title.children().length, 2, "Structure changeable year - title child count" ); + ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); + ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step5(); + }); + } // Read-only first day of week - inp = TestHelpers.datepicker.init("#inp", {changeFirstDay: false}); - inp.focus(); - thead = dp.find(".ui-datepicker-calendar thead tr"); - equal(thead.children().length, 7, "Structure read-only first day - thead child count"); - equal(thead.find("a").length, 0, "Structure read-only first day - thead links count"); - inp.datepicker("hide").datepicker("destroy"); + function step5() { + inp = TestHelpers.datepicker.initNewInput({ changeFirstDay: false }); + + TestHelpers.datepicker.onFocus( inp, function() { + thead = dp.find( ".ui-datepicker-calendar thead tr" ); + equal( thead.children().length, 7, "Structure read-only first day - thead child count" ); + equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + start(); + }); + } + + // TODO: figure out why this setTimeout is needed in IE, + // it only is necessary when the previous baseStructure tests runs first + // Support: IE + setTimeout( step1 ); }); test("keystrokes", function() { diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 1efd854a9..bcb2d28dd 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -87,115 +87,146 @@ test("change", function() { equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); }); -asyncTest("invocation", function() { - expect( 29 ); - var button, image, - inp = TestHelpers.datepicker.init("#inp"), - dp = $("#ui-datepicker-div"), - body = $("body"); +(function() { + var url = window.location.search; + url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) ); - function step1() { - // On focus - button = inp.siblings("button"); - ok(button.length === 0, "Focus - button absent"); - image = inp.siblings("img"); - ok(image.length === 0, "Focus - image absent"); - inp[0].focus(); - setTimeout(function() { - ok(dp.is(":visible"), "Focus - rendered on focus"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - ok(!dp.is(":visible"), "Focus - hidden on exit"); - inp[0].blur(); - setTimeout(function() { - inp[0].focus(); - setTimeout(function() { - ok(dp.is(":visible"), "Focus - rendered on focus"); - body.simulate("mousedown", {}); - ok(!dp.is(":visible"), "Focus - hidden on external click"); - inp.datepicker("hide").datepicker("destroy"); + // TODO: This test occassionally fails in IE in TestSwarm + if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) { + return; + } - step2(); + asyncTest( "invocation", function() { + var button, image, + isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ), + body = $( "body" ); + + expect( isOldIE ? 25 : 29 ); + + function step0() { + var inp = TestHelpers.datepicker.initNewInput(), + dp = $( "#ui-datepicker-div" ); + + button = inp.siblings( "button" ); + ok( button.length === 0, "Focus - button absent" ); + image = inp.siblings( "img" ); + ok( image.length === 0, "Focus - image absent" ); + + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Focus - rendered on focus" ); + inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); + step1(); + }); + } + + function step1() { + + var inp = TestHelpers.datepicker.initNewInput(), + dp = $( "#ui-datepicker-div" ); + + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Focus - rendered on focus" ); + body.simulate( "mousedown", {} ); + ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + step2(); + }); + } + + function step2() { + var inp = TestHelpers.datepicker.initNewInput({ + showOn: "button", + buttonText: "Popup" + }), + dp = $( "#ui-datepicker-div" ); + + ok( !dp.is( ":visible" ), "Button - initially hidden" ); + button = inp.siblings( "button" ); + image = inp.siblings( "img" ); + ok( button.length === 1, "Button - button present" ); + ok( image.length === 0, "Button - image absent" ); + equal( button.text(), "Popup", "Button - button text" ); + + TestHelpers.datepicker.onFocus( inp, function() { + ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); + button.click(); + ok( dp.is( ":visible" ), "Button - rendered on button click" ); + button.click(); + ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + step3(); + }); + } + + function step3() { + var inp = TestHelpers.datepicker.initNewInput({ + showOn: "button", + buttonImageOnly: true, + buttonImage: "images/calendar.gif", + buttonText: "Cal" + }), + dp = $( "#ui-datepicker-div" ); + + ok( !dp.is( ":visible" ), "Image button - initially hidden" ); + button = inp.siblings( "button" ); + ok( button.length === 0, "Image button - button absent" ); + image = inp.siblings( "img" ); + ok( image.length === 1, "Image button - image present" ); + ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); + equal( image.attr( "title" ), "Cal", "Image button - image text" ); + + TestHelpers.datepicker.onFocus( inp, function() { + ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); + image.click(); + ok( dp.is( ":visible" ), "Image button - rendered on image click" ); + image.click(); + ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + step4(); + }); + } + + function step4() { + var inp = TestHelpers.datepicker.initNewInput({ + showOn: "both", + buttonImage: "images/calendar.gif" + }), + dp = $( "#ui-datepicker-div" ); + + ok( !dp.is( ":visible" ), "Both - initially hidden" ); + button = inp.siblings( "button" ); + ok( button.length === 1, "Both - button present" ); + image = inp.siblings( "img" ); + ok( image.length === 0, "Both - image absent" ); + image = button.children( "img" ); + ok( image.length === 1, "Both - button image present" ); + + // TODO: This test occasionally fails to focus in IE8 in BrowserStack + if ( !isOldIE ) { + TestHelpers.datepicker.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Both - rendered on focus" ); + body.simulate( "mousedown", {} ); + ok( !dp.is( ":visible" ), "Both - hidden on external click" ); + button.click(); + ok( dp.is( ":visible" ), "Both - rendered on button click" ); + button.click(); + ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + start(); }); - }); - }); - } - - function step2() { - // On button - inp = TestHelpers.datepicker.init("#inp", {showOn: "button", buttonText: "Popup"}); - ok(!dp.is(":visible"), "Button - initially hidden"); - button = inp.siblings("button"); - image = inp.siblings("img"); - ok(button.length === 1, "Button - button present"); - ok(image.length === 0, "Button - image absent"); - equal(button.text(), "Popup", "Button - button text"); - inp[0].focus(); - setTimeout(function() { - ok(!dp.is(":visible"), "Button - not rendered on focus"); - button.click(); - ok(dp.is(":visible"), "Button - rendered on button click"); - button.click(); - ok(!dp.is(":visible"), "Button - hidden on second button click"); - inp.datepicker("hide").datepicker("destroy"); - - step3(); - }); - } - - function step3() { - // On image button - inp = TestHelpers.datepicker.init("#inp", {showOn: "button", buttonImageOnly: true, - buttonImage: "images/calendar.gif", buttonText: "Cal"}); - ok(!dp.is(":visible"), "Image button - initially hidden"); - button = inp.siblings("button"); - ok(button.length === 0, "Image button - button absent"); - image = inp.siblings("img"); - ok(image.length === 1, "Image button - image present"); - equal(image.attr("src"), "images/calendar.gif", "Image button - image source"); - equal(image.attr("title"), "Cal", "Image button - image text"); - inp[0].focus(); - setTimeout(function() { - ok(!dp.is(":visible"), "Image button - not rendered on focus"); - image.click(); - ok(dp.is(":visible"), "Image button - rendered on image click"); - image.click(); - ok(!dp.is(":visible"), "Image button - hidden on second image click"); - inp.datepicker("hide").datepicker("destroy"); - - step4(); - }); - } - - function step4() { - // On both - inp = TestHelpers.datepicker.init("#inp", {showOn: "both", buttonImage: "images/calendar.gif"}); - ok(!dp.is(":visible"), "Both - initially hidden"); - button = inp.siblings("button"); - ok(button.length === 1, "Both - button present"); - image = inp.siblings("img"); - ok(image.length === 0, "Both - image absent"); - image = button.children("img"); - ok(image.length === 1, "Both - button image present"); - inp[0].blur(); - setTimeout(function() { - inp[0].focus(); - setTimeout(function() { - ok(dp.is(":visible"), "Both - rendered on focus"); - body.simulate("mousedown", {}); - ok(!dp.is(":visible"), "Both - hidden on external click"); - button.click(); - ok(dp.is(":visible"), "Both - rendered on button click"); - button.click(); - ok(!dp.is(":visible"), "Both - hidden on second button click"); - inp.datepicker("hide").datepicker("destroy"); - + } else { start(); - }); - }); - } + } + } - step1(); -}); + step0(); + }); +})(); test("otherMonths", function() { expect( 8 ); @@ -1036,54 +1067,57 @@ test("formatDate", function() { settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; equal($.datepicker.formatDate("D M y", new Date(2001, 4 - 1, 9), settings), - "Lun. Avril 01", "Format date D M y with settings"); + "lun. avril 01", "Format date D M y with settings"); equal($.datepicker.formatDate("DD MM yy", new Date(2001, 4 - 1, 9), settings), - "Lundi Avril 2001", "Format date DD MM yy with settings"); + "lundi avril 2001", "Format date DD MM yy with settings"); equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), - "Lundi, Avril 9, 2001", "Format date DD, MM d, yy with settings"); + "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings"); equal($.datepicker.formatDate("'jour' d 'de' MM (''DD''), yy", - new Date(2001, 4 - 1, 9), settings), "jour 9 de Avril ('Lundi'), 2001", + new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001", "Format date 'jour' d 'de' MM (''DD''), yy with settings"); }); -test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ - expect( 1 ); - var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); - equal(time, "089"); -}); +// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos +// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ +// expect( 1 ); +// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); +// equal(time, "089"); +// }); -test("Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function(){ +test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() { expect( 3 ); - var inp = TestHelpers.datepicker.init("#inp",{ - beforeShow: function(){ - return false; - } - }), - dp = $("#ui-datepicker-div"); - inp.datepicker("show"); - equal(dp.css("display"), "none","beforeShow returns false"); - inp.datepicker("destroy"); - inp = TestHelpers.datepicker.init("#inp",{ - beforeShow: function(){ + var inp, dp; + + inp = TestHelpers.datepicker.init( "#inp", { + beforeShow: function() { } }); - dp = $("#ui-datepicker-div"); - inp.datepicker("show"); - equal(dp.css("display"), "block","beforeShow returns nothing"); - inp.datepicker("hide"); - inp.datepicker("destroy"); + dp = $( "#ui-datepicker-div" ); + inp.datepicker( "show" ); + equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); - inp = TestHelpers.datepicker.init("#inp",{ - beforeShow: function(){ + inp = TestHelpers.datepicker.init( "#inp", { + beforeShow: function() { return true; } }); - dp = $("#ui-datepicker-div"); - inp.datepicker("show"); - equal(dp.css("display"), "block","beforeShow returns true"); - inp.datepicker("hide"); - inp.datepicker("destroy"); + dp = $( "#ui-datepicker-div" ); + inp.datepicker( "show" ); + equal( dp.css( "display" ), "block", "beforeShow returns true" ); + inp.datepicker( "hide" ); + inp.datepicker( "destroy" ); + + inp = TestHelpers.datepicker.init( "#inp", { + beforeShow: function() { + return false; + } + }); + dp = $( "#ui-datepicker-div" ); + inp.datepicker( "show" ); + equal( dp.css( "display" ), "none","beforeShow returns false" ); + inp.datepicker( "destroy" ); }); })(jQuery); diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js index a9605edff..34b41bbc6 100644 --- a/tests/unit/datepicker/datepicker_test_helpers.js +++ b/tests/unit/datepicker/datepicker_test_helpers.js @@ -14,9 +14,14 @@ TestHelpers.datepicker = { d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()); equal(d1.toString(), d2.toString(), message); }, - init: function(id, options) { - $.datepicker.setDefaults($.datepicker.regional[""]); - return $(id).datepicker($.extend({showAnim: ""}, options || {})); + init: function( id, options ) { + $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); + return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) ); }, + initNewInput: function( options ) { + var id = $( "" ).appendTo( "#qunit-fixture" ); + return TestHelpers.datepicker.init( id, options ); + }, + onFocus: TestHelpers.onFocus, PROP_NAME: "datepicker" }; \ No newline at end of file diff --git a/tests/unit/datepicker/images/calendar.gif b/tests/unit/datepicker/images/calendar.gif index d0abaa7c0..52f2863c9 100644 Binary files a/tests/unit/datepicker/images/calendar.gif and b/tests/unit/datepicker/images/calendar.gif differ diff --git a/tests/unit/dialog/all.html b/tests/unit/dialog/all.html index 4bbf7abfd..9efbe3e50 100644 --- a/tests/unit/dialog/all.html +++ b/tests/unit/dialog/all.html @@ -4,7 +4,7 @@ jQuery UI Dialog Test Suite - + diff --git a/tests/unit/dialog/dialog.html b/tests/unit/dialog/dialog.html index 7943b425b..27c51276e 100644 --- a/tests/unit/dialog/dialog.html +++ b/tests/unit/dialog/dialog.html @@ -14,20 +14,20 @@ @@ -52,6 +52,8 @@
    + +
    ...
    Please share some personal information diff --git a/tests/unit/dialog/dialog_common.js b/tests/unit/dialog/dialog_common.js index ea4c91767..fc10fabaa 100644 --- a/tests/unit/dialog/dialog_common.js +++ b/tests/unit/dialog/dialog_common.js @@ -4,7 +4,7 @@ TestHelpers.commonWidgetTests( "dialog", { autoOpen: true, buttons: [], closeOnEscape: true, - closeText: "close", + closeText: "Close", disabled: false, dialogClass: "", draggable: true, diff --git a/tests/unit/dialog/dialog_core.js b/tests/unit/dialog/dialog_core.js index e85759dc9..c08019da9 100644 --- a/tests/unit/dialog/dialog_core.js +++ b/tests/unit/dialog/dialog_core.js @@ -4,6 +4,7 @@ (function($) { +// TODO add teardown callback to remove dialogs module("dialog: core"); test("title id", function() { @@ -40,7 +41,7 @@ test("widget method", function() { }); asyncTest( "focus tabbable", function() { - expect( 5 ); + expect( 6 ); var element, options = { buttons: [{ @@ -50,6 +51,12 @@ asyncTest( "focus tabbable", function() { }; function checkFocus( markup, options, testFn, next ) { + + // Support: IE8 + // For some reason the focus doesn't get set properly if we don't + // focus the body first. + $( "body" ).focus(); + element = $( markup ).dialog( options ); setTimeout(function() { testFn(); @@ -59,43 +66,57 @@ asyncTest( "focus tabbable", function() { } function step1() { - checkFocus( "
    ", options, function() { - equal( document.activeElement, element.find( "input" )[ 1 ], - "1. first element inside the dialog matching [autofocus]" ); - }, step2 ); + element = $( "
    " ).dialog( options ); + setTimeout(function() { + var input = element.find( "input:last" ).focus().blur(); + element.dialog( "instance" )._focusTabbable(); + setTimeout(function() { + equal( document.activeElement, input[ 0 ], + "1. an element that was focused previously." ); + element.remove(); + setTimeout( step2 ); + }); + }); } function step2() { - checkFocus( "
    ", options, function() { - equal( document.activeElement, element.find( "input" )[ 0 ], - "2. tabbable element inside the content element" ); + checkFocus( "
    ", options, function() { + equal( document.activeElement, element.find( "input" )[ 1 ], + "2. first element inside the dialog matching [autofocus]" ); }, step3 ); } function step3() { - checkFocus( "
    text
    ", options, function() { - equal( document.activeElement, - element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" )[ 0 ], - "3. tabbable element inside the buttonpane" ); + checkFocus( "
    ", options, function() { + equal( document.activeElement, element.find( "input" )[ 0 ], + "3. tabbable element inside the content element" ); }, step4 ); } function step4() { - checkFocus( "
    text
    ", {}, function() { + checkFocus( "
    text
    ", options, function() { equal( document.activeElement, - element.dialog( "widget" ).find( ".ui-dialog-titlebar .ui-dialog-titlebar-close" )[ 0 ], - "4. the close button" ); + element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" )[ 0 ], + "4. tabbable element inside the buttonpane" ); }, step5 ); } function step5() { + checkFocus( "
    text
    ", {}, function() { + equal( document.activeElement, + element.dialog( "widget" ).find( ".ui-dialog-titlebar .ui-dialog-titlebar-close" )[ 0 ], + "5. the close button" ); + }, step6 ); + } + + function step6() { element = $( "
    text
    " ).dialog({ autoOpen: false }); element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).hide(); element.dialog( "open" ); setTimeout(function() { - equal( document.activeElement, element.parent()[ 0 ], "5. the dialog itself" ); + equal( document.activeElement, element.parent()[ 0 ], "6. the dialog itself" ); element.remove(); start(); }); @@ -160,4 +181,51 @@ asyncTest( "#9048: multiple modal dialogs opened and closed in different order", start(); }); }); + +asyncTest( "interaction between overlay and other dialogs", function() { + $.widget( "ui.testWidget", $.ui.dialog, { + options: { + modal: true, + autoOpen: false + } + }); + expect( 2 ); + var first = $( "
    " ).dialog({ + modal: true + }), + firstInput = first.find( "input" ), + second = $( "
    " ).testWidget(), + secondInput = second.find( "input" ); + + // Support: IE8 + // For some reason the focus doesn't get set properly if we don't + // focus the body first. + $( "body" ).focus(); + + // Wait for the modal to init + setTimeout(function() { + second.testWidget( "open" ); + + // Simulate user tabbing from address bar to an element outside the dialog + $( "#favorite-animal" ).focus(); + setTimeout(function() { + equal( document.activeElement, secondInput[ 0 ] ); + + // Last active dialog must receive focus + firstInput.focus(); + $( "#favorite-animal" ).focus(); + setTimeout(function() { + equal( document.activeElement, firstInput[ 0 ] ); + + // Cleanup + first.remove(); + second.remove(); + delete $.ui.testWidget; + delete $.fn.testWidget; + start(); + }); + }); + }); +}); + })(jQuery); diff --git a/tests/unit/dialog/dialog_deprecated.html b/tests/unit/dialog/dialog_deprecated.html deleted file mode 100644 index 1f8bac689..000000000 --- a/tests/unit/dialog/dialog_deprecated.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - jQuery UI Dialog Test Suite - - - - - - - - - - - - - - - - - - - - -

    jQuery UI Dialog Test Suite

    -

    -
    -

    -
      -
      -
      -
      -
      -
      - Please share some personal information - - -
      -
      -

      Some more (optional) information

      - -
      -
      -
      -
      -
      - - diff --git a/tests/unit/dialog/dialog_deprecated.js b/tests/unit/dialog/dialog_deprecated.js deleted file mode 100644 index ff6284ea5..000000000 --- a/tests/unit/dialog/dialog_deprecated.js +++ /dev/null @@ -1,63 +0,0 @@ -module("dialog (deprecated): position option with string and array"); - -test( "position, right bottom on window w/array", function() { - expect( 2 ); - - // dialogs alter the window width and height in FF and IE7 - // so we collect that information before creating the dialog - // Support: FF, IE7 - var winWidth = $( window ).width(), - winHeight = $( window ).height(), - element = $("
      ").dialog({ position: [ "right", "bottom" ] }), - dialog = element.dialog("widget"), - offset = dialog.offset(); - closeEnough( offset.left, winWidth - dialog.outerWidth() + $( window ).scrollLeft(), 1, "offset left of right bottom on window w/array" ); - closeEnough( offset.top, winHeight - dialog.outerHeight() + $( window ).scrollTop(), 1, "offset top of right bottom on window w/array" ); - element.remove(); -}); - -test( "position, right bottom on window", function() { - expect( 2 ); - - // dialogs alter the window width and height in FF and IE7 - // so we collect that information before creating the dialog - // Support: FF, IE7 - var winWidth = $( window ).width(), - winHeight = $( window ).height(), - element = $("
      ").dialog({ position: "right bottom" }), - dialog = element.dialog("widget"), - offset = dialog.offset(); - closeEnough( offset.left, winWidth - dialog.outerWidth() + $( window ).scrollLeft(), 1, "offset left of right bottom on window" ); - closeEnough( offset.top, winHeight - dialog.outerHeight() + $( window ).scrollTop(), 1, "offset top of right bottom on window" ); - element.remove(); -}); - -test("position, offset from top left w/array", function() { - expect( 2 ); - var element = $("
      ").dialog({ position: [10, 10] }), - dialog = element.dialog("widget"), - offset = dialog.offset(); - closeEnough(offset.left, 10 + $(window).scrollLeft(), 1); - closeEnough(offset.top, 10 + $(window).scrollTop(), 1); - element.remove(); -}); - -test("position, top on window", function() { - expect( 2 ); - var element = $("
      ").dialog({ position: "top" }), - dialog = element.dialog("widget"), - offset = dialog.offset(); - closeEnough(offset.left, Math.round($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft(), 1); - closeEnough(offset.top, $(window).scrollTop(), 1); - element.remove(); -}); - -test("position, left on window", function() { - expect( 2 ); - var element = $("
      ").dialog({ position: "left" }), - dialog = element.dialog("widget"), - offset = dialog.offset(); - closeEnough(offset.left, 0, 1); - closeEnough(offset.top, Math.round($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop(), 1); - element.remove(); -}); diff --git a/tests/unit/dialog/dialog_events.js b/tests/unit/dialog/dialog_events.js index 7bcd5673e..1384500f6 100644 --- a/tests/unit/dialog/dialog_events.js +++ b/tests/unit/dialog/dialog_events.js @@ -11,7 +11,7 @@ test("open", function() { var element = $("
      "); element.dialog({ open: function(ev, ui) { - ok(element.data("ui-dialog")._isOpen, "interal _isOpen flag is set"); + ok(element.dialog( "instance" )._isOpen, "interal _isOpen flag is set"); ok(true, "autoOpen: true fires open callback"); equal(this, element[0], "context of callback"); equal(ev.type, "dialogopen", "event type in callback"); @@ -30,7 +30,7 @@ test("open", function() { deepEqual(ui, {}, "ui hash in callback"); } }).bind("dialogopen", function(ev, ui) { - ok(element.data("ui-dialog")._isOpen, "interal _isOpen flag is set"); + ok(element.dialog( "instance" )._isOpen, "interal _isOpen flag is set"); ok(true, "dialog('open') fires open event"); equal(this, element[0], "context of event"); deepEqual(ui, {}, "ui hash in event"); diff --git a/tests/unit/dialog/dialog_methods.js b/tests/unit/dialog/dialog_methods.js index 6de185513..d315e5fc3 100644 --- a/tests/unit/dialog/dialog_methods.js +++ b/tests/unit/dialog/dialog_methods.js @@ -63,21 +63,21 @@ test("destroy", function() { // Don't throw errors when destroying a never opened modal dialog (#9004) $( "#dialog1" ).dialog({ autoOpen: false, modal: true }).dialog( "destroy" ); equal( $( ".ui-widget-overlay" ).length, 0, "overlay does not exist" ); - equal( $.ui.dialog.overlayInstances, 0, "overlayInstances equals the number of open overlays"); + equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays"); element = $( "#dialog1" ).dialog({ modal: true }), element2 = $( "#dialog2" ).dialog({ modal: true }); equal( $( ".ui-widget-overlay" ).length, 2, "overlays created when dialogs are open" ); - equal( $.ui.dialog.overlayInstances, 2, "overlayInstances equals the number of open overlays" ); + equal( $( document ).data( "ui-dialog-overlays" ), 2, "ui-dialog-overlays equals the number of open overlays" ); element.dialog( "close" ); equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after closing one dialog" ); - equal( $.ui.dialog.overlayInstances, 1, "overlayInstances equals the number of open overlays" ); + equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); element.dialog( "destroy" ); equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after destroying one dialog" ); - equal( $.ui.dialog.overlayInstances, 1, "overlayInstances equals the number of open overlays" ); + equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); element2.dialog( "destroy" ); equal( $( ".ui-widget-overlay" ).length, 0, "overlays removed when all dialogs are destoryed" ); - equal( $.ui.dialog.overlayInstances, 0, "overlayInstances equals the number of open overlays" ); + equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays" ); }); asyncTest("#9000: Dialog leaves broken event handler after close/destroy in certain cases", function() { @@ -101,11 +101,13 @@ test("#4980: Destroy should place element back in original DOM position", functi }); test( "enable/disable disabled", function() { - expect( 2 ); + expect( 4 ); var element = $( "
      " ).dialog(); element.dialog( "disable" ); equal(element.dialog( "option", "disabled" ), false, "disable method doesn't do anything" ); ok( !element.dialog( "widget" ).hasClass( "ui-dialog-disabled" ), "disable method doesn't add ui-dialog-disabled class" ); + ok( !element.dialog( "widget" ).hasClass( "ui-state-disabled" ), "disable method doesn't add ui-state-disabled class" ); + ok( !element.dialog( "widget" ).attr( "aria-disabled" ), "disable method doesn't add aria-disabled" ); }); test("close", function() { @@ -142,8 +144,8 @@ test("moveToTop", function() { expect( 5 ); function order() { var actual = $( ".ui-dialog" ).map(function() { - return +$( this ).find( ".ui-dialog-content" ).attr( "id" ).replace( /\D+/, "" ); - }).get().reverse(); + return +$( this ).css( "z-index" ); + }).get(); deepEqual( actual, $.makeArray( arguments ) ); } var dialog1, dialog2, @@ -159,10 +161,23 @@ test("moveToTop", function() { equal( focusOn, "dialog2" ); } }); - order( 2, 1 ); + order( 100, 101 ); focusOn = "dialog1"; dialog1.dialog( "moveToTop" ); - order( 1, 2 ); + order( 102, 101 ); +}); + +test( "moveToTop: content scroll stays intact", function() { + expect( 2 ); + var otherDialog = $( "#dialog1" ).dialog(), + scrollDialog = $( "#form-dialog" ).dialog({ + height: 200 + }); + scrollDialog.scrollTop( 50 ); + equal( scrollDialog.scrollTop(), 50 ); + + otherDialog.dialog( "moveToTop" ); + equal( scrollDialog.scrollTop(), 50 ); }); test("open", function() { @@ -205,6 +220,11 @@ asyncTest( "#8958: dialog can be opened while opening", function() { } }); + // Support: IE8 + // For some reason the #favorite-color input doesn't get focus if we don't + // focus the body first, causing the test to hang. + $( "body" ).focus(); + $( "#favorite-animal" ) // We focus the input to start the test. Once it receives focus, the // dialog will open. Opening the dialog, will cause an element inside diff --git a/tests/unit/dialog/dialog_options.js b/tests/unit/dialog/dialog_options.js index 07c2d6860..66aeebde0 100644 --- a/tests/unit/dialog/dialog_options.js +++ b/tests/unit/dialog/dialog_options.js @@ -209,7 +209,7 @@ test("closeText", function() { expect(3); var element = $("
      ").dialog(); - equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "close", + equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "Close", "default close text"); element.remove(); diff --git a/tests/unit/draggable/all.html b/tests/unit/draggable/all.html index e096c88bd..7c4386661 100644 --- a/tests/unit/draggable/all.html +++ b/tests/unit/draggable/all.html @@ -4,7 +4,7 @@ jQuery UI Draggable Test Suite - + diff --git a/tests/unit/draggable/draggable.html b/tests/unit/draggable/draggable.html index c6f16ee17..1a381e314 100644 --- a/tests/unit/draggable/draggable.html +++ b/tests/unit/draggable/draggable.html @@ -8,8 +8,44 @@ @@ -17,18 +53,20 @@ + @@ -46,10 +84,15 @@

        -
        -
        Relative
        -
        Absolute
        -
        Absolute
        +
        +
        +
        Relative
        +
        Absolute
        +
        Absolute
        +
        +
        +
        +
        diff --git a/tests/unit/draggable/draggable_core.js b/tests/unit/draggable/draggable_core.js index 9875a481e..9e977b52d 100644 --- a/tests/unit/draggable/draggable_core.js +++ b/tests/unit/draggable/draggable_core.js @@ -4,18 +4,7 @@ (function( $ ) { -var relativeElement, absoluteElement; - -module( "draggable: core", { - setup: function() { - relativeElement = $("
        Relative
        ").appendTo("#qunit-fixture"); - absoluteElement = $("
        Absolute
        ").appendTo("#qunit-fixture"); - }, - teardown: function() { - relativeElement.remove(); - absoluteElement.remove(); - } -}); +module( "draggable: core" ); test( "element types", function() { var typeNames = ( @@ -54,37 +43,38 @@ test( "element types", function() { }); test( "No options, relative", function() { - expect( 1 ); - TestHelpers.draggable.shouldMove( relativeElement.draggable() ); + expect( 2 ); + TestHelpers.draggable.shouldMove( $( "#draggable1" ).draggable(), "no options, relative" ); }); test( "No options, absolute", function() { - expect( 1 ); - TestHelpers.draggable.shouldMove( absoluteElement.draggable() ); -}); - -test( "resizable handle with complex markup (#8756 / #8757)", function() { expect( 2 ); - - relativeElement - .append( - $("
        ") - .addClass("ui-resizable-handle ui-resizable-w") - .append( $("
        ") ) - ); - - var handle = $(".ui-resizable-w div"), - target = relativeElement.draggable().resizable({ handles: "all" }); - - // todo: fix resizable so it doesn't require a mouseover - handle.simulate("mouseover").simulate( "drag", { dx: -50 } ); - equal( target.width(), 250, "compare width" ); - - // todo: fix resizable so it doesn't require a mouseover - handle.simulate("mouseover").simulate( "drag", { dx: 50 } ); - equal( target.width(), 200, "compare width" ); + TestHelpers.draggable.shouldMove( $( "#draggable2" ).draggable(), "no options, absolute" ); }); +//TODO: re-enable when resizable is ported to interactions +// test( "resizable handle with complex markup (#8756 / #8757)", function() { +// expect( 2 ); + +// $( "#draggable1" ) +// .append( +// $("
        ") +// .addClass("ui-resizable-handle ui-resizable-w") +// .append( $("
        ") ) +// ); + +// var handle = $(".ui-resizable-w div"), +// target = $( "#draggable1" ).draggable().resizable({ handles: "all" }); + +// // todo: fix resizable so it doesn't require a mouseover +// handle.simulate("mouseover").simulate( "drag", { dx: -50 } ); +// equal( target.width(), 250, "compare width" ); + +// // todo: fix resizable so it doesn't require a mouseover +// handle.simulate("mouseover").simulate( "drag", { dx: 50 } ); +// equal( target.width(), 200, "compare width" ); +// }); + test("_blockFrames, absolute parent", function() { expect( 3 ); var el = $("#draggable1").draggable(), @@ -136,7 +126,6 @@ test("_blockFrames, relative parent", function() { equal( left, "30px" ); equal( top, "25px" ); - }); test("_blockFrames, static parent", function() { @@ -166,4 +155,216 @@ test("_blockFrames, static parent", function() { }); +test( "#8269: Removing draggable element on drop", function() { + expect( 2 ); + + var element = $( "#draggable1" ).wrap( "
        " ).draggable({ + stop: function() { + ok( true, "stop still called despite element being removed from DOM on drop" ); + } + }), + dropOffset = $( "#droppable" ).offset(); + + $( "#droppable" ).droppable({ + drop: function() { + $( "#wrapper" ).remove(); + ok( true, "element removed from DOM on drop" ); + } + }); + + // Support: Opera 12.10, Safari 5.1, jQuery <1.8 + if ( TestHelpers.draggable.unreliableContains ) { + ok( true, "Opera <12.14 and Safari <6.0 report wrong values for $.contains in jQuery < 1.8" ); + ok( true, "Opera <12.14 and Safari <6.0 report wrong values for $.contains in jQuery < 1.8" ); + } else { + element.simulate( "drag", { + handle: "corner", + x: dropOffset.left, + y: dropOffset.top + }); + } +}); + +test( "#6258: not following mouse when scrolled and using overflow-y: scroll", function() { + expect( 2 ); + + var element = $( "#draggable1" ).draggable({ + stop: function( event, ui ) { + equal( ui.position.left, 1, "left position is correct despite overflow on HTML" ); + equal( ui.position.top, 1, "top position is correct despite overflow on HTML" ); + $( "html" ) + .css( "overflow-y", oldOverflowY ) + .css( "overflow-x", oldOverflowX ) + .scrollTop( 0 ) + .scrollLeft( 0 ); + } + }), + oldOverflowY = $( "html" ).css( "overflow-y" ), + oldOverflowX = $( "html" ).css( "overflow-x" ); + + TestHelpers.forceScrollableWindow(); + + $( "html" ) + .css( "overflow-y", "scroll" ) + .css( "overflow-x", "scroll" ) + .scrollTop( 300 ) + .scrollLeft( 300 ); + + element.simulate( "drag", { + dx: 1, + dy: 1, + moves: 1 + }); +}); + +test( "#9315: jumps down with offset of scrollbar", function() { + expect( 2 ); + + var element = $( "#draggable2" ).draggable({ + stop: function( event, ui ) { + equal( ui.position.left, 11, "left position is correct when position is absolute" ); + equal( ui.position.top, 11, "top position is correct when position is absolute" ); + $( "html" ).scrollTop( 0 ).scrollLeft( 0 ); + } + }); + + TestHelpers.forceScrollableWindow(); + + $( "html" ).scrollTop( 300 ).scrollLeft( 300 ); + + element.simulate( "drag", { + dx: 1, + dy: 1, + moves: 1 + }); +}); + +test( "#5009: scroll not working with parent's position fixed", function() { + expect( 2 ); + + var startValue = 300, + element = $( "#draggable1" ).wrap( "
        " ).draggable({ + drag: function() { + startValue += 100; + $( document ).scrollTop( startValue ).scrollLeft( startValue ); + }, + stop: function( event, ui ) { + equal( ui.position.left, 10, "left position is correct when parent position is fixed" ); + equal( ui.position.top, 10, "top position is correct when parent position is fixed" ); + $( document ).scrollTop( 0 ).scrollLeft( 0 ); + } + }); + + TestHelpers.forceScrollableWindow(); + + $( "#wrapper" ).css( "position", "fixed" ); + + element.simulate( "drag", { + dx: 10, + dy: 10, + moves: 3 + }); +}); + +test( "#9379: Draggable: position bug in scrollable div", function() { + expect( 2 ); + + $( "#qunit-fixture" ).html( "
        a
        " ); + $( "#i_9379" ).css({ position: "absolute", width: "500px", height: "500px" }); + $( "#o_9379" ).css({ position: "absolute", width: "300px", height: "300px" }); + $( "#d_9379" ).css({ width: "10px", height: "10px" }); + + var moves = 3, + startValue = 0, + dragDelta = 20, + delta = 100, + + // we scroll after each drag event, so subtract 1 from number of moves for expected + expected = delta + ( ( moves - 1 ) * dragDelta ), + element = $( "#d_9379" ).draggable({ + drag: function() { + startValue += dragDelta; + $( "#o_9379" ).scrollTop( startValue ).scrollLeft( startValue ); + }, + stop: function( event, ui ) { + equal( ui.position.left, expected, "left position is correct when grandparent is scrolled" ); + equal( ui.position.top, expected, "top position is correct when grandparent is scrolled" ); + } + }); + + $( "#o_9379" ).css( "overflow", "auto" ); + + element.simulate( "drag", { + dy: delta, + dx: delta, + moves: moves + }); +}); + +test( "#5727: draggable from iframe", function() { + expect( 1 ); + + var iframeBody, draggable1, + iframe = $( " +
        + +
        +

        a bunch of content

        +
        + +
        Just another dialog to test stacking
        + + + diff --git a/tests/visual/effects/all.html b/tests/visual/effects/all.html index 8e7fe106e..0bdfcf7b2 100644 --- a/tests/visual/effects/all.html +++ b/tests/visual/effects/all.html @@ -4,21 +4,21 @@ jQuery UI Effects Test Suite - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/tests/visual/effects/scale.html b/tests/visual/effects/scale.html index 7fadb033e..73606cc70 100644 --- a/tests/visual/effects/scale.html +++ b/tests/visual/effects/scale.html @@ -4,9 +4,9 @@ jQuery UI Effects Test Suite - - - + + + + @@ -33,7 +33,11 @@

        Dialog

        Effects

        @@ -53,6 +57,11 @@
      1. Feedback
      2. +

        Selectmenu

        + +

        Tooltip

        • General
        • diff --git a/tests/visual/menu/menu.html b/tests/visual/menu/menu.html index 968c1662b..d58dcbc8b 100644 --- a/tests/visual/menu/menu.html +++ b/tests/visual/menu/menu.html @@ -3,19 +3,27 @@ Menu Visual Test: Default - - - - - - + + + + + + + + + +
          +

          Event logging tests

          +
          + + + + + + +
          + +
          +
          +
          + +
          +

          Disabled tests

          +
          + + + + + + + + + + + + + + +
          + +

          Empty tests

          +
          + + + + + + + + + + + +
          + +

          Width tests

          +
          + + + + + + + + + + + + + + +
          +
          + +
          + Log: +
          +
          + + + diff --git a/tests/visual/theme.html b/tests/visual/theme.html index 959d2af55..b70c4983a 100644 --- a/tests/visual/theme.html +++ b/tests/visual/theme.html @@ -1,532 +1,525 @@ - - - - jQuery UI Example Page - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + }); - -
          - -

          Accordion

          -
          -
          -
          -

          First

          -
          Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
          -
          -
          -

          Second

          -
          Phasellus mattis tincidunt nibh.
          -
          -
          -

          Third

          -
          Nam dui erat, auctor a, dignissim quis.
          -
          -
          + // Progressbar + $("#progressbar").progressbar({ + value: 20 + }); + + //hover states on the static widgets + $('#dialog_link, ul#icons li').hover( + function() { $(this).addClass('ui-state-hover'); }, + function() { $(this).removeClass('ui-state-hover'); } + ); + + $(".buttonset > button").button() + .next() + .button({ + text: false, + icons: { + primary: "ui-icon-triangle-1-s" + } + }) + .parent() + .buttonset(); + + + $('#beginning').button({ + text: false, + icons: { + primary: 'ui-icon-seek-start' + } + }); + $('#rewind').button({ + text: false, + icons: { + primary: 'ui-icon-seek-prev' + } + }); + $('#play').button({ + text: false, + icons: { + primary: 'ui-icon-play' + } + }); + $('#stop').button({ + text: false, + icons: { + primary: 'ui-icon-stop' + } + }); + $('#forward').button({ + text: false, + icons: { + primary: 'ui-icon-seek-next' + } + }); + $('#end').button({ + text: false, + icons: { + primary: 'ui-icon-seek-end' + } + }); + $("#shuffle").button(); + $("#repeat").buttonset(); + + }); + + + + + +
          + + +

          Accordion

          +
          +
          +
          +

          First

          +
          Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
          -
          -
          -
          -

          First no icons

          -
          Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
          -
          -
          -

          Second no icons

          -
          Phasellus mattis tincidunt nibh.
          -
          -
          -

          Third no icons

          -
          Nam dui erat, auctor a, dignissim quis.
          -
          -
          +
          +

          Second

          +
          Phasellus mattis tincidunt nibh.
          - - - -

          Tabs

          -
          - -
          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
          -
          Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.
          -
          Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.
          +
          +

          Third

          +
          Nam dui erat, auctor a, dignissim quis.
          - - -

          Dialog

          -

          Open Dialog

          - -
          Inline Dialogclose
          -

          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

          -
          - - -

          Overlay and Shadow Classes (not currently used in UI widgets)

          -
          -

          Lorem ipsum dolor sit amet, Nulla nec tortor. Donec id elit quis purus consectetur consequat.

          Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci.

          Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat.

          Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam.

          Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante.

          Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi.

          - - -
          -
          -
          -

          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

          -
          -
          - +
          +
          +
          +
          +
          +

          First no icons

          +
          Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
          +
          +

          Second no icons

          +
          Phasellus mattis tincidunt nibh.
          +
          +
          +

          Third no icons

          +
          Nam dui erat, auctor a, dignissim quis.
          +
          +
          +
          - -
          + +

          Tabs

          +
          + +
          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
          +
          Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.
          +
          Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.
          +
          + + +

          Dialog

          +

          Open Dialog

          + +
          Inline Dialogclose
          +

          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

          +
          + + +

          Overlay and Shadow Classes (not currently used in UI widgets)

          +
          +

          Lorem ipsum dolor sit amet, Nulla nec tortor. Donec id elit quis purus consectetur consequat.

          Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci.

          Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat.

          Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam.

          Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante.

          Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi.

          + + +
          +
          +

          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

          +
          + +
          + + + +
          +

          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

          +
          -

          Framework Icons (content color preview)

          -
            +

            Framework Icons (content color preview)

            +
              -
            • -
            • -
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • -
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • -
            • -
            • -
            • -
            • -
            • -
            +
          • +
          • +
          • +
          • +
          • +
          - -

          Slider

          -
          -
          -
          -
          -
          - 88 - 77 - 55 - 33 - 40 - 45 - 70 -
          -
          + +

          Slider

          +
          +
          +
          +
          +
          + 88 + 77 + 55 + 33 + 40 + 45 + 70 +
          +
          - -

          Datepicker

          -
          -
          -
          -
          -
          -
          + +

          Datepicker

          +
          +
          +
          +
          +
          +
          - -

          Progressbar

          -
          + +

          Progressbar

          +
          - -

          Highlight / Error

          -
          -
          -

          - Hey! Sample ui-state-highlight style.

          -
          -
          -
          -
          -
          -

          - Alert: Sample ui-state-error style.

          -
          -
          + +

          Highlight / Error

          +
          +
          +

          + Hey! Sample ui-state-highlight style.

          +
          +
          +
          +
          +
          +

          + Alert: Sample ui-state-error style.

          +
          +
          -

          Button

          +

          Button

          -
          - - -
          +
          + + +
          - - - - - - - + + + + + + + - + - - - - - - + + + + + + - + - - + + - - - + - - diff --git a/tests/visual/tooltip/animations.html b/tests/visual/tooltip/animations.html index cfb56a18b..95b33a02f 100644 --- a/tests/visual/tooltip/animations.html +++ b/tests/visual/tooltip/animations.html @@ -3,17 +3,17 @@ Tooltip Visual Test: Animations - - - - - - - - - - - + + + + + + + + + + +