Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into popup-widget

  • Loading branch information...
commit 5692aef938d72985abd12ce90b11d89415a4fd34 2 parents f2b23eb + 4b401fe
@gabrielschulhof gabrielschulhof authored
Showing with 976 additions and 310 deletions.
  1. +3 −0  .gitignore
  2. +24 −181 Makefile
  3. +8 −0 README.md
  4. +4 −0 build/bin/build_latest.sh
  5. +4 −0 build/bin/clean.sh
  6. +56 −0 build/bin/config.sh
  7. +35 −0 build/bin/css.sh
  8. +20 −0 build/bin/deploy.sh
  9. +4 −0 build/bin/deploy_latest.sh
  10. +3 −0  build/bin/deploy_nightlies.sh
  11. +29 −0 build/bin/docs.sh
  12. +3 −0  build/bin/init.sh
  13. +26 −0 build/bin/js.sh
  14. +12 −0 build/bin/zip.sh
  15. +103 −0 build/config.js
  16. +10 −0 build/tasks/clean.js
  17. +116 −0 build/tasks/css.js
  18. +11 −0 build/tasks/custom_init.js
  19. +63 −0 build/tasks/js.js
  20. +59 −0 build/tasks/legacy.js
  21. +1 −1  css/structure/jquery.mobile.button.css
  22. +1 −1  css/structure/jquery.mobile.forms.select.css
  23. +2 −2 css/structure/jquery.mobile.transition.css
  24. +1 −1  css/themes/default/jquery.mobile.theme.css
  25. +5 −1 docs/api/data-attributes.html
  26. +6 −5 docs/api/events.html
  27. +1 −1  docs/api/globalconfig.html
  28. +0 −3  docs/buttons/buttons-types.html
  29. +3 −3 docs/lists/docs-lists.html
  30. +1 −1  docs/pages/dialog.html
  31. +2 −0  docs/pages/page-anatomy.html
  32. +1 −0  docs/pages/page-navmodel.html
  33. +1 −1  docs/toolbars/docs-headers.html
  34. +56 −0 grunt.js
  35. +1 −1  js/jquery.mobile.controlGroup.js
  36. +6 −1 js/jquery.mobile.dialog.js
  37. +7 −4 js/jquery.mobile.forms.button.js
  38. +1 −1  js/jquery.mobile.forms.checkboxradio.js
  39. +13 −18 js/jquery.mobile.forms.select.custom.js
  40. +12 −7 js/jquery.mobile.listview.js
  41. +13 −13 js/jquery.mobile.loader.js
  42. +4 −3 js/jquery.mobile.navigation.js
  43. +9 −2 js/jquery.mobile.navigation.pushstate.js
  44. +8 −5 js/jquery.mobile.page.sections.js
  45. +26 −26 js/jquery.mobile.transition.js
  46. +24 −14 js/jquery.tag.inserter.js
  47. +21 −0 package.json
  48. +4 −4 tests/unit/checkboxradio/checkboxradio_core.js
  49. +15 −0 tests/unit/dialog/dialog-no-hash.html
  50. +43 −0 tests/unit/dialog/dialog_no_hash.js
  51. +54 −0 tests/unit/dialog/no-hash-tests.html
  52. +2 −2 tests/unit/jquery.setNameSpace.js
  53. +16 −1 tests/unit/listview/index.html
  54. +16 −0 tests/unit/listview/listview_core.js
  55. +4 −1 tests/unit/page-sections/index.html
  56. +3 −6 tests/unit/widget/widget_core.js
View
3  .gitignore
@@ -13,3 +13,6 @@ tmp/
# branch preview
branches
+
+# node build dependencies
+node_modules
View
205 Makefile
@@ -1,221 +1,64 @@
-# Helper Variables
-# The command to replace the @VERSION in the files with the actual version
-HEAD_SHA = $(shell git log -1 --format=format:"%H")
-VER = sed "s/v@VERSION/$$(git log -1 --format=format:"Git Build: SHA1: %H <> Date: %cd")/"
-VER_MIN = "/*! jQuery Mobile v$$(git log -1 --format=format:"Git Build: SHA1: %H <> Date: %cd") jquerymobile.com | jquery.org/license */"
-VER_OFFICIAL = $(shell cat version.txt)
-SED_VER_REPLACE = 's/__version__/"${VER_OFFICIAL}"/g'
-SED_VER_API = sed ${SED_VER_REPLACE}
-SED_INPLACE_EXT = "whyunowork"
-deploy: VER = sed "s/v@VERSION/${VER_OFFICIAL} ${HEAD_SHA}/"
-deploy: VER_MIN = "/*! jQuery Mobile v${VER_OFFICIAL} ${HEAD_SHA} jquerymobile.com | jquery.org/license */"
+# in build/bin/config.sh this setting will alter the variable definitions to match
+# the changes for the deploy target in the makefile. temp solution
+ARGS = IS_DEPLOY_TARGET=false
+deploy: ARGS = IS_DEPLOY_TARGET=true
# The output folder for the finished files
OUTPUT = compiled
-# The name of the files
-NAME = jquery.mobile
-BASE_NAME = jquery.mobile
-THEME_FILENAME = jquery.mobile.theme
-STRUCTURE = jquery.mobile.structure
-deploy: NAME = jquery.mobile-${VER_OFFICIAL}
-deploy: THEME_FILENAME = jquery.mobile.theme-${VER_OFFICIAL}
-deploy: STRUCTURE = jquery.mobile.structure-${VER_OFFICIAL}
-
-# The CSS theme being used
-THEME = default
-
-# If node is available then use node to run r.js
-# otherwise use good old rhino/java
-NODE = /usr/local/bin/node
-HAS_NODE = $(shell if test -x ${NODE} ;then echo true; fi)
-
-ifeq ($(HAS_NODE), true)
- RUN_JS = @@${NODE}
-else
- RUN_JS = @@java -XX:ReservedCodeCacheSize=64m -classpath build/js.jar:build/google-compiler-20111003.jar org.mozilla.javascript.tools.shell.Main
-endif
-
# Build Targets
-
# When no build target is specified, all gets ran
all: css js zip notify
-clean:
- # -------------------------------------------------
- # Cleaning build output
- @@rm -rf ${OUTPUT}
- @@rm -rf tmp
+clean: init
+ @@node node_modules/.bin/grunt clean
# Create the output directory.
+# NOTE it doesn't appear as though you can override init from a task file
init:
- @@mkdir -p ${OUTPUT}
+ @@if ! (node -v | grep "\(v0.[6-9]\|v[1-9].[0-9]\)" > /dev/null); then echo "!!! node.js ~> 0.6.x required" && exit 1; fi
+ @@npm install
+ @@node node_modules/.bin/grunt custom_init
# Build and minify the CSS files
css: init
- # Build the CSS file with the theme included
- ${RUN_JS} \
- external/r.js/dist/r.js \
- -o cssIn=css/themes/default/jquery.mobile.css \
- optimizeCss=standard.keepComments.keepLines \
- out=${OUTPUT}/${NAME}.compiled.css
- @@cat LICENSE-INFO.txt | ${VER} > ${OUTPUT}/${NAME}.css
- @@cat ${OUTPUT}/${NAME}.compiled.css >> ${OUTPUT}/${NAME}.css
- @@echo ${VER_MIN} > ${OUTPUT}/${NAME}.min.css
- @@java -XX:ReservedCodeCacheSize=64m \
- -jar build/yuicompressor-2.4.6.jar \
- --type css ${OUTPUT}/${NAME}.compiled.css >> ${OUTPUT}/${NAME}.min.css
- @@rm ${OUTPUT}/${NAME}.compiled.css
- # Build the CSS Structure-only file
- ${RUN_JS} \
- external/r.js/dist/r.js \
- -o cssIn=css/structure/jquery.mobile.structure.css \
- out=${OUTPUT}/${STRUCTURE}.compiled.css
- @@cat LICENSE-INFO.txt | ${VER} > ${OUTPUT}/${STRUCTURE}.css
- @@cat ${OUTPUT}/${STRUCTURE}.compiled.css >> ${OUTPUT}/${STRUCTURE}.css
- # ..... and then minify it
- @@echo ${VER_MIN} > ${OUTPUT}/${STRUCTURE}.min.css
- @@java -XX:ReservedCodeCacheSize=64m \
- -jar build/yuicompressor-2.4.6.jar \
- --type css ${OUTPUT}/${STRUCTURE}.compiled.css >> ${OUTPUT}/${STRUCTURE}.min.css
- @@rm ${OUTPUT}/${STRUCTURE}.compiled.css
- # Build the theme only file
- @@cat LICENSE-INFO.txt | ${VER} > ${OUTPUT}/${THEME_FILENAME}.css
- @@cat css/themes/default/jquery.mobile.theme.css >> ${OUTPUT}/${THEME_FILENAME}.css
- # ..... and then minify it
- @@echo ${VER_MIN} > ${OUTPUT}/${THEME_FILENAME}.min.css
- @@java -XX:ReservedCodeCacheSize=64m \
- -jar build/yuicompressor-2.4.6.jar \
- --type css ${OUTPUT}/${THEME_FILENAME}.css >> ${OUTPUT}/${THEME_FILENAME}.min.css
- # Copy in the images
- @@cp -R css/themes/${THEME}/images ${OUTPUT}/
- # Css portion is complete.
- # -------------------------------------------------
-
-
-docs: init js css
- # Create the Demos/Docs/Tests/Tools
- # ... Create staging directories
- @@mkdir -p tmp/demos/js
- @@mkdir -p tmp/demos/css/themes/${THEME}
- # ... Copy script files
- @@cp compiled/*.js tmp/demos/js
- @@cp js/jquery.js tmp/demos/js
- # ... Copy html files
- @@cp index.html tmp/demos
- @@cp -r docs tmp/demos
- # ... Copy css and images
- @@cp compiled/*.css tmp/demos/css/themes/${THEME}
- @@cp -r compiled/images tmp/demos/css/themes/${THEME}
- # ... replace "js/" with "js/jquery.mobile.js"
- @@ # NOTE the deletion here is required by gnu/bsd sed differences
- @@find tmp/demos \( -name '*.html' -o -name '*.php' \) -exec sed -i${SED_INPLACE_EXT} -e 's@js/"@js/${NAME}.js"@' {} \;
- @@find tmp/demos -name "*${SED_INPLACE_EXT}" -exec rm {} \;
- @@ # make sure the docs reference the right css file names (for deploy)
- @@find tmp/demos \( -name '*.html' -o -name '*.php' \) -exec sed -i${SED_INPLACE_EXT} -e 's@${BASE_NAME}.css"@${NAME}.css"@' {} \;
- @@find tmp/demos -name "*${SED_INPLACE_EXT}" -exec rm {} \;
- # ... Move and zip up the the whole folder
- @@rm -f ${OUTPUT}/${BASE_NAME}.docs.zip
- @@cd tmp/demos && zip -rq ../../${OUTPUT}/${NAME}.docs.zip *
- @@rm -rf ${OUTPUT}/demos && mv -f tmp/demos ${OUTPUT}
- # Finish by removing the temporary files
- @@rm -rf tmp
- # -------------------------------------------------
+ @@node node_modules/.bin/grunt css
# Build and minify the JS files
js: init
- # Build the JavaScript file
- ${RUN_JS} \
- external/r.js/dist/r.js \
- -o baseUrl="js" \
- name=jquery.mobile \
- exclude=jquery,../external/requirejs/order,../external/requirejs/depend,../external/requirejs/text,../external/requirejs/text!../version.txt \
- out=${OUTPUT}/${NAME}.compiled.js \
- pragmasOnSave.jqmBuildExclude=true \
- wrap.startFile=build/wrap.start \
- wrap.endFile=build/wrap.end \
- findNestedDependencies=true \
- skipModuleInsertion=true \
- optimize=none
- @@cat LICENSE-INFO.txt | ${VER} > ${OUTPUT}/${NAME}.js
- @@cat ${OUTPUT}/${NAME}.compiled.js | ${SED_VER_API} >> ${OUTPUT}/${NAME}.js
- @@rm ${OUTPUT}/${NAME}.compiled.js
- # ..... and then minify it
- @@echo ${VER_MIN} > ${OUTPUT}/${NAME}.min.js
- @@java -XX:ReservedCodeCacheSize=64m \
- -jar build/google-compiler-20111003.jar \
- --js ${OUTPUT}/${NAME}.js \
- --js_output_file ${OUTPUT}/${NAME}.compiled.js
- @@cat ${OUTPUT}/${NAME}.compiled.js >> ${OUTPUT}/${NAME}.min.js
- @@rm ${OUTPUT}/${NAME}.compiled.js
- # -------------------------------------------------
+ @@node node_modules/.bin/grunt js
+# -------------------------------------------------
+#
+# For jQuery Team Use Only
+#
+# -------------------------------------------------
+docs: init js css
+ @@${ARGS} bash build/bin/docs.sh
# Output a message saying the process is complete
notify: init
@@echo "The files have been built and are in: " $$(pwd)/${OUTPUT}
- # -------------------------------------------------
# Zip up the jQm files without docs
zip: init css js
- # Packaging up the files into a zip archive
- @@mkdir tmp
- @@cp -R ${OUTPUT} tmp/${NAME}
- # ... And remove the Zipped docs so they aren't included twice (for deploy scripts)
- @@rm -rf tmp/${NAME}/*.zip
- @@cd tmp; zip -rq ../${OUTPUT}/${NAME}.zip ${NAME}
- @@rm -rf tmp
- # -------------------------------------------------
+ @@${ARGS} bash build/bin/zip.sh
-# -------------------------------------------------
-# -------------------------------------------------
-# -------------------------------------------------
-#
-# For jQuery Team Use Only
-#
-# -------------------------------------------------
-# NOTE the clean (which removes previous build output) has been removed to prevent a gap in service
build_latest: css docs js zip
- # ... Copy over the lib js, avoid the compiled stuff, to get the defines for tests/unit/*
- @@ # TODO centralize list of built files
- @@find js -name "*.js" -not -name "*.docs.js" -not -name "*.mobile.js" | xargs -L1 -I FILENAME cp FILENAME ${OUTPUT}/demos/js/
+ @@${ARGS} bash build/bin/build_latest.sh
# Push the latest git version to the CDN. This is done on a post commit hook
deploy_latest:
- # Time to put these on the CDN
- @@scp -qr ${OUTPUT}/* jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/latest/
- # -------------------------------------------------
+ @@${ARGS} bash build/bin/deploy_latest.sh
# TODO target name preserved to avoid issues during refactor, latest -> deploy_latest
latest: build_latest deploy_latest
# Push the nightly backups. This is done on a server cronjob
deploy_nightlies:
- # Time to put these on the CDN
- @@scp -qr ${OUTPUT} jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/nightlies/$$(date "+%Y%m%d")
- # -------------------------------------------------
+ @@${ARGS} bash build/bin/deploy_nightlies.sh
# Deploy a finished release. This is manually done.
deploy: clean init css js docs zip
- # Deploying all the files to the CDN
- @@mkdir tmp
- @@cp -R ${OUTPUT} tmp/${VER_OFFICIAL}
- @@scp -qr tmp/* jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/
- @@rm -rf tmp/${VER_OFFICIAL}
- @@mv ${OUTPUT}/demos tmp/${VER_OFFICIAL}
- # Create the Demos/Docs/Tests/Tools for jQueryMobile.com
- # ... By first replacing the paths
- @@ # TODO update jQuery Version replacement on deploy
- @@find tmp/${VER_OFFICIAL} -type f \
- \( -name '*.html' -o -name '*.php' \) \
- -exec perl -pi -e \
- 's|src="(.*)${BASE_NAME}.js"|src="//code.jquery.com/mobile/${VER_OFFICIAL}/${NAME}.min.js"|g;s|href="(.*)${BASE_NAME}.css"|href="//code.jquery.com/mobile/${VER_OFFICIAL}/${NAME}.min.css"|g;s|src="(.*)jquery.js"|src="//code.jquery.com/jquery-1.7.1.min.js"|g' {} \;
- # ... So they can be copied to jquerymobile.com
- @@scp -qr tmp/* jqadmin@jquerymobile.com:/srv/jquerymobile.com/htdocs/demos/
- # Do some cleanup to wrap it up
- @@rm -rf tmp
- @@rm -rf ${OUTPUT}
- # -------------------------------------------------
-
-
+ @@${ARGS} bash build/bin/deploy.sh
View
8 README.md
@@ -15,6 +15,13 @@ Clone this repo and build the js and css files (you'll need Git and Make install
A full version and a minified version of the jQuery Mobile JavaScript and CSS files will be created
in a folder named "compiled". There is also now a Structure only css file so you can add your own theme on top of it.
+Alternatively if you have node.js installed you can run
+
+ npm install
+ node node_modules/.bin/grunt <js|css>
+
+to build either the js or css. This is usefull especially if you're on Windows without support for the make tool and bash.
+
How to build a self-contained version of the Docs/Demos
=======================================================
Once you have your own cloned repo on your computer:
@@ -25,6 +32,7 @@ The docs will be built and available in the compiled/demos folder. You can move
other location. It has no dependencies on anything other than a basic HTML web server.
+
Submitting bugs
===============
If you think you've found a bug, please report it by following these instructions:
View
4 build/bin/build_latest.sh
@@ -0,0 +1,4 @@
+source build/bin/config.sh
+
+# Copy over the lib js, avoid the compiled stuff, to get the defines for tests/unit/*
+find js -name "*.js" -not -name "*.docs.js" -not -name "*.mobile.js" | xargs -L1 -I FILENAME cp FILENAME $OUTPUT/demos/js/
View
4 build/bin/clean.sh
@@ -0,0 +1,4 @@
+source build/bin/config.sh
+
+rm -rf $OUTPUT
+rm -rf tmp
View
56 build/bin/config.sh
@@ -0,0 +1,56 @@
+# fail on any subcommand failure
+set -e
+
+# Helper Variables
+# The command to replace the @VERSION in the files with the actual version
+HEAD_SHA=$(git log -1 --format=format:"%H")
+BUILD_SHA=$(git log -1 --format=format:"Git Build: SHA1: %H <> Date: %cd")
+VER_MIN="/*! jQuery Mobile v$BUILD_SHA jquerymobile.com | jquery.org/license !*/"
+VER_OFFICIAL=$(cat version.txt)
+SED_VER_REPLACE="s/__version__/\"$VER_OFFICIAL\"/g"
+SED_INPLACE_EXT="whyunowork"
+
+function sed_ver_api {
+ sed "$SED_VER_REPLACE"
+}
+
+function ver {
+ sed "s/v@VERSION/$BUILD_SHA/"
+}
+
+function clear_zip_files {
+ find $1 -name "*.zip" | xargs -L1 -I FILENAME rm FILENAME
+}
+
+# The output folder for the finished files
+OUTPUT="compiled"
+
+# The name of the files
+NAME="jquery.mobile"
+BASE_NAME="jquery.mobile"
+THEME_FILENAME="jquery.mobile.theme"
+STRUCTURE="jquery.mobile.structure"
+
+# The CSS theme being used
+THEME="default"
+
+# If node is available then use node to run r.js
+# otherwise use good old rhino/java
+NODE=/usr/local/bin/node
+
+RUN_JS='java -XX:ReservedCodeCacheSize=64m -classpath build/js.jar:build/google-compiler-20111003.jar org.mozilla.javascript.tools.shell.Main'
+
+if [ -x $NODE ]; then
+ RUN_JS=${NODE}
+fi
+
+if [ $IS_DEPLOY_TARGET = "true" ]; then
+ function ver {
+ sed "s/v@VERSION/${VER_OFFICIAL} ${HEAD_SHA}/"
+ }
+
+ VER_MIN="/*! jQuery Mobile v${VER_OFFICIAL} ${HEAD_SHA} jquerymobile.com | jquery.org/license !*/"
+ NAME="jquery.mobile-${VER_OFFICIAL}"
+ THEME_FILENAME="jquery.mobile.theme-${VER_OFFICIAL}"
+ STRUCTURE="jquery.mobile.structure-${VER_OFFICIAL}"
+fi
View
35 build/bin/css.sh
@@ -0,0 +1,35 @@
+source build/bin/config.sh
+
+# Build the CSS file with the theme included
+$RUN_JS \
+ external/r.js/dist/r.js \
+ -o cssIn=css/themes/default/jquery.mobile.css \
+ optimizeCss=standard.keepComments.keepLines \
+ out=$OUTPUT/$NAME.compiled.css
+cat LICENSE-INFO.txt | ver > $OUTPUT/$NAME.css
+cat $OUTPUT/$NAME.compiled.css >> $OUTPUT/$NAME.css
+echo $VER_MIN > $OUTPUT/$NAME.min.css
+java -XX:ReservedCodeCacheSize=64m -jar build/yuicompressor-2.4.6.jar --type css $OUTPUT/$NAME.compiled.css >> $OUTPUT/$NAME.min.css
+rm $OUTPUT/$NAME.compiled.css
+# Build the CSS Structure-only file
+$RUN_JS external/r.js/dist/r.js \
+ -o cssIn=css/structure/jquery.mobile.structure.css \
+ out=$OUTPUT/$STRUCTURE.compiled.css
+cat LICENSE-INFO.txt | ver > $OUTPUT/$STRUCTURE.css
+cat $OUTPUT/$STRUCTURE.compiled.css >> $OUTPUT/$STRUCTURE.css
+# ..... and then minify it
+echo $VER_MIN > $OUTPUT/$STRUCTURE.min.css
+java -XX:ReservedCodeCacheSize=64m \
+ -jar build/yuicompressor-2.4.6.jar \
+ --type css $OUTPUT/$STRUCTURE.compiled.css >> $OUTPUT/$STRUCTURE.min.css
+rm $OUTPUT/$STRUCTURE.compiled.css
+# Build the theme only file
+cat LICENSE-INFO.txt | ver > $OUTPUT/$THEME_FILENAME.css
+cat css/themes/default/jquery.mobile.theme.css >> $OUTPUT/$THEME_FILENAME.css
+# ..... and then minify it
+echo $VER_MIN > $OUTPUT/$THEME_FILENAME.min.css
+java -XX:ReservedCodeCacheSize=64m \
+ -jar build/yuicompressor-2.4.6.jar \
+ --type css $OUTPUT/$THEME_FILENAME.css >> $OUTPUT/$THEME_FILENAME.min.css
+# Copy in the images
+cp -R css/themes/$THEME/images $OUTPUT/
View
20 build/bin/deploy.sh
@@ -0,0 +1,20 @@
+source build/bin/config.sh
+
+# Deploying all the files to the CDN
+mkdir -p tmp
+cp -R $OUTPUT tmp/$VER_OFFICIAL
+scp -qr tmp/* jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/
+rm -rf tmp/$VER_OFFICIAL
+mv $OUTPUT/demos tmp/$VER_OFFICIAL
+# Create the Demos/Docs/Tests/Tools for jQueryMobile.com
+# ... By first replacing the paths
+# TODO update jQuery Version replacement on deploy
+find tmp/$VER_OFFICIAL -type f \
+ \( -name '*.html' -o -name '*.php' \) \
+ -exec perl -pi -e \
+ "s|src=\"(.*)$BASE_NAME.js\"|src=\"//code.jquery.com/mobile/$VER_OFFICIAL/$NAME.min.js\"|g;s|href=\"(.*)$BASE_NAME.css\"|href=\"//code.jquery.com/mobile/$VER_OFFICIAL/$NAME.min.css\"|g;s|src=\"(.*)jquery.js\"|src=\"//code.jquery.com/jquery-1.7.1.min.js\"|g" {} \;
+# ... So they can be copied to jquerymobile.com
+scp -qr tmp/* jqadmin@jquerymobile.com:/srv/jquerymobile.com/htdocs/demos/
+# Do some cleanup to wrap it up
+rm -rf tmp
+rm -rf $OUTPUT
View
4 build/bin/deploy_latest.sh
@@ -0,0 +1,4 @@
+source build/bin/config.sh
+
+# Push the latest git version to the CDN. This is done on a post commit hook
+scp -qr $OUTPUT/* jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/latest/
View
3  build/bin/deploy_nightlies.sh
@@ -0,0 +1,3 @@
+source build/bin/config.sh
+
+scp -qr $OUTPUT jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/nightlies/$(date "+%Y%m%d")
View
29 build/bin/docs.sh
@@ -0,0 +1,29 @@
+source build/bin/config.sh
+
+mkdir -p tmp/demos/js
+mkdir -p tmp/demos/css/themes/$THEME
+# ... Copy script files
+cp compiled/*.js tmp/demos/js
+cp js/jquery.js tmp/demos/js
+# ... Copy html files
+cp index.html tmp/demos
+cp -r docs tmp/demos
+# ... Copy css and images
+cp compiled/*.css tmp/demos/css/themes/$THEME
+cp -r compiled/images tmp/demos/css/themes/$THEME
+# ... replace "js/" with "js/jquery.mobile.js"
+# NOTE the deletion here is required by gnu/bsd sed differences
+find tmp/demos \( -name '*.html' -o -name '*.php' \) -exec sed -i${SED_INPLACE_EXT} -e "s@js/\"@js/$NAME.js\"@" {} \;
+find tmp/demos -name "*$SED_INPLACE_EXT" -exec rm {} \;
+# make sure the docs reference the right css file names (for deploy)
+find tmp/demos \( -name '*.html' -o -name '*.php' \) -exec sed -i${SED_INPLACE_EXT} -e "s@$BASE_NAME.css\"@$NAME.css\"@" {} \;
+find tmp/demos -name "*$SED_INPLACE_EXT" -exec rm {} \;
+
+# clear out old zip files
+clear_zip_files $OUTPUT
+
+# ... Move and zip up the the whole folder
+cd tmp/demos && mkdir -p $OUTPUT && zip -qr $OUTPUT/$BASE_NAME.docs.zip ./* && cd -
+rm -rf $OUTPUT/demos && mv -f tmp/demos $OUTPUT
+# Finish by removing the temporary files
+rm -rf tmp
View
3  build/bin/init.sh
@@ -0,0 +1,3 @@
+source build/bin/config.sh
+
+mkdir -p $OUTPUT
View
26 build/bin/js.sh
@@ -0,0 +1,26 @@
+source build/bin/config.sh
+
+# Build the JavaScript file
+$RUN_JS \
+ external/r.js/dist/r.js \
+ -o baseUrl="js" \
+ name=jquery.mobile \
+ exclude=jquery,../external/requirejs/order,../external/requirejs/depend,../external/requirejs/text,../external/requirejs/text!../version.txt \
+ out=$OUTPUT/$NAME.compiled.js \
+ pragmasOnSave.jqmBuildExclude=true \
+ wrap.startFile=build/wrap.start \
+ wrap.endFile=build/wrap.end \
+ findNestedDependencies=true \
+ skipModuleInsertion=true \
+ optimize=none
+cat LICENSE-INFO.txt | ver > $OUTPUT/$NAME.js
+cat $OUTPUT/$NAME.compiled.js | sed_ver_api >> $OUTPUT/$NAME.js
+rm $OUTPUT/$NAME.compiled.js
+echo $VER_MIN > $OUTPUT/$NAME.min.js
+java -XX:ReservedCodeCacheSize=64m \
+ -jar build/google-compiler-20111003.jar \
+ --js $OUTPUT/$NAME.js \
+ --js_output_file $OUTPUT/$NAME.compiled.js
+cat $OUTPUT/$NAME.compiled.js >> $OUTPUT/$NAME.min.js
+rm $OUTPUT/$NAME.compiled.js
+
View
12 build/bin/zip.sh
@@ -0,0 +1,12 @@
+source build/bin/config.sh
+
+# Packaging up the files into a zip archive
+mkdir -p tmp
+cp -R $OUTPUT tmp/$NAME
+
+# ... And remove the Zipped docs so they aren't included twice (for deploy scripts)
+# clear out old zip files
+clear_zip_files tmp/$NAME
+
+cd tmp; zip -rq ../$OUTPUT/$NAME.zip $NAME
+rm -rf tmp
View
103 build/config.js
@@ -0,0 +1,103 @@
+var fs = require( 'fs' ),
+ path = require( 'path' ),
+ child_process = require( 'child_process' );
+
+module.exports = function( grunt ) {
+ var global = {
+ dirs : {
+ output: 'compiled',
+ temp: 'tmp'
+ },
+
+ files: {
+ license: 'LICENSE-INFO.txt'
+ },
+
+ names: {
+ base: 'jquery.mobile',
+ // this will change for the deploy target to include version information
+ root: 'jquery.mobile',
+ structure: 'jquery.mobile.structure',
+ theme: 'jquery.mobile.theme'
+ },
+
+ // other version information is added via the asyncConfig helper that
+ // depends on git commands (eg ver.min, ver.header)
+ ver: {
+ official: grunt.file.read( 'version.txt' ).replace(/\n/, ''),
+ min: "/*! jQuery Mobile v<%= build_sha %> jquerymobile.com | jquery.org/license !*/"
+ },
+
+ shas: {},
+
+ helpers: {
+ appendFrom: function( output, input, filter ) {
+ var inputString = fs.readFileSync(input).toString();
+
+ this.append( output, inputString, filter );
+ },
+
+ append: function( output, input, filter ) {
+ var id = fs.openSync(output, 'a+');
+
+ input = filter ? filter(input) : input;
+
+ fs.writeSync( id, input );
+ fs.closeSync( id );
+ },
+
+ minify: function( opts ) {
+ var max = grunt.file.read( opts.input ),
+ min = opts.minCallback(max);
+
+ // add the min header into the minified file, and then the min css
+ grunt.file.write( opts.output, opts.header );
+ this.append( opts.output, min );
+
+ grunt.helper( "min_max_info", min, max );
+ },
+
+ // NOTE cargo culting my way to the top :(
+ rmdirRecursive: function(dir) {
+ if( !path.existsSync(dir) ) {
+ return;
+ }
+
+ var list = fs.readdirSync(dir);
+ for(var i = 0; i < list.length; i++) {
+ var filename = path.join(dir, list[i]);
+ var stat = fs.statSync(filename);
+
+ if(filename == "." || filename == "..") {
+ // pass these files
+ } else if(stat.isDirectory()) {
+ // rmdir recursively
+ this.rmdirRecursive(filename);
+ } else {
+ // rm fiilename
+ fs.unlinkSync(filename);
+ }
+ }
+ fs.rmdirSync(dir);
+ },
+
+ asyncConfig: function( callback ) {
+ child_process.exec( 'git log -1 --format=format:"Git Build: SHA1: %H <> Date: %cd"', function( err, stdout, stderr ){
+ global.shas.build_sha = stdout;
+ global.ver.min = grunt.template.process( global.ver.min, global.shas );
+
+ child_process.exec( 'git log -1 --format=format:"%H"', function( err, stdout, stderr ) {
+ global.shas.head_sha = stdout;
+
+ // NOTE not using a template here because the Makefile depends on the v@VERSION
+ global.ver.header = grunt.file.read( global.files.license )
+ .replace(/v@VERSION/, global.shas.build_sha );
+ callback( global );
+ });
+ });
+ }
+ }
+ };
+
+ grunt.config.set( 'global', global );
+};
View
10 build/tasks/clean.js
@@ -0,0 +1,10 @@
+var fs = require( 'fs' );
+
+module.exports = function( grunt ) {
+ var config = grunt.config.get( 'global' );
+
+ grunt.registerTask( 'clean', 'ensure the output directory is present', function() {
+ config.helpers.rmdirRecursive( config.dirs.output );
+ config.helpers.rmdirRecursive( config.dirs.temp );
+ });
+};
View
116 build/tasks/css.js
@@ -0,0 +1,116 @@
+var requirejs = require( 'requirejs' ),
+ path = require( 'path' ),
+ fs = require( 'fs' ),
+ sqwish = require ( 'sqwish' ),
+ util = require( 'util' );
+
+module.exports = function( grunt ) {
+ var config = grunt.config.get( 'global' ),
+ regularFile = path.join( config.dirs.output, config.names.root ),
+ structureFile = path.join( config.dirs.output, config.names.structure ),
+ themeFile = path.join( config.dirs.output, config.names.theme ),
+ helpers = config.helpers;
+
+ grunt.config.set( 'css', {
+ theme: process.env.THEME || 'default',
+
+ require: {
+ all: {
+ cssIn: 'css/themes/default/jquery.mobile.css',
+ optimizeCss: 'standard.keepComments.keepLines',
+ baseUrl: '.',
+ out: regularFile + '.compiled.css'
+ },
+
+ structure: {
+ cssIn: 'css/structure/jquery.mobile.structure.css',
+ out: structureFile + '.compiled.css'
+ }
+ }
+ });
+
+ grunt.registerTask( 'css_without_deps', 'compile and minify the css', function() {
+ var done = this.async(),
+ theme = grunt.config.get( 'css' ).theme,
+ require = grunt.config.get( 'css' ).require;
+
+ helpers.asyncConfig(function( config ) {
+ // pull the includes together using require js
+ requirejs.optimize( require.all );
+
+ // dump the versioned header into the normal css file
+ grunt.file.write( regularFile + '.css', config.ver.header );
+
+ // add the compiled css to the normal css file
+ helpers.appendFrom( regularFile + '.css', require.all.out );
+
+ helpers.minify({
+ output: regularFile + '.min.css',
+ input: regularFile + '.css',
+ header: config.ver.min,
+ minCallback: function( unminified ) {
+ return sqwish.minify( unminified, false );
+ }
+ });
+
+ // pull the includes together using require js
+ requirejs.optimize( require.structure );
+
+ // dump the versioned header into the structure css file
+ grunt.file.write( structureFile + '.css', config.ver.header );
+
+ // add the compiled css to the normal css file
+ helpers.appendFrom( structureFile + '.css', require.all.out );
+
+ // add the min header into the minified file
+ grunt.file.write( structureFile + '.min.css', config.ver.min );
+
+ // minify the structure css
+ helpers.minify({
+ output: structureFile + '.min.css',
+ input: structureFile + '.css',
+ header: config.ver.min,
+ minCallback: function( unminified ) {
+ return sqwish.minify( unminified, false );
+ }
+ });
+
+ // dump the versioned header into the theme css file
+ grunt.file.write( themeFile + '.css', config.ver.header );
+
+ // dump the theme css into the theme css file
+ helpers.appendFrom( themeFile + '.css', 'css/themes/default/jquery.mobile.theme.css' );
+
+ // minify the theme css
+ helpers.minify({
+ output: themeFile + '.min.css',
+ input: themeFile + '.css',
+ header: config.ver.min,
+ minCallback: function( unminified ) {
+ return sqwish.minify( unminified, false );
+ }
+ });
+
+ // remove the requirejs compile output
+ fs.unlink( require.all.out );
+ fs.unlink( require.structure.out );
+
+ // copy images directory
+ var imagesPath = path.join( config.dirs.output, 'images' ), fileCount = 0;
+
+ grunt.file.mkdir( imagesPath );
+ grunt.file.recurse( path.join('css', 'themes', theme, 'images'), function( full, root, sub, filename ) {
+
+ fileCount++;
+ var is = fs.createReadStream( full );
+ var os = fs.createWriteStream( path.join(imagesPath, filename) );
+ util.pump(is, os, function() {
+ fileCount--;
+ if( fileCount == 0 ) { done(); }
+ });
+ });
+ });
+ });
+
+ grunt.registerTask( 'css', 'custom_init css_without_deps' );
+};
View
11 build/tasks/custom_init.js
@@ -0,0 +1,11 @@
+var fs = require( 'fs' ), path = require( 'path' );
+
+module.exports = function( grunt ) {
+ var config = grunt.config.get( 'global' );
+ // TODO having issues overriding default init task
+ grunt.registerTask( 'custom_init', 'ensure the output directory is present', function() {
+ if( !path.existsSync(config.dirs.output) ) {
+ fs.mkdirSync( config.dirs.output );
+ }
+ });
+};
View
63 build/tasks/js.js
@@ -0,0 +1,63 @@
+var requirejs = require( 'requirejs' ),
+ path = require( 'path' ),
+ fs = require( 'fs' );
+
+module.exports = function( grunt ) {
+ var config = grunt.config.get( 'global' ),
+ outputFile = path.join( config.dirs.output, config.names.root ),
+ helpers = config.helpers;
+
+ grunt.config.set( 'js', {
+ require: {
+ baseUrl: 'js',
+ name: 'jquery.mobile',
+ exclude:[
+ 'jquery',
+ '../external/requirejs/order',
+ '../external/requirejs/depend',
+ '../external/requirejs/text',
+ '../external/requirejs/text!../version.txt'
+ ],
+ out: outputFile + '.compiled.js',
+ pragmasOnSave: { jqmBuildExclude: true },
+ wrap: { startFile: 'build/wrap.start', endFile: 'build/wrap.end' },
+ findNestedDependencies: true,
+ skipModuleInsertion: true,
+ optimize: 'none'
+ }
+ });
+
+ grunt.registerTask( 'js_without_deps', 'compile and minify the js', function() {
+ var done = this.async(), require = grunt.config.get( 'js' ).require;
+
+ helpers.asyncConfig(function( config ) {
+ // pull the includes together using require js
+ requirejs.optimize( require );
+
+ // dump the versioned header into the normal js file
+ grunt.file.write( outputFile + '.js', config.ver.header );
+
+ // add the compiled js to the normal js file, replace the version tag
+ // with the contents from version.txt
+ helpers.appendFrom( outputFile + '.js', require.out, function( fileContents ) {
+ return fileContents.replace( /__version__/, '"' + config.ver.official + '"' );
+ });
+
+ helpers.minify({
+ output: outputFile + '.min.js',
+ input: outputFile + '.js',
+ header: config.ver.min,
+ minCallback: function( unminified ) {
+ return grunt.helper( 'uglify', unminified, {});
+ }
+ });
+
+ // remove the requirejs compile output
+ fs.unlink( require.out );
+ done();
+ });
+ });
+
+ // NOTE custom dasks don't accept dependencies so we alias
+ grunt.registerTask( 'js', 'custom_init js_without_deps' );
+};
View
59 build/tasks/legacy.js
@@ -0,0 +1,59 @@
+var util = require('util'),
+ child_process = require('child_process');
+
+module.exports = function( grunt ) {
+ grunt.config.set('legacy_tasks', {
+ clean: {},
+ css: {
+ deps: [ 'init' ]
+ },
+ deploy: {
+ deps: [ 'clean', 'init', 'js', 'css', 'docs', 'zip' ],
+ env: 'IS_DEPLOY_TARGET=true'
+ },
+ docs: {
+ deps: [ 'init', 'js', 'css' ]
+ },
+ init: {},
+ js: {
+ deps: [ 'init' ]
+ },
+ zip: {
+ deps: [ 'init', 'js', 'css' ]
+ }
+ });
+
+ grunt.registerMultiTask('legacy_tasks', 'support for old build targets', function() {
+ var done = this.async(), name = this.name, self = this;
+
+ ( this.data.deps || [] ).forEach(function(dep) {
+ self.requires( 'legacy_tasks:' + dep );
+ });
+
+ child_process.exec( (this.data.env || '') + ' bash build/bin/' + this.target + '.sh', function (error, stdout, stderr) {
+ if( error !== null ) {
+ grunt.log.error( stderr );
+ } else if ( process.env.VERBOSE ) {
+ grunt.log.write( stdout );
+ }
+
+ done();
+ });
+ });
+
+ // register the task alias's to enforce task dependencies for the custom task
+ // TODO this appears to prevent using args eg `grunt legacy:css:verbose` but
+ // more futzing is required
+ var deps, tasks = grunt.config.get( 'legacy_tasks' );
+ for( task in tasks ) {
+ deps = [];
+
+ ( tasks[task].deps || [] ).forEach(function( dep ) {
+ deps.push('legacy_tasks:' + dep);
+ });
+
+ deps.push( 'legacy_tasks:' + task );
+
+ grunt.registerTask( 'legacy:' + task, deps.join(' ') );
+ }
+};
View
2  css/structure/jquery.mobile.button.css
@@ -67,4 +67,4 @@
.ui-mini .ui-btn-icon-bottom .ui-icon { bottom: 5px; }
/*hiding native button,inputs */
-.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: .1; cursor: pointer; background: #fff; background: rgba(255,255,255,0); filter: Alpha(Opacity=.0001); font-size: 1px; border: none; text-indent: -9999px; }
+.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: none; opacity: .1; cursor: pointer; background: #fff; background: rgba(255,255,255,0); filter: Alpha(Opacity=.0001); font-size: 1px; border: none; text-indent: -9999px; }
View
2  css/structure/jquery.mobile.forms.select.css
@@ -2,7 +2,7 @@
.ui-select select { position: absolute; left: -9999px; top: -9999px; }
.ui-select .ui-btn { overflow: hidden; opacity: 1; margin: 0; }
/* Fixes #2588 — When Windows Phone 7.5 (Mango) tries to calculate a numeric opacity for a select—including “inherit”—without explicitly specifying an opacity on the parent to give it context, a bug appears where clicking elsewhere on the page after opening the select will open the select again. */
-.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; min-height: 1.5em; min-height: 100%; height: 3em; max-height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); z-index: 2; }
+.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: none; left: 0; top:0; width: 100%; min-height: 1.5em; min-height: 100%; height: 3em; max-height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); z-index: 2; }
.ui-select .ui-disabled { opacity: .3; }
View
4 css/structure/jquery.mobile.transition.css
@@ -17,5 +17,5 @@
-webkit-animation-timing-function: ease-in;
-webkit-animation-duration: 225ms;
-moz-animation-timing-function: ease-in;
- -moz-animation-duration: 225;
-}
+ -moz-animation-duration: 225ms;
+}
View
2  css/themes/default/jquery.mobile.theme.css
@@ -402,7 +402,7 @@
color: #222 /*{c-bhover-color}*/;
text-shadow: 0 /*{c-bhover-shadow-x}*/ 1px /*{c-bhover-shadow-y}*/ 0 /*{c-bhover-shadow-radius}*/ #ffffff /*{c-bhover-shadow-color}*/;
background-image: -webkit-gradient(linear, left top, left bottom, from( #f6f6f6 /*{c-bhover-background-start}*/), to( #e0e0e0 /*{c-bhover-background-end}*/)); /* Saf4+, Chrome */
- background-image: -webkit-linear-gradient( #f9f9f9 /*{c-bhover-background-start}*/, #e0e0e0 /*{c-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */
+ background-image: -webkit-linear-gradient( #f6f6f6 /*{c-bhover-background-start}*/, #e0e0e0 /*{c-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient( #f6f6f6 /*{c-bhover-background-start}*/, #e0e0e0 /*{c-bhover-background-end}*/); /* FF3.6 */
background-image: -ms-linear-gradient( #f6f6f6 /*{c-bhover-background-start}*/, #e0e0e0 /*{c-bhover-background-end}*/); /* IE10 */
background-image: -o-linear-gradient( #f6f6f6 /*{c-bhover-background-start}*/, #e0e0e0 /*{c-bhover-background-end}*/); /* Opera 11.10+ */
View
6 docs/api/data-attributes.html
@@ -369,12 +369,16 @@
<td>swatch letter (a-z)</td>
</tr>
<tr>
+ <th>data-header-theme</th>
+ <td>swatch letter (a-z)</td>
+ </tr>
+ <tr>
<th>data-inset</th>
<td>true | <strong>false</strong></td>
</tr>
<tr>
<th>data-split-icon</th>
- <td>home | delete | plus | arrow-u | arrow-d | check | gear | grid | star | custom | arrow-r | arrow-l | minus | refresh | forward | back | alert | info | search</td>
+ <td>home | delete | plus | arrow-u | arrow-d | check | gear | grid | star | custom | <strong>arrow-r</strong> | arrow-l | minus | refresh | forward | back | alert | info | search</td>
</tr>
<tr>
<th>data-split-theme</th>
View
11 docs/api/events.html
@@ -43,13 +43,14 @@ <h4 style="margin:.5em 0">Important: <code>$(document).bind('pagecreate')</code>
<dl>
<dt><code>tap</code></dt>
<dd><p>Triggers after a quick, complete touch event.</p>
- <ul>
- <li><code>tapholdThreshold</code> (default: 750ms) – This value dictates how long the user must hold their tap before the taphold event is fired on the target element.</li>
- </ul>
- </dd>
+ </dd>
<dt><code>taphold</code></dt>
- <dd>Triggers after a held complete touch event (close to one second).</dd>
+ <dd><p>Triggers after a held complete touch event (close to one second).</p>
+ <ul>
+ <li><code>tapholdThreshold</code> (default: 750ms) – This value dictates how long the user must hold their tap before the taphold event is fired on the target element.</li>
+ </ul>
+ </dd>
<dt><code>swipe</code></dt>
<dd><p>Triggers when a horizontal drag of 30px or more (and less than 20px vertically) occurs within 1 second duration but these can be configured:</p>
View
2  docs/api/globalconfig.html
@@ -130,7 +130,7 @@
<p class="ui-bar-e">Deprecated in 1.2 - use <code>$.mobile.loader.prototype.options.theme</code> instead. See the <a href="../../docs/pages/loader.html">loader docs</a> for more.</p>
</dd>
- <dt><code>minScrollBack</code> <em>string</em>, default: 250</dt>
+ <dt><code>minScrollBack</code> <em>integer</em>, default: 250</dt>
<dd>Minimum scroll distance that will be remembered when returning to a page.</dd>
<dt><code>ns</code> <em>string</em>, default: ""</dt>
View
3  docs/buttons/buttons-types.html
@@ -85,9 +85,6 @@
<p><strong>Input type="reset"</strong> based button:</p>
<input type="reset" value="resetBtn" />
- <p><strong>Input type="image"</strong> based button:</p>
- <input type="image" value="imageBtn" />
-
</div><!--/content-primary -->
<div class="content-secondary">
View
6 docs/lists/docs-lists.html
@@ -71,7 +71,7 @@
<h2>List dividers</h2>
- <p>List items can be turned into dividers to organize and group the list items. This is done by adding the <code> data-role="list-divider"</code> to any list item. These items are styled with the bar swatch "b" by default (blue in the default theme) but you can specify a theme for dividers by adding the <code>data-dividertheme</code> attribute to the list element (<code>ul</code> or <code>ol</code>) and specifying a theme swatch letter.</p>
+ <p>List items can be turned into dividers to organize and group the list items. This is done by adding the <code> data-role="list-divider"</code> to any list item. These items are styled with the bar swatch "b" by default (blue in the default theme) but you can specify a theme for dividers by adding the <code>data-divider-theme</code> attribute to the list element (<code>ul</code> or <code>ol</code>) and specifying a theme swatch letter.</p>
<a href="lists-divider.html" data-role="button" data-icon="arrow-r" data-iconpos="right">List divider example</a>
@@ -80,7 +80,7 @@
<p>A listview can be configured to automatically generate dividers for its items. This is done by adding a <code>data-autodividers="true"</code> attribute to any listview.</p>
- <p>By default, the text used to create dividers is the uppercased first letter of either the item's link text (for link lists) or the item's text (for read-only lists). Alternatively, if you are using formatted list items, you can specify divider text by setting the <code>autodividersSelector</code> option on the listview programmatically. For example, to add a custom selector to the element with <code>id="mylistview"</code>:</p>
+ <p>By default, the text used to create dividers is the uppercased first letter of either the item's link text (for linked lists) or the item's text (for read-only lists). Alternatively, if you are using formatted list items, you can specify divider text by setting the <code>autodividersSelector</code> option on the listview programmatically. For example, to add a custom selector to the element with <code>id="mylistview"</code>:</p>
<pre><code>
$("#mylistview").listview({
@@ -157,7 +157,7 @@
<h3>More in this section</h3>
- <ul data-role="listview" data-theme="c" data-dividertheme="d">
+ <ul data-role="listview" data-theme="c" data-divider-theme="d">
<li data-role="list-divider">List views</li>
<li data-theme="a"><a href="docs-lists.html">List basics &amp; API</a></li>
View
2  docs/pages/dialog.html
@@ -31,4 +31,4 @@
</body>
-</html>
+</html>
View
2  docs/pages/page-anatomy.html
@@ -173,6 +173,8 @@
<p>PLEASE NOTE: Since we are using the hash to track navigation history for all the Ajax 'pages', it's not currently possible to deep link to an anchor (<code>index.html#foo</code>) on a page in jQuery Mobile, because the framework will look for a 'page' with an <code>ID</code> of <code>#foo</code> instead of the native behavior of scrolling to the content with that <code>ID</code>.</p>
+ <p>The <code>id</code> attribute of all your elements must be not only unique on a given page, but also unique across the pages in a site. This is because jQuery Mobile's single-page navigation model allows many different &quot;pages&quot; to be present in the DOM at the same time. This also applies when using a multi-page template, since all &quot;pages&quot; on the template are loaded at once.</p>
+
<h2>Conventions, not requirements</h2>
View
1  docs/pages/page-navmodel.html
@@ -138,6 +138,7 @@ <h4 style="margin:.5em 0">Important: rel="external" and $.mobile.ajaxEnabled=fal
<li><p>When traveling back to a previously loaded jQuery Mobile document from an external <b>or</b> internal document with the push state plugin enabled, some browsers load and trigger the <code>popstate</code> event on the wrong document or for the wrong reasons (two edge cases recorded so far). If you are regularly linking to external documents and find the application behaving erratically try disabling pushstate support.</p></li>
<li><p>jQuery Mobile does not support query parameter passing to internal/embedded pages but there are two plugins that you can add to your project to support this feature. There is a lightweight <a href="https://github.com/jblas/jquery-mobile-plugins/tree/master/page-params" rel="external">page params plugin</a> and a more fully featured <a href="https://github.com/azicchetti/jquerymobile-router" rel="external">jQuery Mobile router plugin</a> for use with backbone.js or spine.js.</p></li>
<li><p>Since we use the URL hash to preserve Back button behavior, using page anchors to jump down to a position on the page isn't supported by using the traditional anchor link (#foo). Use the <a href="../api/methods.html"><code>silentScroll</code></a> method to scroll to a particular Y position without triggering scroll event listeners. You can pass in a <code>yPos</code> arguments to scroll to that Y location.</p></li>
+ <li><p>Some external applications (notably Facebook's OAuth implementation) modify their response URL in such a way that interferes with jQuery Mobile. In particular, Facebook appends <code>#_=_</code> to the end of the callback. Currently the best solution for this is to remove it from the location hash before jQuery Mobile loads using something like: <code>if (window.location.hash == "#_=_") window.location.hash = ""; </code>. jQuery Mobile can then process &amp; enhance the page properly.</p></li>
</ul>
View
2  docs/toolbars/docs-headers.html
@@ -164,7 +164,7 @@
<pre><code>
&lt;div <strong>class=&quot;ui-bar ui-bar-b&quot;</strong>&gt;
- &lt;h3&gt;I&#x27;m just a div with bar classes and a mini inline &lt;a href=&quot;#&quot; data-role=&quot;button&quot;&gt; data-mini=&quot;true&quot;&gt;Button&lt;/a&gt;&lt;/h3&gt;
+ &lt;h3&gt;I&#x27;m just a div with bar classes and a mini inline &lt;a href=&quot;#&quot; data-role=&quot;button&quot; data-mini=&quot;true&quot;&gt;Button&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;
</code></pre>
View
56 grunt.js
@@ -0,0 +1,56 @@
+var path = require( 'path' );
+
+module.exports = function( grunt ) {
+
+ // Project configuration.
+ grunt.config.init({
+ jshint: {
+ options: {
+ curly: true,
+ eqeqeq: true,
+
+ // (function(){})() seems acceptable
+ immed: false,
+ latedef: true,
+ newcap: true,
+ noarg: true,
+ sub: true,
+ undef: true,
+ boss: true,
+ eqnull: true,
+ browser: true
+ },
+ globals: {
+ jQuery: true,
+ "$": true,
+
+ // qunit globals
+ // TODO would be nice to confine these to test files
+ module: true,
+ ok: true,
+ test: true,
+ asyncTest: true,
+ same: true,
+ start: true,
+ stop: true,
+ expect: true,
+
+ // require js global
+ define: true
+ }
+ },
+
+ lint: {
+ files: ['grunt.js', 'js/*.js', 'tests/**/*.js']
+ }
+ });
+
+ // set the default task.
+ grunt.registerTask('default', 'lint');
+
+ // load the project wide config before loading the tasks
+ require( path.resolve(path.join('build', 'config')) )( grunt );
+
+ // load the project's default tasks
+ grunt.loadTasks( path.join('build', 'tasks') );
+};
View
2  js/jquery.mobile.controlGroup.js
@@ -10,7 +10,7 @@ define( [ "jquery", "./jquery.mobile.buttonMarkup" ], function( $ ) {
$.fn.controlgroup = function( options ) {
function flipClasses( els, flCorners ) {
- els.removeClass( "ui-btn-corner-all ui-shadow" )
+ els.removeClass( "ui-btn-corner-all ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-controlgroup-last ui-shadow" )
.eq( 0 ).addClass( flCorners[ 0 ] )
.end()
.last().addClass( flCorners[ 1 ] ).addClass( "ui-controlgroup-last" );
View
7 js/jquery.mobile.dialog.js
@@ -84,7 +84,12 @@ $.widget( "mobile.dialog", $.mobile.widget, {
close: function() {
if ( !this._isClosed ) {
this._isClosed = true;
- window.history.back();
+ if ( $.mobile.hashListeningEnabled ) {
+ window.history.back();
+ }
+ else {
+ $.mobile.changePage( $.mobile.urlHistory.getPrev().url );
+ }
}
}
});
View
11 js/jquery.mobile.forms.button.js
@@ -1,6 +1,6 @@
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Custom-styled native input/buttons
-//>>label: Buttons: Input or button-based
+//>>label: Buttons: Input or button-based
//>>group: Forms
//>>css: ../css/themes/default/jquery.mobile.theme.css,../css/structure/jquery.mobile.button.css
@@ -31,9 +31,12 @@ $.widget( "mobile.button", $.mobile.widget, {
// if this is a link, check if it's been enhanced and, if not, use the right function
if( $el[ 0 ].tagName === "A" ) {
- !$el.hasClass( "ui-btn" ) && $el.buttonMarkup();
- return;
- }
+ if( !$el.hasClass( "ui-btn" ) ) {
+ $el.buttonMarkup();
+ }
+
+ return;
+ }
// get the inherited theme
// TODO centralize for all widgets
View
2  js/jquery.mobile.forms.checkboxradio.js
@@ -21,7 +21,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
var self = this,
input = this.element,
inheritAttr = function( input, dataAttr ) {
- return input.jqmData( dataAttr ) || input.closest( "form,fieldset" ).jqmData( dataAttr )
+ return input.jqmData( dataAttr ) || input.closest( "form,fieldset" ).jqmData( dataAttr );
},
// NOTE: Windows Phone could not find the label through a selector
// filter works though.
View
31 js/jquery.mobile.forms.select.custom.js
@@ -3,7 +3,7 @@
*/
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
-//>>description: Extension to select menus to support menu styling, placeholder options, and multi-select features.
+//>>description: Extension to select menus to support menu styling, placeholder options, and multi-select features.
//>>label: Selects: Custom menus
//>>group: Forms
//>>css: ../css/themes/default/jquery.mobile.theme.css, ../css/structure/jquery.mobile.forms.select.css
@@ -101,9 +101,9 @@ define( [
// Button events
self.button.bind( "vclick keydown" , function( event ) {
- if ( event.type == "vclick" ||
- event.keyCode && ( event.keyCode === $.mobile.keyCode.ENTER ||
- event.keyCode === $.mobile.keyCode.SPACE ) ) {
+ if (event.type === "vclick" ||
+ event.keyCode && (event.keyCode === $.mobile.keyCode.ENTER ||
+ event.keyCode === $.mobile.keyCode.SPACE)) {
self.open();
event.preventDefault();
@@ -160,7 +160,7 @@ define( [
// switch logic based on which key was pressed
switch ( event.keyCode ) {
// up or left arrow keys
- case 38:
+ case 38:
prev = li.prev().not( ".ui-selectmenu-placeholder" );
if( prev.is( ".ui-li-divider" ) ) {
@@ -177,10 +177,8 @@ define( [
}
return false;
- break;
-
// down or right arrow keys
- case 40:
+ case 40:
next = li.next();
if( next.is( ".ui-li-divider" ) ) {
@@ -197,15 +195,12 @@ define( [
}
return false;
- break;
-
// If enter or space is pressed, trigger click
- case 13:
- case 32:
+ case 13:
+ case 32:
target.trigger( "click" );
return false;
- break;
}
});
@@ -238,7 +233,7 @@ define( [
// Close button on small overlays
if( self.isMultiple ){
self.headerClose.click( function() {
- if ( self.menuType == "overlay" ) {
+ if ( self.menuType === "overlay" ) {
self.close();
return false;
}
@@ -308,7 +303,7 @@ define( [
var self = this;
- if ( self.menuType == "page" ) {
+ if ( self.menuType === "page" ) {
// doesn't solve the possible issue with calling change page
// where the objects don't define data urls which prevents dialog key
// stripping - changePage has incoming refactor
@@ -365,7 +360,7 @@ define( [
self.thisPage.unbind( "pagehide.remove" );
//for WebOS/Opera Mini (set lastscroll using button offset)
- if ( scrollTop == 0 && btnOffset > screenHeight ) {
+ if ( scrollTop === 0 && btnOffset > screenHeight ) {
self.thisPage.one( "pagehide", function() {
$( this ).jqmData( "lastScroll", btnOffset );
});
@@ -468,7 +463,7 @@ define( [
// Are we inside an optgroup?
if (parent !== select && parent.nodeName.toLowerCase() === "optgroup"){
var optLabel = parent.getAttribute('label');
- if ( optLabel != optGroup) {
+ if ( optLabel !== optGroup) {
var divider = document.createElement('li');
divider.setAttribute(dataRoleAttr,'list-divider');
divider.setAttribute('role','option');
@@ -479,7 +474,7 @@ define( [
}
}
- if (needPlaceholder && (!option.getAttribute( "value" ) || text.length == 0 || $option.jqmData( "placeholder" ))) {
+ if (needPlaceholder && (!option.getAttribute( "value" ) || text.length === 0 || $option.jqmData( "placeholder" ))) {
needPlaceholder = false;
if ( o.hidePlaceholderMenuItems ) {
classes.push( "ui-selectmenu-placeholder" );
View
19 js/jquery.mobile.listview.js
@@ -184,8 +184,9 @@ $.widget( "mobile.listview", $.mobile.widget, {
if ( create || !item.hasClass( "ui-li" ) ) {
itemTheme = item.jqmData("theme") || o.theme;
a = this._getChildrenByTagName( item[ 0 ], "a", "A" );
+ var isDivider = ( item.jqmData( "role" ) === "list-divider" );
- if ( a.length ) {
+ if ( a.length && !isDivider ) {
icon = item.jqmData("icon");
item.buttonMarkup({
@@ -197,7 +198,7 @@ $.widget( "mobile.listview", $.mobile.widget, {
theme: itemTheme
});
- if ( ( icon != false ) && ( a.length == 1 ) ) {
+ if ( ( icon !== false ) && ( a.length === 1 ) ) {
item.addClass( "ui-li-has-arrow" );
}
@@ -233,7 +234,7 @@ $.widget( "mobile.listview", $.mobile.widget, {
})
);
}
- } else if ( item.jqmData( "role" ) === "list-divider" ) {
+ } else if ( isDivider ) {
itemClass += " ui-li-divider ui-bar-" + dividertheme;
item.attr( "role", "heading" );
@@ -342,8 +343,8 @@ $.widget( "mobile.listview", $.mobile.widget, {
list = $( this ),
listId = list.attr( "id" ) || parentListId + "-" + i,
parent = list.parent(),
- nodeEls = $( list.prevAll().toArray().reverse() ),
- nodeEls = nodeEls.length ? nodeEls : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" ),
+ nodeElsFull = $( list.prevAll().toArray().reverse() ),
+ nodeEls = nodeElsFull.length ? nodeElsFull : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" ),
title = nodeEls.first().getEncodedText(),//url limits to first 30 chars of text
id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId,
theme = list.jqmData( "theme" ) || o.theme,
@@ -380,13 +381,17 @@ $.widget( "mobile.listview", $.mobile.widget, {
parentPage.data("page").options.domCache === false ) {
var newRemove = function( e, ui ){
- var nextPage = ui.nextPage, npURL;
+ var nextPage = ui.nextPage, npURL,
+ prEvent = new $.Event( "pageremove" );
if( ui.nextPage ){
npURL = nextPage.jqmData( "url" );
if( npURL.indexOf( parentUrl + "&" + $.mobile.subPageUrlKey ) !== 0 ){
self.childPages().remove();
- parentPage.remove();
+ parentPage.trigger( prEvent );
+ if( !prEvent.isDefaultPrevented() ){
+ parentPage.removeWithDependents();
+ }
}
}
};
View
26 js/jquery.mobile.loader.js
@@ -24,12 +24,12 @@ define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.init" ], function(
// with the following shape: { theme: '', text: '', html: '', textVisible: '' }
// NOTE that the $.mobile.loading* settings and params past the first are deprecated
showPageLoadingMsg: function( theme, msgText, textonly ) {
- this.loading( 'show', theme, msgText, textonly );
+ $.mobile.loading( 'show', theme, msgText, textonly );
},
// DEPRECATED
hidePageLoadingMsg: function() {
- this.loading( 'hide' );
+ $.mobile.loading( 'hide' );
},
loading: function() {
@@ -58,9 +58,9 @@ define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.init" ], function(
},
defaultHtml: "<div class='" + loaderClass + "'>" +
- "<span class='ui-icon ui-icon-loading'></span>" +
- "<h1></h1>" +
- "</div>",
+ "<span class='ui-icon ui-icon-loading'></span>" +
+ "<h1></h1>" +
+ "</div>",
// For non-fixed supportin browsers. Position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top
fakeFixLoader: function(){
@@ -103,7 +103,7 @@ define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.init" ], function(
var loadSettings;
// support for object literal params
- if( $.type(theme) == "object" ){
+ if( $.type(theme) === "object" ){
loadSettings = $.extend({}, this.options, theme);
// prefer object property from the param then the old theme setting
@@ -115,22 +115,22 @@ define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.init" ], function(
$html.addClass( "ui-loading" );
- if ( $.mobile.loadingMessage != false || loadSettings.html ) {
+ if ( $.mobile.loadingMessage !== false || loadSettings.html ) {
// text visibility from argument takes priority
var textVisible, message, $header;
// boolean values require a bit more work :P
// support object properties and old settings
- if( $.mobile.loadingMessageTextVisible != undefined ) {
+ if( $.mobile.loadingMessageTextVisible !== undefined ) {
textVisible = $.mobile.loadingMessageTextVisible;
} else {
textVisible = loadSettings.textVisible;
}
- this.element.attr( "class", loaderClass +
- " ui-corner-all ui-body-" + theme +
- " ui-loader-" + ( textVisible ? "verbose" : "default" )
- + ( loadSettings.textonly || textonly ? " ui-loader-textonly" : "" ) );
+ this.element.attr("class", loaderClass +
+ " ui-corner-all ui-body-" + theme +
+ " ui-loader-" + ( textVisible ? "verbose" : "default" ) +
+ ( loadSettings.textonly || textonly ? " ui-loader-textonly" : "" ) );
// TODO verify that jquery.fn.html is ok to use in both cases here
// this might be overly defensive in preventing unknowing xss
@@ -164,7 +164,7 @@ define( [ "jquery", "./jquery.mobile.core", "./jquery.mobile.init" ], function(
}
});
- $window.on( 'pagecontainercreate', function() {
+ $window.bind( 'pagecontainercreate', function() {
$.mobile.loaderWidget = $.mobile.loaderWidget || $( $.mobile.loader.prototype.defaultHtml ).loader();
});
})(jQuery, this);
View
7 js/jquery.mobile.navigation.js
@@ -168,7 +168,8 @@ define( [
} else if ( path.isSameDomain( u, documentBase ) ) {
return u.hrefNoHash.replace( documentBase.domain, "" );
}
- return absUrl;
+
+ return window.decodeURIComponent(absUrl);
},
//get path from current hash, or from a file path
@@ -492,7 +493,7 @@ define( [
$.mobile.hidePageLoadingMsg();
transition = $.mobile._maybeDegradeTransition( transition );
-
+
//find the transition handler for the specified transition. If there
//isn't one in our transitionHandlers dictionary, use the default one.
//call the handler immediately to kick-off the transition.
@@ -770,7 +771,7 @@ define( [
&& RegExp.$1
&& dataUrlRegex.test( RegExp.$1 )
&& RegExp.$1 ) {
- url = fileUrl = path.getFilePath( RegExp.$1 );
+ url = fileUrl = path.getFilePath( $( "<div>" + RegExp.$1 + "</div>" ).text() );
}
if ( base ) {
View
11 js/jquery.mobile.navigation.pushstate.js
@@ -12,7 +12,13 @@ define( [ "jquery", "./jquery.mobile.navigation", "../external/requirejs/depend!
var pushStateHandler = {},
self = pushStateHandler,
$win = $( window ),
- url = $.mobile.path.parseUrl( location.href );
+ url = $.mobile.path.parseUrl( location.href ),
+ mobileinitDeferred = $.Deferred(),
+ domreadyDeferred = $.Deferred();
+
+ $( document ).ready( $.proxy( domreadyDeferred, "resolve" ) );
+
+ $( document ).one( "mobileinit", $.proxy( mobileinitDeferred, "resolve" ) );
$.extend( pushStateHandler, {
// TODO move to a path helper, this is rather common functionality
@@ -138,7 +144,8 @@ define( [ "jquery", "./jquery.mobile.navigation", "../external/requirejs/depend!
}
});
- $( function() {
+ // We need to init when both "mobileinit" and "domready" have happened
+ $.when( domreadyDeferred, mobileinitDeferred ).done( function() {
if( $.mobile.pushStateEnabled && $.support.pushState ){
pushStateHandler.init();
}
View
13 js/jquery.mobile.page.sections.js
@@ -3,7 +3,7 @@
//>>label: Page Sections
//>>group: Core
-define( [ "jquery", "./jquery.mobile.page", "./jquery.mobile.core", "./jquery.mobile.buttonMarkup" ], function( $ ) {
+define( [ "jquery", "./jquery.mobile.page", "./jquery.mobile.core" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {
@@ -14,14 +14,17 @@ $.mobile.page.prototype.options.headerTheme = "a";
$.mobile.page.prototype.options.footerTheme = "a";
$.mobile.page.prototype.options.contentTheme = null;
-$( document ).delegate( ":jqmData(role='page'), :jqmData(role='dialog')", "pagecreate", function( e ) {
-
- var $page = $( this ),
+// NOTE bind used to force this binding to run before the buttonMarkup binding
+// which expects .ui-footer top be applied in its gigantic selector
+// TODO remove the buttonMarkup giant selector and move it to the various modules
+// on which it depends
+$( document ).bind( "pagecreate", function( e ) {
+ var $page = $( e.target ),
o = $page.data( "page" ).options,
pageRole = $page.jqmData( "role" ),
pageTheme = o.theme;
- $( ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')", this )
+ $( ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')", $page )
.jqmEnhanceable()
.each(function() {
View
52 js/jquery.mobile.transition.js
@@ -10,12 +10,12 @@ define( [ "jquery", "./jquery.mobile.core" ], function( $ ) {
(function( $, window, undefined ) {
var createHandler = function( sequential ){
-
+
// Default to sequential
if( sequential === undefined ){
sequential = true;
}
-
+
return function( name, reverse, $to, $from ) {
var deferred = new $.Deferred(),
@@ -33,9 +33,9 @@ var createHandler = function( sequential ){
// By using scrollTo instead of silentScroll, we can keep things better in order
// Just to be precautios, disable scrollstart listening like silentScroll would
$.event.special.scrollstart.enabled = false;
-
+
window.scrollTo( 0, toScroll );
-
+
// reenable scrollstart listening like silentScroll would
setTimeout(function() {
$.event.special.scrollstart.enabled = true;
@@ -52,66 +52,66 @@ var createHandler = function( sequential ){
doneOut();
}
else {
- $from.animationComplete( doneOut );
+ $from.animationComplete( doneOut );
}
-
+
// Set the from page's height and start it transitioning out
// Note: setting an explicit height helps eliminate tiling in the transitions
$from
.height( screenHeight + $(window ).scrollTop() )
.addClass( name + " out" + reverseClass );
},
-
+
doneOut = function() {
if ( $from && sequential ) {
cleanFrom();
}
-
+
startIn();
},
-
- startIn = function(){
-
- $to.addClass( $.mobile.activePageClass + toPreClass );
-
+
+ startIn = function(){
+
+ $to.addClass( $.mobile.activePageClass + toPreClass );
+
// Send focus to page as it is now display: block
$.mobile.focusPage( $to );
// Set to page height
$to.height( screenHeight + toScroll );
-
+
scrollPage();
-
+
if( !none ){
$to.animationComplete( doneIn );
}
-
+
$to
.removeClass( toPreClass )
.addClass( name + " in" + reverseClass );
-
+
if( none ){
doneIn();
}
-
+
},
-
+
doneIn = function() {
-
+
if ( !sequential ) {
-
+
if( $from ){
cleanFrom();
}
}
-
+
$to
.removeClass( "out in reverse " + name )
.height( "" );
-
+
toggleViewportClass();
-
+
// In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
// This ensures we jump to that spot after the fact, if we aren't there already.
if( $( window ).scrollTop() !== toScroll ){
@@ -122,7 +122,7 @@ var createHandler = function( sequential ){
};
toggleViewportClass();
-
+
if ( $from && !none ) {
startOut();
}
@@ -132,7 +132,7 @@ var createHandler = function( sequential ){
return deferred.promise();
};
-}
+};
// generate the handlers from the above
var sequentialHandler = createHandler(),
View
38 js/jquery.tag.inserter.js
@@ -5,27 +5,37 @@
var jqueryRE = /[\\?&]jquery=([^&#]*)/,
results = jqueryRE.exec( location.search ),
version = "",
- jq,
myScriptTag = document.getElementsByTagName( "script" )[document.getElementsByTagName( "script" ).length - 1],
baseUrl = myScriptTag.src.replace( /(.*)\/.*$/, "$1/" ),
- url = baseUrl + "jquery-1.7.1.js";
+ url = baseUrl + "jquery.js";
if( results ) {
version = decodeURIComponent(results[results.length - 1].replace(/\+/g, " "));
- }
- switch( version ) {
- case "1.6.4":
- url = baseUrl + "jquery-1.6.4.js";
- break;
- case "git":
- url = "http://code.jquery.com/jquery-git.js";
- break;
- }
+ switch( version ) {
+ // Local versions
+ case "1.6.4":
+ case "1.7.1":
+ case "1.7.2":
+ url = baseUrl + "jquery-" + version + ".js";
+ break;
+ // CDN versions
+ default:
+ url = "http://code.jquery.com/jquery-"+version+".js";
+ break;
+ }
+ }
document.write( "<script src='" + url + "'></script>" );
- if ( parseInt( version.replace( /\./g, "" ), 10 ) < 170 && window.define && window.define.amd ) {
- document.write( '<script>define( "jquery", [], function () { return jQuery; } );</script>' );
- }
+ document.write(
+ '<script>' +
+ 'console.warn( "jQuery version: " + jQuery.fn.jquery );' +
+ 'if ( parseInt( jQuery.fn.jquery.replace( /\\./g, "" ), 10 ) < 170 && window.define && window.define.amd ) {' +
+ 'console.warn( "Exporting \'jquery\' AMD module" );' +
+ 'define( "jquery", [], function () { return jQuery; } );'+
+ '}'+
+ '</script>'
+ );
+
}());
View
21 package.json
@@ -0,0 +1,21 @@
+{
+ "name": "jquery-mobile-build",
+ "description": "dependencies for the grunt based build",
+ "version": "0.0.1",
+ "scripts": {
+ "lint" : "grunt"
+ },
+ "main": "grunt.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/jquery/jquery-mobile.git"
+ },
+ "dependencies": {
+ "grunt": "0.3.x",
+ "requirejs": "1.0.8",
+ "sqwish": "0.2.0"
+ },
+ "engine": {
+ "node": ">=6.0"
+ }
+}
View
8 tests/unit/checkboxradio/checkboxradio_core.js
@@ -185,7 +185,7 @@
test( "theme should be inherited", function() {
var $inherited = $( "#checkbox-inherit-theme" ),
- $explicit = $( "#checkbox-explicit-theme" );
+ $explicit = $( "#checkbox-explicit-theme" );
ok( $inherited.siblings("label").hasClass( "ui-btn-up-a" ), "should inherit from page" );
ok( $explicit.siblings("label").hasClass( "ui-btn-up-b" ), "should not inherit" );
@@ -250,7 +250,7 @@
ok( $checkbox.parent().hasClass("ui-checkbox"), "enhancement has occured");
});
-
+
test( "nested label (no [for]) checkbox still renders", function() {
var $checkbox = $( "#checkbox-nested-label-no-for" );
@@ -262,9 +262,9 @@
ok( $checkbox.parent().hasClass("ui-checkbox"), "enhancement has occured");
});
-
+
test( "Icon positioning", function() {
- var bottomicon = $("[for='bottomicon']")
+ var bottomicon = $("[for='bottomicon']"),
topicon = $("[for='topicon']");
ok( bottomicon.hasClass("ui-btn-icon-bottom"), "Icon position set on label adds the appropriate class." );
View
15 tests/unit/dialog/dialog-no-hash.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ </head>
+ <body>
+ <div data-nstest-role="dialog" id="dialog-no-hash">
+ <div data-nstest-role="header">
+ <h1>No-hash dialog test</h1>
+ </div>
+ <div data-nstest-role="content">
+ <p>Content</p>
+ </div>
+ </div>
+ </body>
+</html>
View
43 tests/unit/dialog/dialog_no_hash.js
@@ -0,0 +1,43 @@
+/*
+ * mobile dialog unit tests
+ */
+(function($) {
+ module( "jquery.mobile.dialog.js", {
+ setup: function() {
+ $.mobile.page.prototype.options.contentTheme = "d";
+ }
+ });
+
+ asyncTest( "dialog opens and closes correctly when hash handling is off", function() {
+ var activePage;
+
+ expect( 3 );
+
+ $.testHelper.pageSequence([
+ function() {
+ $.mobile.changePage( $( "#mypage" ) );
+ },
+
+ function() {
+ activePage = $.mobile.activePage;
+ //bring up the dialog
+ $( "#dialog-no-hash-link" ).click();
+ },
+
+ function() {
+ // make sure the dialog came up
+ ok( $( "#dialog-no-hash" ).is( ":visible" ), "dialog showed up" );
+
+ // close the dialog
+ $( "#dialog-no-hash a" ).click();
+ },
+
+ function() {
+ ok( !$( "#dialog-no-hash" ).is( ":visible" ), "dialog disappeared" );
+ ok( $.mobile.activePage[0] === activePage[0], "active page has been restored" );
+ start();
+ }
+ ]);
+ });
+
+})( jQuery );
View
54 tests/unit/dialog/no-hash-tests.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery Mobile Dialog Test Suite</title>
+ <script src="../../../external/requirejs/require.js"></script>
+ <script src="../../../js/jquery.tag.inserter.js"></script>
+ <script>
+ $(document).bind('mobileinit',function(){
+ $.mobile.changePage.defaults.changeHash = false;
+ $.mobile.hashListeningEnabled = false;
+ $.mobile.pushStateEnabled = false;
+ });
+ </script>
+ <script src="../jquery.setNameSpace.js"></script>
+ <script src="../../jquery.testHelper.js"></script>
+ <script src="../../../external/qunit.js"></script>
+ <script>
+ $.testHelper.asyncLoad([
+ [
+ "jquery.mobile.dialog",
+ "jquery.mobile.page",
+ "jquery.mobile.page.sections"
+ ],
+ [ "jquery.mobile.init" ],
+ [
+ "dialog_no_hash.js"
+ ]
+ ]);
+ </script>
+
+
+ <link rel="stylesheet" href="../../../css/themes/default/jquery.mobile.css"/>
+ <link rel="stylesheet" href="../../../external/qunit.css"/>
+
+ <script src="../swarminject.js"></script>
+</head>
+<body>
+
+<h1 id="qunit-header">jQuery Mobile Dialog Test Suite</h1>
+<h2 id="qunit-banner"></h2>
+<h2 id="qunit-userAgent"></h2>
+<ol id="qunit-tests">
+</ol>
+
+<div id="mypage" data-nstest-role="page" data-nstest-theme="a">
+ <div data-nstest-role="content">
+ <a id="dialog-no-hash-link" href="dialog-no-hash.html" data-role="dialog">Dialog</a>
+ </div>
+</div>
+
+</body>
+</html>
View
4 tests/unit/jquery.setNameSpace.js
@@ -1,4 +1,4 @@
//set namespace for unit test markp
-$( document ).bind( "mobileinit", function(){
- $.mobile.ns = "nstest-";
+jQuery( document ).bind( "mobileinit", function(){
+ jQuery.mobile.ns = "nstest-";
});
View
17 tests/unit/listview/index.html
@@ -385,7 +385,6 @@ <h2 id="qunit-userAgent"></h2>
</ul>
</div>
-
<div data-nstest-role="page" id="split-list-icon">
<div data-nstest-role="content">
<ul data-nstest-role="listview" data-nstest-split-icon="delete">
@@ -397,5 +396,21 @@ <h2 id="qunit-userAgent"></h2>
</ul>
</div>
</div>
+
+<div data-nstest-role="page" id="list-divider-ignore-link">
+ <div data-nstest-role="content">
+ <ul data-nstest-role="listview">
+ <li data-nstest-role="list-divider">A</li>
+ <li><a href="index.html">Adam Kinkaid</a></li>
+ <li><a href="index.html">Alex Wickerham</a></li>
+ <li><a href="index.html">Avery Johnson</a></li>
+ <li data-nstest-role="list-divider" id="ignored-link">B has a <a href="#">link</a></li>
+ <li><a href="index.html">Bob Cabot</a></li>
+ <li data-nstest-role="list-divider">C</li>
+ <li><a href="index.html">Caleb Booth</a></li>
+ <li><a href="index.html">Christopher Adams</a></li>
+ </ul>
+ </div><!-- /content -->
+</div>
</body>
</html>
View
16 tests/unit/listview/listview_core.js
@@ -1035,4 +1035,20 @@
start
]);
});
+
+ asyncTest( "links in list dividers are ignored", function() {
+ $.testHelper.pageSequence([
+ function() {
+ $.mobile.changePage("#list-divider-ignore-link");
+ },
+
+ function() {
+ same($.mobile.activePage.find("#ignored-link .ui-btn-inner").length, 0, "no buttons in list dividers");
+
+ window.history.back();
+ },
+
+ start
+ ]);
+ });
})(jQuery);
View
5 tests/unit/page-sections/index.html
@@ -16,7 +16,10 @@
"jquery.mobile.page",
"jquery.mobile.page.sections"
],
- [ "page_core.js" ],
+ [
+ "jquery.mobile.buttonMarkup",
+ "page_core.js"
+ ],
[ "jquery.mobile.init" ]
]);
</script>
View
9 tests/unit/widget/widget_core.js
@@ -9,8 +9,7 @@
$.mobile.widget.prototype.options = { "fooBar" : true };
$.mobile.widget.prototype.element = $("<div data-"+$.mobile.ns+"foo-bar=" + expected + ">");
- same($.mobile.widget.prototype._getCreateOptions()["fooBar"],
- expected);
+ same($.mobile.widget.prototype._getCreateOptions()["fooBar"], expected);
});
test( "getting no data when the options are empty", function(){
@@ -18,8 +17,7 @@
$.mobile.widget.prototype.options = {};
$.mobile.widget.prototype.element = $("<div data-"+$.mobile.ns+"foo-bar=" + expected + ">");
- same($.mobile.widget.prototype._getCreateOptions(),
- expected);
+ same($.mobile.widget.prototype._getCreateOptions(), expected);
});
test( "getting no data when the element has none", function(){
@@ -27,8 +25,7 @@
$.mobile.widget.prototype.options = { "fooBar" : true };
$.mobile.widget.prototype.element = $("<div>");
- same($.mobile.widget.prototype._getCreateOptions(),
- expected);
+ same($.mobile.widget.prototype._getCreateOptions(), expected);
});
test( "elements embedded in sub page elements are excluded on create when they match the keep native selector", function() {