diff --git a/.csscomb.json b/.csscomb.json new file mode 100644 index 00000000000..51f4b8ce6ac --- /dev/null +++ b/.csscomb.json @@ -0,0 +1,24 @@ +{ + "remove-empty-rulesets": true, + "always-semicolon": true, + "color-case": "lower", + "block-indent": "\t", + "color-shorthand": true, + "element-case": "lower", + "eof-newline": true, + "leading-zero": false, + "quotes": "double", + "sort-order-fallback": "abc", + "space-before-colon": "", + "space-after-colon": " ", + "space-before-combinator": " ", + "space-after-combinator": " ", + "space-between-declarations": "\n", + "space-before-opening-brace": " ", + "space-after-opening-brace": "\n", + "space-after-selector-delimiter": "\n", + "space-before-selector-delimiter": "", + "space-before-closing-brace": "\n", + "strip-spaces": true, + "unitless-zero": true +} diff --git a/.csslintrc b/.csslintrc new file mode 100644 index 00000000000..fbc95a0a750 --- /dev/null +++ b/.csslintrc @@ -0,0 +1,20 @@ +{ + "adjoining-classes": false, + "box-model": false, + "box-sizing": false, + "compatible-vendor-prefixes": false, + "duplicate-background-images": false, + "import": false, + "important": false, + "outline-none": false, + "overqualified-elements": false, + "text-indent": false, + + // These are not ideal but needed for current theme + "qualified-headings": false, + "regex-selectors": false, + "unqualified-attributes": false, + "universal-selector": false, + "unique-headings": false, + "vendor-prefix": false +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..679b38de766 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# This file is for unifying the coding style for different editors and IDEs +# See http://editorconfig.org/ + +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[external/**] +trim_trailing_whitespace = false +insert_final_newline = varies +end_of_line = varies \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..b7ca95b5b77 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# JS files must always use LF for tools to work +*.js eol=lf diff --git a/.gitignore b/.gitignore index 98473d11edd..3480a14ba30 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ combine/ compiled/ dist/ tmp/ +temp/ *.swp .gitignore @@ -18,5 +19,8 @@ branches # node build dependencies node_modules +# tests output +_tests/ + # phantom junit output -build/test-results/ \ No newline at end of file +build/test-results/ diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 00000000000..53c053fef6b --- /dev/null +++ b/.jscsrc @@ -0,0 +1,6 @@ +{ + "preset": "jquery", + + // We want to output all errors + "maxErrors": 1000000 +} diff --git a/.jshintrc b/.jshintrc index 13a9e01b91f..176632b5f1d 100644 --- a/.jshintrc +++ b/.jshintrc @@ -6,7 +6,6 @@ "expr": true, "immed": true, "noarg": true, - "onevar": true, "quotmark": "double", "smarttabs": true, "trailing": true, diff --git a/.travis.yml b/.travis.yml index f9972983835..1814fa29e79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,41 @@ -language: node_js -node_js: - - 0.8 -before_script: +language: php + +php: + - "5.5" + +sudo: required + +dist: trusty +cache: + directories: + - node_modules + +before_script: - npm install -g grunt-cli -branches: - only: - - master - - 1.3-stable + - npm install + - npm install -g casperjs + - npm i -g npm + +script: travis_wait npm run-script ci + env: - - JQUERIES=1.8.3 - JQUERIES=1.10.2 - - JQUERIES=2.0.3 + CITYPE=test + SUITES=-navigation/sequence/sequence-dialog-hash-key-tests.html,-navigation/sequence/sequence-push-state-disabled-path1-path2-dialog-hash-key-tests.html,-navigation/sequence/sequence-path1-path2-dialog-hash-key-tests.html + - JQUERIES=1.11.3 + CITYPE=test + SUITES=-navigation/sequence/sequence-dialog-hash-key-tests.html,-navigation/sequence/sequence-push-state-disabled-path1-path2-dialog-hash-key-tests.html,-navigation/sequence/sequence-path1-path2-dialog-hash-key-tests.html + - JQUERIES=2.2.4 + CITYPE=test + SUITES=-navigation/sequence/sequence-dialog-hash-key-tests.html,-navigation/sequence/sequence-push-state-disabled-path1-path2-dialog-hash-key-tests.html,-navigation/sequence/sequence-path1-path2-dialog-hash-key-tests.html + - JQUERIES=3.0.0 + CITYPE=test + SUITES=-navigation/sequence/sequence-dialog-hash-key-tests.html,-navigation/sequence/sequence-push-state-disabled-path1-path2-dialog-hash-key-tests.html,-navigation/sequence/sequence-path1-path2-dialog-hash-key-tests.html - JQUERIES=git + CITYPE=test + SUITES=-navigation/sequence/sequence-dialog-hash-key-tests.html,-navigation/sequence/sequence-push-state-disabled-path1-path2-dialog-hash-key-tests.html,-navigation/sequence/sequence-path1-path2-dialog-hash-key-tests.html + - CITYPE=demos + notifications: irc: channels: diff --git a/AUTHORS.txt b/AUTHORS.txt index c1bfb8ecd2f..83b403ace97 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,24 +1,24 @@ Authors ordered by first contribution -A list of current team members is available at http://jquery.org/team -Scott Jehl +Scott Jehl John Resig Scott González Jörn Zaefferer Kin Blas Douglas Neiner +jblas@adobe.com Todd Parker Patty Toland Jordan Dobson Burin Asavesna -Josh Dean +imjoshdean Brandon Aaron -Wu Yuntao -Gabriel Hollombe -Marek Majkowski +wuyuntao +Gabe Hollombe +marek Matt Curry -Jeffrey Way -Christoph Hochgatterer +Jeffrey Way +hochi Beau Smith Karan Bhangui Alexander Dimitrov @@ -27,48 +27,53 @@ Matt Lins Dave Penfold Jonathan Sharp D. Elmo Peele -Schalk Neethling +ossreleasefeed Ben Alman Alexandre Capt Richard Stutfield -Yuki Kodama +Yuki KODAMA Leon Brocard John Bender Eric Hynds Jesse Streb -Michael J Rubinsky -Mitchell Foley +Michael J. Rubinsky +Mitch Foley +louy Louy Alakkad Maggie Wachs Jonathan Hinkle Ben Clinkinbeard Pavel Karoukin -Dan Croak +Dan Croak Adam Messinger Alex Kovar -Chris Hubbard +chrisvire Mark Schuette +Torey Maerz Davide Bertola -Ryan Westphal +Ryan Michael O'Hearn +chrsMon Ernesto Jiménez -Tim Schaub +tschaub +unknown Ashley Streb -Martin Kou +Martin Kou Jim Hoskins -Steffen Baumgart +Bra1n +Martin Kou Mark Bennett -Eddie Monge Jr. -Dave Hulbert +Eddie Monge +Dave Hulbert Andrew Haller -Ray Carter +ray58750034 Phil Barnes -Kevin Hakanson -Alexander Wunschik +hakanson +Alexander Wunschik Ivan Rubanov Curtis Mathews Felipe Brahm -Brad Broulik +Brad Broulik Martin Kou Ray Ling Mario Zaizar @@ -83,16 +88,16 @@ Paul Nicholls Marek Stepien Ghislain Seguin Abhishek Joshi -Platon Dickey -Mike Woods +gnikibog +vtwoods Shana Golden Mat Marquis Matthias Derer Oliver Frietsch -Álvaro Lázaro Gallego +Álvaro Lázaro Wolfram Twelker -Luke Young -Adam Vaughan +Luke Young +Adam Vaughan Christoph Burgdorf Tobias Bosch Martin Sutherland @@ -100,17 +105,17 @@ Jacob Gable Konstantin Pozin Rick Waldron Wietse Venema -Eugen Bolz -Théophile Helleboid -Matthew Litwin -Sam Blowes +Eugen Bolz +Théophile Helleboid - chtitux +Matthew David Litwin +blowsie Ryan Neufeld Tak Tran -Matt Freeman -Mayank Varia +Matt +Mayank Varia Andy Matthews -James Brady -Samuel Padou +James Brady +Samuel Padou Faolan Cheslack-Postava Omar Vargas Casey Justus @@ -120,74 +125,79 @@ Max Rabin Michel Hartmann Richard D. Worth Michael Platov -Zach Leatherman -Hernán Schmidt +Zachary Leatherman +lagartoflojo Matt Doyle -Daniel Tao +dtao Maurice Gottlieb Hans-Peter Buniat -Brandon Johnson +Danny +Brandon Johnson Robert Gregor Gabriel Schulhof -Masataka Yakura +Masataka Yakura Gabriele Rabbiosi Matthew Leon Grinshpun Jake Boone -Riaz Missaghi -Michael D. H. Griffiths +unknown +Riaz +Michael Samat K Jain Alex Roberts Jean-Pierre Fiset -Charlie Collins +Charlie Collins Petko Bossakov Dan Heberden Garann Means -Anne-Gaelle Colom +Anne-Gaelle Colom Tyler Benziger Jason Crane +tichou Thomas Lallement -Ethan Romba +Ethan Romba Jonathan Rowny Stéphane Reynaud Peter Körner Luke Brookhart -Alexey Astafiev +Lamaster Marcus Lunzenauer Pavel Zubkou -Nicolas Bartoli -Sergei Grebnov +Nicolas Bartoli +sgrebnov Chetan K Jain Frederik Lassen +Sergei Grebnov James Burke Josh Dean -Jason Scott -Jasper de Groot +Jason Scott +Jasper de Groot Deric Crago -Dmitry Apresian -Teddy Caddy +dmapr Brian Antonelli -Eugene Pavliy +pavliy Robby Dermody Dave Methvin Richard Trott Ron Waldon Simon Ratner Toru Yoshikawa -Laurentiu Macovei +dotnetwise Elliot Smith Arne Hormann Jim Holby -Matthew Hensrud +Jason Scott +mbhnyc Dan Jacka -Jeff Gabhart -Eugene Baranov -Takashi Okamoto +Jeff Gabhart +ebaranov +Takashi Okamoto Adria Jimenez +Azuo Pavel Savara Alexander Casassovici Nicholas Hall Adrian Pike -Dirk Heider +drkhdr Darío Javier Cravero David L. Carrithers Corey Frang @@ -197,37 +207,91 @@ Marcin Szczepanski Robin Helgelin Elijah Manor Eric Caron -Jeroen Van Warmerdam +jerone Ryan McGeary Jonah Schulte +Alex Schmitz Alexander Schmitz Keith Pepin -Greg Franko +System Administrator Jeffrey Lembeck -Collin Forrester +Collin F +Collin F +Collin F Timo Tijhof Erwan MAS Jordan Harband -Changsuk Ha +Changsuk, Ha +Mathew Marquis +Wilto Oiva Eskola Erik Yuzwa -Jonathan Hogervorst +Jonathan Hogervorst Przemyslaw Ciezkowski +Nick Schonning Max Lynch John Chacko +Jonathan D. Knezek +unknown Ralph Whitbeck Jonathan Sampson -Tomas Cassidy +tomascassidy +Sergio Lavanga Aurelio De Rosa Brandon Belvin Sven Franck -Andrew Johnson +Aetherpoint Kangsik Kim +Amir Nathoo Craig Patik Rob Schmuecker Pere Orga Spencer Oberstadt -Richard Pangborn +PangbornIdentity Rocco Georgi -Hyunsook Park -Cristi Citea \ No newline at end of file +hyunsook +Cristi Citea +Calvin Tam +Patrick Stapleton +Lou Franco +Vasu Bhardwaj +Richard McDaniel +Timothy Elliott +Florian Böhle +Marcus Krahl +siokoshou +Cory Gackenheimer +Ben Harrison +Dick van den Brink +Dylan Barrell +Markus Staab +Mike Pennisi +Jules Gravinese +Dimitri Benin +Peter Dave Hello +Rob DiCiuccio +Simon Reinhardt +TrueEddie +Josh Kalderimis +Lisa Seacat DeLuca +Ian Maffett +Amanpreet Singh +Sho Sawada +Kakul Chandra +Kapil Garg +Mate Solymosi +Andrew Page +Adam Mesha +Veres Lajos +Kevin Kirsche +Sarah Frisk +Patrick H. Lauke +Willy Aguirre +Romeo Zivoin +Shawn Miller +kapil garg +Michał Gołębiowski +Brad Tippett +Sonali-Goyal +Ivan Enderlin +Robert Cochran diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de0fd39ce12..b2da960e950 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,14 +1,21 @@ -## Contribution Guides +# Contributing to jQuery Mobile -In the spirit of open source software development, jQuery always encourages community code contribution. To help you get started and before you jump into writing code, be sure to read these important contribution guidelines thoroughly: +Welcome! Thanks for your interest in contributing to jQuery Mobile. You're **almost** in the right place. More 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/). + + +## Getting Involved + +More information about the project, the jQuery Mobile team, our weekly meetings, and how to get more involved can be found on the "[About](http://jquerymobile.com/about/)" page on the project website. On this page we provide project specific information regarding [reporting bugs](#issues), [suggesting new features](#feature-requests), and [contributing code or content](#pull-requests). Please take a moment to read this before opening a ticket or submitting a pull request. -1. [Getting Involved](http://contribute.jquery.org/) -2. [Code Style Guide](http://contribute.jquery.org/style-guide/) ## Issues If you encounter a bug in the framework you can report it on the issue tracker here on Github. Questions about how to use the framework or problems with your custom code can be posted on the [forum](https://forum.jquery.com/jquery-mobile). -The jQuery Mobile [API Documentation](https://github.com/jquery/api.jquerymobile.com), [ThemeRoller](https://github.com/jquery/web-jquery-mobile-theme-roller) and [Download Builder](https://github.com/jquery/jquery-mobile-builder) have their own repo where you can report issues. +The jQuery Mobile [API Documentation](https://github.com/jquery/api.jquerymobile.com), [ThemeRoller](https://github.com/jquery/themeroller.jquerymobile.com) and [Download Builder](https://github.com/jquery/jquerymobile.com) have their own repo where you can report issues. Before opening a new issue please check if the same or a similar issue already has been reported. Tip: Besides the search tool of the issue tracker you can filter issues by label. @@ -21,9 +28,10 @@ When [submitting an issue](https://github.com/jquery/jquery-mobile/issues/new) i 5. Actual outcome 6. Platforms/browsers (including version) and devices tested 7. jQuery Mobile and jQuery core version used -8. Other relevant information, e.g. using PhoneGap +8. Other relevant information, e.g. using Apache Cordova + +In the interest of creating readable issues please include code snippets inside a triple backtick box appropriate for the JavaScript, CSS, or HTML snippet you wish to discuss. More information is available on the [introduction page](http://github.github.com/github-flavored-markdown/) for GitHub Flavored Markdown (see Syntax Highlighting). -In the interest of creating more readable issues please include code snippets inside a triple backtick box appropriate for the JavaScript/HTML/CSS snippet you wish to discuss. More information is available at the [introduction page](http://github.github.com/github-flavored-markdown/) for github flavored markdown (see Syntax Highlighting). ### Test page @@ -33,7 +41,7 @@ It is IMPORTANT that you always provide a test page when submitting an issue! * What? - Keep the test page as simple as possible. Only include markup/code that is required to reproduce the issue. -* How? - Use our [JS Bin template](http://jsbin.com/IFolanOW/1/edit) which uses latest code on branch "master". Do not replace the links to the the framework CSS and JavaScript: always test with latest code! +* How? - Use our [JS Bin template](http://jsbin.com/huvoraba/1/edit) which uses latest code on branch "master". Do not replace the links to the the framework CSS and JavaScript: always test with latest code! * You will notice if the issue has been fixed already * It enables us to edit your code if necessary @@ -42,6 +50,7 @@ It is IMPORTANT that you always provide a test page when submitting an issue! JS Bin instructions: When you start editing the JS Bin, the url will update and contain a new version number. As long as you keep the JS Bin open in your browser this url won't change. Copy the url in your issue report when you are done editing. If your test case requires multiple "single" jQuery Mobile pages, open the JS Bin on multiple tabs on your browser and each of them will get an unique url. Link to this url without "/edit" at the end on your other page(s). + ## Feature Requests If you have an idea for a new feature or a suggestion how to improve an existing feature, let us know! @@ -51,34 +60,109 @@ If you have an idea for a new feature or a suggestion how to improve an existing Please note that we will flag the issue as feature request and then close it. We check requests on regular base and when we decide to implement a feature we set a milestone and re-open the ticket. + ## Pull Requests -When submitting a pull request for review there are a few important steps you can take to ensure that it gets reviewed quickly and increase the chances that it will be merged (in order of descending importance): +When submitting a pull request for review there are a few important steps you have to take to ensure that it gets reviewed quickly and increase the chances that it will be merged: + +* If you are new to contributing code or content to jQuery projects, read the information at [contribute.jquery.org](http://contribute.jquery.org/) first +* Make sure you have signed the [CLA](http://contribute.jquery.org/CLA/) +* Before opening a pull request for a bug fix or new feature, make sure there is a ticket for it (don't include a bug report in a pull request) +* Limit the scope to one issue/feature +* Add and run unit tests +* Follow the [style guides](http://contribute.jquery.org/style-guide/) +* Follow the [commit message guidelines](http://contribute.jquery.org/commits-and-pull-requests/#commit-guidelines) + +If you need help or feedback, or want to get more involved in the jQuery Mobile project, don't hesitate to reach out to us. You can find us on [IRC](http://irc.jquery.org/) in #jqueryui-dev (Freenode). + + +### Tips For Bug Patching + + +#### Environment: localhost with PHP, Node.js, and Grunt + +jQuery Mobile uses Node.js and Grunt to automate the building and validation of source code. + +The Demos depend on PHP running locally, so make sure you have the following installed: + +* 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](http://gruntjs.com/) (install with: `npm install -g grunt-cli`) + + +#### Build a Local Copy of jQuery Mobile + +Create a fork of the jQuery Mobile repo on GitHub at http://github.com/jquery/jquery-mobile. + +Change directory to your web root directory, whatever that might be: + +```bash +$ cd /path/to/your/www/root/ +``` + +Clone your jQuery Mobile fork to work locally. + +*Note: be sure to replace `[USERNAME]` with your GitHub username.* + +```bash +$ git clone git@github.com:[USERNAME]/jquery-mobile.git +``` + +Change to the newly created directory. + +```bash +$ cd jquery-mobile +``` + +Add the official jQuery repository as a remote. We recommend naming it "upstream". + +```bash +$ git remote add upstream git://github.com/jquery/jquery-mobile.git +``` + +Get in the habit of pulling in the "upstream" master to stay up to date as jQuery Mobile receives new commits. + +```bash +$ git pull upstream master +``` + +Install the dependencies. + +```bash +npm install +``` + +To lint the JavaScript and CSS, as well as build the Demos, run grunt: + +```bash +$ grunt +``` + + +#### Testing + +You can run all the test suites by running the following command: -1. Include tests (see [Testing](https://github.com/jquery/jquery-mobile/blob/master/README.md#testing)) -2. Follow the [jQuery Core style guide](http://docs.jquery.com/JQuery_Core_Style_Guidelines) -3. Limit the scope to one Issue/Feature -4. Small focused commits, ideally less than 10 to 20 lines -5. Avoid merge commits (see Pro Git's [chapter on rebasing](http://git-scm.com/book/ch3-6.html), section [Rebasing](#rebasing) below) -6. Add the appropriate commit message (see below) +```bash +$ grunt test +``` -Taken together, the above reduces the effort that's required of the contributor reviewing your pull request. +You can choose to run only a subset of the tests by adding the `--suites` option like: -### Commit messages +```bash +$ grunt test --suites=button,checkboxradio +``` -Commit messages should include four components: +will only run the tests under `tests/unit/button/` and `tests/unit/checkboxradio/`. -* The WHERE - a single word that categorizes and provides context for the commit and its message, followed by a colon (:). This is typically the name of the plugin being worked on, but sometimes might be something like Build: or Docs: -* The WHAT - a sufficient summary of the fix or change made (example: modified the foo to no longer bar), followed by a period (.) -* The WHY #Num - the ticket number with a #sign so Trac creates a hyperlink (example: #1234), followed by a hyphen/dash (-) -* The WHY Name - the name of the ticket. Notice this is different than summary of the fix. This is a short description of the issue (example: dialog: IE6 crashed when foo is set to bar) +You can also specify which versions of jQuery you want to test jQuery Mobile with by using the `--jqueries` option: -Combined into one, here's a full example: +```bash +$ grunt test --jqueries=1.11.1,git +``` - "Dialog: modified the foo to no longer bar. Fixed #1234 - dialog: IE6 crashed when foo is set to bar" - \WHERE/:\------------- WHAT -------------/.\ WHY #Num /-\---------------- WHY Name ----------------/ -### Rebasing +#### Rebasing Often times when working on a feature or bug fix branch it's useful to pull in the latest from the parent branch. If you're doing this _before_ submitting a pull request it's best to use git's rebase to apply your commits onto the latest from the parent branch. For example, working on `new-feature` branch where `upstream` is the remote at `git://github.com/jquery/jquery-mobile.git`: diff --git a/Gruntfile.js b/Gruntfile.js index c8637f54c38..3237959f7ba 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,94 +1,26 @@ module.exports = function( grunt ) { - "use strict"; - - var _ = require( "underscore" ), - - replaceCombinedCssReference = function( content, processedName ) { - return content.replace( /\.\.\/css\//, "css/" ) - .replace( /jquery\.mobile\.css/gi, processedName + ".min.css" ); - }, - - // Ensure that modules specified via the --modules option are in the same - // order as the one in which they appear in js/jquery.mobile.js. To achieve - // this, we parse js/jquery.mobile.js and reconstruct the array of - // dependencies listed therein. - makeModulesList = function( modules ) { - var start, end, index, - modulesHash = {}, - fixedModules = [], - jsFile = grunt.file.read( path.join( "js", "jquery.mobile.js" ) ); - - modules = modules.split( "," ); - - // This is highly dependent on the contents of js/jquery.mobile.js - if ( jsFile ) { - start = jsFile.indexOf( "[" ); - if ( start > -1 ) { - start++; - end = jsFile.indexOf( "]" ); - if ( start < jsFile.length && - end > -1 && end < jsFile.length && end > start ) { - - // Convert list of desired modules to a hash - for ( index = 0 ; index < modules.length ; index++ ) { - modulesHash[ modules[ index ] ] = true; - } - - // Split list of modules from js/jquery.mobile.js into an array - jsFile = jsFile - .slice( start, end ) - .match( /"[^"]*"/gm ); - - // Add each desired module to the fixed list of modules in the - // correct order - for ( index = 0 ; index < jsFile.length ; index++ ) { - - // First we need to touch up each module from js/jquery.mobile.js - jsFile[ index ] = jsFile[ index ] - .replace( /"/g, "" ) - .replace( /^.\//, "" ); - - // Then, if it's in the hash of desired modules, add it to the - // list containing the desired modules in the correct order - if ( modulesHash[ jsFile[ index ] ] ) { - fixedModules.push( jsFile[ index ] ); - } - } - - // If we've found all the desired modules, we re-create the comma- - // separated list and return it. - if ( fixedModules.length === modules.length ) { - modules = fixedModules; - } - } - } - } - - return modules; - }, - path = require( "path" ), - httpPort = Math.floor( 9000 + Math.random()*1000 ), - name = "jquery.mobile", - dist = "dist" + path.sep, - copyrightYear = grunt.template.today( "UTC:yyyy" ), - banner = { - normal: [ - "/*!", - "* jQuery Mobile <%= version %>", - "* <%if ( headHash ) {%>Git HEAD hash: <%= headHash %> <> <% } %>Date: "+ grunt.template.today( "UTC:ddd mmm d yyyy HH:MM:ss Z" ), - "* http://jquerymobile.com", - "*", - "* Copyright 2010, " + copyrightYear + " jQuery Foundation, Inc. and other contributors", - "* Released under the MIT license.", - "* http://jquery.org/license", - "*", - "*/", - "", - "", - "" ].join( grunt.util.linefeed ), - minified: "/*! jQuery Mobile <%= version %> | <%if ( headShortHash ) {%>Git HEAD hash: <%= headShortHash %> <> <% } %>" + grunt.template.today( "UTC:yyyy-mm-dd" ) + "T" + grunt.template.today( "UTC:HH:MM:ss" ) + "Z | (c) 2010, " + copyrightYear + " jQuery Foundation, Inc. | jquery.org/license */\n" - }, - dirs = { +"use strict"; + +var path = require( "path" ); +var dist = "dist" + path.sep; +var today = grunt.template.today( "UTC:yyyy" ); + +require( "load-grunt-config" )( grunt, { + configPath: [ + path.join( process.cwd(), "build/tasks/options" ), + path.join( process.cwd(), "build/tasks" ) + ], + init: true, + data: { + pkg: grunt.file.readJSON( "package.json" ), + dist: dist, + name: "jquery.mobile", + phpPort: Math.floor( 8000 + Math.random() * 1000 ), + versionSuffix: "", + headHash: "", + headShortHash: "", + version: "<%= version %>", + dirs: { dist: dist, cdn: { google: path.join( dist, "cdn-google" ), @@ -97,699 +29,28 @@ module.exports = function( grunt ) { }, tmp: path.join( dist, "tmp" ) }, - files = { - css: { - structure: { - src: "css/structure/jquery.mobile.structure.css", - unminified: name + ".structure<%= versionSuffix %>.css" - }, - theme: { - src: "css/themes/default/jquery.mobile.theme.css", - unminified: name + ".theme<%= versionSuffix %>.css" - }, - bundle: { - src: "css/themes/default/jquery.mobile.css", - unminified: name + "<%= versionSuffix %>.css" - }, - inlinesvg: { - src: "css/themes/default/jquery.mobile.inline-svg.css", - unminified: name + ".inline-svg<%= versionSuffix %>.css" - }, - inlinepng: { - src: "css/themes/default/jquery.mobile.inline-png.css", - unminified: name + ".inline-png<%= versionSuffix %>.css" - }, - externalpng: { - src: "css/themes/default/jquery.mobile.external-png.css", - unminified: name + ".external-png<%= versionSuffix %>.css" - }, - icons: { - src: "css/themes/default/jquery.mobile.icons.css", - unminified: name + ".icons<%= versionSuffix %>.css" - } - }, - getCSSFiles: function( destDir ) { - destDir = destDir || "."; - var list = []; - _.values( files.css ).forEach( function( value ) { - list.push({ - src: value.src, - dest: path.join( destDir, value.unminified ) - }); - }); - return list; - }, - getMinifiedCSSFiles: function( destDir ) { - destDir = destDir || "."; - var list = []; - _.values( files.css ).forEach( function( value ) { - list.push({ - src: path.join( destDir, value.unminified ), - dest: path.join( destDir, value.minified ) - }); - }); - return list; - }, - cdn: [ - name + "<%= versionSuffix %>.js", - name + "<%= versionSuffix %>.min.js", - name + "<%= versionSuffix %>.min.map", - - "<%= files.css.structure.unminified %>", - "<%= files.css.structure.minified %>", - "<%= files.css.bundle.unminified %>", - "<%= files.css.bundle.minified %>", - "<%= files.css.inlinesvg.unminified %>", - "<%= files.css.inlinesvg.minified %>", - "<%= files.css.inlinepng.unminified %>", - "<%= files.css.inlinepng.minified %>", - "<%= files.css.externalpng.unminified %>", - "<%= files.css.externalpng.minified %>", - "<%= files.css.icons.unminified %>", - "<%= files.css.icons.minified %>", - - "images/*.*", - "images/icons-png/**" - ], - - distZipContent: [ - "<%= files.cdn %>", - - "<%= files.css.theme.unminified %>", - "<%= files.css.theme.minified %>", - - "images/icons-svg/**", - "demos/**" - ], - - zipFileName: name + "<%= versionSuffix %>.zip", - - distZipOut: path.join( dist, name + "<%= versionSuffix %>.zip" ), - - imagesZipOut: path.join( dist, name + ".images<%= versionSuffix %>.zip" ), - - googleCDNZipOut: path.join( "<%= dirs.cdn.google %>","<%= files.zipFileName %>" ) - }; - - // Add minified property to files.css.* - _.forEach( files.css, function( o ) { - o.minified = o.unminified.replace( /\.css$/, ".min.css" ); - }); - - // Project configuration. - grunt.config.init({ - pkg: grunt.file.readJSON( "package.json" ), - - version: "<%= pkg.version %>", - - versionSuffix: "", - - headHash: "", - - headShortHash: "", - - dirs: dirs, - - files: files, - - jshint: { - js: { - options: { - jshintrc: "js/.jshintrc" - }, - files: { - src: [ - "js/**/*.js", - "!js/jquery.hashchange.js", - "!js/jquery.js", - "!js/jquery.ui.widget.js", - "!js/widgets/jquery.ui.tabs.js", - "!js/jquery.ui.core.js" - ] - } - }, - grunt: { - options: { - jshintrc: ".jshintrc" - }, - files: { - src: [ "Gruntfile.js" ] - } - } - }, - - requirejs: { - js: { - options: { - baseUrl: "js", - - optimize: "none", - - //Finds require() dependencies inside a require() or define call. - findNestedDependencies: true, - - //If skipModuleInsertion is false, then files that do not use define() - //to define modules will get a define() placeholder inserted for them. - //Also, require.pause/resume calls will be inserted. - //Set it to true to avoid this. This is useful if you are building code that - //does not use require() in the built project or in the JS files, but you - //still want to use the optimization tool from RequireJS to concatenate modules - //together. - skipModuleInsertion: true, - - mainConfigFile: "js/requirejs.config.js", - - include: ( grunt.option( "modules" ) ? - makeModulesList( grunt.option( "modules" ) ) : - [ "jquery.mobile" ] ), - - exclude: [ - "jquery", - "json", - "json!../package.json" - ], - - out: path.join( dist, name ) + "<%= versionSuffix %>.js", - - pragmasOnSave: { - jqmBuildExclude: true - }, - - //File paths are relative to the build file, or if running a commmand - //line build, the current directory. - wrap: { - startFile: "build/wrap.start", - endFile: "build/wrap.end" - }, - - onBuildWrite: function (moduleName, path, contents) { - return contents.replace(/__version__/g, grunt.config.process( "\"<%= version %>\"" ) ); - } - } - } - }, - - concat: { - js: { - options: { - banner: banner.normal - }, - - src: [ path.join( dist, name ) + "<%= versionSuffix %>.js" ], - dest: path.join( dist, name ) + "<%= versionSuffix %>.js" - }, - demos: { - src: [ "demos/_assets/js/*.js" ], - dest: path.join( dist, "demos/_assets/js/index.js" ) - } - }, - - uglify: { - all: { - options: { - banner: banner.minified, - sourceMap: path.join( dist, name ) + "<%= versionSuffix %>.min.map", - sourceMappingURL: name + "<%= versionSuffix %>.min.map", - beautify: { - ascii_only: true - } - }, - files: { - "dist/jquery.mobile<%= versionSuffix %>.min.js": path.join( dist, name ) + "<%= versionSuffix %>.js" - } - } - }, - - cssbuild: { - options: { - banner: banner.normal, - - //Allow CSS optimizations. Allowed values: - //- "standard": @import inlining, comment removal and line returns. - //Removing line returns may have problems in IE, depending on the type - //of CSS. - //- "standard.keepLines": like "standard" but keeps line returns. - //- "none": skip CSS optimizations. - //- "standard.keepComments": keeps the file comments, but removes line - //returns. (r.js 1.0.8+) - //- "standard.keepComments.keepLines": keeps the file comments and line - //returns. (r.js 1.0.8+) - optimizeCss: "standard.keepComments.keepLines", - - //If optimizeCss is in use, a list of of files to ignore for the @import - //inlining. The value of this option should be a string of comma separated - //CSS file names to ignore (like 'a.css,b.css'. The file names should match - //whatever strings are used in the @import calls. - cssImportIgnore: null - }, - all: { - files: files.getCSSFiles( dist ) - } - }, - - cssmin: { - options: { - banner: banner.minified, - keepSpecialComments: 0 - }, - minify: { - files: files.getMinifiedCSSFiles( dist ), - } - }, - - copy: { - images: { - expand: true, - cwd: "css/themes/default/images", - src: "**", - dest: path.join( dist, "images/" ) - }, - "demos.nested-includes": { - options: { - // TODO duplicated in demos.firstpass - processContent: function( content, srcPath ) { - content = content.replace( /^\s*<\?php include\(\s*['"]([^'"]+)['"].*$/gmi, - function( match, includePath /*, offset, string */ ) { - - var fileToInclude = path.resolve( path.join( path.dirname( srcPath ), includePath ) ); - return grunt.file.read( fileToInclude ); - } - ); - return content; - } - }, - files: [ - { - expand: true, - src: [ "demos/jqm-contents.php", "demos/jqm-navmenu.php", "demos/jqm-search.php" ], - dest: dist - } - ] - - }, - "demos.processed": { - options: { - processContent: function( content, srcPath ) { - var processedName = grunt.config.process( name + "<%= versionSuffix %>" ); - content = content.replace( /_assets\/js\/">/gi, "_assets/js/index.js\">" ); - content = content.replace( /\.\.\/js\//gi, "js/" ); - content = content.replace( /js\/"/gi, "js/" + processedName + ".min.js\"" ); - content = replaceCombinedCssReference( content, processedName ); - content = content.replace( /^\s*<\?php include\(\s*['"]([^'"]+)['"].*$/gmi, - function( match, includePath /*, offset, string */ ) { - var fileToInclude, newSrcPath = srcPath; - - // If we've already handled the nested includes use the version - // that was copied to the dist folder - // TODO use the config from copy:demos.nested.files - if( includePath.match(/jqm\-contents.php|jqm\-navmenu.php|jqm\-search.php/) ) { - newSrcPath = "dist/" + newSrcPath; - } - - fileToInclude = path.resolve( path.join(path.dirname(newSrcPath), includePath) ); - - return grunt.file.read( fileToInclude ); - } - ); - content = content.replace( /\.php/gi, ".html" ); - - // Demos that separately refer to the structure need to be processed here - content = content.replace( /css\/structure\/jquery\.mobile\.structure\.css/gi, - path.join( "css", "themes", "default", processedName + ".structure" + ".min.css" ) ); - - // References to the icons CSS file need to be processed here - content = content.replace( /css\/themes\/default\/jquery\.mobile\.icons\.css/gi, - path.join( "..", "jquery.mobile.icons.min.css" ) ); - return content; - } - }, - files: [ - { - expand: true, - src: [ "index.php", "demos/**/*.php", "demos/**/*.html", "!demos/navigation-php-redirect/**" ], - dest: dist, - ext: ".html" - } - ] - }, - "demos.backbone": { - options: { - processContent: function( content /*, srcPath */ ) { - var processedName = grunt.config.process( name + "<%= versionSuffix %>" ); - content = content.replace( /"jquery": "\.\.\/\.\.\/\.\.\/js\/jquery"/, - "\"jquery\": \"../../js/jquery\"" ); - content = replaceCombinedCssReference( content, processedName ); - - // Update dependency to jquery.mobile claimed by jquerymobile.js - content = content.replace( /\[ "\.\.\/\.\.\/js\/\?noext" \]/, - "[ \"../../../" + processedName + "\" ]" ); - return content; - } - }, - files: [ - { - expand: true, - src: [ "demos/backbone-requirejs/**/*" ], - dest: dist - } - ] - }, - "demos.unprocessed": { - files: [ - { - expand: true, - cwd: "js", - src: [ "jquery.js" ], - dest: path.join( dist, "demos/js/" ) - }, - { - expand: true, - cwd: dist, - src: [ "*.js", "*.map" ], - dest: path.join( dist, "demos/js/" ) - }, - { - expand: true, - cwd: dist, - src: [ - "images/**" - ].concat( _.pluck( files.getMinifiedCSSFiles(), "dest" ) ), - dest: path.join( dist, "demos/css/themes/default/" ) - }, - { - expand: true, - src: [ "demos/**/*", "!**/*.php", "!**/*.html", "!demos/backbone-requirejs/**/*" ], - dest: dist - } - ] - }, - sourcemap: { - // Processes the sourceMap to fix issue: https://github.com/mishoo/UglifyJS2/issues/47 - options: { - processContent: function( content /*, srcPath*/ ) { - content = content.replace( /"dist\//g, "\"" ); - return content; - } - }, - files: [ - { - src: "<%= uglify.all.options.sourceMap %>", - dest: "<%= uglify.all.options.sourceMap %>" - } - ] - }, - "jqueryCDN": { - files: [{ - expand: true, - cwd: dist, - src: "<%= files.cdn %>", - dest: "<%= dirs.cdn.jquery %>/" - }] - }, - "googleCDN": { - options: { - processContent: function( content, srcPath ) { - if ( /\.min.js$|\.min.map$/.test( srcPath ) ) { - // We need to rewrite the map info - var re = new RegExp( grunt.template.process( "<%= versionSuffix %>" ), "g" ); - content = content.replace( re, "" ); - } - return content; - }, - }, - files: { - // WARNING: This will be modified by the config:copy:noversion task - cwd: dist, - src: "<%= files.cdn %>", - dest: "<%= dirs.tmp %>" - } - }, - git: { - options: { - processContent: function( content, srcPath ) { - if ( /\.min.js$|\.min.map$/.test( srcPath ) ) { - // We need to rewrite the map info - var re = new RegExp( grunt.template.process( name ), "g" ); - content = content.replace( re, name + "-git" ); - } - return content; - }, - processContentExclude: [ "**/*.zip", "**/*.gif", "**/*.png" ] - }, - files: { - // WARNING: This will be modified by the config:copy:git task - cwd: dist, - src: "<%= files.cdn %>", - dest: "<%= dirs.cdn.git %>" - } - } - }, - - "hash-manifest": { - googleCDN: { - options: { - algo: "md5", - cwd: "<%= dirs.tmp %>" - }, - src: [ "**/*" ], - dest: "MANIFEST" - } - }, - - compress: { - dist: { - options: { - archive: "<%= files.distZipOut %>" - }, - files: [ - { - expand: true, - cwd: dist, - src: "<%= files.distZipContent %>" - } - ] - }, - images: { - options: { - archive: "<%= files.imagesZipOut %>" - }, - files: [ - { - expand: true, - cwd: dist, - src: [ "images/**" ] - } - ] - }, - "googleCDN": { - options: { - archive: "<%= files.googleCDNZipOut %>" - }, - files: [ - { - expand: true, - cwd: "<%= dirs.tmp %>", - src: [ "**/*" ] - } - ] - } - }, - - connect: { - server: { - options: { - port: httpPort, - base: ".", - middleware: function( connect, options ) { - return [ - // For requests to "[...]/js/" return the built jquery.mobile.js - // as opposed to the php combined version - function(req, res, next){ - var bundle = grunt.config.process( "<%= requirejs.js.options.out %>" ); - if (req.url === "/js/") { - grunt.log.debug( req.url + " requested, serving: " + bundle ); - res.end( grunt.file.read( bundle ) ); - } else { - next(); - } - }, - - // Serve static files. - connect[ "static" ](options.base), - // Make empty directories browsable. - connect.directory(options.base) - ]; - } - } - } - }, - - qunit_junit: { - options: { - dest: "build/test-results", - namer: function (url) { - var match = url.match(/tests\/([^\/]*)\/(.*)$/); - return match[2].replace(/\//g, ".").replace(/\.html/, "" ).replace(/\?/, "-"); - } - } - }, - - qunit: { - options: { - timeout: 30000 - }, - - files: {}, - - http: { - options: { - urls: (function() { - // Find the test files - var suites = _.without( ( grunt.option( "suites" ) || "" ).split( "," ), "" ), - types = _.without( ( grunt.option( "types" ) || "" ).split( "," ), "" ).sort().reverse(), // So that unit runs before integration - patterns, paths, - prefixes = ["tests/unit/", "tests/integration/"], - versionedPaths = [], - jQueries = _.without( ( grunt.option( "jqueries" ) || process.env.JQUERIES || "" ).split( "," ), "" ); - - if( types.length ){ - prefixes = []; - types.forEach(function( type ) { - prefixes.push( "tests/" + type +"/" ); - }); - } - - patterns = []; - - if ( suites.length ) { - suites.forEach( function( unit ) { - prefixes.forEach( function( prefix ) { - patterns = patterns.concat([ - prefix + unit + "/", - prefix + unit + "/index.html", - prefix + unit + "/*/index.html", - prefix + unit + "/**/*-tests.html" - ]); - }); - }); - } else { - prefixes.forEach( function( prefix ) { - patterns = patterns.concat([ - prefix + "*/index.html", - prefix + "*/*/index.html", - prefix + "**/*-tests.html" - ]); - }); - } - - paths = grunt.file.expand( patterns ) - .filter( function( testPath ) { - if ( grunt.file.isDir( testPath ) ) { - testPath = path.join( testPath, "index.html" ); - } - return grunt.file.exists( testPath ); - }) - .map( function( path ) { - // Some of our tests (ie. navigation) don't like having the index.html too much - return path.replace( /\/\index.html$/, "/" ); - }); - - paths = grunt.util._.uniq( paths ); - - if ( jQueries.length ) { - paths.forEach( function( path ) { - versionedPaths = versionedPaths.concat( jQueries.map( function( jQVersion ) { - return path + "?jquery=" + jQVersion; - }) ); - }); - } - - if ( versionedPaths.length ) { - paths = versionedPaths; - } - - return paths.map( function( path ) { - return "http://localhost:<%= connect.server.options.port %>/" + path; - }); - }()) - } - } - }, - - clean: { - dist: [ dist ], - git: [ path.join( dist, "git" ) ], - tmp: [ "<%= dirs.tmp %>" ], - "googleCDN": [ "<%= dirs.cdn.google %>" ], - "jqueryCDN": [ "<%= dirs.cdn.jquery %>" ] - } - }); - - // grunt plugins - grunt.loadNpmTasks( "grunt-contrib-jshint" ); - grunt.loadNpmTasks( "grunt-contrib-clean" ); - grunt.loadNpmTasks( "grunt-contrib-copy" ); - grunt.loadNpmTasks( "grunt-contrib-compress" ); - grunt.loadNpmTasks( "grunt-contrib-concat" ); - grunt.loadNpmTasks( "grunt-contrib-connect" ); - grunt.loadNpmTasks( "grunt-contrib-cssmin" ); - grunt.loadNpmTasks( "grunt-contrib-qunit" ); - grunt.loadNpmTasks( "grunt-contrib-requirejs" ); - grunt.loadNpmTasks( "grunt-contrib-uglify" ); - grunt.loadNpmTasks( "grunt-git-authors" ); - grunt.loadNpmTasks( "grunt-qunit-junit" ); - grunt.loadNpmTasks( "grunt-hash-manifest" ); - - // load the project's default tasks - grunt.loadTasks( "build/tasks"); - - grunt.registerTask( "release:init", function() { - // Set the version suffix for releases - grunt.config.set( "versionSuffix", "-<%= pkg.version%>" ); - }); - - grunt.registerTask( "lint", [ "jshint" ] ); - - grunt.registerTask( "changelog", ["changelog:create"] ); - - grunt.registerTask( "js", [ "requirejs", "concat:js" ] ); - grunt.registerTask( "js:release", [ "js", "uglify", "copy:sourcemap" ] ); - - grunt.registerTask( "css", [ "cssbuild" ] ); - grunt.registerTask( "css:release", [ "css", "cssmin" ] ); - - grunt.registerTask( "demos", [ - "concat:demos", - "copy:demos.nested-includes", - "copy:demos.processed", - "copy:demos.unprocessed", - "copy:demos.backbone" - ]); - - grunt.registerTask( "cdn", [ - "release:init", - "clean:jqueryCDN", "copy:jqueryCDN", - "clean:tmp", - "config:copy:googleCDN", "copy:googleCDN", "hash-manifest:googleCDN", "compress:googleCDN", - "clean:tmp" - ]); - - grunt.registerTask( "dist", [ - "config:fetchHeadHash", - "js:release", - "css:release", - "copy:images", - "demos", - "compress:dist", - "compress:images" - ]); - grunt.registerTask( "dist:release", [ "release:init", "dist", "cdn" ] ); - grunt.registerTask( "dist:git", [ "dist", "clean:git", "config:copy:git:-git", "copy:git" ] ); - - grunt.registerTask( "test", [ "jshint", "config:fetchHeadHash", "js:release", "connect", "qunit:http" ] ); - grunt.registerTask( "test:ci", [ "qunit_junit", "connect", "qunit:http" ] ); - - // Default grunt - grunt.registerTask( "default", [ "dist" ] ); - + banner: [ + "/*!", + "* jQuery Mobile <%= version %>", + "* <%if ( headHash ) {%>Git HEAD hash: <%= headHash %> <> <% } %>Date: " + + grunt.template.today( "UTC:ddd mmm d yyyy HH:MM:ss Z" ), + "* http://jquerymobile.com", + "*", + "* Copyright 2010, " + today + " jQuery Foundation, Inc. and other" + + " contributors", + "* Released under the MIT license.", + "* http://jquery.org/license", + "*", + "*/", + "", + "", + "" + ].join( grunt.util.linefeed ), + + bannerMin: "/*! jQuery Mobile <%= version %> | <%if ( headShortHash ) {%>Git HEAD" + + "hash: <%= headShortHash %> <> <% } %>" + grunt.template.today( "UTC:yyyy-mm-dd" ) + + "T" + grunt.template.today( "UTC:HH:MM:ss" ) + "Z | (c) 2010, " + + today + " jQuery Foundation, Inc. | jquery.org/license */\n" + } +} ); }; diff --git a/LICENSE-INFO.min.txt b/LICENSE-INFO.min.txt index 2c3798d3b52..664884e39a0 100644 --- a/LICENSE-INFO.min.txt +++ b/LICENSE-INFO.min.txt @@ -1 +1 @@ -/*! jQuery Mobile v@VERSION | Copyright 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */ +/*! jQuery Mobile v@VERSION | Copyright jQuery Foundation, Inc. | jquery.org/license */ diff --git a/LICENSE-INFO.txt b/LICENSE-INFO.txt index d42b1cc2055..dfe79ee211f 100644 --- a/LICENSE-INFO.txt +++ b/LICENSE-INFO.txt @@ -2,7 +2,7 @@ * jQuery Mobile v@VERSION * http://jquerymobile.com * -* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors +* Copyright jQuery Foundation, Inc. and other contributors * Released under the MIT license. * http://jquery.org/license * diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000000..3903de8d0bd --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,44 @@ +Copyright jQuery Foundation and other contributors, +https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-mobile + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. diff --git a/README.md b/README.md index fe3cca8ea09..e3014e1ee28 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# jQuery Mobile [![Build Status](https://travis-ci.org/jquery/jquery-mobile.png?branch=master)](https://travis-ci.org/jquery/jquery-mobile) +# jQuery Mobile [![Build Status](https://travis-ci.org/jquery/jquery-mobile.svg?branch=master)](https://travis-ci.org/jquery/jquery-mobile) [![Coverage Status](http://img.shields.io/coveralls/jquery/jquery-mobile/master.svg)](https://coveralls.io/r/jquery/jquery-mobile?branch=master) -This is the main repository for the jQuery Mobile project. From the [official website](http://jquerymobile.com): +_**Note:** jQuery Mobile is not maintained anymore. Please read [the project status blog post](https://blog.jquerymobile.com/2021/10/07/jquery-maintainers-continue-modernization-initiative-with-deprecation-of-jquery-mobile/) for more information._ -> A unified, HTML5-based user interface system for all popular mobile device platforms, built on the rock-solid jQuery and jQuery UI foundation. Its lightweight code is built with progressive enhancement, and has a flexible, easily themeable design. +jQuery Mobile is a unified, HTML5-based user interface system for all popular mobile device platforms, built on the rock-solid jQuery and jQuery UI foundation. Its lightweight code is built with progressive enhancement, and has a flexible, easily themeable design. -jQuery Mobile 1.3 (1.3.2) works with versions of jQuery core from 1.7.0 to 1.9.1. You can find more information about how the library works, and what it is capable of, by reading the [documentation](http://api.jquerymobile.com) and exploring the [demos](http://view.jquerymobile.com/1.3.2/dist/demos/). +jQuery Mobile 1.4.x works with versions of jQuery core from 1.8.3 to 1.11.1 / 2.1.1. You can find more information about how the library works, and what it is capable of, by reading the [documentation](http://api.jquerymobile.com) and exploring the [demos](http://demos.jquerymobile.com/). Alternatively, more information can also be found on the [jquerymobile site](http://jquerymobile.com). ## Contributing @@ -19,8 +19,6 @@ Currently the library is shipped on the jQuery CDN/download as a single monolith * `js` - resolve dependencies, build, concat, and minify the JavaScript used for jQuery Mobile * `css` - resolve dependencies, build, concat, and minify all the css, just the structure css, and just the theme css * `demos` - build the js and css, and make the docs ready for static consumption -* `zip` - package all the JavaScript and all the css into a zip archive -* `dist` (default target) - all of the above * `lint` - Validates JavaScript files using [JSHint](http://jshint.com/) ### Download Builder @@ -29,8 +27,8 @@ The easiest way to obtain a custom build is to use the [download builder](http:/ ### Requirements -* [Node.js](http://nodejs.org/) ~0.8.22 -* [Grunt](http://gruntjs.com/) >=0.4.0 +* [node.js](http://nodejs.org/) +* [grunt-cli](http://gruntjs.com/) ### Commands @@ -67,7 +65,7 @@ index 6200fe6..3a4625c 100644 And then run the build: - grunt js + grunt build:js ### CSS @@ -77,7 +75,7 @@ To create a new theme: 2. Add customizations to the `jquery.mobile.theme.css` file. 3. From the project root run the following `grunt` command: - THEME=my-theme grunt css + THEME=my-theme grunt build:css 4. The output will be available in the `$PROJECT_ROOT/dist` @@ -113,13 +111,19 @@ You can run all the test suites by running the following command: You can choose to run only a subset of the tests by adding the `--suites` option like: - grunt test --suites=button,slider + grunt test --suites=table,slider -will only run the tests under `tests/unit/button/` and `tests/unit/slider/`. +will only run the tests under `tests/unit/table/` and `tests/unit/slider/`. -You can also specify which versions of jQuery you want to test jQuery Mobile with by using the `--jqueries` option: +You can also exclude some tests by using `!`. For instance: - grunt test --jqueries=1.8.2,git + grunt test --type=integration --suites=\!navigation + +will run all the integration tests but the navigation suite. + +You can also specify which versions of jQuery you want to test jQuery Mobile by using the `--jqueries` option: + + grunt test --jqueries=1.11.1,git Additionally, jQuery Mobile's test suite is split between integration and unit tests. Where the unit tests are meant to focus on a single piece of the library (eg, a widget) and the integration tests require multiple pieces of the library to function. You can target either type by including the `--types` option when testing: diff --git a/bower.json b/bower.json new file mode 100644 index 00000000000..0ae0c6c51c0 --- /dev/null +++ b/bower.json @@ -0,0 +1,30 @@ +{ + "name": "jquery-mobile", + "main": [ + "js/jquery.mobile.js", + "css/themes/default/jquery.mobile.css" + ], + "ignore": [ + ".jshintrc", + "**/*.txt", + "!LICENSE-INFO.txt", + "build", + "demos", + "tests", + "tools" + ], + "dependencies": { + "jquery": ">=1.8.0", + "jquery-ui": "jquery/jquery-ui#1.12.1" + }, + "devDependencies": { + "requirejs": "2.1.2", + "requirejs-plugins": "1.0.3", + "requirejs-text": "2.0.3", + "qunit": "1.18.0", + "qunit-assert-classes": "1.0.2", + "jquery-1.11.3": "jquery#1.11.3", + "jquery-mobile-datepicker-wrapper": "arschmitz/jquery-mobile-datepicker-wrapper#0.1.9", + "jshint": "2.4.0" + } +} diff --git a/build/branch-preview.sh b/build/branch-preview.sh deleted file mode 100755 index 355f710b752..00000000000 --- a/build/branch-preview.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# determine the project root -output="branches" -index_page="$output/index.html" - -function log { - echo "[branches preview] $1" -} - -# Make the output directory if it doesnt exist -mkdir -p "$output" - -branches=$(git ls-remote --heads origin | cut -f2 -s | sed 's@refs/heads/@@') - -log "fetching to get new branches" -git fetch origin - -echo "jQm Branches Preview" > "$index_page" -echo "

jQuery Mobile Branches Live Previews


" >> "$index_page" -echo "Updated: $(date)" >> "$index_page" -echo "
    " >> "$index_page" -# Loop through the array to export each branch -for branch in $branches; do - # skip master - if [ $branch = "master" ]; then - continue - fi - - # TODO shell escape the $branch value it safe for executing - log "archiving ref $branch" - git archive -o "$output/$branch.tar" "origin/$branch" - mkdir -p "$output/$branch" - - log "untarring $branch.tar into $output/$branch/" - tar -C "$output/$branch" -xf "$output/$branch.tar" - - # Manipulate the commit message - # TODO add commit and description - echo "
  • Branch: $branch
  • " >> "$index_page" -done - -# close out the list -echo "
" >> "$index_page" - -# close out the index file -echo "" >> "$index_page" diff --git a/build/files.js b/build/files.js new file mode 100644 index 00000000000..429238ef90e --- /dev/null +++ b/build/files.js @@ -0,0 +1,128 @@ +module.exports = function( grunt ) { +var path = require( "path" ); +var _ = require( "underscore" ); +var files = { + css: { + structure: { + src: "css/structure/jquery.mobile.structure.css", + unminified: "<%= name %>.structure<%= versionSuffix %>.css" + }, + theme: { + src: "css/themes/default/jquery.mobile.theme.css", + unminified: "<%= name %>.theme<%= versionSuffix %>.css" + }, + bundle: { + src: "css/themes/default/jquery.mobile.css", + unminified: "<%= name %><%= versionSuffix %>.css" + }, + inlinesvg: { + src: "css/themes/default/jquery.mobile.inline-svg.css", + unminified: "<%= name %>.inline-svg<%= versionSuffix %>.css" + }, + inlinepng: { + src: "css/themes/default/jquery.mobile.inline-png.css", + unminified: "<%= name %>.inline-png<%= versionSuffix %>.css" + }, + externalpng: { + src: "css/themes/default/jquery.mobile.external-png.css", + unminified: "<%= name %>.external-png<%= versionSuffix %>.css" + }, + icons: { + src: "css/themes/default/jquery.mobile.icons.css", + unminified: "<%= name %>.icons<%= versionSuffix %>.css" + } + }, + getCSSFiles: function( destDir ) { + destDir = destDir || "."; + var list = []; + _.values( files.css ).forEach( function( value ) { + list.push( { + src: value.src, + dest: path.join( destDir, value.unminified ) + } ); + } ); + return list; + }, + getMinifiedCSSFiles: function( destDir ) { + destDir = destDir || "."; + var list = []; + _.values( files.css ).forEach( function( value ) { + list.push( { + src: path.join( destDir, value.unminified ), + dest: path.join( destDir, value.minified ) + } ); + } ); + return list; + }, + cdn: [ + "<%= name %><%= versionSuffix %>.js", + "<%= name %><%= versionSuffix %>.min.js", + "<%= name %><%= versionSuffix %>.min.map", + + "<%= files.css.structure.unminified %>", + "<%= files.css.structure.minified %>", + "<%= files.css.bundle.unminified %>", + "<%= files.css.bundle.minified %>", + "<%= files.css.inlinesvg.unminified %>", + "<%= files.css.inlinesvg.minified %>", + "<%= files.css.inlinepng.unminified %>", + "<%= files.css.inlinepng.minified %>", + "<%= files.css.externalpng.unminified %>", + "<%= files.css.externalpng.minified %>", + "<%= files.css.icons.unminified %>", + "<%= files.css.icons.minified %>", + + "images/*.*", + "images/icons-png/**" + ], + + zipFileName: "<%= name %><%= versionSuffix %>.zip", + + distZipOut: path.join( "<%= dist %>", "<%= name %><%= versionSuffix %>.zip" ), + + imagesZipOut: path.join( "<%= dist %>", "<%= name %>.images<%= versionSuffix %>.zip" ) + +}; + +// Add minified property to files.css.* +_.forEach( files.css, function( o ) { + o.minified = o.unminified.replace( /\.css$/, ".min.css" ); +} ); + +files.cdn = [ + "<%= name %><%= versionSuffix %>.js", + "<%= name %><%= versionSuffix %>.min.js", + "<%= name %><%= versionSuffix %>.min.map", + + files.css.structure.unminified, + files.css.structure.minified, + files.css.bundle.unminified, + files.css.bundle.minified, + files.css.inlinesvg.unminified, + files.css.inlinesvg.minified, + files.css.inlinepng.unminified, + files.css.inlinepng.minified, + files.css.externalpng.unminified, + files.css.externalpng.minified, + files.css.icons.unminified, + files.css.icons.minified, + + "images/*.*", + "images/icons-png/**" +]; + +files.distZipContent = [ + files.cdn, + + files.css.theme.unminified, + files.css.theme.minified, + + "images/icons-svg/**", + "demos/**" +]; + +files.googleCDNZipOut = path.join( path.join( "<%= dist %>", "cdn-google" ), + files.zipFileName ); + +return files; +}; diff --git a/build/filter.js b/build/filter.js index 4d607f69d4c..22005491f98 100644 --- a/build/filter.js +++ b/build/filter.js @@ -1,10 +1,11 @@ // This file is used by the AMD web builder service. // When the micro modules are used the version is pulled as a text module. -// When building with r.js we need to replace the version token by its value since we strip the AMD layer with the pragma. +// When building with r.js we need to replace the version token by its value since we strip the +// AMD layer with the pragma. -var fs = require( 'fs' ), - path = require( 'path' ), - pkg = require('../package.json' ), +var fs = require( "fs" ), + path = require( "path" ), + pkg = require( "../package.json" ), buildDir = __dirname, copyrightVersionRegExp = /@VERSION/g, apiVersionRegExp = /__version__/g, @@ -12,24 +13,24 @@ var fs = require( 'fs' ), copyrightRegFile = copyrightBaseName + ".txt", copyrightMinFile = copyrightBaseName + ".min.txt"; -module.exports = function ( contents, ext, callback ) { - var version = pkg.version.trim(); +module.exports = function( contents, ext, callback ) { +var version = pkg.version.trim(); - if ( /^\.min/.test( ext ) ) { - copyrightFile = copyrightMinFile; - } else { - copyrightFile = copyrightRegFile; - } - fs.readFile( path.join( buildDir, copyrightFile ), "utf8", - function( err, copyright ) { - if ( err ) { - callback( err ); - } else { - contents = copyright.replace( copyrightVersionRegExp, version ) + "\n" + contents; - contents = contents.replace( apiVersionRegExp, '"' + version + '"' ); +if ( /^\.min/.test( ext ) ) { + copyrightFile = copyrightMinFile; +} else { + copyrightFile = copyrightRegFile; +} +fs.readFile( path.join( buildDir, copyrightFile ), "utf8", + function( err, copyright ) { + if ( err ) { + callback( err ); + } else { + contents = copyright.replace( copyrightVersionRegExp, version ) + "\n" + contents; + contents = contents.replace( apiVersionRegExp, "\"" + version + "\"" ); - callback( null, contents ); - } + callback( null, contents ); } - ) + } +); }; diff --git a/build/release.js b/build/release.js index 0ce9f38c0cc..1f6c79d56b0 100644 --- a/build/release.js +++ b/build/release.js @@ -1,151 +1,179 @@ +module.exports = function( Release ) { var cheerio = require( "cheerio" ), fs = require( "fs" ), - scp = require( "scp" ), - path = require( "path" ), semver = require( "semver" ), - shell = require( "shelljs" ); + shell = require( "shelljs" ), + clonedRepos = {}; -module.exports = function( Release ) { - Release.define({ - issueTracker: "github", - changelogShell: function() { - return "# Changelog for jQuery Mobile v" + Release.newVersion + "\n"; - }, - - generateArtifacts: function( done ) { - Release.exec( - "grunt dist:release" - ); - done([]); - }, - - _uploadZipToWebsite: function( done ) { - var releaseDist = path.join( Release.dir.repo, "dist" ), - zipFilename = "jquery.mobile-" + Release.newVersion + ".zip"; - - console.log( "Uploading " + zipFilename + " to jquerymobile.com..." ); - scp.send({ - user: "jqadmin", - host: "jquerymobile.com", - file: path.join( releaseDist, zipFilename), - path: "/var/www/jquerymobile.com/htdocs/resources/download/" - }, function( err ) { - if ( err ) { - Release.abort( "Error while uploading " + zipFilename + " to the website: " + err ); - } - done(); - }); - }, - - _cloneDemosRepo: function() { - var local = Release.dir.base + "/demos.jquerymobile.com", - remote = "git@github.com:jquery/demos.jquerymobile.com"; +Release.define( { + issueTracker: "github", + changelogShell: function() { + return "# Changelog for jQuery Mobile v" + Release.newVersion + "\n"; + }, + + generateArtifacts: function( done ) { + Release.exec( "grunt build:release" ); + done( [] ); + }, + _cloneDemosRepo: function() { + var local = Release.dir.base + "/demos.jquerymobile.com", + remote = "git@github.com:jquery/demos.jquerymobile.com"; + + if ( !clonedRepos[ remote ] ) { console.log( "Cloning " + remote.cyan + "..." ); - Release.git( "clone " + remote + " " + local, "Error cloning Demos repo." ); + Release.exec( "git clone " + remote + " " + local, "Error cloning Demos repo." ); console.log(); - return local; - }, + clonedRepos[ remote ] = local; + } - _publishDemos: function() { - var index, - repo = Release._cloneDemosRepo(), - dest = repo + "/" + Release.newVersion, - src = Release.dir.repo + "/dist/demos", - commitMessage = "Added version " + Release.newVersion; + return clonedRepos[ remote ]; + }, - shell.mkdir( "-p", dest ); - shell.cp( "-r", src + "/*", dest ); + _publishDemos: function() { + var index, + repo = Release._cloneDemosRepo(), + dest = repo + "/" + Release.newVersion, + src = Release.dir.repo + "/dist/demos", + commitMessage = "Added version " + Release.newVersion; - if (!Release.preRelease) { - console.log( "Updating demos index..." ); - fs.writeFileSync( repo + "/index.php", "" + Release.newVersion + "\n\t\t" - option = $( "select#branch optgroup[label='Unstable'] option" ).eq( 0 ); - } else { - // If it's a release the option should be selected and need to be inserted in the stable optgroup - newOption = "\n\t\t"; - option = $( "select#branch optgroup[label='Stable'] option[selected]" ); - if ( semver.gt( Release.newVersion, option.val() ) ) { - option.removeAttr( "selected" ); - } - } + clonedRepos[ remote ] = local; + } - // Figure out where to insert the new option - while( option.length - && semver.valid( option.val() ) - && semver.lt( Release.newVersion, option.val() ) ) { - option = option.next(); + return clonedRepos[ remote ]; + }, + + _updateBuilder: function() { + var builder, $, option, newOption, + repo = Release._cloneWebsiteRepo(), + dest = repo + "/resources/download", + src = Release.dir.repo + "/dist/jquery.mobile.images-" + + Release.newVersion + ".zip", + commitMessage = "Builder: Added version " + Release.newVersion; + + shell.cp( src, dest ); + + console.log( "Updating builder page..." ); + $ = cheerio.load( fs.readFileSync( repo + "/pages/download-builder.html", "utf8" ) ); + + if ( Release.preRelease ) { + + // If it's a prerelease the option should not be selected + // and need to be inserted in the unstable optgroup + newOption = "\n\t\t"; + option = $( "select#branch optgroup[label='Unstable'] option" ).eq( 0 ); + } else { + + // If it's a release the option should be selected and need to be + // inserted in the stable optgroup + newOption = "\n\t\t"; + option = $( "select#branch optgroup[label='Stable'] option[selected]" ); + if ( semver.gt( Release.newVersion, option.val() ) ) { + option.removeAttr( "selected" ); } + } - if ( option.length ) { - option.before( newOption ); - } + // Figure out where to insert the new option + while ( option.length && semver.valid( option.val() ) && + semver.lt( Release.newVersion, option.val() ) ) { + option = option.next(); + } + + if ( option.length ) { + option.before( newOption ); + } - fs.writeFileSync( repo + "/pages/download-builder.html", $.html() ); + fs.writeFileSync( repo + "/pages/download-builder.html", $.html() ); - console.log( "Adding files..." ); - process.chdir( repo ); - Release.git( "add ." , "Error adding files." ); - Release.git( "commit -m '" + commitMessage + "'" , "Error commiting files." ); + console.log( "Adding files..." ); + process.chdir( repo ); + Release.exec( "git add .", "Error adding files." ); + Release.exec( "git commit -m '" + commitMessage + "'", + "Error commiting builder files." ); + if ( !Release.isTest ) { console.log( "Pushing to github..." ); - Release.git( "push", "Error pushing demos to github." ); - console.log(); - }, - - _complete: function( done ) { - Release._walk([ - Release._section( "publishing zip file" ), - Release._uploadZipToWebsite, - Release._section( "publishing demos" ), - Release._publishDemos, - Release._section( "updating builder" ), - Release._updateBuilder - ], done ); - }, - - complete: function() { - Release._complete(function() { - console.log( "Release of " + Release.project + " version " + Release.newVersion + " complete." ); - }); + Release.exec( "git push", "Error pushing builder update to github." ); } - }); + console.log(); + }, + + _publishZipsToWebsite: function() { + var repo = Release._cloneWebsiteRepo(), + dest = repo + "/resources/download", + dist = Release.dir.repo + "/dist/jquery.mobile-" + Release.newVersion + ".zip", + images = Release.dir.repo + "/dist/jquery.mobile.images-" + + Release.newVersion + ".zip", + commitMessage = "Release: Added zip for version " + Release.newVersion; + + shell.mkdir( "-p", dest ); + shell.cp( dist, dest ); + shell.cp( images, dest ); + + console.log( "Adding files..." ); + process.chdir( repo ); + Release.exec( "git add .", "Error adding zip files." ); + Release.exec( "git commit -m '" + commitMessage + "'", "Error commiting zip files." ); + if ( !Release.isTest ) { + console.log( "Pushing to github..." ); + Release.exec( "git push", "Error pushing zip files to github." ); + } + console.log(); + }, + + _complete: function( done ) { + Release.walk( [ + Release._section( "publishing demos" ), + Release._publishDemos, + Release._section( "publishing zip files" ), + Release._publishZipsToWebsite, + Release._section( "updating builder" ), + Release._updateBuilder + ], done ); + }, + + complete: function() { + Release._complete( function() { + console.log( "Release of " + Release.project + " version " + + Release.newVersion + " complete." ); + } ); + } +} ); }; + +module.exports.dependencies = [ + "semver@2.2.1", + "shelljs@0.2.6" +]; diff --git a/build/tasks/alias.js b/build/tasks/alias.js new file mode 100644 index 00000000000..8e703dcafc8 --- /dev/null +++ b/build/tasks/alias.js @@ -0,0 +1,95 @@ +module.exports = function( grunt ) { + +var pkg = require( "../../package.json" ); + +// Ci is a magic task that changes based on options we do this to optimize travis build +grunt.registerTask( "ci", [ "ci:" + ( grunt.option( "citype" ) || process.env.CITYPE ) ] ); +grunt.registerTask( "ci:demos", [ "test:demos" ] ); +grunt.registerTask( "ci:test", [ "test" ] ); + +grunt.registerTask( "release:init", function() { + + // Set the version suffix for releases + grunt.config.set( "versionSuffix", "-" + pkg.version ); +} ); + +//Build Tasks these build the various js, css, and demo files +grunt.registerTask( "build", [ + "clean", + "config:fetchHeadHash", + "build:js", + "build:css", + "build:demos", + "compress:dist", + "compress:images" +] ); +grunt.registerTask( "build:js", [ + "modules", + "requirejs", + "concat:js", + "uglify", + "copy:sourcemap" +] ); +grunt.registerTask( "build:css", [ + "cssbuild", + "csslint", + "cssmin" +] ); +grunt.registerTask( "build:demos", [ + "htmllint:demos", + "concat:demos", + "copy:images", + "copy:demos.nested-includes", + "copy:demos.processed", + "copy:demos.php", + "copy:demos.unprocessed", + "copy:demos.backbone", + "copy:demos.datepicker" +] ); +grunt.registerTask( "build:cdn", [ + "copy:jqueryCDN", + "clean:tmp", + "config:copy:googleCDN", + "copy:googleCDN", + "hash-manifest:googleCDN", + "compress:googleCDN", + "clean:tmp" +] ); +grunt.registerTask( "build:release", [ + "release:init", + "build", + "build:cdn" +] ); +grunt.registerTask( "build:git", [ + "build", + "config:copy:git:-git", + "copy:git" +] ); + +grunt.registerTask( "test", [ + "clean:testsOutput", + "jshint", + "jscs:build", + "jscs:good", + "htmllint:tests", + "build:js", + "connect", + "qunit:http" +] ); +grunt.registerTask( "test:demos", [ + "htmllint:demos", + "test:demos:src", + "test:demos:dist" +] ); +grunt.registerTask( "test:demos:src", [ + "php", + "spider:src" +] ); +grunt.registerTask( "test:demos:dist", [ + "build", + "php", + "spider:dist" +] ); + +grunt.registerTask( "default", [ "build", "test" ] ); +}; diff --git a/build/tasks/changelog-shell b/build/tasks/changelog-shell deleted file mode 100644 index f43fe2a591e..00000000000 --- a/build/tasks/changelog-shell +++ /dev/null @@ -1,109 +0,0 @@ - -This file contains a shell for the changelog, followed by a list of every commit for this release. - -Choose the appropriate line for the Summary section. - -Move all commit notes to the appropriate section. -- Each line should be in the following format: - [Fixed|Added]: The ticket description. ([Ticket link], [Commit link]) -- If the commit is not related to a bug or feature, e.g., whitepsace cleanup, remove it. -- If there is no ticket number, search Trac for the relevant ticket. - - If there is no ticket, create one (if needed), or leave just the commit link. - -Double check that "TICKETREF" does not appear anywhere in the changelog. - -Add this changelog to jqueryui.com. - - - -DELETE EVERYTHING ABOVE THE FOLLOWING LINE ------------------------------------------- - - -## Build - - -## Core & Utilities - -### UI Core - - -### Mouse - - -### Widget Factory - - -### Position - - -## Interactions - -### Draggable - - -### Droppable - - -### Resizable - - -### Selectable - - -### Sortable - - -## Widgets - -### Accordion - - -### Autocomplete - - -### Button - - -### Datepicker - - -### Dialog - - -### Menu - - -### Progressbar - - -### Slider - - -### Spinner - - -### Tabs - - -### Tooltip - - -## Effects - - -### Individual effects - - -## CSS Framework - - -## Demos - - -## Website - - -### Download Builder \ No newline at end of file diff --git a/build/tasks/changelog.js b/build/tasks/changelog.js deleted file mode 100644 index e68670c6b27..00000000000 --- a/build/tasks/changelog.js +++ /dev/null @@ -1,285 +0,0 @@ -#!/usr/bin/env node -module.exports = function( grunt ) { - "use strict"; - - var prevVersion, major, minor, patch, baseVersion, parts, repo, baseDir, repoDir, linkNextPage, changelog, changelogPath, done, - issues = [], - firstRun = true, - pkg = { version: "1.4.0pre" }, - rnewline = /\r?\n/, - fs = require( "fs" ), - $ = require( "jquery" ); - - grunt.registerTask( "changelog:create", function() { - done = this.async(); - walk([ - bootstrap, - getVersions, - generateChangelog - ]); - - }); - - function setup( fn ){ - console.log( "Determining directories..." ); - baseDir = process.cwd() + "/"; - repoDir = baseDir + "/repo"; - console.log( "Installing dependencies..." ); - require( "child_process" ).exec( "npm install shelljs colors", function( error ) { - if ( error ) { - return process.exit( 1 ); - } - - require( "shelljs/global" ); - require( "colors" ); - fn(); - }); - } - - function parseHttpHeaders(jqXHR) { - - // Parse the HTTP headers - // ------------------------------------------- - - var linksArray, linksJSON, - // Split headers at newline into array - headersArray = jqXHR.getAllResponseHeaders().split("\r\n"), - - // Crate JSON object to populate - headersJSON = {}; - - // Iterate over HTTP headers - $.each( headersArray, function(index, value){ - - // Extract key and value for JSON object - var delIdx = value.indexOf(":"), - key = value.substr(0, delIdx); - value = value.substr(delIdx+1, value.length); - - // Update JSON object - headersJSON[key.trim()] = value.trim(); - } ); - - - // Parse the HTTP Link header - linksArray = headersJSON.link != null ? headersJSON.link.split( "," ) : []; - - // Create JSON object - linksJSON = {}; - $.each( linksArray, function(index, value){ - var keyValue = value.split( ";" ); - linksJSON[keyValue[1].trim()] = keyValue[0].trim().substr(1, keyValue[0].trim().length-2 ); - }); - - linkNextPage = linksJSON[ "rel='next'" ]; - console.log( "parseHttpHeaders: metadata of response: " + linksJSON[ "rel='next'" ] ); - } - - - function getIssues(repo_url) { - - console.log( "listRepoIssues: Starting getting issues for jquery-mobile ..." ); - - var request = $.ajax({ - - url: repo_url, - type: "GET", - - success: function(data, textStatus, jqXHR){ - console.log( "listRepoIssues: Yeah, it worked..." + textStatus + " - " ); - - $.each( data, function(index, value) { - issues.push( "* " + ( ( value.labels[0] !== undefined && /:/.test( value.title ) ) ? value.labels[0].name + ": " : "" ) + value.title + " [# " + value.number + "](" + value.html_url + ")" ); - }); - - parseHttpHeaders(jqXHR); - - }, - - error: function(data){ - abort('listRepoIssues: Shit hit the fan...' + JSON.stringify(data)); - } - - }); - - return request; - } - - function recurse() { - if(linkNextPage != null) { - $.when( getIssues(linkNextPage) ) - .then( function() { recurse(); } ) - .fail( function() { abort('Failed getting next page...'); } ) - } else { - issuesComplete(); - } - } - - function generateChangelog() { - - var commits, - fullFormat = "* %s (TICKETREF, [%h](http://github.com/jquery/jquery-mobile/commit/%H))"; - - changelogPath = baseDir + "dist/changelog.md" - changelog = cat( "build/tasks/changelog-shell" ) + "\n", - changelog = changelog.replace( "{title}", "jQuery Mobile " + baseVersion + " Changelog" ); - - echo ( "Adding commits..." ); - commits = gitLog( fullFormat ); - - echo( "Adding links to tickets..." ); - changelog += commits - // Add ticket references - .map(function( commit ) { - var tickets = []; - commit.replace( /Fixe[sd] #(\d+)/g, function( match, ticket ) { - tickets.push( ticket ); - }); - - return tickets.length ? - commit.replace( "TICKETREF", tickets.map(function( ticket ) { - return "[#" + ticket + "](http://github.com/jquery/jquery-mobile/issues/" + ticket + ")"; - }).join( ", " ) ) : - // Leave TICKETREF token in place so it's easy to find commits without tickets - commit; - }).sort() - .join( "\n" ) + "\n"; - // Sort commits so that they're grouped by component - - linkNextPage = "https://api.github.com/repos/jquery/jquery-mobile/issues?state=closed&per_page=100&milestone=" + 20; - changelog += "\n###Closed Issues\n"; - //recurse(); - linkNextPage = "https://api.github.com/repos/jquery/jquery-mobile/issues?state=closed&per_page=100&since=2013-02-20T00:00:01Z&milestone=none"; - //recurse(); - - } - - function issuesComplete(){ - if( !firstRun ){ - changelog += issues.sort().join( "\n" ) + "\n"; - fs.writeFileSync( changelogPath, changelog ); - echo( "Stored changelog in " + changelogPath.cyan + "." ); - done(); - } - - firstRun = false; - } - - function getVersions(){ - - baseVersion = pkg.version.replace( "pre", "" ); - parts = baseVersion.split( "." ); - major = parseInt( parts[ 0 ], 10 ); - minor = parseInt( parts[ 1 ], 10 ); - patch = parseInt( parts[ 2 ], 10 ); - baseVersion = baseVersion + "-alpha.2"; - - if ( minor === 0 && patch === 0 ) { - abort( "This script is not smart enough to handle major release (eg. 2.0.0)." ); - } else if( parts[ 2 ] === "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( "." ); - } - } - - function git( command, errorMessage ) { - var result = exec( "git " + command ); - if ( result.code !== 0 ) { - abort( errorMessage ); - } - - return result.output; - } - - function gitLog( format ) { - var result = exec( "git log " + prevVersion + ".." + baseVersion + " " + - "--format='" + format + "'", - { silent: true }); - console.log("git log " + prevVersion + ".." + baseVersion + " " + - "--format='" + format + "'"); - if ( result.code !== 0 ) { - abort( "Error getting git log." ); - } - - result = result.output.split( rnewline ); - if ( result[ result.length - 1 ] === "" ) { - result.pop(); - } - - return result; - } - - function abort( msg ) { - echo( msg.red ); - echo( "Aborting.".red ); - exit( 1 ); - } - - function walk( methods ) { - var method = methods.shift(); - - function next() { - if ( methods.length ) { - walk( methods ); - } - } - - if ( !method.length ) { - method(); - next(); - } else { - method( next ); - } - } - - function bootstrap( fn ) { - getRemote(function( remote ) { - if ( (/:/).test( remote ) || fs.existsSync( remote ) ) { - repo = remote; - } else { - repo = "git@github.com:" + remote + ".git"; - } - setup( fn ); - }); - } - - function prompt( fn ) { - process.stdin.once( "data", function( chunk ) { - process.stdin.pause(); - fn( chunk.toString().trim() ); - }); - process.stdin.resume(); - } - - 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-mobile !!" ); - 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" ); - }); - } -}; diff --git a/build/tasks/config.js b/build/tasks/config.js index 828d6678099..f4ab5af8139 100644 --- a/build/tasks/config.js +++ b/build/tasks/config.js @@ -1,59 +1,59 @@ module.exports = function( grunt ) { - "use strict"; +"use strict"; - var _ = grunt.util._, - path = require( "path" ); +var _ = grunt.util._, + path = require( "path" ); - grunt.registerTask( 'config:fetchHeadHash', 'Retrieve git hashes for output headers', function() { - var done = this.async(); +grunt.registerTask( "config:fetchHeadHash", "Fetch git hashes for output headers", function() { + var done = this.async(); - grunt.util.spawn( - { - cmd: "git", - args: [ "log", "-1", "--format=%H" ] - }, - function(error, result, code) { - var hash = "" + result; - grunt.config.set( "headHash", hash ); - grunt.config.set( "headShortHash", hash.substring( 0, 7 ) ); - done(); - } - ); - }); + grunt.util.spawn( + { + cmd: "git", + args: [ "log", "-1", "--format=%H" ] + }, + function( error, result, code ) { + var hash = "" + result; + grunt.config.set( "headHash", hash ); + grunt.config.set( "headShortHash", hash.substring( 0, 7 ) ); + done(); + } + ); +} ); - grunt.registerTask( "config:copy", function( target, suffix ) { - var arrayOfFiles = []; - var versionSuffix = grunt.template.process( "<%= versionSuffix %>" ); - suffix = suffix || ""; - var versionSuffixRE = new RegExp( grunt.template.process( "<%= versionSuffix %>" ), "g" ); - var suffixRE = new RegExp( "((\.min)?\.(js|css|map))$", "g" ); - var blobRE = new RegExp( "\\*", "g" ); - var cwd = grunt.template.process( "<%= copy." + target + ".files.cwd %>" ); - var src = grunt.template.process( "<%= copy." + target + ".files.src %>" ); - var dest = grunt.template.process( "<%= copy." + target + ".files.dest %>" ); - src.split( "," ).forEach( function( file ) { - if ( blobRE.test( file ) ) { - arrayOfFiles.push({ - expand: true, - cwd: cwd, - src: file, - dest: dest - }); +grunt.registerTask( "config:copy", function( target, suffix ) { + var arrayOfFiles = []; + var versionSuffix = grunt.template.process( "<%= versionSuffix %>" ); + suffix = suffix || ""; + var versionSuffixRE = new RegExp( grunt.template.process( "<%= versionSuffix %>" ), "g" ); + var suffixRE = new RegExp( "((\.min)?\.(js|css|map))$", "g" ); + var blobRE = new RegExp( "\\*", "g" ); + var cwd = grunt.template.process( "<%= copy." + target + ".files.cwd %>" ); + var src = grunt.template.process( "<%= copy." + target + ".files.src %>" ); + var dest = grunt.template.process( "<%= copy." + target + ".files.dest %>" ); + src.split( "," ).forEach( function( file ) { + if ( blobRE.test( file ) ) { + arrayOfFiles.push( { + expand: true, + cwd: cwd, + src: file, + dest: dest + } ); + } else { + if ( suffix ) { + arrayOfFiles.push( { + src: path.join( cwd, file ), + dest: path.join( dest, file.replace( suffixRE, suffix + "$1" ) ) + } ); } else { - if ( suffix ) { - arrayOfFiles.push({ - src: path.join( cwd, file ), - dest: path.join( dest, file.replace( suffixRE, suffix + "$1" ) ) - }); - } else { - arrayOfFiles.push({ - src: path.join( cwd, file ), - dest: path.join( dest, file.replace( versionSuffixRE, "" ) ) - }); - } + arrayOfFiles.push( { + src: path.join( cwd, file ), + dest: path.join( dest, file.replace( versionSuffixRE, "" ) ) + } ); } - }); - grunt.log.debug( "arrayOfFiles: ", JSON.stringify( arrayOfFiles, null, " " ) ); - grunt.config( "copy." + target + ".files", arrayOfFiles ); - }); -}; \ No newline at end of file + } + } ); + grunt.log.debug( "arrayOfFiles: ", JSON.stringify( arrayOfFiles, null, " " ) ); + grunt.config( "copy." + target + ".files", arrayOfFiles ); +} ); +}; diff --git a/build/tasks/cssbuild.js b/build/tasks/cssbuild.js index b6c9ec140b6..275a00bbae8 100644 --- a/build/tasks/cssbuild.js +++ b/build/tasks/cssbuild.js @@ -1,62 +1,63 @@ module.exports = function( grunt ) { - var requirejs = require( 'requirejs' ), - async = grunt.util.async; - - requirejs.define('node/print', [], function() { - return function print(msg) { - if (msg.substring(0, 5) === 'Error') { - grunt.log.errorlns(msg); - grunt.fail.warn('RequireJS failed.'); - } else { - grunt.log.oklns(msg); - } - }; - }); - - function expandFiles( files ) { - return grunt.util._.pluck( grunt.file.expandMapping( files ), "src" ); - } - - grunt.registerMultiTask( 'cssbuild', 'Resolve CSS @imports and concat files', function() { - var done = this.async(), - _ = grunt.util._, - options = _.clone( this.options({ - banner: '' - })), - banner = options.banner; - - delete options.banner; - - async.forEach( this.files, - function( file, callback ) { - var src = grunt.template.process( file.orig.src[0] ), - dest = file.dest; - - grunt.log.debug( "Building '" + src + "' -> '" + dest + "'" ); - - async.series([ - function( next ) { - // pull the includes together using require js - requirejs.optimize( - _.extend({ - cssIn: src, - out: dest - }, options +var requirejs = require( "requirejs" ), + async = grunt.util.async; + +requirejs.define( "node/print", [], function() { + return function print( msg ) { + if ( msg.substring( 0, 5 ) === "Error" ) { + grunt.log.errorlns( msg ); + grunt.fail.warn( "RequireJS failed." ); + } else { + grunt.log.oklns( msg ); + } + }; +} ); + +function expandFiles( files ) { + return grunt.util._.pluck( grunt.file.expandMapping( files ), "src" ); +} + +grunt.registerMultiTask( "cssbuild", "Resolve CSS @imports and concat files", function() { + var done = this.async(), + _ = grunt.util._, + options = _.clone( this.options( { + banner: "" + } ) ), + banner = options.banner; + + delete options.banner; + + async.forEach( this.files, + function( file, callback ) { + var src = grunt.template.process( file.orig.src[ 0 ] ), + dest = file.dest; + + grunt.log.debug( "Building '" + src + "' -> '" + dest + "'" ); + + async.series( [ + function( next ) { + + // Pull the includes together using require js + requirejs.optimize( + _.extend( { + cssIn: src, + out: dest + }, options ), function( response ) { next(); - }); - }, - function( next ) { - var contents = grunt.file.read( dest ); - if ( banner ) { - contents = banner + contents; - } - grunt.file.write( dest, contents ); - grunt.log.writeln( "File '" + dest + "' written." ); - next(); + } ); + }, + function( next ) { + var contents = grunt.file.read( dest ); + if ( banner ) { + contents = banner + contents; } - ], callback ); - }, done - ); - }); -}; \ No newline at end of file + grunt.file.write( dest, contents ); + grunt.log.writeln( "File '" + dest + "' written." ); + next(); + } + ], callback ); + }, done + ); +} ); +}; diff --git a/build/tasks/curl.js b/build/tasks/curl.js deleted file mode 100644 index b50a3ea48b1..00000000000 --- a/build/tasks/curl.js +++ /dev/null @@ -1,80 +0,0 @@ -module.exports = function ( grunt ) { - 'use strict'; - - var _ = grunt.util._, - async = grunt.util.async, - path = require( "path" ); - - var detectDestType = function(dest) { - if (grunt.util._.endsWith(dest, '/')) { - return 'directory'; - } else { - return 'file'; - } - }; - - var unixifyPath = function(filepath) { - if (process.platform === 'win32') { - return filepath.replace(/\\/g, '/'); - } else { - return filepath; - } - }; - - grunt.registerMultiTask( "curl", "Curls URLs built with files", function () { - var done = this.async(), - options = _.clone( this.options({ - baseUrl: "http://localhost/", - querystring: "", - cwd: "." - })), - dry = grunt.option( "no-write" ); - - if ( dry ) { - grunt.log.writeln( "Running in dry mode" ); - } - - async.forEach( - this.files, - function( filePair, nextFilePair ) { - var isExpandedPair = filePair.orig.expand || false; - - async.forEach( - filePair.src, - function( src, next ) { - var dest, - url = options.baseUrl; - if ( detectDestType( filePair.dest ) === 'directory') { - dest = ( isExpandedPair ) ? filePair.dest : unixifyPath( path.join( filePair.dest, path.relative( options.cwd, src ) )); - } else { - dest = filePair.dest; - } - - url += dest + options.querystring; - grunt.log.writeln( "Curling '" + url + "'" ); - if ( !dry ) { - grunt.util.spawn( - { - cmd: "curl", - args: [ url ] - }, - next - ); - } else { - next; - } - - }, nextFilePair - ); - - }, - function( err ) { - if ( err ) { - grunt.log.error( err ); - done( false ); - } - done( true ); - } - ); - }); -}; \ No newline at end of file diff --git a/build/tasks/modules.js b/build/tasks/modules.js new file mode 100644 index 00000000000..3377eb40846 --- /dev/null +++ b/build/tasks/modules.js @@ -0,0 +1,259 @@ +#!/usr/bin/env node +module.exports = function( grunt ) { +"use strict"; + +var css = require( "css" ), + esprima = require( "esprima" ), + path = require( "path" ), + cssFiles = { + theme: { present: {}, list: [] }, + structure: { present: {}, list: [] } + }; + +// Ensure that modules specified via the --modules option are in the same +// order as the one in which they appear in js/jquery.mobile.js. To achieve +// this, we parse js/jquery.mobile.js and reconstruct the array of +// dependencies listed therein. +function makeModulesList( modules ) { + var parsedFile, desiredModulesHash, listedModules, index, singleListedModule, + fixedModules = [], + jsFile = grunt.file.read( path.join( "js", "jquery.mobile.js" ) ); + + modules = modules.split( "," ); + + // This is highly dependent on the contents of js/jquery.mobile.js. It assumes that all + // dependencies are listed flatly in the first argument of the first expression in the + // file. + if ( jsFile ) { + parsedFile = esprima.parse( jsFile, { raw: true, comment: true } ); + + // Descend into the parsed file to grab the array of deps + if ( parsedFile && parsedFile.body && parsedFile.body.length > 0 && + parsedFile.body[ 0 ] && parsedFile.body[ 0 ].expression && + parsedFile.body[ 0 ].expression.arguments && + parsedFile.body[ 0 ].expression.arguments.length && + parsedFile.body[ 0 ].expression.arguments.length > 0 && + parsedFile.body[ 0 ].expression.arguments[ 0 ] && + parsedFile.body[ 0 ].expression.arguments[ 0 ].elements && + parsedFile.body[ 0 ].expression.arguments[ 0 ].elements.length > 0 ) { + + listedModules = parsedFile.body[ 0 ].expression.arguments[ 0 ].elements; + desiredModulesHash = {}; + + // Convert list of desired modules to a hash + for ( index = 0; index < modules.length; index++ ) { + desiredModulesHash[ modules[ index ] ] = true; + } + + // Then, if a listed module is in the hash of desired modules, add it to the + // list containing the desired modules in the correct order + for ( index = 0; index < listedModules.length; index++ ) { + singleListedModule = listedModules[ index ].value.replace( /^\.\//, "" ); + if ( desiredModulesHash[ singleListedModule ] ) { + fixedModules.push( singleListedModule ); + } + } + + // If we've found all the desired modules we can return the list of modules + // assembled, because that list contains the modules in the correct order. + if ( fixedModules.length === modules.length ) { + modules = fixedModules; + } + } + } + + return modules; +} +; + +grunt.registerTask( "modules", function() { + var modulesList = grunt.option( "modules" ), + requirejsModules = grunt.config( "requirejs.js.options.include" ), + onBuildWrite = grunt.config( "requirejs.js.options.onBuildWrite" ), + onModuleBundleComplete = grunt.config( "requirejs.js.options.onModuleBundleComplete" ); + + if ( !modulesList ) { + return; + } + + if ( !requirejsModules ) { + throw ( new Error( "Missing configuration key 'requirejs.js.options.include" ) ); + } + + grunt.config( "requirejs.js.options.include", makeModulesList( modulesList ) ); + + grunt.config( "requirejs.js.options.onBuildWrite", function( moduleName, path, contents ) { + var index, match, + + // We parse the file for the special comments in order to assemble a list of + // structure and theme CSS files to serve as the basis for custom theme and + // structure files which we then feed to the optimizer + parsedFile = esprima.parse( contents, { comment: true } ), + addCSSFile = function( file ) { + file = file.trim(); + if ( !cssFiles[ match[ 1 ] ].present[ file ] ) { + cssFiles[ match[ 1 ] ].list.push( file ); + cssFiles[ match[ 1 ] ].present[ file ] = true; + } + }; + + if ( parsedFile.comments && parsedFile.comments.length > 0 ) { + for ( index = 0; index < parsedFile.comments.length; index++ ) { + match = parsedFile.comments[ index ].value + .match( /^>>css\.(theme|structure): (.*)/ ); + + // Parse the special comment and add the files listed on the right hand + // side of the flag to the appropriate list of CSS files + if ( match && match.length > 2 ) { + match[ 2 ].split( "," ).forEach( addCSSFile ); + } + } + } + + return onBuildWrite ? onBuildWrite.apply( this, arguments ) : contents; + } ); + + grunt.config( "requirejs.js.options.onModuleBundleComplete", function() { + + // We assume that the source for the structure file is called + // "jquery.mobile.structure.css", that the source for the theme file is called + // "jquery.mobile.theme.css", and that the source for the combined theme+structure file + // is called "jquery.mobile.css" + var cssFileContents, structure, theme, all, + allFiles = grunt.config( "cssbuild.all.files" ), + destinationPath = grunt.config.process( "<%= dirs.tmp %>" ), + + // Traverse the tree produced by the CSS parser and update import paths + updateImportUrl = function( cssFilePath, cssRoot ) { + var index, item, match, filename; + + for ( index in cssRoot ) { + item = cssRoot[ index ]; + + if ( item && item.type === "import" ) { + + // NB: The regex below assumes there's no whitespace in the + // @import reference, i.e. url("https://github.com/path/to/filename"); + match = item.import.match( /(url\()(.*)(\))$/ ); + if ( match ) { + + // Strip the quotes from around the filename + filename = match[ 2 ] + .substr( 1, match[ 2 ].length - 2 ); + + // Replace theme and structure with our custom + // reference + if ( path.basename( filename ) === + "jquery.mobile.theme.css" ) { + item.import = + "url(https://github.com/%22jquery.mobile.custom.theme.css/")"; + } else if ( path.basename( filename ) === + "jquery.mobile.structure.css" ) { + item.import = + "url(https://github.com/%22jquery.mobile.custom.structure.css/")"; + + // Adjust the relative path for all other imports + } else { + item.import = + + // Url( + match[ 1 ] + + + // Quotation mark + match[ 2 ].charAt( 0 ) + + + // Path adjusted to be relative to the + // temporary directory + path.relative( destinationPath, + path.normalize( path.join( cssFilePath, + filename ) ) ) + + + // Quotation mark + match[ 2 ].charAt( 0 ) + + + // ) + match[ 3 ]; + } + } + } else if ( typeof item === "object" ) { + updateImportUrl( cssFilePath, item ); + } + } + + return cssRoot; + }; + + // Find the entries for the structure, the theme, and the combined + // theme+structure file, because we want to update them to point to our + // custom-built version + allFiles.forEach( function( singleCSSFile ) { + if ( path.basename( singleCSSFile.src ) === + "jquery.mobile.structure.css" ) { + structure = singleCSSFile; + } else if ( path.basename( singleCSSFile.src ) === + "jquery.mobile.theme.css" ) { + theme = singleCSSFile; + } else if ( path.basename( singleCSSFile.src ) === + "jquery.mobile.css" ) { + all = singleCSSFile; + } + } ); + + // Create temporary structure file and update the grunt config + // reference + cssFileContents = ""; + if ( cssFiles.structure.list.length > 0 ) { + cssFiles.structure.list.forEach( function( file ) { + + // Recalculate relative path from destination in the temporary + // directory + file = path.relative( destinationPath, + + // Css files are originally relative to "js/" + path.join( "js", file ) ); + cssFileContents += "@import url(https://github.com/%22%22%20+%20file%20+%20%22/");\n"; + } ); + structure.src = path.join( destinationPath, + "jquery.mobile.custom.structure.css" ); + grunt.file.write( structure.src, cssFileContents, + { encoding: "utf8" } ); + } + + // Create temporary theme file and update the grunt config reference + cssFileContents = ""; + if ( cssFiles.theme.list.length > 0 ) { + cssFiles.theme.list.forEach( function( file ) { + + // Recalculate relative path from destination in the temporary + // directory + file = path.relative( destinationPath, + + // Css files are originally relative to "js/" + path.join( "js", file ) ); + cssFileContents += "@import url(https://github.com/%22%22%20+%20file%20+%20%22/");\n"; + } ); + theme.src = path.join( destinationPath, + "jquery.mobile.custom.theme.css" ); + grunt.file.write( theme.src, cssFileContents, + { encoding: "utf8" } ); + } + + // Create temporary theme+structure file by replacing references to the + // standard theme and structure files with references to the custom + // theme and structure files created above, and update the grunt config + // reference + cssFileContents = css.stringify( updateImportUrl( + path.dirname( all.src ), + css.parse( grunt.file.read( all.src, { encoding: "utf8" } ) ) ) ); + all.src = path.join( destinationPath, "jquery.mobile.custom.css" ); + grunt.file.write( all.src, cssFileContents, { encoding: "utf8" } ); + + // Update grunt configuration + grunt.config( "cssbuild.all.files", allFiles ); + + if ( onModuleBundleComplete ) { + return onModuleBundleComplete.apply( this, arguments ); + } + } ); +} ); +}; diff --git a/build/tasks/options/bowercopy.js b/build/tasks/options/bowercopy.js new file mode 100644 index 00000000000..73cfb162d0d --- /dev/null +++ b/build/tasks/options/bowercopy.js @@ -0,0 +1,87 @@ +module.exports = function( grunt ) { +return { + options: { + + // Bower components folder will be removed afterwards + clean: true, + ignore: [ "jquery" ], + destPrefix: "external" + }, + tests: { + files: { + "qunit/qunit.js": "qunit/qunit/qunit.js", + "qunit/qunit.css": "qunit/qunit/qunit.css", + "qunit/LICENSE.txt": "qunit/LICENSE.txt", + "qunit-assert-classes/qunit-assert-classes.js": + "qunit-assert-classes/qunit-assert-classes.js", + "qunit-assert-classes/LICENSE.txt": "qunit-assert-classes/LICENSE", + "jshint/jshint.js": "jshint/dist/jshint.js" + } + }, + demos: { + files: { + "jquery-mobile-datepicker-wrapper/jquery.mobile.datepicker.js": + "jquery-mobile-datepicker-wrapper/jquery.mobile.datepicker.js", + "jquery-mobile-datepicker-wrapper/jquery.mobile.datepicker.css": + "jquery-mobile-datepicker-wrapper/jquery.mobile.datepicker.css", + "jquery-mobile-datepicker-wrapper/jquery.mobile.datepicker.theme.css": + "jquery-mobile-datepicker-wrapper/jquery.mobile.datepicker.theme.css" + } + }, + requirejs: { + files: { + "requirejs/require.js": "requirejs/require.js", + "requirejs/plugins/json.js": "requirejs-plugins/src/json.js", + "requirejs/plugins/text.js": "requirejs-text/text.js" + } + }, + "jquery": { + files: { + "jquery/": "jquery-1.11.3/dist/" + } + }, + "jquery-ui": { + options: { + copyOptions: { + process: function( content ) { + var version = grunt + .file + .readJSON( "bower.json" ) + .dependencies[ "jquery-ui" ]; + if ( /#/.test( version ) ) { + version = version.split( "#" )[ 1 ]; + } + return content.replace( /@VERSION/g, version ); + } + } + }, + files: { + "jquery-ui/data.js": "jquery-ui/ui/data.js", + "jquery-ui/disable-selection.js": "jquery-ui/ui/disable-selection.js", + "jquery-ui/escape-selector.js": "jquery-ui/ui/escape-selector.js", + "jquery-ui/focusable.js": "jquery-ui/ui/focusable.js", + "jquery-ui/form.js": "jquery-ui/ui/form.js", + "jquery-ui/form-reset-mixin.js": "jquery-ui/ui/form-reset-mixin.js", + "jquery-ui/ie.js": "jquery-ui/ui/ie.js", + "jquery-ui/jquery-1-7.js": "jquery-ui/ui/jquery-1-7.js", + "jquery-ui/keycode.js": "jquery-ui/ui/keycode.js", + "jquery-ui/labels.js": "jquery-ui/ui/labels.js", + "jquery-ui/LICENSE.txt": "jquery-ui/LICENSE.txt", + "jquery-ui/plugin.js": "jquery-ui/ui/plugin.js", + "jquery-ui/safe-active-element.js": "jquery-ui/ui/safe-active-element.js", + "jquery-ui/safe-blur.js": "jquery-ui/ui/safe-blur.js", + "jquery-ui/scroll-parent.js": "jquery-ui/ui/scroll-parent.js", + "jquery-ui/tabbable.js": "jquery-ui/ui/tabbable.js", + "jquery-ui/unique-id.js": "jquery-ui/ui/unique-id.js", + "jquery-ui/version.js": "jquery-ui/ui/version.js", + "jquery-ui/widget.js": "jquery-ui/ui/widget.js", + "jquery-ui/widgets/accordion.js": "jquery-ui/ui/widgets/accordion.js", + "jquery-ui/widgets/button.js": "jquery-ui/ui/widgets/button.js", + "jquery-ui/widgets/checkboxradio.js": "jquery-ui/ui/widgets/checkboxradio.js", + "jquery-ui/widgets/controlgroup.js": "jquery-ui/ui/widgets/controlgroup.js", + "jquery-ui/widgets/datepicker.js": "jquery-ui/ui/widgets/datepicker.js", + "jquery-ui/widgets/tabs.js": "jquery-ui/ui/widgets/tabs.js" + } + } +}; +}; diff --git a/build/tasks/options/clean.js b/build/tasks/options/clean.js new file mode 100644 index 00000000000..c759f75a6bd --- /dev/null +++ b/build/tasks/options/clean.js @@ -0,0 +1,10 @@ +var path = require( "path" ); + +module.exports = { + dist: [ "<%= dist %>" ], + git: [ path.join( "<%= dist %>", "git" ) ], + tmp: [ "<%= dirs.tmp %>" ], + testsOutput: [ "_tests" ], + "googleCDN": [ "<%= dirs.cdn.google %>" ], + "jqueryCDN": [ "<%= dirs.cdn.jquery %>" ] +}; diff --git a/build/tasks/options/compress.js b/build/tasks/options/compress.js new file mode 100644 index 00000000000..b8151716a2b --- /dev/null +++ b/build/tasks/options/compress.js @@ -0,0 +1,42 @@ +module.exports = function( grunt ) { +var files = require( "../../files.js" )( grunt ); + +return { + dist: { + options: { + archive: files.distZipOut + }, + files: [ + { + expand: true, + cwd: "<%= dist %>", + src: files.distZipContent + } + ] + }, + images: { + options: { + archive: files.imagesZipOut + }, + files: [ + { + expand: true, + cwd: "<%= dist %>", + src: [ "images/**" ] + } + ] + }, + "googleCDN": { + options: { + archive: files.googleCDNZipOut + }, + files: [ + { + expand: true, + cwd: "<%= dirs.tmp %>", + src: [ "**/*" ] + } + ] + } +}; +}; diff --git a/build/tasks/options/concat.js b/build/tasks/options/concat.js new file mode 100644 index 00000000000..9e06d6c16c0 --- /dev/null +++ b/build/tasks/options/concat.js @@ -0,0 +1,16 @@ +var path = require( "path" ); + +module.exports = { + js: { + options: { + banner: "<%= banner %>" + }, + + src: [ path.join( "<%= dist %>", "<%= name %>" ) + "<%= versionSuffix %>.js" ], + dest: path.join( "<%= dist %>", "<%= name %>" ) + "<%= versionSuffix %>.js" + }, + demos: { + src: [ "demos/_assets/js/*.js" ], + dest: path.join( "<%= dist %>", "demos/_assets/js/index.js" ) + } +}; diff --git a/build/tasks/options/connect.js b/build/tasks/options/connect.js new file mode 100644 index 00000000000..7701c865e4d --- /dev/null +++ b/build/tasks/options/connect.js @@ -0,0 +1,34 @@ +module.exports = function( grunt ) { +return { + server: { + options: { + port: httpPort = Math.floor( 9000 + Math.random() * 1000 ), + base: ".", + middleware: function( connect, options ) { + return [ + + // For requests to "[...]/js/" return the built jquery.mobile.js + // as opposed to the php combined version + function( req, res, next ) { + var bundle = grunt.config.process( + "<%= requirejs.js.options.out %>" + ); + if ( req.url === "/js/" ) { + grunt.log.debug( req.url + " requested, serving: " + bundle ); + res.end( grunt.file.read( bundle ) ); + } else { + next(); + } + }, + + // Serve static files. + connect[ "static" ]( options.base ), + + // Make empty directories browsable. + connect.directory( options.base ) + ]; + } + } + } +}; +}; diff --git a/build/tasks/options/copy.js b/build/tasks/options/copy.js new file mode 100644 index 00000000000..cd63c8c4ee4 --- /dev/null +++ b/build/tasks/options/copy.js @@ -0,0 +1,368 @@ +module.exports = function( grunt ) { +var pkg = grunt.file.readJSON( "package.json" ); +var _ = require( "underscore" ); +var path = require( "path" ); +var cheerio = require( "cheerio" ); +var files = require( "../../files" )( grunt ); +var name = "jquery.mobile"; +var replaceCombinedCssReference = function( href, processedName ) { + return href + .replace( /^css/, "demos/css" ) + .replace( /\.\.\/css/, "css" ) + .replace( /jquery\.mobile\.css/, processedName + ".min.css" ); +}; +var processDemos = function( content, srcPath ) { + var processedName, $; + + content = content.replace( /^\s*<\?php include\(\s*['"]([^'"]+)['"].*$/gmi, + function( match, includePath /*, offset, string */ ) { + var newSrcPath = srcPath; + + // If we've already handled the nested includes use the version + // that was copied to the dist folder + // TODO use the config from copy:demos.nested.files + if ( includePath.match( /jqm\-(contents|navmenu|search)\.php/ ) ) { + newSrcPath = "dist/" + newSrcPath; + } + + return grunt.file.read( path.resolve( path.join( + path.dirname( newSrcPath ), includePath ) ) ); + } + ); + if ( content.substring( 0, 15 ).toLowerCase() === "" || + srcPath.match( /\.php$/ ) ) { + processedName = grunt.config.process( name + "<%= versionSuffix %>" ); + $ = cheerio.load( content ); + $( "script" ).each( function() { + var text, + element = $( this ), + src = element.attr( "src" ); + + if ( src ) { + element.attr( "src", src + .replace( /_assets\/js\/?$/, "_assets/js/index.js" ) + .replace( /\.\.\/external\/jquery\/jquery.js$/, + "js/jquery.js" ) + .replace( /\.\.\/js\/?$/, + "js/" + processedName + ".min.js" ) + .replace( /external\/jquery\/jquery.js$/, + "demos/js/jquery.min.js" ) + .replace( /^js\/?$/, "demos/js/" + processedName + ".min.js" ) ); + } else { + text = element.text(); + + // References to stylesheets via grunticon need to be updated + text = text.replace( /(grunticon\( \[([^\]]*))/, + function( match, group ) { + var index, + offset = group.indexOf( "[" ), + prefix = group.substring( 0, offset + 1 ); + + group = group.substring( offset + 1 ).split( "," ); + + for ( index in group ) { + group[ index ] = "\"" + group[ index ] + .trim() + .replace( /(^['"])|(['"]$)/g, "" ) + .replace( /\.\.\/css\//, "css/" ) + .replace( /\.css$/, ".min.css" ) + "\""; + } + + return prefix + " " + group.join( "," ) + " "; + } ); + + //Element.html( text ); + element[ 0 ].children[ 0 ].data = text; + } + } ); + $( "link[rel='stylesheet'][href]" ).each( function() { + var element = $( this ); + + element.attr( "href", + replaceCombinedCssReference( element.attr( "href" ), + processedName ) + + // Demos that separately refer to the structure need to be + // processed here + .replace( /css\/structure\/jquery\.mobile\.structure\.css/gi, + path.join( "css", "themes", "default", + grunt.config.process( name + ".structure" + "<%= versionSuffix %>" ) + + ".min.css" ) + ) + + // References to the icons CSS file need to be processed here + .replace( /css\/themes\/default\/jquery\.mobile\.icons\.css/, + path.join( "css/themes/default", "jquery.mobile.icons.min.css" ) + ) ); + + } ); + + $( "a[href]" ).each( function() { + var element = $( this ); + + element.attr( "href", + element.attr( "href" ).replace( /\.php$/, ".html" ) ); + } ); + + content = $.html(); + } + return content; +}; + +return { + images: { + expand: true, + cwd: "css/themes/default/images", + src: "**", + dest: path.join( "<%= dist %>", "images/" ) + }, + "demos.nested-includes": { + options: { + + // TODO duplicated in demos.firstpass + processContent: function( content, srcPath ) { + content = content.replace( /^\s*<\?php include\(\s*['"]([^'"]+)['"].*$/gmi, + function( match, includePath /*, offset, string */ ) { + + var fileToInclude = path.resolve( + path.join( path.dirname( srcPath ), includePath ) + ); + return grunt.file.read( fileToInclude ); + } + ); + return content; + } + }, + files: [ + { + expand: true, + src: [ + "demos/jqm-contents.php", + "demos/jqm-navmenu.php", + "demos/jqm-search.php" + ], + dest: "<%= dist %>" + } + ] + + }, + "demos.processed": { + options: { + processContent: function( content, srcPath ) { + return processDemos( content, srcPath ); + } + }, + files: [ + { + expand: true, + src: [ + "index.php", + "demos/**/*.php", + "demos/**/*.html", + "!demos/navigation-php-redirect/**", + "demos/navigation-php-redirect/index.php" + ], + dest: "<%= dist %>", + ext: ".html" + } + ] + }, + "demos.php": { + options: { + processContent: function( content, srcPath ) { + return processDemos( content, srcPath ); + } + }, + files: [ + { + expand: true, + src: [ + "demos/navigation-php-redirect/*.php", + "!demos/navigation-php-redirect/index.php", + "demos/page-events/*.php", + "!demos/page-events/index.php" + ], + dest: "<%= dist %>" + } + ] + }, + "demos.backbone": { + options: { + processContent: function( content, srcPath ) { + var processedName = grunt.config.process( name + "<%= versionSuffix %>" ); + + if ( /\.html$/.test( srcPath ) ) { + + var $ = cheerio.load( content ); + + $( "link[rel='stylesheet'][href]" ).each( function() { + var element = $( this ); + + element.attr( "href", + replaceCombinedCssReference( element.attr( "href" ), + processedName ) ); + } ); + + $( "script" ).each( function( idx, element ) { + var script = $( element ); + if ( /requirejs\.config\.js$/.test( script.attr( "src" ) ) ) { + + // Get rid of the requirejs.config.js script tag since we're + // using the built bundle + script.remove(); + } else if ( /require.js$/.test( script.attr( "src" ) ) ) { + + // Use the CDN version for requirejs + script.attr( "src", + "//cdn.jsdelivr.net/requirejs/" + + pkg.devDependencies.requirejs + + "/require.min.js" ); + } + } ); + + // Write out newly created file contents + content = $.html(); + } else if ( /\.js$/.test( srcPath ) ) { + + // Redifines paths for compiled demos + content = content.replace( /baseUrl:.*$/m, "baseUrl: \"../js\"," ); + content = content.replace( /\.\.\/external\/jquery\//, "" ); + content = content.replace( /jquery\.mobile/, processedName ); + content = content.replace( + /"backbone-requirejs-demos".*$/m, + "\"backbone-requirejs-demos\": \"../backbone-requirejs/js\"" ); + } + + return content; + } + }, + files: [ + { + expand: true, + src: [ + "demos/backbone-requirejs/**/*", + "!demos/backbone-requirejs/index.php" + ], + dest: "<%= dist %>" + } + ] + }, + "demos.datepicker": { + files: [ + { + expand: true, + src: [ "external/jquery-mobile-datepicker-wrapper/**/*" ], + dest: path.join( "<%= dist %>" ) + }, + { + expand: true, + src: [ "external/jquery-ui/widgets/datepicker.js" ], + dest: path.join( "<%= dist %>" ) + } + ] + }, + "demos.unprocessed": { + files: [ + { + expand: true, + cwd: "external/jquery", + src: [ "jquery.js", "jquery.min.js", "jquery.min.map.js" ], + dest: path.join( "<%= dist %>", "demos/js/" ) + }, + { + expand: true, + cwd: "<%= dist %>", + src: [ "*.js", "*.map" ], + dest: path.join( "<%= dist %>", "demos/js/" ) + }, + { + expand: true, + cwd: "<%= dist %>", + src: [ + "images/**" + ].concat( _.pluck( files.getMinifiedCSSFiles(), "dest" ) ), + dest: path.join( "<%= dist %>", "demos/css/themes/default/" ) + }, + { + expand: true, + src: [ + "demos/**/*", + "!**/*.php", + "!**/*.html", + "!demos/backbone-requirejs/js/*" + ], + dest: "<%= dist %>" + } + ] + }, + sourcemap: { + + // Processes the sourceMap to fix + // issue: https://github.com/mishoo/UglifyJS2/issues/47 + options: { + processContent: function( content /*, srcPath*/ ) { + content = content.replace( /"dist\//g, "\"" ); + return content; + } + }, + files: [ + { + src: "<%= uglify.all.options.sourceMap %>", + dest: "<%= uglify.all.options.sourceMap %>" + } + ] + }, + "jqueryCDN": { + files: [ { + expand: true, + cwd: "<%= dist %>", + src: files.cdn, + dest: "<%= dirs.cdn.jquery %>/" + } ] + }, + "googleCDN": { + options: { + processContent: function( content, srcPath ) { + if ( /\.min.js$|\.min.map$/.test( srcPath ) ) { + + // We need to rewrite the map info + var re = new RegExp( + grunt.template.process( "<%= versionSuffix %>" ), + "g" ); + content = content.replace( re, "" ); + } + return content; + }, + processContentExclude: [ "**/*.+(gif|png)" ] + }, + files: { + + // WARNING: This will be modified by the config:copy:noversion task + cwd: "<%= dist %>", + src: files, + dest: "<%= dirs.tmp %>" + } + }, + git: { + options: { + processContent: function( content, srcPath ) { + if ( /\.min.js$|\.min.map$/.test( srcPath ) ) { + + // We need to rewrite the map info + var re = new RegExp( name, "g" ); + content = content.replace( re, name + "-git" ); + } + return content; + }, + processContentExclude: [ "**/*.zip", "**/*.gif", "**/*.png" ] + }, + files: { + + // WARNING: This will be modified by the config:copy:git task + cwd: "<%= dist %>", + src: files, + dest: "<%= dirs.cdn.git %>" + } + } +}; +}; diff --git a/build/tasks/options/coveralls.js b/build/tasks/options/coveralls.js new file mode 100644 index 00000000000..1959d4b9906 --- /dev/null +++ b/build/tasks/options/coveralls.js @@ -0,0 +1,10 @@ +module.exports = { + options: { + force: true + }, + all: { + + // LCOV coverage file relevant to every target + src: "_tests/reports/lcov/lcov.info" + } +}; diff --git a/build/tasks/options/cssbuild.js b/build/tasks/options/cssbuild.js new file mode 100644 index 00000000000..894e713d3f5 --- /dev/null +++ b/build/tasks/options/cssbuild.js @@ -0,0 +1,30 @@ +module.exports = function( grunt ) { +var files = require( "../../files.js" )( grunt ); + +return { + options: { + banner: "<%= banner %>", + + //Allow CSS optimizations. Allowed values: + //- "standard": @import inlining, comment removal and line returns. + //Removing line returns may have problems in IE, depending on the type + //of CSS. + //- "standard.keepLines": like "standard" but keeps line returns. + //- "none": skip CSS optimizations. + //- "standard.keepComments": keeps the file comments, but removes line + //returns. (r.js 1.0.8+) + //- "standard.keepComments.keepLines": keeps the file comments and line + //returns. (r.js 1.0.8+) + optimizeCss: "standard.keepComments.keepLines", + + //If optimizeCss is in use, a list of of files to ignore for the @import + //inlining. The value of this option should be a string of comma separated + //CSS file names to ignore (like 'a.css,b.css'. The file names should match + //whatever strings are used in the @import calls. + cssImportIgnore: null + }, + all: { + files: files.getCSSFiles( "<%= dist %>" ) + } +}; +}; diff --git a/build/tasks/options/csscomb.js b/build/tasks/options/csscomb.js new file mode 100644 index 00000000000..ca9a6ce0894 --- /dev/null +++ b/build/tasks/options/csscomb.js @@ -0,0 +1,11 @@ +module.exports = { + structure: { + options: { + config: ".csscomb.json" + }, + files: [ { + expand: true, + src: [ "css/structure/*.css" ] + } ] + } +}; diff --git a/build/tasks/options/csslint.js b/build/tasks/options/csslint.js new file mode 100644 index 00000000000..303a7aa70b1 --- /dev/null +++ b/build/tasks/options/csslint.js @@ -0,0 +1,6 @@ +module.exports = { + options: { + csslintrc: ".csslintrc" + }, + src: [ "css/**/*.css" ] +}; diff --git a/build/tasks/options/cssmin.js b/build/tasks/options/cssmin.js new file mode 100644 index 00000000000..82216cd883a --- /dev/null +++ b/build/tasks/options/cssmin.js @@ -0,0 +1,13 @@ +module.exports = function( grunt ) { +var files = require( "../../files.js" )( grunt ); + +return { + options: { + banner: "<%= bannerMin =>", + keepSpecialComments: 0 + }, + minify: { + files: files.getMinifiedCSSFiles( "<%= dist %>" ) + } +}; +}; diff --git a/build/tasks/options/esformatter.js b/build/tasks/options/esformatter.js new file mode 100644 index 00000000000..9f00b733e67 --- /dev/null +++ b/build/tasks/options/esformatter.js @@ -0,0 +1,14 @@ +module.exports = { + options: { + preset: "jquery", + plugins: [ "esformatter-jquery-chain" ] + }, + files: { + src: [ + "js/**/*.js", + "tests/**/*.js", + "build/**/*.js", + "*.js" + ] + } +}; diff --git a/build/tasks/options/hash-manifest.js b/build/tasks/options/hash-manifest.js new file mode 100644 index 00000000000..c303761276c --- /dev/null +++ b/build/tasks/options/hash-manifest.js @@ -0,0 +1,10 @@ +module.exports = { + googleCDN: { + options: { + algo: "md5", + cwd: "<%= dirs.tmp %>" + }, + src: [ "**/*" ], + dest: "MANIFEST" + } +}; diff --git a/build/tasks/options/htmllint.js b/build/tasks/options/htmllint.js new file mode 100644 index 00000000000..d0265ae2998 --- /dev/null +++ b/build/tasks/options/htmllint.js @@ -0,0 +1,25 @@ +var htmllintBad = [ + "!tests/integration/popup/weird-characters-in-id-tests.html", + "!tests/integration/navigation/blank.html", + "!tests/integration/listview/index.html", + "!demos/map-list-toggle/showMore.html" +]; + +module.exports = { + options: { + ignore: [ + /The text content of element “script” was not in the required format: Expected space, tab, newline, or slash but found “.” instead/, + /Empty heading/, + /The “color” input type is not supported in all browsers. Please be sure to test, and consider using a polyfill/ + ] + }, + all: { + src: [ "demos/**/*.html", "tests/**/*.html" ].concat( htmllintBad ) + }, + demos: { + src: [ "demos/**/*.html" ].concat( htmllintBad ) + }, + tests: { + src: [ "tests/**/*.html" ].concat( htmllintBad ) + } +}; diff --git a/build/tasks/options/jscs.js b/build/tasks/options/jscs.js new file mode 100644 index 00000000000..e626215650a --- /dev/null +++ b/build/tasks/options/jscs.js @@ -0,0 +1,118 @@ +module.exports = function( grunt ) { + +return { + options: { + config: true, + + // Check if fix is enabled + fix: grunt.option( "fix" ) || process.env.FIX || false + }, + build: { + src: [ "build/**/*.js", "*.js" ] + }, + src: { + src: "js/**/*.js" + }, + good: { + src: [ + + // Source + "js/widgets/forms/autogrow.js", + "js/widgets/forms/clearButton.js", + "js/widgets/forms/textinput.backcompat.js", + "js/widgets/forms/textinput.js", + "js/widgets/page.dialog.backcompat.js", + "js/widgets/page.dialog.js", + "js/widgets/page.js", + "js/widgets/accordion.js", + "js/widgets/widget.backcompat.js", + "js/widgets/widget.theme.js", + "js/widgets/forms/button.js", + "js/widgets/forms/button.backcompat.js", + "js/widgets/forms/checkboxradio.js", + "js/widgets/forms/checkboxradio.backcompat.js", + "js/widgets/forms/flipswitch.js", + "js/widgets/forms/flipswitch.backcompat.js", + "js/widgets/forms/rangeslider.js", + "js/widgets/forms/rangeslider.backcompat.js", + "js/widgets/forms/select.js", + "js/widgets/forms/select.custom.js", + "js/widgets/forms/select.backcompat.js", + "js/widgets/forms/select.custom.backcompat.js", + "js/widgets/forms/slider.js", + "js/widgets/forms/slider.backcompat.js", + "js/widgets/controlgroup.js", + "js/widgets/controlgroup.selectmenu.js", + "js/widgets/controlgroup.backcompat.js", + "js/widgets/tabs.ajax.js", + "js/widgets/toolbar.js", + "js/widgets/toolbar.backcompat.js", + "js/widgets/fixedToolbar.js", + "js/widgets/fixedToolbar.backcompat.js", + "js/widgets/fixedToolbar.tapToggle.js", + "js/widgets/enhancer.js", + "js/widgets/enhancer.backcompat.js", + "js/degradeInputs.js", + "js/widgets/popup.arrow.backcompat.js", + "js/widgets/popup.arrow.js", + "js/widgets/popup.backcompat.js", + "js/widgets/popup.js", + "js/widgets/loader.js", + "js/widgets/loader.backcompat.js", + "js/widgets/listview.autodividers.js", + "js/widgets/listview.backcompat.js", + "js/widgets/listview.hidedividers.js", + "js/widgets/listview.js", + "js/widgets/navbar.js", + "js/widgets/navbar.backcompat.js", + "js/widgets/navbar.morebutton.js", + "js/widgets/panel.js", + + // Tests + "tests/integration/listview/autodividers_core.js", + "tests/integration/listview/listview_core.js", + "tests/integration/listview/backcompat_core.js", + "tests/unit/textinput/settings.js", + "tests/unit/textinput/textinput_core.js", + "tests/integration/dialog/dialog_events.js", + "tests/integration/navigation/navigation_core.js", + "tests/css/controlgroup/controlgroup_core.js", + "tests/integration/dialog-extension/dialog_events.js", + "tests/integration/select/select_events.js", + "tests/unit/select/controlgroup_interaction_core.js", + "tests/unit/select/new_backcompat_core.js", + "tests/unit/select/new_core.js", + "tests/unit/select/select_core.js", + "tests/integration/page/page_enhance_within.js", + "tests/integration/page/page_theme.js", + "tests/integration/page/page_title_entity.js", + "tests/unit/flipswitch/*.js", + "tests/unit/slider/*.js", + "tests/unit/rangeslider/*.js", + "tests/unit/toolbar/*.js", + "tests/unit/fixed-toolbar/*.js", + "tests/unit/navbar/*.js", + "tests/integration/fixed-toolbar/*.js", + "tests/integration/toolbar/*.js", + "tests/unit/dialog/dialog_count.js", + "tests/unit/init/init_dialog.js", + "tests/unit/pagecontainer/pagecontainer_core.js", + "tests/unit/degrade-inputs/degradeInputs.js", + "tests/unit/enhancer/enhancer.js", + "tests/integration/popup/popup_core.js", + "tests/integration/popup/backcompat_core.js", + "tests/unit/popup/popup_core.js", + "tests/unit/loader/loader_core.js", + "tests/unit/loader/backcompat_core.js", + "tests/unit/panel/panel_core.js", + "tests/unit/content/content_core.js" + ] + }, + tests: { + src: "test/**/*.js" + }, + demos: { + src: "demos/**/*.js" + } +}; +}; diff --git a/build/tasks/options/jshint.js b/build/tasks/options/jshint.js new file mode 100644 index 00000000000..43c7d478495 --- /dev/null +++ b/build/tasks/options/jshint.js @@ -0,0 +1,29 @@ +module.exports = { + js: { + options: { + jshintrc: "js/.jshintrc" + }, + files: { + src: [ + "js/**/*.js", + "demos/_assets/js/**/*.js", + "tests/**/*.js", + "!js/jquery.js", + "!js/jquery.ui.widget.js", + "!js/widgets/jquery.ui.tabs.js", + "!js/jquery.ui.core.js", + "!tests/lib/**/*.js", + "!demos/_assets/js/view-source.js", + "!demos/_assets/js/syntaxhighlighter.js" + ] + } + }, + grunt: { + options: { + jshintrc: ".jshintrc" + }, + files: { + src: [ "Gruntfile.js" ] + } + } +}; diff --git a/build/tasks/options/php.js b/build/tasks/options/php.js new file mode 100644 index 00000000000..068b3930f27 --- /dev/null +++ b/build/tasks/options/php.js @@ -0,0 +1,9 @@ +module.exports = { + server: { + options: { + port: "<%= phpPort %>", + baseUrl: ".", + silent: true + } + } +}; diff --git a/build/tasks/options/qunit.js b/build/tasks/options/qunit.js new file mode 100644 index 00000000000..36602203536 --- /dev/null +++ b/build/tasks/options/qunit.js @@ -0,0 +1,142 @@ +var _ = require( "underscore" ); +var path = require( "path" ); + +module.exports = function( grunt ) { +return { + options: { + timeout: 60000, + "--web-security": "no" + }, + + http: { + options: { + urls: ( function() { + var allSuites, patterns, paths, + testDirs = [ "unit", "integration", "css", "no-bootstrap" ], + suites = ( grunt.option( "suites" ) || process.env.SUITES || "" ) + .split( "," ), + types = ( grunt.option( "types" ) || process.env.TYPES || "" ) + .split( "," ), + versionedPaths = [], + jQueries = ( grunt.option( "jqueries" ) || process.env.JQUERIES || "" ) + .split( "," ), + excludes = _.chain( suites ) + .filter( function( suite ) { + return ( /^-/.test( suite ) ); + } ) + .map( function( suite ) { + return suite.substring( 1 ); + } ) + .value(); + + // Trim empties + suites = _.without( suites, "" ); + types = _.without( types, "" ); + jQueries = _.without( jQueries, "" ); + + // So that unit suites runs before integration suites + types = types.sort().reverse(); + + allSuites = _.chain( grunt.file.expand( + { + filter: "isDirectory", + cwd: "tests" + }, + _.map( testDirs, function( dir ) { + return dir + "/*"; + } ) + ) ) + .map( function( dir ) { + return dir.split( "/" )[ 1 ]; + } ) + .difference( excludes ) + .unique() + .value(); + + // Remove negations from list of suites + suites = _.filter( suites, function( suite ) { + return ( !/^-/.test( suite ) ); + } ); + + if ( types.length ) { + testDirs = []; + types.forEach( function( type ) { + testDirs.push( type ); + } ); + } + + patterns = []; + + if ( !suites.length ) { + suites = allSuites; + } + + _.chain( suites ) + .difference( excludes ) + .forEach( function( suite ) { + testDirs.forEach( function( dir ) { + dir = "tests/" + dir; + + if ( suite.indexOf( "/" ) >= 0 ) { + + // If the suite is a path, then append it exactly + patterns.push( dir + "/" + suite ); + + } else { + + // If not, append all patterns we care about + patterns = patterns.concat( [ + dir + "/" + suite + "/index.html", + dir + "/" + suite + "/*/index.html", + dir + "/" + suite + "/**/*-tests.html" + ] ); + } + } ); + } ); + paths = grunt.file.expand( patterns ) + .filter( function( testPath ) { + if ( grunt.file.isDir( testPath ) ) { + testPath = path.join( testPath, "index.html" ); + } + return grunt.file.exists( testPath ); + } ) + .map( function( path ) { + + // Some of our tests (ie. navigation) don't like having the + // index.html too much + return path.replace( /\/index.html$/, "/" ); + } ); + + paths = grunt.util._.uniq( paths ); + + if ( jQueries.length ) { + paths.forEach( function( path ) { + versionedPaths = versionedPaths.concat( + jQueries.map( function( jQVersion ) { + return path + "?jquery=" + jQVersion; + } ) ); + } ); + } + + if ( versionedPaths.length ) { + paths = versionedPaths; + } + + paths = _.filter( paths, function( path ) { + var found = false; + excludes.forEach( function( exclude ) { + if ( new RegExp( exclude ).test( path ) ) { + found = true; + } + } ); + return !found; + } ); + + return paths.map( function( path ) { + return "http://localhost:<%= connect.server.options.port %>/" + path; + } ); + }() ) + } + } +}; +}; diff --git a/build/tasks/options/qunit_junit.js b/build/tasks/options/qunit_junit.js new file mode 100644 index 00000000000..51dd7e4b7c6 --- /dev/null +++ b/build/tasks/options/qunit_junit.js @@ -0,0 +1,9 @@ +module.exports = { + options: { + dest: "build/test-results", + namer: function( url ) { + var match = url.match( /tests\/([^\/]*)\/(.*)$/ ); + return match[ 2 ].replace( /\//g, "." ).replace( /\.html/, "" ).replace( /\?/, "-" ); + } + } +}; diff --git a/build/tasks/options/requirejs.js b/build/tasks/options/requirejs.js new file mode 100644 index 00000000000..909317949e7 --- /dev/null +++ b/build/tasks/options/requirejs.js @@ -0,0 +1,48 @@ +module.exports = function( grunt ) { +var path = require( "path" ); + +return { + js: { + options: { + baseUrl: "js", + + optimize: "none", + + //Finds require() dependencies inside a require() or define call. + findNestedDependencies: true, + + //If skipModuleInsertion is false, then files that do not use define() + //to define modules will get a define() placeholder inserted for them. + //Also, require.pause/resume calls will be inserted. + //Set it to true to avoid this. This is useful if you are building code that + //does not use require() in the built project or in the JS files, but you + //still want to use the optimization tool from RequireJS to concatenate + //modules together. + skipModuleInsertion: true, + + mainConfigFile: "js/requirejs.config.js", + + include: [ "jquery.mobile" ], + + exclude: [ "jquery" ], + + excludeShallow: [ "jquery.mobile" ], + + out: path.join( "dist", "<%= name %>" ) + "<%= versionSuffix %>.js", + + //File paths are relative to the build file, or if running a commmand + //line build, the current directory. + wrap: { + startFile: "build/wrap.start", + endFile: "build/wrap.end" + }, + + onBuildWrite: function( moduleName, path, contents ) { + return contents.replace( /__version__/g, grunt.config.process( + "\"<%= version %>\"" + ) ); + } + } + } +}; +}; diff --git a/build/tasks/options/spider.js b/build/tasks/options/spider.js new file mode 100644 index 00000000000..f9362e0c475 --- /dev/null +++ b/build/tasks/options/spider.js @@ -0,0 +1,20 @@ +module.exports = { + "src": { + options: { + url: "http://localhost/" + "<%= phpPort %>", + ignore: + "api\\.jquerymobile\\.com/accordion|notapage|intel|" + + "api\\.jquerymobile\\.com/[0-9]\\.[0-9]|packt|twitter\\.com/jquery|" + + "demos/backbone\-requirejs/backbone\-require\.html" + } + }, + "dist": { + options: { + url: "http://localhost/" + "<%= phpPort %>" + "/dist/", + ignore: + "api\\.jquerymobile\\.com/accordion|notapage|intel|" + + "api\\.jquerymobile\\.com/[0-9]\\.[0-9]|packt|twitter\\.com/jquery|" + + "demos/backbone\-requirejs/backbone\-require\.html" + } + } +}; diff --git a/build/tasks/options/uglify.js b/build/tasks/options/uglify.js new file mode 100644 index 00000000000..6bbe1c0650f --- /dev/null +++ b/build/tasks/options/uglify.js @@ -0,0 +1,18 @@ +var path = require( "path" ); + +module.exports = { + all: { + options: { + banner: "<%= bannerMin %>", + sourceMap: path.join( "<%= dist %>", "<%= name %>" ) + "<%= versionSuffix %>.min.map", + sourceMappingURL: "<%= name %>" + "<%= versionSuffix %>.min.map", + beautify: { + "ascii_only": true + } + }, + files: { + "dist/jquery.mobile<%= versionSuffix %>.min.js": + path.join( "<%= dist %>", "<%= name %>" ) + "<%= versionSuffix %>.js" + } + } +}; diff --git a/build/tasks/rsync.js b/build/tasks/rsync.js deleted file mode 100644 index 53db0451ac7..00000000000 --- a/build/tasks/rsync.js +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Adapted from https://github.com/maxdaten/grunt-rsync - * - * Copyright (c) 2012 Jan-Philip Loos - * Licensed under the MIT license. - */ - -module.exports = function ( grunt ) { - 'use strict'; - - var _ = grunt.util._, - async = grunt.util.async, - path = require( "path" ); - - grunt.registerMultiTask( "rsync", "Copy files to a (remote) machine with rsync.", function () { - var done = this.async(), - options = _.clone( this.options({ - user: process.env.USER, - host: "localhost", - cwd: ".", - remoteBase: "~", - verbose: false, - preserveTimes: false, - preservePermissions: true, - compression: true, - createDirs: true, - recursive: true, - additionalOptions: [] - }) ), - dry = grunt.option( "no-write" ), - args = [], - url = ( options.user ? options.user + "@" : "" ) + options.host + ":" + options.remoteBase; - - // these flags must be set before the src/dest args - if ( options.recursive ) { - args.push( "-r" ); - } - - if ( options.verbose ) { - args.push( "-v" ); - } - - if ( options.preserveTimes ) { - args.push( "-t" ); - } - - if ( options.preservePermissions ) { - args.push( "-p" ); - } - - if ( options.compression ) { - args.push( "-z" ); - } - - if ( options.createDirs ) { - args.push( "--dirs" ); - } - - if ( dry ) { - args.push( "--dry-run" ); - } - - if ( options.additionalOptions.length ) { - args = args.concat( options.additionalOptions ); - } - - var detectDestType = function(dest) { - if ( _.endsWith( dest, '/' ) ) { - return 'directory'; - } else { - return 'file'; - } - }; - - var unixifyPath = function( filepath ) { - if (process.platform === 'win32') { - return filepath.replace(/\\/g, '/'); - } else { - return filepath; - } - }; - - if ( dry ) { - grunt.log.writeln( "Running in dry mode" ); - } - - async.forEach( - this.files, - function( filePair, nextFilePair ) { - var isExpandedPair = filePair.orig.expand || false; - var src = filePair.src[0], - dest; - - async.forEach( - filePair.src, - function(src, next) { - dest = url + filePair.dest; - grunt.log.writeln( "Copying '" + src + "' to '" + dest + "'" ); - grunt.util.spawn( - { - cmd: "rsync", - args: args.concat([ - src, - dest - ]) - }, - next - ); - }, nextFilePair - ); - - }, - function( err ) { - if ( err ) { - grunt.log.error( err ); - done( false ); - } - done( true ); - } - ); - }); -}; \ No newline at end of file diff --git a/changelog b/changelog deleted file mode 100644 index 7d7e0836828..00000000000 --- a/changelog +++ /dev/null @@ -1,2754 +0,0 @@ - -This file contains a shell for the changelog, followed by a list of every commit for this release. - -Choose the appropriate line for the Summary section. - -Move all commit notes to the appropriate section. -- Each line should be in the following format: - [Fixed|Added]: The ticket description. ([Ticket link], [Commit link]) -- If the commit is not related to a bug or feature, e.g., whitepsace cleanup, remove it. -- If there is no ticket number, search Trac for the relevant ticket. - - If there is no ticket, create one (if needed), or leave just the commit link. - -Double check that "TICKETREF" does not appear anywhere in the changelog. - -Add this changelog to jqueryui.com. - - - -DELETE EVERYTHING ABOVE THE FOLLOWING LINE ------------------------------------------- - - -## Build - - -## Core & Utilities - -### UI Core - - -### Mouse - - -### Widget Factory - - -### Position - - -## Interactions - -### Draggable - - -### Droppable - - -### Resizable - - -### Selectable - - -### Sortable - - -## Widgets - -### Accordion - - -### Autocomplete - - -### Button - - -### Datepicker - - -### Dialog - - -### Menu - - -### Progressbar - - -### Slider - - -### Spinner - - -### Tabs - - -### Tooltip - - -## Effects - - -### Individual effects - - -## CSS Framework - - -## Demos - - -## Website - - -### Download Builder -* 'Changed version to: 1.4.0-alpha.1' (TICKETREF, [d17d2ba](http://github.com/jquery/jquery-mobile/commit/d17d2ba7a10af43dac930d1ee65b6b46268bb08d)) -* 'Changed version to: 1.4.0-alpha.2' (TICKETREF, [1e27844](http://github.com/jquery/jquery-mobile/commit/1e27844a1c0b9103a0948480637e6a67f5212dfd)) -* 'Changed version to: 1.4.0pre' (TICKETREF, [702af72](http://github.com/jquery/jquery-mobile/commit/702af72a07a541ac8938cef2d73a5a12d2bdecee)) -* Accessibility: We don't need to move hidden elements off screen when we set height, width and clip. (TICKETREF, [963151c](http://github.com/jquery/jquery-mobile/commit/963151cdc2782e7c195fec892d419250bda2e282)) -* Add swipestart and swipestop data to swipe event (TICKETREF, [57c7038](http://github.com/jquery/jquery-mobile/commit/57c703854c485d63a97861f71e7565338da95e87)) -* Added ! to normal banner (TICKETREF, [24ae0b7](http://github.com/jquery/jquery-mobile/commit/24ae0b77311e98222d24552c7bc95599c983f1e1)) -* Added --units argument to specify a list of units to run tests on. Fixed up jQuery's default version when no --jquery is passed. (TICKETREF, [5c845fe](http://github.com/jquery/jquery-mobile/commit/5c845fe8e17bcdfb781333037e81b6a84abaa40a)) -* Added .jshintrc files (TICKETREF, [4e2bcc0](http://github.com/jquery/jquery-mobile/commit/4e2bcc027bfb221b20b8e4c4cd28728638ea3784)) -* Added 1.3-stable branch to Travis CI builds (TICKETREF, [93a5068](http://github.com/jquery/jquery-mobile/commit/93a5068bf164960a11a767fca661388fb621772c)) -* Added CSS build Replaces version on build write DRYed banners (TICKETREF, [8390361](http://github.com/jquery/jquery-mobile/commit/8390361e496ef811252f7ad22fa2a794372aaa6f)) -* Added Google Maps examples (TICKETREF, [b63304f](http://github.com/jquery/jquery-mobile/commit/b63304f2c597deba21d88f4bfb000081edcec4c2)) -* Added RequireJS json plugin (TICKETREF, [fb29293](http://github.com/jquery/jquery-mobile/commit/fb292939129a51846547458e495cbec1a725147a)) -* Added Travis CI config (TICKETREF, [bd5247e](http://github.com/jquery/jquery-mobile/commit/bd5247eaab041d53307eea55b580cd7c6577310c)) -* Added Travis CI config (cherry picked from commit bd5247eaab041d53307eea55b580cd7c6577310c) (TICKETREF, [b50d487](http://github.com/jquery/jquery-mobile/commit/b50d4873d0dbdb25c52e386610fc5556a9f64d38)) -* Added Travis CI test status (TICKETREF, [8cf4d1d](http://github.com/jquery/jquery-mobile/commit/8cf4d1da4ecbf1627b638525b84a5bbf1a812e35)) -* Added a "cdn" task that creates a zip of the the js/css/map and images with an associated MD5 manifest Fixes #5882 ([#5882](http://github.com/jquery/jquery-mobile/issues/5882), [569ea47](http://github.com/jquery/jquery-mobile/commit/569ea47d454eb20a77be342ce1b22f1f6ef7d594)) -* Added collapsibles to test page. (TICKETREF, [981d384](http://github.com/jquery/jquery-mobile/commit/981d38414e608ea11d6f17037698aa823a28dc59)) -* Added comments to CSS to explain why the rules are there. (TICKETREF, [12acffe](http://github.com/jquery/jquery-mobile/commit/12acffe5509f642ce30c2febe75f03cd5f512309)) -* Added contribution guides paragraph (TICKETREF, [e7b15e3](http://github.com/jquery/jquery-mobile/commit/e7b15e38cdb44edfe60c1749483477ae80cd9ef0)) -* Added default icons stylesheet with inline SVG and external PNG as fallback. (TICKETREF, [541ad66](http://github.com/jquery/jquery-mobile/commit/541ad6627a4e628e353eda3aeb0e65471787c940)) -* Added demos target (TICKETREF, [1f514b8](http://github.com/jquery/jquery-mobile/commit/1f514b838f76228e38c825c43ea65191717e15be)) -* Added dependency on grunt-qunit-junit Added target test:ci (TICKETREF, [f5b9cf6](http://github.com/jquery/jquery-mobile/commit/f5b9cf687114c94cb2a1582eb51af386f825c1d3)) -* Added devDependency on async (TICKETREF, [42449d2](http://github.com/jquery/jquery-mobile/commit/42449d278eb34f0675d7b587584aa4445bd684fe)) -* Added devDependency on async (TICKETREF, [eff01ef](http://github.com/jquery/jquery-mobile/commit/eff01efe8bee6d274f3b59efb1058c6580a4a0a3)) -* Added dist folder to .gitignore (TICKETREF, [209d3a4](http://github.com/jquery/jquery-mobile/commit/209d3a4d48361f9269df40cbf165196fee2cf063)) -* Added dist:common and copy:images Some house cleaning (TICKETREF, [d26ab7f](http://github.com/jquery/jquery-mobile/commit/d26ab7f0258f54f0c6cb27fd52391ae7ce9cc22b)) -* Added font icons test (TICKETREF, [a399250](http://github.com/jquery/jquery-mobile/commit/a3992503b7bf9dfee24de3b73d2dea653bdce70b)) -* Added forms prefix to button widget CSS file. (TICKETREF, [61951a3](http://github.com/jquery/jquery-mobile/commit/61951a367e871ccfee889cf7aa232efd68063bc2)) -* Added injection of requirejs config (TICKETREF, [2ed2dd6](http://github.com/jquery/jquery-mobile/commit/2ed2dd6f46ac9512458dfd357bf1cefd9243b4fd)) -* Added injection of requirejs.config.js (TICKETREF, [398b863](http://github.com/jquery/jquery-mobile/commit/398b863d73e48ea0df22ec2f32b35bb9b0f1e8c0)) -* Added inline SVG support test; add "no-svg" class if not supported. (TICKETREF, [ab07386](http://github.com/jquery/jquery-mobile/commit/ab0738604cc8b05f9ee0166e010902363f1f7186)) -* Added jquery.mobile.transition.fade.css as a css structure dependency (TICKETREF, [b5b296f](http://github.com/jquery/jquery-mobile/commit/b5b296fcab23fa298aeb861d557d6bae5cef3cfe)) -* Added link to demos folder on the index page in case the redirect fails. (TICKETREF, [628b198](http://github.com/jquery/jquery-mobile/commit/628b19832ee9ae169dfe7c19c20c561ee2ab4f0c)) -* Added main, engines and scripts (TICKETREF, [51b7bd3](http://github.com/jquery/jquery-mobile/commit/51b7bd3903c310f73c201d82aacf6d15cc953429)) -* Added middleware to connect to get rid of the PHP dependency. The test target has now a dependency on requirejs:js. The middleware will intercept requests for /js/ and redirect to the built bundle dist/jquery.mobile.js. Also we get the validation of the build for free. Added file lookup to qunit target as well as jquery version selector through --jquery argument at the command line (TICKETREF, [df8f76f](http://github.com/jquery/jquery-mobile/commit/df8f76f9aef803f06d75f53cac41f86c2deb9ac6)) -* Added missing class on form disabled test pages. (TICKETREF, [951e1cf](http://github.com/jquery/jquery-mobile/commit/951e1cfa454540a78b0fb55d09ab32fc561c0a0b)) -* Added missing semi-colon in listview CSS. (TICKETREF, [c2e0a2f](http://github.com/jquery/jquery-mobile/commit/c2e0a2fcce42e93e904675de5e8fa09e8f4dabce)) -* Added missing semi-colon in navigate events. (TICKETREF, [ababcaf](http://github.com/jquery/jquery-mobile/commit/ababcafa73c56395c69d653921b51846fdadd9e6)) -* Added missing semicolons. (TICKETREF, [60df261](http://github.com/jquery/jquery-mobile/commit/60df26130919221c7ebb9ccfffc2242e5d8a7998)) -* Added more examples to listview test pages. (TICKETREF, [0c38dda](http://github.com/jquery/jquery-mobile/commit/0c38dda5c6517a884f99c99ec4f5eb0a4da04d07)) -* Added option passing to RequireJS (TICKETREF, [8ffd365](http://github.com/jquery/jquery-mobile/commit/8ffd36599d437eedd9a208eb2ff67751cd289937)) -* Added shim config for widgets/jquery.ui.tabs (TICKETREF, [19a7f27](http://github.com/jquery/jquery-mobile/commit/19a7f27a7987905b0f8ef9943c2dcc133ad89734)) -* Added swatch "b" test pages. (TICKETREF, [31c4b01](http://github.com/jquery/jquery-mobile/commit/31c4b01b74f105847a10fa50d10f4e46d5415437)) -* Added task config:dev which generates the version string from the current git SHA1 hash (TICKETREF, [f5a5920](http://github.com/jquery/jquery-mobile/commit/f5a592037fd847380a863c233f80d2ee12d9e1ff)) -* Added zip target (TICKETREF, [79a7446](http://github.com/jquery/jquery-mobile/commit/79a7446c8b2918154009d2932ed1f97517272051)) -* Adds exported black and white svg / png files from grunticon (TICKETREF, [377d18d](http://github.com/jquery/jquery-mobile/commit/377d18de578d58e8fdd1803f615a6bf7deae3986)) -* Adjusted globbing patterns when specifying --units flag (TICKETREF, [d56f590](http://github.com/jquery/jquery-mobile/commit/d56f5903e9ef4f03cebd4f7f57e57c5c7d208668)) -* Adjusted label margin. Fixes #5976. ([#5976](http://github.com/jquery/jquery-mobile/issues/5976), [37cd8b2](http://github.com/jquery/jquery-mobile/commit/37cd8b27fe30e8813240042d11deed52788f8dcd)) -* Adjusted rules for ui-mini. (TICKETREF, [27851f1](http://github.com/jquery/jquery-mobile/commit/27851f1e5373c402f334d8cb9102d294d5e2e9f6)) -* Allow Cross Domain Request for Trigger.io apps (TICKETREF, [31470eb](http://github.com/jquery/jquery-mobile/commit/31470eb4d740aab1bb9fea35a5913426919b65e1)) -* Autogrow: adds padding omitted from clientHeight by Firefox. Fixes #6179 - Textinput: height not correctly calculated in Firefox ([#6179](http://github.com/jquery/jquery-mobile/issues/6179), [b4d5158](http://github.com/jquery/jquery-mobile/commit/b4d51581bb245e409ed6a2925f2716613bd29d64)) -* Autogrow: fix height calculation to account for borders Fixes #6180 - Autogrow: calculated height contains border height and Fixes #6178 - Textinput: height not correctly calculated due to box-sizing thanks @jhogervorst ([#6180](http://github.com/jquery/jquery-mobile/issues/6180), [#6178](http://github.com/jquery/jquery-mobile/issues/6178), [48139f8](http://github.com/jquery/jquery-mobile/commit/48139f86ede5516aa746113d1df60e3712afb9f4)) -* Autogrow: removed trailing whitespace (TICKETREF, [791754f](http://github.com/jquery/jquery-mobile/commit/791754face028788bccd6ba715dbb2e82f611c32)) -* Autoinit: Add wrapper to $.widget to inject default initSelector to widgets, add enhanceWithin function to helpers (TICKETREF, [0e61e08](http://github.com/jquery/jquery-mobile/commit/0e61e08a9f7fd4543a1ed1c2d7b7b75a80b53c8c)) -* Autoinit: Remove registry and replace with new auto init (TICKETREF, [cd13e36](http://github.com/jquery/jquery-mobile/commit/cd13e366ca46361dc8230b7160ae5fb798c0c9e1)) -* Automated tests: Custom select: Move highlight checking test from unit tests to integration tests. (TICKETREF, [4e69a1b](http://github.com/jquery/jquery-mobile/commit/4e69a1b791d775c25c96d1d1e637f2e184b0378f)) -* Automated tests: Custom select: Moving test that checks whether adding options causes them to be reflected in the widget from unit tests to integration tests. (TICKETREF, [5b27d44](http://github.com/jquery/jquery-mobile/commit/5b27d4401d65a9a71fb569c02b0588d964c07551)) -* Automated tests: Select: Move label overflow test to integration tests. (TICKETREF, [ef7bf36](http://github.com/jquery/jquery-mobile/commit/ef7bf3690ba41fbcd9277076dc8b07537bd54f11)) -* Automated tests: Select: Moving test for correct placeholder handling from unit tests to integration tests, because it is asynchronous. (TICKETREF, [981194a](http://github.com/jquery/jquery-mobile/commit/981194a718d93f14a3e5bc4c19a80f8ab0536e2a)) -* Back to body theme class for count bubbles. Tweaked count bubble style. (TICKETREF, [de95bcf](http://github.com/jquery/jquery-mobile/commit/de95bcfca51074f3818f4724bcb220f564ebebee)) -* Base class: Depend on jquery.mobile.data, because _getCreateOptions calls $.mobile.getAttribute. Fixes: #6288 - Download Builder(latest): A input or button-based Button widget has an error. (TICKETREF, [d7b5750](http://github.com/jquery/jquery-mobile/commit/d7b5750d662f271e7bb7e834a3116298b1c903b7)) -* Base class: Ignore null option values coming in from the DOM. (TICKETREF, [1d82f72](http://github.com/jquery/jquery-mobile/commit/1d82f725fb4c29ccbce027bd3b59c758aee2dbb8)) -* Base class: Improve performance of _getCreateOptions by removing $.each() and moving string replace callback and regex to the outer IIFE. (TICKETREF, [f976a5a](http://github.com/jquery/jquery-mobile/commit/f976a5ab2a1a2220a74317db7d954ef91f7dab95)) -* Base widget: Remove _toggleClasses. (TICKETREF, [3b954a2](http://github.com/jquery/jquery-mobile/commit/3b954a2d8dd3f95c420119ca2626701173948f28)) -* Base widget: Remove _toggleClasses. (TICKETREF, [94c4677](http://github.com/jquery/jquery-mobile/commit/94c4677325be8ce994bd9180e60bca587c17a2e6)) -* Border styling. (TICKETREF, [d61403d](http://github.com/jquery/jquery-mobile/commit/d61403d8b5e017591b57d87727537aa8ae1e839f)) -* Bring back icons in listview buttons. Will look into performance of selectors later. (TICKETREF, [bc766a7](http://github.com/jquery/jquery-mobile/commit/bc766a7df1a500283b26c27cad52da57171b8ae6)) -* Build: Add a dist:git task, along with a copy:git target for git-cdn deploys (TICKETREF, [988d0dd](http://github.com/jquery/jquery-mobile/commit/988d0dd43a94f7d6df867c2f7cabffa6bb8f4abb)) -* Build: Added a clean step for the git build (TICKETREF, [e98f21e](http://github.com/jquery/jquery-mobile/commit/e98f21ed9476a833a47c7688c8d3bdc23c6d8885)) -* Build: Added deploy and deploy:git tasks. Now version the files directly in dist instead of doing it at rsync time. That allows us to use the "dir/" syntax for rsync to have rsync create the destination directory. (TICKETREF, [af24edc](http://github.com/jquery/jquery-mobile/commit/af24edcfd6f8b6083efbca85ad7b5d13024f0d0f)) -* Build: Added deploy tasks ( WIP ) (TICKETREF, [827f2a5](http://github.com/jquery/jquery-mobile/commit/827f2a54681069356aa0d25256d6ef90e56aec70)) -* Build: Added grunt-contrib-clean (TICKETREF, [8c227ae](http://github.com/jquery/jquery-mobile/commit/8c227aef013ebb7659aaa1953b515e9ef2129c46)) -* Build: Added new grunt tasks: curl, rsync, release and recurse (TICKETREF, [8be2ce7](http://github.com/jquery/jquery-mobile/commit/8be2ce708d9eb40de5ce3c03cfd4c742e828bd4f)) -* Build: Added possibility to set jqueries using environment variable JQUERIES (TICKETREF, [700aa8c](http://github.com/jquery/jquery-mobile/commit/700aa8cbd2663dfa1a8416469b6db726dc4b6426)) -* Build: Added setting of versionSuffix config attribute in release:init task (TICKETREF, [f87ccfb](http://github.com/jquery/jquery-mobile/commit/f87ccfb2f14ab07f77523486ba27ce8abdc826bd)) -* Build: Added tagging task (TICKETREF, [d531826](http://github.com/jquery/jquery-mobile/commit/d531826aee25af5689de736a9357bf36589c0372)) -* Build: Added task "lint" as an alias to "jshint" (TICKETREF, [b22a856](http://github.com/jquery/jquery-mobile/commit/b22a8564a3ed2573fddb829c7880d0ca37bb48c1)) -* Build: Changed banner to display git HEAD hash in a new fashion and the build date instead of the commit date (TICKETREF, [0ff5f25](http://github.com/jquery/jquery-mobile/commit/0ff5f256b5fbc3906fa93a507f6b3ddd2bfc4c73)) -* Build: Changed dependencies versions to official ones (TICKETREF, [2ede2ec](http://github.com/jquery/jquery-mobile/commit/2ede2ecb0374dc3acc3a3219775becc4ea70a4be)) -* Build: Changed dest path format so rsync will create destination directory when needed (TICKETREF, [babbae7](http://github.com/jquery/jquery-mobile/commit/babbae7c397205172f82b404e1ce005186077d9a)) -* Build: Changed rsync target to production settings (TICKETREF, [e8cb008](http://github.com/jquery/jquery-mobile/commit/e8cb00831f1f95e9b00697c39f79c65e9724b7f5)) -* Build: Don't process *.ico in demos.secondpass (TICKETREF, [d1b90f0](http://github.com/jquery/jquery-mobile/commit/d1b90f08ce0ea26a75607697952f79bfdd3c403c)) -* Build: Execute "release:init" before "release:fail-if-pre" in "deploy" task (TICKETREF, [71001d1](http://github.com/jquery/jquery-mobile/commit/71001d1aeec08fec5545f5c04920f8a5e5c97b2a)) -* Build: Exposed deploy task to be able to do test deploys. Changed baseUrls to not add trailing slash. Added message when running in dry mode. (TICKETREF, [5322b54](http://github.com/jquery/jquery-mobile/commit/5322b5420659323d3f2ee44279b64004ae1e1159)) -* Build: Fixed demos build Split files.css by type (TICKETREF, [f862d70](http://github.com/jquery/jquery-mobile/commit/f862d706ae7b5503011cfd9822c158e38dfd1798)) -* Build: Fixed destination for zip file (TICKETREF, [9c16581](http://github.com/jquery/jquery-mobile/commit/9c165811651295a6907642ad06e2ad0992bfa5c4)) -* Build: Fixed destination path for files (TICKETREF, [aaaafe7](http://github.com/jquery/jquery-mobile/commit/aaaafe7655cc6e841af1cc6112c87de511829e2c)) -* Build: Fixed function that selects tests to run Stripped index.html from test urls as some tests don't react well to it Added comments (TICKETREF, [b50bdc1](http://github.com/jquery/jquery-mobile/commit/b50bdc14616ec4dd9b1dfb8b0ce8b47cdf6e926e)) -* Build: Fixed images by moving the copy of non-html, non-php to the unprocessed pass (TICKETREF, [bbc1ed3](http://github.com/jquery/jquery-mobile/commit/bbc1ed383766bdd40689d9b74674375cc3921f57)) -* Build: Fixed js and css targets (TICKETREF, [effd619](http://github.com/jquery/jquery-mobile/commit/effd61962750f0333b5d153eb51d44838d68b0e4)) -* Build: Fixed sourceMap by removing the leading "dist/" Added a linefeed at the end of the minified copyright Whitespace changes (TICKETREF, [d5aaae5](http://github.com/jquery/jquery-mobile/commit/d5aaae5abc3202394c1aeb8d86fee24600630cec)) -* Build: Fixed syntax error in package.json (TICKETREF, [7b7e0ec](http://github.com/jquery/jquery-mobile/commit/7b7e0ec6b78705827cdded95daee1fe7db130ee3)) -* Build: Fixed tagging task (TICKETREF, [45ffb10](http://github.com/jquery/jquery-mobile/commit/45ffb10d1ac602c6e8d21ee96de002c4ce81dc3c)) -* Build: Fixed test task (TICKETREF, [27f835b](http://github.com/jquery/jquery-mobile/commit/27f835bbce065b453f793e573199b585c9fc674b)) -* Build: Fixed up release:set-version (TICKETREF, [d388d1a](http://github.com/jquery/jquery-mobile/commit/d388d1af85555ec01e91429176744e20d0464c0a)) -* Build: Fixed various archives where files where missing Removed theme files from CDN zip (TICKETREF, [d6a084c](http://github.com/jquery/jquery-mobile/commit/d6a084c6a0de7e32e2bdaf21631944bf241a6946)) -* Build: Images were missing from the dist/images directory and therefore from the zip file (TICKETREF, [a35837a](http://github.com/jquery/jquery-mobile/commit/a35837a919bfc4db2bbbd6340bb17d2a633b0f59)) -* Build: Minified date in .min banner. Automated copyright end date. (TICKETREF, [991142e](http://github.com/jquery/jquery-mobile/commit/991142e3334e6a36f7c8a8376c8cacf598339d39)) -* Build: Move the versionSuffix template out of name it was causing rsync:release to miss files (TICKETREF, [8ea352f](http://github.com/jquery/jquery-mobile/commit/8ea352f2314cfb0b1d19c9a840a71fe1e9519d2b)) -* Build: New demos + clean target (TICKETREF, [663f80c](http://github.com/jquery/jquery-mobile/commit/663f80ce425d4b626a12b0668537064ed4016ed9)) -* Build: Only clean:dist when releasing because really that's all we need (TICKETREF, [0ef6d39](http://github.com/jquery/jquery-mobile/commit/0ef6d3920c210f666e9f44dbe0fc764a86926cdc)) -* Build: Removed *:git (TICKETREF, [56b261e](http://github.com/jquery/jquery-mobile/commit/56b261ebf584f2a295c176c549aae691fcfdd070)) -* Build: Removed am/pm from build date since we're using 24H format (TICKETREF, [8b8eac8](http://github.com/jquery/jquery-mobile/commit/8b8eac86e04fba245c3b6eaa5c3e3592a08ba761)) -* Build: Removed deploy:latest, renamed deploy:release to release (TICKETREF, [5a696e1](http://github.com/jquery/jquery-mobile/commit/5a696e108674d88501e0ea7daf31c42011916789)) -* Build: Removed redefinition of "release" task (TICKETREF, [e3c1927](http://github.com/jquery/jquery-mobile/commit/e3c192786888306fff6710c718b4b869e1f4767f)) -* Build: Rename demos.firstpass to demos.processed, it now processes *.php and *.html. Removed redundant demo.secondpass (TICKETREF, [99947cc](http://github.com/jquery/jquery-mobile/commit/99947ccb8222c46907deeb23cf2e2907e812431a)) -* Build: Restored rsync user and host to production values (TICKETREF, [bbeb818](http://github.com/jquery/jquery-mobile/commit/bbeb818ac384f20e9f232a477b7ef183696b1560)) -* Build: Restored test target to `grunt test` (TICKETREF, [c5acaf7](http://github.com/jquery/jquery-mobile/commit/c5acaf783a2c9c75944368f3fa273dab778814a9)) -* Build: Use exact version numbers for dependencies. (TICKETREF, [dbc85a0](http://github.com/jquery/jquery-mobile/commit/dbc85a073a8bb0ef6cdc644ca4ccb211e2c4f51d)) -* Build: Use local variable _ for underscore (TICKETREF, [660efc5](http://github.com/jquery/jquery-mobile/commit/660efc58df39223341152dcab40ddfe4c9e4ba1d)) -* Build: fix CDN reload querystring (TICKETREF, [332646b](http://github.com/jquery/jquery-mobile/commit/332646bfe36d5c6a10fc5194fc5890d9a2144d4a)) -* Build: rsync was failing to copy demos and images dir, fixed. (TICKETREF, [2ad2b83](http://github.com/jquery/jquery-mobile/commit/2ad2b83a6a39a2c735c7353d27e93e0b1f6bb452)) -* Build: use grunt-contrib-compress instead of grunt-zip (TICKETREF, [cc7d264](http://github.com/jquery/jquery-mobile/commit/cc7d264fbc553be89fc3200b7ee9e05a3851aa18)) -* Button markup: Allow reading of DOM attributes from $.fn.buttonMarkup to retain backwards compatibility. (TICKETREF, [990e5ce](http://github.com/jquery/jquery-mobile/commit/990e5ceb6ccf8c9f8133cad229af41d220810b24)) -* Button: Adjustments to selectors ui-btn-left and -right CSS rules. Fixes #5869. ([#5869](http://github.com/jquery/jquery-mobile/issues/5869), [287d379](http://github.com/jquery/jquery-mobile/commit/287d3796fd64e2ee020967a89afec08a6dbca9c2)) -* Button: Changed ui-btn-corner-all to ui-corner-all (TICKETREF, [0043089](http://github.com/jquery/jquery-mobile/commit/0043089d9e829cd544c93f9fb32967edb095619e)) -* Button: Class ui-input-btn for all input buttons instead of ui-submit. Adjusted rules for buttons in field containers. (TICKETREF, [2c2be73](http://github.com/jquery/jquery-mobile/commit/2c2be730b41c888e3e17ca1a1cdbc0ab26bd3ebd)) -* Button: Correct width of icon only buttons. (TICKETREF, [c15eb08](http://github.com/jquery/jquery-mobile/commit/c15eb08da95e07e63dd4fbca1b4e72401d78d0cf)) -* Button: Don't add class ui-btn-hidden to native inputs but use a type selector. (TICKETREF, [86bb286](http://github.com/jquery/jquery-mobile/commit/86bb286949475793139cacf901ce2a0bd1890598)) -* Button: Don't use diplay none to hide the native input when disabled, because this makes a difference for screen readers. (TICKETREF, [3707c55](http://github.com/jquery/jquery-mobile/commit/3707c55b482e9872442892fd9cb3f40bca5d089c)) -* Button: First pass on buttons without calls to buttonMarkup(). (TICKETREF, [c747016](http://github.com/jquery/jquery-mobile/commit/c7470167dbdd5577bb1487b77fdb30166bcfdd55)) -* Button: Fix Tests from moving button (TICKETREF, [bcd97c9](http://github.com/jquery/jquery-mobile/commit/bcd97c926b28389fb403d595334c6497d217a8c7)) -* Button: Fix initSelector to only do input[type=button] to exclude button elements with type=button Fixes #6237 - JQM 1.4 alpha button on form has a large border ([#6237](http://github.com/jquery/jquery-mobile/issues/6237), [b2d9570](http://github.com/jquery/jquery-mobile/commit/b2d9570a665219fe5ca81843b6cc500cfe331c5d)) -* Button: Fix initselector to only target inputs (TICKETREF, [e6eaab6](http://github.com/jquery/jquery-mobile/commit/e6eaab6c51ccc01a0a1e90d85557b9cb1fc3f2ed)) -* Button: Fixed different height of button elements on Firefox. (TICKETREF, [f58166c](http://github.com/jquery/jquery-mobile/commit/f58166cb7cd19bd56663872800f927410a50f2a3)) -* Button: Icon positioning and padding. (TICKETREF, [2772d1d](http://github.com/jquery/jquery-mobile/commit/2772d1d7184534f520f1bc15e1b8b2340678093d)) -* Button: If a button element doesn't contain text we use the value if provided. (TICKETREF, [472b2ad](http://github.com/jquery/jquery-mobile/commit/472b2ad4d3832f97cc85662fc22371d2b2278a35)) -* Button: Implement widget(), _destroy(), and perform _setOptions() via buttonMarkup() (TICKETREF, [981cae7](http://github.com/jquery/jquery-mobile/commit/981cae71f7669dfd74e4cec3220da59c68338288)) -* Button: Increased specificity of ui-btn-left/right margin 0 rule to make it override default margins on controlgroups, etc. (TICKETREF, [f9a1c98](http://github.com/jquery/jquery-mobile/commit/f9a1c98366349e4dbcd8ba36d2117abdef5fbc51)) -* Button: Linting changes that are slightly more sensitive. (TICKETREF, [c396bab](http://github.com/jquery/jquery-mobile/commit/c396babc7042df6f2e980ab4d5b85aba0e6864f5)) -* Button: Made sure that icon-only buttons always have white-space nowrap. (TICKETREF, [ac9892e](http://github.com/jquery/jquery-mobile/commit/ac9892e82f3d773b747663d5531046d2dc1d4d02)) -* Button: Only check if the element is an input once. (TICKETREF, [5515807](http://github.com/jquery/jquery-mobile/commit/5515807af968269edb600823b6fb209fe903eedf)) -* Button: Only margin-right for inline buttons. Fixes #5816. ([#5816](http://github.com/jquery/jquery-mobile/issues/5816), [e003997](http://github.com/jquery/jquery-mobile/commit/e0039978d14a67896cfb167b2db57e0737998ed6)) -* Button: Only unset the margin in grids for 100% width button elements. (TICKETREF, [723eb53](http://github.com/jquery/jquery-mobile/commit/723eb534fada4eb9c1513727670b9c10ec0a0ec2)) -* Button: Optimized CSS for button elements. (TICKETREF, [feab6bc](http://github.com/jquery/jquery-mobile/commit/feab6bc2ba15aa48e5787d42d450e0f2d3609c6a)) -* Button: Remove button element from button widget (TICKETREF, [4a90506](http://github.com/jquery/jquery-mobile/commit/4a90506924c3c0996bb2eba849c2a0ba67604c97)) -* Button: Remove selectors that should really be buttonMarkup. (TICKETREF, [c1ca96c](http://github.com/jquery/jquery-mobile/commit/c1ca96cf2340af2473ebdead4da344f016507e7f)) -* Button: Removed option disabled and enable/disable methods because the Widget Factory already implements them. Thanks Gabriel! (TICKETREF, [c5b24d0](http://github.com/jquery/jquery-mobile/commit/c5b24d054187652f0275d6d6b5b14c5843aaa9a8)) -* Button: Set button text as title attribute value for icon-only buttons. (TICKETREF, [a53090e](http://github.com/jquery/jquery-mobile/commit/a53090efe77f068c4036004b41003e60d615c6c4)) -* Button: Simplified the selector for native input style. (TICKETREF, [b131bfd](http://github.com/jquery/jquery-mobile/commit/b131bfd58d12781b9da837bb3642a6c9811eb0d9)) -* Button: Update _create method to add enhanced option (TICKETREF, [d455be8](http://github.com/jquery/jquery-mobile/commit/d455be8d27db22bcf1ccef237af3caa17f4366a5)) -* Button: add missing space in class for icon Fixes #6217 - Icons not showing correctly on input buttons ([#6217](http://github.com/jquery/jquery-mobile/issues/6217), [147ee42](http://github.com/jquery/jquery-mobile/commit/147ee420b36f3b9e678ac9cf99ad23b2df134d95)) -* Button: buttons without buttonMarkup(). (TICKETREF, [d15dc59](http://github.com/jquery/jquery-mobile/commit/d15dc59ea31e411521c03a8afc454600a6abd9e6)) -* Button: check to ensure icon is set before applying icon position class Fixes #6212 - Button text not correctly aligned to center ([#6212](http://github.com/jquery/jquery-mobile/issues/6212), [69699d0](http://github.com/jquery/jquery-mobile/commit/69699d00faaff979241f5e90f1399ef6a7ca8d80)) -* Button: handle inital options in button creation and handle disabled buttons in buttonMarkup (TICKETREF, [035a829](http://github.com/jquery/jquery-mobile/commit/035a82951d6e77a865c1b33f6ca4ea18c718aa27)) -* Button: header and footer buttons. (TICKETREF, [903c1fe](http://github.com/jquery/jquery-mobile/commit/903c1fe61f690fa36a05771e7ecd3e4af0cdf13a)) -* Button: remove duplicated call to buttonMarkup (TICKETREF, [546fc72](http://github.com/jquery/jquery-mobile/commit/546fc7237e3502f42c3d56476dacbfb13e2f0b24)) -* Button: remove inherit theme btn should have no default theme class (TICKETREF, [9481425](http://github.com/jquery/jquery-mobile/commit/94814258d0f97b1c57b36e786b1be5a62f09b03d)) -* Button: removed border-radius inherit for ui-btn-text and added it to listview because that's the only place where we need this. Fixes #5709. ([#5709](http://github.com/jquery/jquery-mobile/issues/5709), [d9eb855](http://github.com/jquery/jquery-mobile/commit/d9eb855191538eb0a3626bdd31d866eafd90f863)) -* Button: removed code for buttons in headers. buttonMarkup enhances them as buttons and the new toolbar widget will set the mini and inline options. (TICKETREF, [aeaec3d](http://github.com/jquery/jquery-mobile/commit/aeaec3d43059cdfd8af9b53bd09b9055a7d088a3)) -* Button: renamed variable (TICKETREF, [862ad5a](http://github.com/jquery/jquery-mobile/commit/862ad5a20815cebb17b515448d2211f5b04fe29e)) -* Button: store data in the widget instead of on the element. (TICKETREF, [260a5ff](http://github.com/jquery/jquery-mobile/commit/260a5ff904963aefd0a813c5ea6aaff1516205de)) -* Button: theme inheritance. (TICKETREF, [43c1b77](http://github.com/jquery/jquery-mobile/commit/43c1b775efed7117f4254cb5e8374a3bf29ac98d)) -* Button: use extend instead of expando (TICKETREF, [2b5a775](http://github.com/jquery/jquery-mobile/commit/2b5a7759e19e429c7cc8082624bb70aca8118622)) -* Button: user-select none for all buttons. (TICKETREF, [7eddc2c](http://github.com/jquery/jquery-mobile/commit/7eddc2cc7373d717515d7604d1b300737f947bbe)) -* Button: width auto for inline button elements was gone. (TICKETREF, [982f66f](http://github.com/jquery/jquery-mobile/commit/982f66f17b2421ea814d0453298a3343293070b3)) -* CI: Added IRC notification for Travis CI tests (TICKETREF, [5be1817](http://github.com/jquery/jquery-mobile/commit/5be1817945006a83e845b819ba2eee88eb09b1ca)) -* CI: Added multiple versions of jQuery to test against (TICKETREF, [e1e2028](http://github.com/jquery/jquery-mobile/commit/e1e202844e20e6e7d5c68940cc99369098d7c3dc)) -* CI: Change travis ci config to run only on master (TICKETREF, [a864fe0](http://github.com/jquery/jquery-mobile/commit/a864fe03e684df19209051a7a173243fe81e56c1)) -* CI: Changed irc.freenode.net to chat.freenode.net (TICKETREF, [325c522](http://github.com/jquery/jquery-mobile/commit/325c5226d609d3d43a740dc64aaae6c5766e3cd4)) -* CI: How about using the right IRC channel? (TICKETREF, [641a58e](http://github.com/jquery/jquery-mobile/commit/641a58e2662437fc7428ff213861f3674ef00790)) -* CI: Set build matrix to test against different versions of jQuery ( another attempt at ) (TICKETREF, [5290032](http://github.com/jquery/jquery-mobile/commit/5290032fa417097e761268a5b1788f4a466ea4e8)) -* CI: Set build matrix to test against different versions of jQuery (TICKETREF, [2e63ebe](http://github.com/jquery/jquery-mobile/commit/2e63ebe847f7be9348039f1f6e5d996e89340cfb)) -* Changed .is() to .hasClass() where possible for performance. (TICKETREF, [c3b58b3](http://github.com/jquery/jquery-mobile/commit/c3b58b312a1938cedcb07938400190be1bdbd448)) -* Changed font-size 16px to 1em or removed the setting if not really needed. (TICKETREF, [774c71e](http://github.com/jquery/jquery-mobile/commit/774c71ef7ea4d9b2eeff499c2240db645d3fe425)) -* Changed freenode.org to freenode.net (TICKETREF, [81379a9](http://github.com/jquery/jquery-mobile/commit/81379a9b0c4183ea6859bdf91ea97d2f8add7abe)) -* Changed getInheritedTheme fallback to swatch "a" (TICKETREF, [08bcd6c](http://github.com/jquery/jquery-mobile/commit/08bcd6c996a216c1af998b7656d8ed426553184c)) -* Changed option theme default to "a". (TICKETREF, [98b90c3](http://github.com/jquery/jquery-mobile/commit/98b90c3f03bb30b126b2d0b9079e9ab920e0d301)) -* Changed the order of the CSS to reveal possible specificity issues when using Download Builder. (TICKETREF, [4fe1dc0](http://github.com/jquery/jquery-mobile/commit/4fe1dc01f660d289b9859cde9ea5261af1be50fd)) -* Changed the qunit_junit namer Took out some debug logging (TICKETREF, [e3266fa](http://github.com/jquery/jquery-mobile/commit/e3266fa99e48deda36c1a96e2e29042fb3ccf30f)) -* Changed version in demo center from 1.3.0 to 1.4.0-alpha.1 (TICKETREF, [616d6d1](http://github.com/jquery/jquery-mobile/commit/616d6d12d57bdf4ff2322014ab49f1e0b64a79ad)) -* Changed version to 1.4.0pre (TICKETREF, [b45797f](http://github.com/jquery/jquery-mobile/commit/b45797f9596a8966ef8ff236a77aa0d2a34c4b7a)) -* Checkbox: Native input and icon style. Fixes #5740. ([#5740](http://github.com/jquery/jquery-mobile/issues/5740), [8f5ad89](http://github.com/jquery/jquery-mobile/commit/8f5ad893813eb611c4f809d2fbbe3fed302a3d3c)) -* Checkbox: replaced ui-btn-corner-all by ui-corner-all. (TICKETREF, [df87173](http://github.com/jquery/jquery-mobile/commit/df8717318c137bf1e28a68afd40188b2132a0e76)) -* Checkboxradio: Accessibility. See also 3707c55. (TICKETREF, [9637fc8](http://github.com/jquery/jquery-mobile/commit/9637fc89418dd51d94c93380364a801aa2110f6b)) -* Checkboxradio: According to the unit tests setting data-iconpos on the label element is supposed to work. (TICKETREF, [2b80339](http://github.com/jquery/jquery-mobile/commit/2b80339ee9ae252ccd5af56541d08bc00fe53fa1)) -* Checkboxradio: Escape ID when it is being used as a selector for netting the corresponding