├── .gitignore ├── .gitmodules ├── .npmignore ├── .travis.yml ├── Gruntfile.coffee ├── LICENSE.txt ├── README.md ├── VERSIONS.md ├── demos ├── clock │ ├── clock.css │ ├── icon.png │ ├── img │ │ ├── face.png │ │ ├── hour.png │ │ ├── minute.png │ │ ├── second.png │ │ └── startup.png │ └── index.html ├── customanimation │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png ├── customanimation2 │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png ├── ext_autotitles │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png ├── ext_floaty │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png ├── ext_location │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png ├── ext_offline │ ├── .htaccess │ ├── cache.manifest │ ├── index.html │ ├── jqt_startup.png │ ├── jqtouch.png │ └── sample.htaccess ├── index.html ├── mail │ ├── index.html │ └── mail.png ├── main │ ├── ajax.html │ ├── ajax_long.html │ ├── ajax_post.php │ ├── index.html │ ├── jqt_startup.png │ ├── jqtouch.png │ ├── jqtouch4.png │ └── video │ │ └── fireworks.jpg ├── public_objects │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png ├── skel │ ├── index.html │ ├── jqt_startup.png │ └── jqtouch.png └── todo │ ├── icon.png │ ├── index.html │ └── startup.png ├── etc ├── fingerprint └── sample.htaccess ├── extensions ├── jqt.actionsheet.css ├── jqt.actionsheet.js ├── jqt.autotitles.coffee ├── jqt.floaty.coffee ├── jqt.location.coffee ├── jqt.menusheet.css ├── jqt.menusheet.js ├── jqt.offline.js └── jqt.themeswitcher.coffee ├── lib └── jquery │ └── jquery-1.7.js ├── package.json ├── src ├── jqt.coffee ├── jqtouch-jquery2.js └── reference │ └── jqtouch.js ├── test ├── runner │ └── overlay-report.css └── unit │ ├── basic-initialization.html │ ├── disabled │ └── jquery-jqtouch2.html │ ├── initialization-variety.html │ ├── page-animation.html │ ├── page-navigation.html │ └── touch │ ├── jquery-jqtouch.html │ └── test-touch.js └── themes ├── img ├── apple │ ├── loading.gif │ └── on_off.png ├── innsbruck │ ├── loading.gif │ └── on_off.png ├── jqt │ ├── loading.gif │ └── on_off.png └── vanilla │ ├── loading.gif │ └── on_off.png └── scss ├── apple.scss ├── config.rb ├── include ├── _animations.scss ├── _base.scss ├── _core.scss ├── _skeleton.scss └── _widgets.scss ├── innsbruck.scss ├── jqtouch.scss ├── reference ├── apple.old.css ├── default.old.css └── jqtouch.old.css └── vanilla.scss /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | **.sublime-project 3 | **.sublime-workspace 4 | .externalToolBuilders 5 | .project 6 | .settings 7 | .buildpath 8 | .DS_Store 9 | .~* 10 | node_modules/ 11 | jqtouch-*/ 12 | npm-debug.log 13 | build/ 14 | dist/ 15 | archive/ 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/zepto"] 2 | path = submodules/zepto 3 | url = git://github.com/madrobby/zepto.git 4 | [submodule "submodules/compass-recipes"] 5 | path = submodules/compass-recipes 6 | url = git://github.com/senchalabs/compass-recipes.git 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Source and Build Files 2 | demos/ 3 | etc/ 4 | extensions/ 5 | lib/jquery 6 | src/ 7 | submodules/ 8 | test/ 9 | themes/ 10 | build/ 11 | archive/ 12 | .git* 13 | .travis.xml 14 | Gruntfile.coffee 15 | sample.htaccess 16 | 17 | # Temp Files 18 | .~* 19 | .sass-cache 20 | 21 | # IDE and OS Files 22 | **.sublime-project 23 | **.sublime-workspace 24 | .externalToolBuilders 25 | .project 26 | .settings 27 | .DS_Store 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | rvm: 5 | - "1.8.7" 6 | notifications: 7 | email: 8 | on_success: never 9 | on_failure: change 10 | before_install: npm install -g grunt-cli && gem install sass && gem install compass 11 | 12 | -------------------------------------------------------------------------------- /Gruntfile.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (grunt) -> 2 | extend = require('util')._extend 3 | path = require('path') 4 | 5 | # Project configuration. 6 | grunt.initConfig 7 | pkg: grunt.file.readJSON('package.json') 8 | meta: 9 | version: "<%= pkg.version %>-<%= pkg.versionId %>" 10 | tag: "v<%= pkg.version %><%= pkg.versionId %>" 11 | build: "jqt-<%= meta.tag %>" 12 | dist: "<%= meta.build %>" 13 | demo: "jqt-demo-<%= meta.tag %>" 14 | banner: """ 15 | /* 16 | _/ _/_/ _/_/_/_/_/ _/ 17 | _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ 18 | _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ 19 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ 20 | _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ 21 | _/ 22 | _/ 23 | 24 | Created by David Kaneda 25 | Maintained by Thomas Yip 26 | Sponsored by Sencha Labs 27 | Special thanks to Jonathan Stark 28 | 29 | Documentation and issue tracking on GitHub 30 | 31 | (c) 2009-<%= grunt.template.today("yyyy") %> Sencha Labs 32 | 33 | Version: <%= meta.version %> - <%= grunt.template.today("yyyy-mm-dd") %> 34 | 35 | jQTouch may be freely distributed under the MIT license. 36 | */\n 37 | """ 38 | dirs: 39 | src: "src" 40 | etc: "etc" 41 | build: "build" 42 | dist: "dist" 43 | archive: "archive" 44 | package: "<%= dirs.archive %>/package" 45 | css: "<%= dirs.build %>/themes/css" 46 | 47 | clean: 48 | build: ["<%= dirs.build %>"] 49 | dist: ["<%= dirs.dist %>"] 50 | package: ["<%= dirs.package%>"] 51 | zepto: ["submodules/zepto/dist"] 52 | 53 | coffee: 54 | script: 55 | expand: yes 56 | cwd: 'src' 57 | src: ['**.coffee'] 58 | dest: '<%= dirs.build %>/src/' 59 | ext: '.js' 60 | 61 | extension: 62 | expand: yes 63 | cwd: 'extensions' 64 | src: ['**.coffee'] 65 | dest: '<%= dirs.build %>/extensions/' 66 | rename: (dest, filepath) -> 67 | path.join dest, filepath.replace /\.coffee$/, '.js' 68 | 69 | demo: 70 | expand: yes 71 | cwd: 'demos' 72 | src: ['**/*.coffee'] 73 | dest: '<%= dirs.build %>/demos/' 74 | rename: (dest, filepath) -> 75 | path.join dest, filepath.replace /\.coffee$/, '.js' 76 | 77 | copy: 78 | lib: 79 | expand: yes 80 | cwd: 'lib' 81 | src: ["**/*", "!.*"] 82 | dest: "<%= dirs.build %>/lib/" 83 | 84 | script: 85 | expand: yes 86 | cwd: 'src' 87 | src: ["**/*.js", "!reference/**"] 88 | dest: "<%= dirs.build %>/src/" 89 | 90 | demo: 91 | expand: true 92 | cwd: 'demos' 93 | src: ["**/*", "!.*"] 94 | dest: "<%= dirs.build %>/demos" 95 | 96 | extension: 97 | expand: true 98 | cwd: 'extensions' 99 | src: ["**/*", "!.*", "!*.coffee"] 100 | dest: "<%= dirs.build %>/extensions" 101 | 102 | theme: 103 | expand: true 104 | cwd: 'themes' 105 | src: ["img/**/*", "!.*"] 106 | dest: "<%= dirs.build %>/themes" 107 | 108 | dist: 109 | files: [ 110 | expand: yes 111 | src: ["{src,extensions,themes}/**","lib/zepto/**"] 112 | dest: '<%= dirs.dist %>' 113 | cwd: '<%= dirs.package %>' 114 | , 115 | src: "<%= dirs.package %>/fingerprint" 116 | dest: "<%= dirs.dist %>/fingerprint" 117 | cwd: '' 118 | ] 119 | 120 | package: 121 | files: [ 122 | expand: yes 123 | src: ["**/*"] 124 | dest: '<%= dirs.package %>' 125 | cwd: '<%= dirs.build %>' 126 | , 127 | expand: yes 128 | src: ["README.md","VERSIONS.md","LICENSE.txt","package.json"] 129 | dest: '<%= dirs.package %>' 130 | cwd: '' 131 | , 132 | src: "<%= dirs.etc %>/sample.htaccess" 133 | dest: "<%= dirs.package %>/.htaccess" 134 | cwd: '' 135 | , 136 | src: "<%= dirs.etc %>/fingerprint" 137 | dest: "<%= dirs.package %>/fingerprint" 138 | cwd: '' 139 | ] 140 | 141 | options: 142 | processContentExclude: ['**/*.{png,gif,jpg,ico,psd}'] 143 | processContent: (content, path) -> 144 | # Strip warnings from JavaScript 145 | if path.match /\.js$/ 146 | content.replace /\n\s*warn\(.*/g, '' 147 | 148 | # Update to minified JS/CSS paths in HTML 149 | else if path.match /\.html$/ 150 | content 151 | .replace(/([\w-\.]*)(\.min)?\.js/g, '$1.min.js') 152 | .replace(/(themes\/css\/[\w-\.]*)(\.min)?\.css/g, '$1.min.css') 153 | 154 | else if path.match /\/fingerprint$/ 155 | content 156 | .replace(/\{build_id\}/, grunt.config('meta.build')) 157 | .replace(/\{build_git_revision\}/, grunt.config('meta.revision')) 158 | .replace(/\{build_date\}/, grunt.template.today('yyyy-mm-dd hh:mmZ')) 159 | 160 | else 161 | content 162 | 163 | test: 164 | expand: yes 165 | cwd: '<%= dirs.build %>' 166 | dest: 'test/build/' 167 | src: '**/*' 168 | 169 | zepto: 170 | files: [ 171 | expand: yes 172 | cwd: 'submodules/zepto/dist/' 173 | src: ['zepto.js', 'zepto.min.js'] 174 | dest: '<%= dirs.build %>/lib/zepto' 175 | , 176 | src: 'submodules/zepto/src/touch.js' 177 | dest: '<%= dirs.build %>/src/jqtouch-jquery.js' 178 | ] 179 | 180 | "jquery-bridge": 181 | options: 182 | # Convert Zepto's touch class to work for jQuery 183 | processContent: (content) -> 184 | content 185 | .replace(/e\.touches/g, '(e.originalEvent||e).touches') 186 | .replace('(Zepto)', '(jQuery)') 187 | 188 | files: 189 | "<%= dirs.build %>/src/jqtouch-jquery.js": ["submodules/zepto/src/touch.js"] 190 | 191 | compress: 192 | archive: 193 | options: 194 | archive: "<%= dirs.archive %>/<%= meta.demo %>.tgz" 195 | files: [ 196 | src: ["package/**/*"] 197 | dest: "" 198 | cwd: '<%= dirs.archive %>' 199 | expand: true 200 | ] 201 | dist: 202 | options: 203 | archive: "<%= dirs.archive %>/<%= meta.dist %>.tgz" 204 | files: [ 205 | src: ["dist/**/*"] 206 | dest: "package" 207 | cwd: '' 208 | expand: true 209 | , 210 | src: ["README.md","LICENSE.txt","VERSIONS.md","package.json"] 211 | dest: "package/dist" 212 | cwd: '' 213 | expand: true 214 | ] 215 | 216 | "npm-command": 217 | zepto: 218 | command: "run-script" 219 | script: "dist" 220 | params: "" 221 | options: 222 | cwd: "submodules/zepto" 223 | env: extend(process.env, {'MODULES': 'zepto event ajax form ie detect fx data touch'}) 224 | 225 | compass: 226 | theme: 227 | files: [ 228 | src: 'themes/scss/**/*.scss' 229 | ] 230 | options: 231 | load: 'submodules/compass-recipes/' 232 | sassDir: 'themes/scss' 233 | cssDir: '<%= dirs.css %>' 234 | 235 | demo: 236 | files: [ 237 | src: 'demos/**/*.scss' 238 | ] 239 | options: 240 | load: 'submodules/compass-recipes/' 241 | sassDir: 'demos/' 242 | cssDir: "<%= dirs.build %>/demos/" 243 | 244 | extension: 245 | files: [ 246 | src: 'extensions/**/*.scss' 247 | ] 248 | options: 249 | load: 'submodules/compass-recipes/' 250 | sassDir: 'extensions/' 251 | cssDir: "<%= dirs.build %>/extensions/" 252 | 253 | # Concat is only used to add our banner 254 | concat: 255 | script: 256 | expand: yes 257 | cwd: '<%= dirs.build %>/src/' 258 | src: ['**/*.js', '!**/jqtouch-jquery.js'] 259 | dest: '<%= dirs.build %>/src/' 260 | options: 261 | banner: "<%= meta.banner %>" 262 | 263 | theme: 264 | expand: yes 265 | cwd: '<%= dirs.build %>/themes/' 266 | src: '**/*.css' 267 | dest: '<%= dirs.build %>/themes/' 268 | options: 269 | banner: "<%= meta.banner %>" 270 | 271 | qunit: 272 | files: ['test/unit/**/*.html', '!**/disabled/**'] 273 | options: 274 | timeout: 15000 275 | 276 | uglify: 277 | options: 278 | globals: 279 | jQTouch: yes 280 | 281 | jqtouch: 282 | expand: yes 283 | cwd: '<%= dirs.package %>/src/' 284 | src: ['**/*.js', '!**/jqtouch-jquery.js', '!**/*.min.js'] 285 | dest: '<%= dirs.package %>/src/' 286 | ext: '.min.js' 287 | options: 288 | banner: '<%= meta.banner %>' 289 | 290 | lib: 291 | expand: yes 292 | cwd: '<%= dirs.package %>' 293 | src: ['lib/**/*.js', 'src/jqtouch-jquery.js', '!**/*.min.js'] 294 | dest: '<%= dirs.package %>' 295 | rename: (dest, filepath) -> 296 | path.join dest, filepath.replace /\.js$/, '.min.js' 297 | 298 | options: 299 | preserveComments: (comment) -> 300 | # Preserve comments near the top of the file. 301 | # Loosey-goosey, I know, but I want to make sure we keep any 302 | # Zepto and jQuery lines about (c) and license 303 | if comment.start.line < 6 304 | yes 305 | else 306 | no 307 | 308 | extension: 309 | expand: yes 310 | cwd: "<%= dirs.package %>/extensions/" 311 | src: '**/*.js' 312 | dest: "<%= dirs.package %>/extensions/" 313 | rename: (dest, filepath) -> 314 | path.join dest, filepath.replace /\.js$/, '.min.js' 315 | options: 316 | banner: "<%= meta.banner %>" 317 | 318 | cssmin: 319 | theme: 320 | expand: yes 321 | cwd: "<%= dirs.package %>/themes/css" 322 | src: ['**/*.css', '!**/*.min.css'] 323 | dest: "<%= dirs.package %>/themes/css" 324 | ext: '.min.css' 325 | options: 326 | banner: "<%= meta.banner %>" 327 | 328 | extension: 329 | expand: yes 330 | cwd: "<%= dirs.package %>/extensions" 331 | src: ['**/*.css', '!**/*.min.css'] 332 | dest: "<%= dirs.package %>/extensions" 333 | rename: (dest, filepath) -> 334 | path.join dest, filepath.replace /\.css$/, '.min.css' 335 | options: 336 | banner: "<%= meta.banner %>" 337 | 338 | cover: 339 | compile: 340 | files: 341 | "<%= dirs.build %>/test/instrumented/jqtouch.js": ["src/jqtouch.js"] 342 | 343 | watch_files: 344 | live: 345 | files: ['build/**', '!.*', '!.**/*'] 346 | options: 347 | livereload: true # default port: 35729, add 348 | theme: 349 | files: ['themes/scss/**/*.scss', '!.*', '!.**/*'] 350 | tasks: ['compass'] 351 | dot: false 352 | coffee: 353 | files: ['src/**/*.coffee', '!.*', '!.**/*'] 354 | tasks: ['coffee:script'] 355 | dot: false 356 | script: 357 | files: ['src/**/*.js', '!.*', '!.**/*'] 358 | tasks: ['copy:script'] 359 | dot: false 360 | demo: 361 | files: ['demos/**/*', '!.*', '!.**/*'] 362 | tasks: ['demo'] 363 | dot: false 364 | extension: 365 | files: ['extensions/**/*', '!.*', '!.**/*'] 366 | tasks: ['extension'] 367 | dot: false 368 | 369 | jshint: 370 | src: "<%= dirs.src %>/**/*.js" 371 | options: 372 | camelcase: true 373 | curly: false 374 | eqeqeq: true 375 | immed: true 376 | latedef: true 377 | newcap: true 378 | noarg: true 379 | sub: true 380 | undef: true 381 | boss: true 382 | eqnull: true 383 | browser: true 384 | 385 | globals: 386 | $: true 387 | console: true 388 | 389 | # Task definitions 390 | require('load-grunt-tasks')(grunt); 391 | 392 | grunt.registerMultiTask "npm-command", "Run an NPM command in a specific module", -> 393 | cb = @async() # Tell grunt the task is async 394 | command = @data["command"] 395 | params = grunt.template.process(@data["params"]) 396 | script = grunt.template.process(@data["script"]) 397 | options = @data["options"] 398 | 399 | exec = require("child_process").exec 400 | child = exec("npm install", options, (error, stdout, stderr) -> 401 | grunt.log.write stdout if stdout 402 | grunt.log.error stdout if stderr 403 | if error isnt null 404 | cb(error) # Execute the callback when the async task is done 405 | else 406 | child = exec(["npm", command, script, params].join(' '), options, (error, stdout, stderr) -> 407 | grunt.log.write stdout if stdout 408 | grunt.log.error stdout if stderr 409 | cb(error) # Execute the callback when the async task is done 410 | ) 411 | ) 412 | 413 | grunt.registerTask "git-describe", "Describes current git commit", -> 414 | # prefer to use our own task for better control over cmd line args 415 | done = this.async(); 416 | args = ["describe", "--tags", "--always", "--long", "--dirty=*", "--abbrev=12"] 417 | grunt.util.spawn cmd: "git", args: args, (err, result) -> 418 | if err 419 | grunt.log.error err 420 | return done(false) 421 | grunt.config("meta.revision", result) 422 | grunt.config("meta.dist", 'jqt-' + result) 423 | grunt.config("meta.demo", 'jqt-demo-' + result) 424 | return done(result) 425 | 426 | grunt.registerTask "git-tag", "Tag the current git commit", -> 427 | done = this.async(); 428 | args = ["tag", grunt.config("meta.tag")] 429 | console.log('$ git ' + args.join(' ')) 430 | grunt.util.spawn cmd: "git", args: args, (err, result) -> 431 | if err 432 | grunt.log.error err 433 | return done(false) 434 | return done(result) 435 | 436 | grunt.renameTask 'watch', 'watch_files' 437 | 438 | # Build Zepto 439 | grunt.registerTask 'zepto', ['npm-command:zepto', 'copy:zepto', 'copy:jquery-bridge'] 440 | 441 | # Build Lib 442 | grunt.registerTask 'lib', ['zepto', 'copy:lib'] 443 | 444 | # Build Scripts 445 | grunt.registerTask 'script', ['copy:script', 'coffee:script', 'concat:script'] 446 | 447 | # jQT Theme 448 | grunt.registerTask 'theme', ['script', 'copy:theme', 'compass:theme', 'concat:theme'] 449 | 450 | # Main jQT bits 451 | grunt.registerTask 'main', ['script', 'theme'] 452 | 453 | # Build Extensions 454 | grunt.registerTask 'extension', ['copy:extension', 'coffee:extension', 'compass:extension'] 455 | 456 | # Build Demos 457 | grunt.registerTask 'demo', ['copy:demo', 'coffee:demo', 'compass:demo'] 458 | 459 | # Build 460 | grunt.registerTask 'build', ['lib', 'main', 'extension', 'demo'] 461 | 462 | # Watch 463 | grunt.registerTask 'watch', ['build', 'watch_files'] 464 | 465 | # Full (Clean and Build) 466 | grunt.registerTask 'full', ['clean', 'update_submodules', 'build'] 467 | 468 | # Default (Same as full) 469 | grunt.registerTask 'default', ['full'] 470 | 471 | # Test 472 | grunt.registerTask 'test', ['copy:test', 'qunit'] 473 | 474 | # Minify Assets 475 | grunt.registerTask 'minify', ['uglify', 'cssmin'] 476 | 477 | # Build full, and and minifies all artifacts 478 | grunt.registerTask 'pack', ['git-describe', 'copy:package', 'minify'] 479 | 480 | # Pack and compress into a versioned archive 481 | grunt.registerTask 'archive', ['pack', 'compress:archive'] 482 | 483 | # Select the core from package to make a `dist` structure 484 | grunt.registerTask 'dist', ['full', 'test', 'archive', 'copy:dist', 'compress:dist'] 485 | 486 | # Npm Prepublish 487 | grunt.registerTask 'release', ['git-tag', 'dist'] 488 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | Copyright (c) 2009-2013 Sencha Labs 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jQT 2 | 3 | ## Create powerful mobile apps with just HTML, CSS, and Zepto.js (or jQuery). 4 | 5 | [![Build Status](https://api.travis-ci.org/senchalabs/jQTouch.png?branch=master)](http://travis-ci.org/senchalabs/jQTouch) 6 | 7 | jQTouch is a JavaScript plugin which works with either Zepto.js or jQuery, and comes with smooth animations, navigation, and themes for mobile WebKit browsers (as found in iOS, Android, BlackBerry, and WebOS). 8 | 9 | - [Easy to install](https://github.com/senchalabs/jQTouch/wiki/Getting-Started). Get up and running in a few minutes. 10 | - [Entirely customizable](https://github.com/senchalabs/jQTouch/wiki/Initialization-Options) with selector options 11 | - [Theme support](https://github.com/senchalabs/jQTouch/wiki/Theming), including default Apple and jQTouch custom themes 12 | - [Callback functions](https://github.com/senchalabs/jQTouch/wiki/Callback-Events) throughout, including swipe and orientation change detection 13 | - [Zepto](https://github.com/madrobby/zepto) integration - Use Zepto.js instead of jQuery to cut down on precious bandwidth. Zepto.js features a similar API to jQuery, but optimized for WebKit and much smaller. 14 | - Sass-based stylesheets, easily modified with variables and optimized for size. 15 | - Image-less stylesheets -- Using [Compass Recipes](https://github.com/senchalabs/compass-recipes), we have recreated all of the gradients and background patterns with CSS. This way, they are resolution independent, dynamically theme-able, and lower bandwidth. 16 | - Page history management and CSS3 page transitions, including 3D flip, cube, and swap 17 | - Failover to 2D animations for devices that don't support 3D 18 | - Easily allow apps to run in fullscreen mode with custom icons and startup screens 19 | - The power of jQuery to build AJAX applications 20 | - New demos: Clock and Todo 21 | 22 | ## Getting Started 23 | 24 | The easiest way to try out jQT is with the demo archive, which can be found in the release tab on Github: 25 | 26 | - [jQT Releases](https://github.com/senchalabs/jQTouch/releases) 27 | 28 | Please look for the download (green button) with filename prefixed with `jqt-demo` (ie, `jqt-demo-<< version >>.tar.gz`.) 29 | 30 | Once unzipped and untar, you can open `package/demons/index.html` with any WebkitBrowser on a desktop. 31 | 32 | ## Links 33 | 34 | Recently added features can be found at [New and Noteworthy](https://github.com/senchalabs/jQTouch/blob/master/VERSIONS.md) page. 35 | 36 | [Source code](http://github.com/senchalabs/jQTouch/archives/master), [issue tracking](http://github.com/senchalabs/jQTouch/issues), and [documentation](http://wiki.github.com/senchalabs/jQTouch/) are available on github. 37 | 38 | [Watch this video preview](http://www.jqtouch.com/) to see it in action. 39 | 40 | ## Building your own version of jQTouch 41 | 42 | ### Dependencies 43 | 44 | We have quite a few dependencies at the moment, as we build with Compass/SASS for stylesheets, which is only available via Ruby. The actual build system, however, is built on Grunt. 45 | 46 | Please make sure you have the following installed: 47 | 48 | * [Ruby](http://www.ruby-lang.org) — Comes default on Macs, Windows users can use [RubyInstaller](http://rubyinstaller.org) 49 | * [Sass](http://sass-lang.com) & [Compass](http://compass-style.org) — Install both with `sudo gem install compass` once you have Ruby/RubyGems installed 50 | * [Node.js & NPM](http://nodejs.org) — `brew install node` 51 | * [Grunt CLI](http://gruntjs.com) — Install with `npm install -g grunt-cli` once you have Node.js as listed above. 52 | * Local node packages — Run `npm install` from this directory 53 | 54 | ### Commands 55 | 56 | #### `grunt` (default) 57 | 58 | Will create a build of jQTouch in the `build/` directory, compiling any theme files and updating with source from the Zepto submodule. This must be run to preview jQTouch. 59 | 60 | #### `grunt build` 61 | 62 | This task is used only for iterative development. It does not update submodule, nor clean the build. (The `default` grunt task must be called once before this task.) 63 | 64 | #### `grunt watch` 65 | 66 | Will create the same build as `grunt build`, but will continue to watch for file changes to theme and source files, compiling/copying them into build every time you save. If you have a livereload browser extension installed and enabled, the page will update live after every change. (The `default` grunt task must be called once before this task.) 67 | 68 | #### `grunt compass` 69 | 70 | Only build the theme files. Typically, you'll want to use `grunt watch` for developing a custom theme. (The `default` grunt task must be called once before this task.) 71 | 72 | #### `grunt test` 73 | 74 | Run our test suite. (The `default` grunt task must be called once before this task.) 75 | 76 | #### `grunt dist` 77 | 78 | This is typically used internally for creating releases — It does everything the standard build does, but then additionally minifies all JS/CSS and updates the paths in demo files. 79 | 80 | 81 | 82 | External Guides 83 | --------------- 84 | 85 | Jonathan Stark has created an excellent introduction to jQTouch as part of his book, [Building iPhone Apps with HTML, CSS, and Javascript](http://ofps.oreilly.com/titles/9780596805784/chapAnimation.html). 86 | 87 | [PeepCode did a screencast](http://peepcode.com/products/jqtouch) ($9), as well as a [cheat sheet](http://blog.peepcode.com/tutorials/2009/jqtouch-cheat-sheet), which have been helpful to many people. 88 | 89 | Credits 90 | ------- 91 | 92 | Created, and still occasionally maintained, by [David Kaneda](http://www.davidkaneda.com). 93 | 94 | Maintained by [Thomas Yip](https://github.com/thomasyip). 95 | 96 | Special thanks to [pinch/zoom](http://www.pinchzoom.com/) and [Jonathan Stark](http://jonathanstark.com/). 97 | 98 | (c) 2009-2013 Sencha Labs. 99 | 100 | jQTouch may be freely distributed under the MIT license. 101 | See LICENSE.txt for license. 102 | -------------------------------------------------------------------------------- /VERSIONS.md: -------------------------------------------------------------------------------- 1 | # New and Noteworthy — jQTouch 2 | 3 | ## 1.0rc7 4 | 5 | ### Innsbruck (iOS 7) Theme 6 | 7 | ###### Dec, 2013 8 | 9 | A new theme that resemble to iOS 7 is added. 10 | 11 | ![Innsbruck Screenshot 1][11] | ![Innsbruck Screenshot 2][12] | ![Innsbruck Screenshot 3][13] | ![Innsbruck Screenshot 4][14] 12 | 13 | ## 1.0rc6 14 | 15 | ### Coffee Script 16 | 17 | ###### Feb, 2013 -- Dec, 2013 18 | 19 | The main JavaScript file was ported / rewritten in CoffeeScript. Dave simplified the codebase and fixed a good number of bugs. 20 | 21 | 22 | ## 1.0.0 - b5 23 | 24 | ### Actionsheet 25 | 26 | ###### Oct, 2012 27 | 28 | ![ActionSheet Screenshot][9] 29 | 30 | Actionsheet is similar to iOS's [UIActionSheet][2]. It is a modal sheet that can be used to prompt user for choices. 31 | 32 | It is added to this version as an extension: `jqt.actionsheet.js`. When loaded, it attempts to load `jqt.actionsheet.css` from the same directory. (If you use ASL, such as require.js, you might need to include the css explicitly.) 33 | 34 | The actionsheet uses the same markup as a jQT page and must be a direct child of `
`. 35 | 36 | To trigger an actionsheet, use an anchor with class, `action` (ie, ``) 37 | 38 | Tapping on any anchor on the sheet causes the sheet to dismiss. After the sheet is dismissed, the original jQT action will be triggered. 39 | 40 | Here is an example sniplet: 41 | 42 | ```html 43 |
44 | < ... > 45 | 48 | < ... > 49 |
50 |
51 |
52 | Open in Safari 53 | Plan B 54 | Cancel 55 |
56 |
57 | ``` 58 | 59 | Please refers to [demos/main/index.html#ui][4] for code sample. 60 | 61 | ### Menusheet 62 | 63 | ###### Oct, 2012 64 | 65 | ![MenuSheet Screenshot][10] 66 | 67 | Menusheet is first made popular by facebook app on iOS. The menusheet hides beneath the main page and is revealed by a slide animation when activated. 68 | 69 | Its usage is very similar to actionsheet. 70 | 71 | It is added to this version of jQT as an extension: `jqt.menusheet.js`. When loaded, it attempts to load `jqt.menusheet.css` from the same directory. (If you use ASL, such as require.js, you might need to include the css explicitly.) 72 | 73 | The menusheet uses the same markup as a jQT page and must be a direct child of `
`. 74 | 75 | To trigger an actionsheet, use an anchor with class, menu (ie, ``) 76 | 77 | Tapping on any anchor on the sheet will cause the sheet to dismiss. After the sheet is dismissed, the original jQT action will be triggered. 78 | 79 | Please refers to [demos/main/index.html#ui][4] for code sample. 80 | 81 | ### Unit Tests 82 | 83 | ###### Dec 18th, 2012 84 | 85 | We have added unit tests into this release. 86 | 87 | They can be found under test/unit/. Each test is a *.html file and can be run by simply open it with a web browser. 88 | 89 | The tests can also be run from a command line. Under build/, exec `grunt test`. 90 | 91 | ### Init Options: updateHash 92 | 93 | ###### Dec 18th, 2012 94 | 95 | When options updateHash is set to true (default), page navigation will cause the url hash(#) to be updated. 96 | 97 | ```javascript 98 | var jQT = new $.jQTouch({updateHash: false}); 99 | ``` 100 | 101 | ### Init Options: starter (Experimental) 102 | 103 | ###### Dec 23rd, 2012 104 | 105 | Added init options, starter. By defaults, jQTouch is started upon `$(document).ready`. 106 | 107 | For example, this option can be overridden: 108 | 109 | - to work with dynamically loaded body. The relevant part of the dom might not be available at `$(document).ready`. 110 | 111 | - to react upon user action 112 | 113 | Here is some code example: 114 | 115 | ```javascript 116 | function starter(start) { 117 | $(document).bind('ready', function() { 118 | $('https://beedesk.fwd.wf#magic_button').bind('touchstart mousedown', function() { 119 | start(); 120 | }); 121 | }); 122 | } 123 | var jQT = new $.jQTouch({starter: starter}); 124 | ``` 125 | 126 | ### Fixed Tap During Animation Break Navigation Bug 127 | 128 | ###### Nov 2012 129 | 130 | Prior to this release, rapid taps on anchor before page transition ended might cause page navigation to break. The problem is fixed in this release. 131 | 132 | ### Fixed intermittent touchscroll not-scrollable problem 133 | 134 | ###### Dec 19th, 2012 135 | 136 | For .scroll, overflow-y: scroll is used instead. Some old workaround on minHeight is removed. Tested on iPhone 4s, iPad 3, Nexus 7 and Safari 137 | 138 | 139 | ### Grunt.js Build 140 | 141 | ###### Jan 24th, 2012 142 | 143 | We converted our build system from `Ant` into `Gruntjs`, for better dependeincies mangaement, build performance and flexibility. 144 | 145 | ### Travis CI Integration 146 | 147 | ###### Jan 24th, 2012 148 | 149 | jQTouch repository is now connected to Travis CI. 150 | 151 | ## 1.0 - b4 152 | 153 | ### Improved Theming System 154 | 155 | ![Theme Screenshot][3] 156 | 157 | See, [jQTouch blog][6] for details. 158 | 159 | ### iOS Native Scrolling 160 | 161 | See, [jQTouch blog][7] for details. 162 | 163 | ### Zepto.js Integration 164 | 165 | See, [jQTouch blog][8] for details. 166 | 167 | [1]: images/ActionSheet_Small.png 168 | [2]: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html 169 | [3]: http://25.media.tumblr.com/tumblr_lwknln4IbI1qa206po1_500.png 170 | [4]: demos/main/index.html#ui 171 | [6]: http://blog.jqtouch.com/post/14579716419/improved-theming 172 | [7]: http://blog.jqtouch.com/post/14586457670/ios5-scrolling 173 | [8]: http://blog.jqtouch.com/post/14576505296/zepto-js 174 | [9]: https://raw.github.com/senchalabs/jQTouch/gh-pages/screenshots/ActionSheet_Small.png 175 | [10]: https://raw.github.com/senchalabs/jQTouch/gh-pages/screenshots/MenuSheet_Small.png 176 | [11]: https://raw.github.com/senchalabs/jQTouch/gh-pages/screenshots/Innsbruck_Main_Small.png 177 | [12]: https://raw.github.com/senchalabs/jQTouch/gh-pages/screenshots/Innsbruck_EdgetoEdge_List_Small.png 178 | [13]: https://raw.github.com/senchalabs/jQTouch/gh-pages/screenshots/Innsbruck_Buttons_Small.png 179 | [14]: https://raw.github.com/senchalabs/jQTouch/gh-pages/screenshots/Innsbruck_Actionsheet_Small.png 180 | -------------------------------------------------------------------------------- /demos/clock/clock.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | body { 6 | font-family: "Helvetica Neue",Arial,Helvetica,Geneva,sans-serif; 7 | } 8 | .clock { 9 | background: url(img/face.png); 10 | position: relative; 11 | width: 78px; 12 | height: 78px; 13 | margin: 5px auto; 14 | overflow: hidden; 15 | } 16 | .hour,.min,.sec { 17 | width: 9px; 18 | height: 78px; 19 | position: absolute; 20 | top: 0; 21 | left: 35px; 22 | } 23 | .hour { 24 | background: url(img/hour.png); 25 | } 26 | .min { 27 | background: url(img/minute.png); 28 | } 29 | .sec { 30 | background: url(img/second.png); 31 | } 32 | #clocks > div { 33 | background: -webkit-gradient(linear,0% 0%,0% 100%,from(#dadadc),to(#b4b3b8)); 34 | border-bottom: 1px solid #9a9fa5; 35 | border-top: 1px solid #dbdbdd; 36 | text-shadow: rgba(255,255,255,.5) 0 1px 0; 37 | position: relative; 38 | } 39 | .city { 40 | display: block; 41 | position: absolute; 42 | top: 35px; 43 | font-weight: bold; 44 | color: #333; 45 | left: 10px; 46 | } 47 | .time { 48 | display: block; 49 | position: absolute; 50 | right: 10px; 51 | top: 30px; 52 | } 53 | .time span { 54 | } 55 | -------------------------------------------------------------------------------- /demos/clock/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/clock/icon.png -------------------------------------------------------------------------------- /demos/clock/img/face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/clock/img/face.png -------------------------------------------------------------------------------- /demos/clock/img/hour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/clock/img/hour.png -------------------------------------------------------------------------------- /demos/clock/img/minute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/clock/img/minute.png -------------------------------------------------------------------------------- /demos/clock/img/second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/clock/img/second.png -------------------------------------------------------------------------------- /demos/clock/img/startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/clock/img/startup.png -------------------------------------------------------------------------------- /demos/clock/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQTouch β 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | 78 | 79 | 80 |
81 |
82 | 87 |
88 |
89 |
90 |
91 |
92 |

New Time Zone

93 | Cancel 94 |
95 |
96 |
    97 |
  • 98 |
  • 131 |
132 | Add Clock 133 |
134 |
135 |
136 |
137 |

About

138 | Cancel 139 |
140 |
141 | This is a demo for jQTouch. 142 |
143 |
144 |
145 | 146 | 147 | -------------------------------------------------------------------------------- /demos/customanimation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQTouch β 6 | 7 | 8 | 9 | 10 | 31 | 63 | 64 | 65 |
66 |
67 | 70 |
71 |
72 |
73 | Pretty smooth, eh? 74 |
75 | Go back 76 |
77 |
78 | 79 | 80 | -------------------------------------------------------------------------------- /demos/customanimation/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/customanimation/jqt_startup.png -------------------------------------------------------------------------------- /demos/customanimation/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/customanimation/jqtouch.png -------------------------------------------------------------------------------- /demos/customanimation2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQTouch β 6 | 7 | 8 | 9 | 10 | 43 | 83 | 84 | 85 |
86 |
87 |
88 | Swipe to go to the next page. 89 |
90 |
91 |
92 |
93 | Swipe to go back. 94 |
95 |
96 |
97 | 98 | 99 | -------------------------------------------------------------------------------- /demos/customanimation2/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/customanimation2/jqt_startup.png -------------------------------------------------------------------------------- /demos/customanimation2/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/customanimation2/jqtouch.png -------------------------------------------------------------------------------- /demos/ext_autotitles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQT.AutoTitles 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 |
24 |
25 |
26 |

Auto Titles

27 |
28 | 33 |
34 |
35 |
36 | back 37 |

38 |
39 |
40 | The title for this page was automatically set from it’s referring link, no extra scripts required. Just include the extension and this happens. 41 |
42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /demos/ext_autotitles/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_autotitles/jqt_startup.png -------------------------------------------------------------------------------- /demos/ext_autotitles/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_autotitles/jqtouch.png -------------------------------------------------------------------------------- /demos/ext_floaty/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQT.Floaty 6 | 7 | 8 | 9 | 10 | 11 | 12 | 40 | 55 | 56 | 57 |
58 |
59 |
    60 |
  • Dummy Data
  • 61 |
  • Dummy Data
  • 62 |
  • Dummy Data
  • 63 |
  • Dummy Data
  • 64 |
  • Dummy Data
  • 65 |
  • Dummy Data
  • 66 |
  • Dummy Data
  • 67 |
  • Dummy Data
  • 68 |
  • Dummy Data
  • 69 |
  • Dummy Data
  • 70 |
  • Dummy Data
  • 71 |
  • Dummy Data
  • 72 |
  • Dummy Data
  • 73 |
74 | 78 |
79 |
80 |
81 | Pretty smooth, eh? 82 |
83 | Go back 84 |
85 |
86 | I’m the Floaty bar!
87 | Testing multiple lines
88 | Should be flexible. 89 |
90 |
91 | 92 | 93 | -------------------------------------------------------------------------------- /demos/ext_floaty/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_floaty/jqt_startup.png -------------------------------------------------------------------------------- /demos/ext_floaty/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_floaty/jqtouch.png -------------------------------------------------------------------------------- /demos/ext_location/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQT.Location 6 | 7 | 8 | 9 | 10 | 11 | 12 | 55 | 61 | 62 | 63 |
64 |
65 |
66 |

Geo Location

67 |
68 |
69 | 72 |
73 | 74 |
75 |
76 |
77 |
78 |

Map

79 | Back 80 |
81 |
82 | 83 |
84 |
85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /demos/ext_location/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_location/jqt_startup.png -------------------------------------------------------------------------------- /demos/ext_location/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_location/jqtouch.png -------------------------------------------------------------------------------- /demos/ext_offline/.htaccess: -------------------------------------------------------------------------------- 1 | AddType text/cache-manifest .manifest -------------------------------------------------------------------------------- /demos/ext_offline/cache.manifest: -------------------------------------------------------------------------------- 1 | CACHE MANIFEST 2 | # Rev 17 3 | 4 | index.html 5 | jqtouch.png 6 | ../../jqtouch/jqtouch.css 7 | ../../jqtouch/jqtouch.js 8 | ../../jqtouch/jquery-1.7.js 9 | ../../jqtouch/jquery-1.7.min.js 10 | ../../themes/jqt/theme.css 11 | ../../extensions/jqt.offline.js 12 | ../../themes/jqt/img/back_button.png 13 | ../../themes/jqt/img/back_button_clicked.png 14 | ../../themes/jqt/img/button.png 15 | ../../themes/jqt/img/button_clicked.png 16 | ../../themes/jqt/img/chevron.png 17 | ../../themes/jqt/img/chevron_circle.png 18 | ../../themes/jqt/img/grayButton.png 19 | ../../themes/jqt/img/loading.gif 20 | ../../themes/jqt/img/on_off.png 21 | ../../themes/jqt/img/rowhead.png 22 | ../../themes/jqt/img/toggle.png 23 | ../../themes/jqt/img/toggleOn.png 24 | ../../themes/jqt/img/toolbar.png 25 | ../../themes/jqt/img/whiteButton.png -------------------------------------------------------------------------------- /demos/ext_offline/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQT.Offline 6 | 7 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | 25 |
26 |
27 |
28 |

Offline

29 |
30 |
This page saves all of its resources locally on your device, and can run even when offline.
31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /demos/ext_offline/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_offline/jqt_startup.png -------------------------------------------------------------------------------- /demos/ext_offline/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/ext_offline/jqtouch.png -------------------------------------------------------------------------------- /demos/ext_offline/sample.htaccess: -------------------------------------------------------------------------------- 1 | AddType text/cache-manifest .manifest -------------------------------------------------------------------------------- /demos/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | jQT Demo 4 | 5 | 6 | 7 |

Redirecting to main demo.

8 | 9 | 10 | -------------------------------------------------------------------------------- /demos/mail/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQT Mail 5 | 6 | 18 | 19 | 20 | 40 | 41 | 42 |
43 |
44 |
45 |

Accounts

46 | 47 |
48 | 53 |
54 |
55 |
56 | Accounts 57 |

Work

58 | + 59 |
60 | 66 |
67 | 80 |
81 |
82 |
83 |

New Message

84 | Cancel Send 85 |
86 |
87 |
    88 |
  • 89 |
  • 90 |
  • 91 |
  • 92 |
93 |
94 | 95 |
96 |
97 |
98 |
99 | Back 100 |

Message

101 |
102 |
103 | 104 |
105 |
106 |
107 |
108 |

Features

109 | jQTouch 110 |
111 |
112 |

113 |
114 |
115 |
    116 |
  • One-line setup, with options for selectors, viewport settings, icon path and glossiness, and status bar style
  • 117 |
  • Pages can be built in a single HTML file, or loaded dynamically via GET or POST
  • 118 |
  • Native, hardware-accelerated, page animations, including slide in/out, slide up/down, and 3D flip. All with history support.
  • 119 |
  • Image preloading functions
  • 120 |
  • Easy to theme
  • 121 |
122 |
123 |
124 |
125 |
126 |
127 | Pretty smooth, eh? 128 |
Go back 129 |
130 |
131 |
132 |
133 |

134 | Demos 135 |

Home 136 |
137 |
138 |
139 |
140 | 141 |
142 |
143 | 144 |
145 |
146 |
147 |
148 |
149 |
150 |

Music Search

151 | Cancel Search 152 |

This form retrieves the next page with Ajax via a POST request.

153 |
154 |
155 |
156 |
157 |

The MIT License

158 |

Copyright © 2009 David Kaneda

159 |

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:

160 |

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

161 |

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.

162 | Return 163 |
164 |
165 |
166 | 167 | 168 | -------------------------------------------------------------------------------- /demos/mail/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/mail/mail.png -------------------------------------------------------------------------------- /demos/main/ajax.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

GET Example

4 | AJAX 5 |
6 |
7 | This page was loaded via AJAX. 8 |
9 | 12 |
13 |
14 |
15 |

Events test

16 | AJAX 17 | Home 18 |
19 |
20 | This transition was fired from a dynamically loaded view. 21 |
22 |
-------------------------------------------------------------------------------- /demos/main/ajax_long.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

GET Example

4 | AJAX 5 |
6 |
7 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lacinia 8 | varius odio, vel lobortis neque luctus vel. Etiam euismod turpis a augue 9 | laoreet eu rutrum lectus vehicula. Integer elementum tellus non erat 10 | dapibus et venenatis augue condimentum. Nullam pretium scelerisque purus 11 | sed auctor. Proin id augue quis massa dictum tempus in a magna. Morbi vitae 12 | bibendum orci. Curabitur quis orci tellus, id dignissim erat. Sed eros 13 | elit, dapibus eu tincidunt quis, sagittis ut nulla. Vivamus ornare ultrices 14 | fermentum. Cras ornare tempor lacus, eget scelerisque lacus pretium sit 15 | amet.

16 | 17 |

Duis vel imperdiet risus. Cras vestibulum consequat mauris, vulputate 18 | iaculis enim sagittis ac. Morbi imperdiet, sapien nec condimentum sagittis, 19 | lacus ligula luctus nulla, a commodo est mi quis elit. Maecenas eu nisl 20 | risus. Vivamus sed est nisi, gravida adipiscing sem. Curabitur quis 21 | porttitor lorem. Suspendisse non mauris leo, a euismod dolor. Donec eget 22 | condimentum dui. Maecenas rutrum sem eu nulla auctor consequat. Suspendisse 23 | id sapien ut lacus hendrerit vulputate. Donec euismod tellus sed elit 24 | consequat vestibulum faucibus nisi tincidunt. Donec libero nunc, lacinia ut 25 | euismod id, sagittis sit amet massa. Aliquam ullamcorper tellus urna. Nam a 26 | sem ac est dignissim aliquet a eu urna. Curabitur sit amet justo velit, sit 27 | amet pulvinar dolor. Vivamus sapien orci, congue at feugiat sed, dignissim 28 | nec lacus. Nunc eleifend sem id risus condimentum non gravida mi bibendum. 29 | Fusce et elementum arcu.

30 | 31 |

Etiam viverra leo non purus tempus interdum. Quisque ullamcorper 32 | hendrerit hendrerit. Mauris commodo, purus vitae ultrices varius, turpis 33 | sem volutpat augue, eget luctus risus nunc vitae metus. Nulla ut risus 34 | enim, a congue lectus. Phasellus id tellus metus, eget dapibus diam. Morbi 35 | dignissim rutrum ultricies. Suspendisse potenti. Integer vel metus et urna 36 | lobortis hendrerit vitae sed metus. Etiam nunc augue, elementum non 37 | convallis vestibulum, convallis in purus. Pellentesque habitant morbi 38 | tristique senectus et netus et malesuada fames ac turpis egestas. Ut 39 | adipiscing tellus vel erat feugiat eget ultricies nulla viverra. Vivamus 40 | dictum vulputate urna in mattis. Nullam sit amet urna vitae nisl sodales 41 | semper. Nunc at vulputate libero.

42 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce lacinia 43 | varius odio, vel lobortis neque luctus vel. Etiam euismod turpis a augue 44 | laoreet eu rutrum lectus vehicula. Integer elementum tellus non erat 45 | dapibus et venenatis augue condimentum. Nullam pretium scelerisque purus 46 | sed auctor. Proin id augue quis massa dictum tempus in a magna. Morbi vitae 47 | bibendum orci. Curabitur quis orci tellus, id dignissim erat. Sed eros 48 | elit, dapibus eu tincidunt quis, sagittis ut nulla. Vivamus ornare ultrices 49 | fermentum. Cras ornare tempor lacus, eget scelerisque lacus pretium sit 50 | amet.

51 | 52 |

Duis vel imperdiet risus. Cras vestibulum consequat mauris, vulputate 53 | iaculis enim sagittis ac. Morbi imperdiet, sapien nec condimentum sagittis, 54 | lacus ligula luctus nulla, a commodo est mi quis elit. Maecenas eu nisl 55 | risus. Vivamus sed est nisi, gravida adipiscing sem. Curabitur quis 56 | porttitor lorem. Suspendisse non mauris leo, a euismod dolor. Donec eget 57 | condimentum dui. Maecenas rutrum sem eu nulla auctor consequat. Suspendisse 58 | id sapien ut lacus hendrerit vulputate. Donec euismod tellus sed elit 59 | consequat vestibulum faucibus nisi tincidunt. Donec libero nunc, lacinia ut 60 | euismod id, sagittis sit amet massa. Aliquam ullamcorper tellus urna. Nam a 61 | sem ac est dignissim aliquet a eu urna. Curabitur sit amet justo velit, sit 62 | amet pulvinar dolor. Vivamus sapien orci, congue at feugiat sed, dignissim 63 | nec lacus. Nunc eleifend sem id risus condimentum non gravida mi bibendum. 64 | Fusce et elementum arcu.

65 | 66 |

Etiam viverra leo non purus tempus interdum. Quisque ullamcorper 67 | hendrerit hendrerit. Mauris commodo, purus vitae ultrices varius, turpis 68 | sem volutpat augue, eget luctus risus nunc vitae metus. Nulla ut risus 69 | enim, a congue lectus. Phasellus id tellus metus, eget dapibus diam. Morbi 70 | dignissim rutrum ultricies. Suspendisse potenti. Integer vel metus et urna 71 | lobortis hendrerit vitae sed metus. Etiam nunc augue, elementum non 72 | convallis vestibulum, convallis in purus. Pellentesque habitant morbi 73 | tristique senectus et netus et malesuada fames ac turpis egestas. Ut 74 | adipiscing tellus vel erat feugiat eget ultricies nulla viverra. Vivamus 75 | dictum vulputate urna in mattis. Nullam sit amet urna vitae nisl sodales 76 | semper. Nunc at vulputate libero.

77 |
78 |
-------------------------------------------------------------------------------- /demos/main/ajax_post.php: -------------------------------------------------------------------------------- 1 | 11 |
12 |
13 |

14 | Back 15 |
16 | 29 | 30 |
31 |
    32 |
  • 33 |
34 | Submit 35 |
36 |
-------------------------------------------------------------------------------- /demos/main/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/main/jqt_startup.png -------------------------------------------------------------------------------- /demos/main/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/main/jqtouch.png -------------------------------------------------------------------------------- /demos/main/jqtouch4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/main/jqtouch4.png -------------------------------------------------------------------------------- /demos/main/video/fireworks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/main/video/fireworks.jpg -------------------------------------------------------------------------------- /demos/public_objects/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQTouch β 7 | 8 | 9 | 10 | 11 | 28 | 31 | 32 | 33 |
34 |
35 |
36 |

Public Functions

37 |
38 |
39 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed aliquet euismod venenatis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse laoreet, dui et elementum elementum, nibh neque laoreet dolor, vel malesuada nunc lorem in turpis. Go to Page 2 » Quisque malesuada, lacus at viverra euismod, enim tellus gravida mauris, et placerat turpis massa in arcu. Go to Ajax page » 40 | 41 |
42 |
43 |
44 |

Success!

45 | Back 46 |
47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /demos/public_objects/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/public_objects/jqt_startup.png -------------------------------------------------------------------------------- /demos/public_objects/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/public_objects/jqtouch.png -------------------------------------------------------------------------------- /demos/skel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQTouch β 7 | 8 | 9 | 10 | 22 | 25 | 26 | 27 |
28 |
29 | 30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /demos/skel/jqt_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/skel/jqt_startup.png -------------------------------------------------------------------------------- /demos/skel/jqtouch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/skel/jqtouch.png -------------------------------------------------------------------------------- /demos/todo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/todo/icon.png -------------------------------------------------------------------------------- /demos/todo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQTodo β 6 | 7 | 74 | 75 | 76 | 77 | 109 | 110 | 111 |
112 |
113 |
114 |

Todos

115 | Add 116 |
117 |
118 |
    119 |
  • Do something Blah
  • 120 |
  • Do something else
  • 121 |
  • Finish these damn demos
  • 122 |
123 |

Completed

124 |
    125 |
  • Do something
  • 126 |
  • Write eblast
  • 127 |
128 |
129 |
130 |
131 |
132 |
133 |

New Todo

134 | Cancel 135 |
136 |
    137 |
  • 138 | 139 |
140 | Add 141 |
142 |
143 |
144 | 145 | 146 | -------------------------------------------------------------------------------- /demos/todo/startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/demos/todo/startup.png -------------------------------------------------------------------------------- /etc/fingerprint: -------------------------------------------------------------------------------- 1 | Package ID: {build_id} 2 | Build Date/Time: {build_date} 3 | Git Revision: {build_git_revision} 4 | -------------------------------------------------------------------------------- /etc/sample.htaccess: -------------------------------------------------------------------------------- 1 | # A .htaccess file is a hidden file which runs on Unix servers 2 | # and provides directives. Renaming this file to .htaccess and 3 | # placing in your root directory _should_ enable GZip compression, 4 | # reducing the weight of pages/scripts being served. 5 | 6 | # Please note that all of these rules are optimizations 7 | # and not necessary for jQTouch to work. If this causes 8 | # any issues with your server, just remove. 9 | 10 | 11 | mod_gzip_on Yes 12 | mod_gzip_dechunk Yes 13 | mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$ 14 | mod_gzip_item_include handler ^cgi-script$ 15 | mod_gzip_item_include mime ^text/.* 16 | mod_gzip_item_include mime ^application/x-javascript.* 17 | mod_gzip_item_exclude mime ^image/.* 18 | mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* 19 | 20 | 21 | 22 | AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript 23 | 24 | 25 | 26 | ExpiresActive On 27 | ExpiresDefault "access plus 1 seconds" 28 | ExpiresByType text/html "access plus 1 seconds" 29 | ExpiresByType image/gif "access plus 2592000 seconds" 30 | ExpiresByType image/jpeg "access plus 2592000 seconds" 31 | ExpiresByType image/png "access plus 2592000 seconds" 32 | ExpiresByType text/css "access plus 604800 seconds" 33 | ExpiresByType text/javascript "access plus 216000 seconds" 34 | ExpiresByType application/x-javascript "access plus 216000 seconds" 35 | 36 | 37 | 38 | Header unset ETag 39 | 40 | 41 | FileETag None 42 | 43 | 44 | Header unset Last-Modified 45 | 46 | 47 | AddType text/cache-manifest .manifest -------------------------------------------------------------------------------- /extensions/jqt.actionsheet.css: -------------------------------------------------------------------------------- 1 | /* @group Modal */ 2 | 3 | #jqt > .current::after { 4 | /* semi-transparent overlay */ 5 | display: none; 6 | z-index: 0; 7 | position: absolute; 8 | content: ""; 9 | top: 0; bottom: 0; left: 0; right: 0; 10 | background-color: rgba(63, 63, 63, 0.6); 11 | opacity: 0; 12 | -webkit-transition: opacity 375ms ease-out; 13 | } 14 | 15 | #jqt.modal > .current::after, 16 | #jqt.transition > .current::after { 17 | display: block; 18 | z-index: 10; 19 | } 20 | 21 | #jqt.modal > .current::after { 22 | opacity: 1; 23 | } 24 | 25 | /* @end group Modal */ 26 | 27 | 28 | /* @group Action Sheet */ 29 | 30 | #jqt > .actionsheet { 31 | z-index: 30; 32 | -webkit-transform: translateY(90%); 33 | -webkit-transition: -webkit-transform 375ms linear; 34 | } 35 | 36 | #jqt > .actionsheet.shown, 37 | #jqt > .actionsheet.transition { 38 | display: block; 39 | } 40 | 41 | #jqt > .actionsheet.shown:not(.current):not(.in):not(.out), 42 | #jqt > .actionsheet.transition:not(.current):not(.in):not(.out) { 43 | /* workaround long css in jqt/_base.scss */ 44 | display: block; 45 | } 46 | 47 | #jqt > .actionsheet.shown { 48 | -webkit-transform: translateY(0); 49 | } 50 | 51 | #jqt > .actionsheet { 52 | height: 100%; min-height: 100%; 53 | background-color: transparent; 54 | background-image: none; 55 | } 56 | 57 | #jqt > .actionsheet > div.actionchoices { 58 | position: absolute; 59 | top: auto; bottom: 0; 60 | left: 0; right: 0; 61 | padding-bottom: 10px; 62 | } 63 | 64 | /* theme specifics style */ 65 | #jqt:not([data-jqt-theme]) > .actionsheet > div.actionchoices, 66 | #jqt[data-jqt-theme="jqtouch"] > .actionsheet > div.actionchoices, 67 | #jqt[data-jqt-theme="vanilla"] > .actionsheet > div.actionchoices, 68 | #jqt[data-jqt-theme="apple"] > .actionsheet > div.actionchoices { 69 | border-top: 1px solid #333; 70 | background-color: rgba(0, 0, 0, 0.25); 71 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(160, 168, 172, 0.75)), color-stop(0.08, rgba(112, 120, 128, 0.5)), color-stop(0.08, rgba(96, 102, 114, 0.5)), to(rgba(96, 102, 114, 0.5))); 72 | } 73 | 74 | #jqt > .actionsheet > div.actionchoices > fieldset { 75 | border: 0; 76 | } 77 | 78 | #jqt:not([data-jqt-theme]) > div.actionsheet > div.actionchoices > *, 79 | #jqt[data-jqt-theme="jqtouch"] > div.actionsheet > div.actionchoices > *, 80 | #jqt[data-jqt-theme="vanilla"] > div.actionsheet > div.actionchoices > *, 81 | #jqt[data-jqt-theme="apple"] > div.actionsheet > div.actionchoices > * { 82 | margin-top: 25px; 83 | } 84 | 85 | #jqt:not([data-jqt-theme]) > div.actionsheet > div.actionchoices > .dismiss, 86 | #jqt[data-jqt-theme="jqtouch"] > div.actionsheet > div.actionchoices > .dismiss, 87 | #jqt[data-jqt-theme="vanilla"] > div.actionsheet > div.actionchoices > .dismiss, 88 | #jqt[data-jqt-theme="apple"] > div.actionsheet > div.actionchoices > .dismiss { 89 | margin-top: 30px; 90 | } 91 | 92 | #jqt:not([data-jqt-theme]) > div.actionsheet > div.actionchoices::before, 93 | #jqt[data-jqt-theme="jqtouch"] > div.actionsheet > div.actionchoices::before, 94 | #jqt[data-jqt-theme="vanilla"] > div.actionsheet > div.actionchoices::before, 95 | #jqt[data-jqt-theme="apple"] > div.actionsheet > div.actionchoices::before { 96 | display: block; 97 | position: relative; 98 | height: 10px; 99 | content: ""; 100 | border-top: 1px solid #CCC; 101 | width: 100%; 102 | } 103 | 104 | #jqt:not([data-jqt-theme]) > div.actionsheet > div.actionchoices > fieldset > div, 105 | #jqt[data-jqt-theme="jqtouch"] > div.actionsheet > div.actionchoices > fieldset > div, 106 | #jqt[data-jqt-theme="vanilla"] > div.actionsheet > div.actionchoices > fieldset > div, 107 | #jqt[data-jqt-theme="apple"] > div.actionsheet > div.actionchoices > fieldset > div { 108 | color: white; 109 | margin: -10px 20px 20px 20px; 110 | text-align: center; 111 | } 112 | 113 | /* temp solution until we have a theme-base extension mechanism in place */ 114 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices { 115 | padding-bottom: 8px; 116 | } 117 | 118 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > div, 119 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > div { 120 | display: block; 121 | font-weight: normal; 122 | margin: 10px 20px; 123 | text-align: center; 124 | text-decoration: inherit; 125 | background-image: none; 126 | background-color: rgba(255, 255, 255, 0.95); 127 | color: #777; 128 | text-shadow: none; 129 | font-size: 1em; 130 | line-height: 1.7em; 131 | padding: 15px 15px; 132 | } 133 | 134 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > a, 135 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > a { 136 | font-size: 20px; 137 | color: #007aff; 138 | line-height: 44px; 139 | } 140 | 141 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > a, 142 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > a, 143 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > div, 144 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > div { 145 | margin: 0 8px 0 8px; 146 | border-radius: 4px; 147 | } 148 | 149 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > a, 150 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > div { 151 | border-radius: 0; 152 | } 153 | 154 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > * { 155 | border: 0 solid transparent; 156 | border-bottom: 1px solid #e6e6e6; 157 | } 158 | 159 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > :first-child { 160 | border-top-left-radius: 4px; 161 | border-top-right-radius: 4px; 162 | } 163 | 164 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset > :last-child { 165 | border-bottom-left-radius: 4px; 166 | border-bottom-right-radius: 4px; 167 | border-bottom: 0 solid transparent; 168 | } 169 | 170 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > fieldset .caution { 171 | color: #fd472a; 172 | } 173 | 174 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > .dismiss { 175 | margin-top: 8px; 176 | margin-bottom: 0; 177 | border: none; 178 | background-color: #f4f4f4; 179 | color: #007aff; 180 | font-weight: bold; 181 | } 182 | 183 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > .dismiss:active, 184 | #jqt[data-jqt-theme="innsbruck"] > div.actionsheet > div.actionchoices > .dismiss.active { 185 | background-color: #dcdcdd; 186 | } 187 | 188 | /* @end group Action Sheet */ 189 | -------------------------------------------------------------------------------- /extensions/jqt.actionsheet.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | _/ _/_/ _/_/_/_/_/ _/ 4 | _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ 5 | _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ 6 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ 7 | _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ 8 | _/ 9 | _/ 10 | 11 | Created by David Kaneda 12 | Maintained by Thomas Yip 13 | Sponsored by Sencha Labs 14 | Special thanks to Jonathan Stark 15 | 16 | Documentation and issue tracking on GitHub 17 | 18 | (c) 2009-2012 Sencha Labs 19 | jQTouch may be freely distributed under the MIT license. 20 | */ 21 | 22 | (function($) { 23 | // load css 24 | var src = $("head script").last().attr("src") || ''; 25 | var scriptpath = src.split('?')[0].split('/').slice(0, -1).join('/')+'/'; 26 | var csspath = scriptpath + 'jqt.actionsheet.css'; 27 | var link = $(''); 28 | $('head').append($(link)); 29 | 30 | function hide(callback) { 31 | var $target = $(this), 32 | $jqt = $('#jqt'); 33 | 34 | $target 35 | .addClass('transition') 36 | .removeClass('shown') 37 | .one('webkitTransitionEnd', function(event) { 38 | if (event.target === this) { 39 | $target.removeClass('transition'); 40 | !callback || callback.apply(this, arguments); 41 | } 42 | }); 43 | 44 | $jqt 45 | .addClass('transition') 46 | .removeClass('modal') 47 | .find('.current') 48 | .one('webkitTransitionEnd watchdog', function(event) { 49 | if (event.target === this) { 50 | $jqt.removeClass('transition'); 51 | } 52 | }) 53 | .each(function() { 54 | // to take care of the case where .current 55 | // become display: none and animation ceased 56 | var $current = $(this); 57 | setTimeout(function() { 58 | $current.trigger('watchdog'); 59 | }, 500); 60 | }); 61 | 62 | return $target; 63 | } 64 | 65 | function show(callback) { 66 | var $target = $(this), 67 | $jqt = $('#jqt'); 68 | 69 | $target 70 | .addClass('transition') 71 | .one('webkitTransitionEnd', function(event) { 72 | if (event.target === this) { 73 | $target.removeClass('transition'); 74 | !callback || callback.apply(this, arguments); 75 | } 76 | }); 77 | 78 | $jqt 79 | .addClass('transition') 80 | .find('.current') 81 | .one('webkitTransitionEnd', function(event) { 82 | if (event.target === this) { 83 | $jqt.removeClass('transition'); 84 | } 85 | }); 86 | 87 | setTimeout(function() { 88 | $target.addClass('shown'); 89 | $jqt.addClass('modal'); 90 | }, 25); 91 | return $target; 92 | } 93 | 94 | var methods = { 95 | init: function(options) { 96 | $(this).addClass('actionsheet'); 97 | }, 98 | show: show, 99 | hide: hide 100 | }; 101 | 102 | $.fn.actionsheet = function(method) { 103 | if (methods[method]) { 104 | if ($(this).is('.actionsheet')) { 105 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 106 | } else { 107 | var msg = 'Target is not a `actionsheet`. Action `' + method + '` is ignored.'; 108 | console.warn(msg); 109 | } 110 | } else if ( typeof method === 'object' || ! method ) { 111 | return methods.init.apply(this, arguments); 112 | } else { 113 | $.error('Method "' + method + '" does not exist on jqt.actionsheet' ); 114 | } 115 | }; 116 | 117 | if ($.jQT) { 118 | $.jQT.addTapHandler({ 119 | name: 'open-actionsheet', 120 | isSupported: function(e, params) { 121 | return params.$el.is('.action'); 122 | }, 123 | fn: function(e, params) { 124 | params.$el.closest('.active').removeClass('active'); 125 | 126 | var $target = $(params.hash); 127 | $target.actionsheet('show'); 128 | 129 | return false; 130 | } 131 | }); 132 | $.jQT.addTapHandler({ 133 | name: 'follow-actionlink', 134 | isSupported: function(e, params) { 135 | if ($('#jqt > .actionsheet.shown').length > 0) { 136 | return params.$el.is('.actionsheet a'); 137 | } 138 | return false; 139 | }, 140 | fn: function(e, params) { 141 | params.$el.closest('.active').removeClass('active'); 142 | 143 | var $target = params.$el.closest('.actionsheet'); 144 | $target.actionsheet('hide', function() { 145 | if (!params.$el.is('.dismiss')) { 146 | params.$el.trigger('tap'); 147 | setTimeout(function() { 148 | params.$el.removeClass('active'); 149 | }, 100); 150 | } 151 | }); 152 | return false; 153 | } 154 | }); 155 | } else { 156 | console.error('Extension `jqt.actionsheet` failed to load. jQT not found'); 157 | } 158 | })($); 159 | -------------------------------------------------------------------------------- /extensions/jqt.autotitles.coffee: -------------------------------------------------------------------------------- 1 | if $.jQT 2 | $.jQT.addExtension (jQT) -> 3 | titleSelector = '.toolbar h1' 4 | 5 | # Bind events on document.ready 6 | $ -> 7 | $('#jqt').bind 'pageAnimationStart', (e, data) -> 8 | $el = $(e.target) 9 | 10 | if data.direction is 'in' 11 | $title = $(titleSelector, $el) 12 | $ref = $el.data('referrer') 13 | 14 | 15 | $title.html($ref.text()) if $title.length and $ref 16 | 17 | # Public function added to jQT instance 18 | setTitleSelector = (sel) -> titleSelector = sel 19 | 20 | return setTitleSelector: setTitleSelector -------------------------------------------------------------------------------- /extensions/jqt.floaty.coffee: -------------------------------------------------------------------------------- 1 | if $.jQT 2 | $.jQT.addExtension (jQT) -> 3 | 4 | $.fn.makeFloaty = (options) -> 5 | settings = $.extend {}, 6 | align: 'top' 7 | spacing: 20 8 | time: '.3s' 9 | , options 10 | 11 | # Only allow top/bottom for now 12 | settings.align = 'bottom' if settings.align isnt 'top' 13 | 14 | this.each -> 15 | $el = $(this) 16 | $el 17 | .css 18 | '-webkit-transition': 'top ' + settings.time + ' ease-in-out' 19 | 'display': 'block' 20 | 'min-height': '0 !important' 21 | .data 'settings', settings 22 | 23 | $(document).scroll -> 24 | $el.scrollFloaty() if $el.data('floatyVisible') 25 | 26 | $el.scrollFloaty() 27 | 28 | $.fn.scrollFloaty = -> 29 | this.each -> 30 | $el = $(this) 31 | settings = $el.data('settings') 32 | wHeight = $('html').attr('clientHeight') 33 | newY = window.pageYOffset + if settings.align is 'top' then settings.spacing else wHeight - settings.spacing - $el.get(0).offsetHeight 34 | 35 | $el.css('top', newY).data 'floatyVisible', yes 36 | 37 | $.fn.hideFloaty = -> 38 | this.each -> 39 | $el = $(this) 40 | oh = $el.get(0).offsetHeight 41 | $el.css('top', -oh-10).data 'floatyVisible', no 42 | 43 | $.fn.toggleFloaty = -> 44 | this.each -> 45 | $el = $(this) 46 | if $el.data('floatyVisible') 47 | $el.hideFloaty() 48 | else 49 | $el.scrollFloaty() -------------------------------------------------------------------------------- /extensions/jqt.location.coffee: -------------------------------------------------------------------------------- 1 | if $.jQT 2 | $.jQT.addExtension (jQT) -> 3 | latitude = null 4 | longitude = null 5 | 6 | updateLocation = (successCallback, failCallback) -> 7 | 8 | unless navigator.geolocation 9 | console.warn 'Device not capable of geolocation.' 10 | failCallback() if failCallback 11 | return no 12 | 13 | navigator.geolocation.getCurrentPosition (position) -> # Success callback 14 | latitude = position.coords.latitude 15 | longitude = position.coords.longitude 16 | 17 | successCallback(getLocation()) if successCallback 18 | 19 | , (error) -> 20 | failCallback error 21 | 22 | getLocation = -> 23 | if latitude and longitude 24 | latitude: latitude 25 | longitude: longitude 26 | else 27 | console.warn 'No location available. Try calling jQT.updateLocation() first.' 28 | false 29 | 30 | # Extend jQT object 31 | updateLocation: updateLocation 32 | getLocation: getLocation -------------------------------------------------------------------------------- /extensions/jqt.menusheet.css: -------------------------------------------------------------------------------- 1 | /* @group Menu Sheet */ 2 | 3 | #jqt > div.menusheet { 4 | -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; 5 | height: 100%; 6 | width: 260px; 7 | } 8 | #jqt.black-translucent > div.menusheet { 9 | padding-top: 20px; 10 | } 11 | #jqt.menuopened { 12 | width: 100%; 13 | overflow: hidden; 14 | } 15 | 16 | #jqt > .transition { 17 | -webkit-transition-property: translate3d, opacity, background-color; 18 | -webkit-transition-duration: 250ms; 19 | -webkit-transition-fill-mode: both; 20 | -webkit-transition-timing-function: ease-in-out; 21 | } 22 | 23 | #jqt.menuopened > .current { 24 | -webkit-transform: translate3d(260px, 0, 0) rotate(0) scale(1); 25 | -webkit-box-shadow: -3px 0px 3px rgba(63, 63, 63, 0.5); 26 | border-left: 0.5px solid rgba(127, 127, 127, 0.01); 27 | z-index: 20; 28 | } 29 | 30 | #jqt.menuopened > .current::after { 31 | display: block; 32 | position: absolute; 33 | opacity: 1; 34 | background-color: rgba(0, 0, 0, 0); 35 | top: 0; bottom: 0; left: 0; right: 0; 36 | z-index: 20; 37 | content: ""; 38 | } 39 | 40 | #jqt.menuopened > .menusheet.current { 41 | -webkit-transform: translate3d(0, 0, 0) rotate(0) scale(1); 42 | -webkit-box-shadow: none; 43 | border-left: none; 44 | z-index: 0; 45 | } 46 | 47 | #jqt.menuopened > .menusheet.current::after { 48 | display: none; 49 | } 50 | 51 | #jqt > div.menusheet > *:first-child { 52 | margin-top: 0px; 53 | } 54 | 55 | #jqt > div.menusheet > div.menuchoices { 56 | position: absolute; 57 | top: auto; 58 | bottom: 0px; 59 | left: 0px; 60 | right: 0px; 61 | padding-bottom: 10px; 62 | border-top: 1px solid #333; 63 | background-color: rgba(0, 0, 0, 0.25); 64 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(160, 168, 172, 0.75)), color-stop(0.08, rgba(112, 120, 128, 0.5)), color-stop(0.08, rgba(96, 102, 114, 0.5)), to(rgba(96, 102, 114, 0.5))); 65 | } 66 | 67 | /* @end */ 68 | -------------------------------------------------------------------------------- /extensions/jqt.menusheet.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | _/ _/_/ _/_/_/_/_/ _/ 4 | _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ 5 | _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ 6 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ 7 | _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ 8 | _/ 9 | _/ 10 | 11 | Created by David Kaneda 12 | Maintained by Thomas Yip 13 | Sponsored by Sencha Labs 14 | Special thanks to Jonathan Stark 15 | 16 | Documentation and issue tracking on GitHub 17 | 18 | (c) 2009-2012 Sencha Labs 19 | jQTouch may be freely distributed under the MIT license. 20 | */ 21 | 22 | (function($) { 23 | var src = $("head script").last().attr("src") || ''; 24 | var scriptpath = src.split('?')[0].split('/').slice(0, -1).join('/')+'/'; 25 | var csspath = scriptpath + 'jqt.menusheet.css'; 26 | var link = $(''); 27 | $('head').append($(link)); 28 | 29 | function hide(callback) { 30 | var $target = $(this); 31 | var data = $(this).data('menusheet'); 32 | if (data.shown) { 33 | $(this).data('menusheet', {}); 34 | var $source = data.source; 35 | $target.trigger('pageAnimationStart', { 36 | direction: 'out', animation: undefined, back: true 37 | }); 38 | $source.unbind('touchstart mousedown', data.closehandler); 39 | $source.one('webkitTransitionEnd', function() { 40 | $source.removeClass('inmotion transition in'); 41 | $target.removeClass('inmotion out'); 42 | $target.trigger('pageAnimationEnd', { 43 | direction: 'out', animation: undefined, back: true 44 | }); 45 | !callback || callback.apply(this, arguments); 46 | }); 47 | 48 | $source.addClass('inmotion transition in'); 49 | $target.addClass('inmotion out').removeClass('current'); 50 | $('#jqt').removeClass('menuopened'); 51 | } 52 | return $target; 53 | } 54 | 55 | function show(callback) { 56 | var $target = $(this); 57 | var data = $(this).data('menusheet') || {}; 58 | if (!data.shown) { 59 | var $source = $('#jqt .current:not(.menusheet)'); 60 | $target.trigger('pageAnimationStart', { 61 | direction: 'in', animation: undefined, back: false 62 | }); 63 | var closehandler = function() { 64 | $target.menusheet('hide'); 65 | return false; 66 | }; 67 | 68 | $source.one('webkitTransitionEnd', function() { 69 | $source.one('touchstart mousedown', closehandler); 70 | $source.removeClass('inmotion transition out'); 71 | $target.removeClass('inmotion in'); 72 | $target.trigger('pageAnimationEnd', { 73 | direction: 'in', animation: undefined, back: false 74 | }); 75 | !callback || callback.apply(this, arguments); 76 | }); 77 | 78 | data.shown = true; 79 | data.closehandler = closehandler; 80 | data.source = $source; 81 | $(this).data('menusheet', data); 82 | 83 | $source.addClass('inmotion transition out'); 84 | $target.addClass('current in'); 85 | $('#jqt').addClass('menuopened'); 86 | } 87 | return $target; 88 | } 89 | 90 | var methods = { 91 | init: function(options) { 92 | $(this).addClass('menusheet'); 93 | $(this).data('menusheet', {shown: false}); 94 | }, 95 | show: show, 96 | hide: hide 97 | }; 98 | 99 | $.fn.menusheet = function(method) { 100 | if (methods[method]) { 101 | if ($(this).is('.menusheet')) { 102 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 103 | } else { 104 | var msg = 'Target is not a `menusheet`. Action `' + method + '` is ignored.'; 105 | console.warn(msg); 106 | } 107 | } else if ( typeof method === 'object' || ! method ) { 108 | return methods.init.apply(this, arguments); 109 | } else { 110 | $.error('Method "' + method + '" does not exist on jqt.menusheet' ); 111 | } 112 | }; 113 | 114 | if ($.jQT) { 115 | $.jQT.addTapHandler({ 116 | name: 'open-menusheet', 117 | isSupported: function(e, params) { 118 | return params.$el.is('.menu'); 119 | }, 120 | fn: function(e, params) { 121 | params.$el.removeClass('active'); 122 | 123 | var $target = $(params.hash); 124 | $target.menusheet('show'); 125 | 126 | return false; 127 | } 128 | }); 129 | $.jQT.addTapHandler({ 130 | name: 'follow-menulink', 131 | isSupported: function(e, params) { 132 | if ($('#jqt').hasClass('menuopened')) { 133 | return params.$el.is('.menusheet a'); 134 | } 135 | return false; 136 | }, 137 | fn: function(e, params) { 138 | params.$el.removeClass('active'); 139 | 140 | var $target = params.$el.closest('.menusheet'); 141 | $target.menusheet('hide', function() { 142 | if (!params.$el.is('.dismiss')) { 143 | params.$el.trigger('tap'); 144 | } 145 | }); 146 | return false; 147 | } 148 | }); 149 | } else { 150 | console.error('Extension `jqt.menusheet` failed to load. jQT not found'); 151 | } 152 | })($); 153 | -------------------------------------------------------------------------------- /extensions/jqt.offline.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | if ($.jQT) 3 | { 4 | $.jQT.addExtension(function Offline(){ 5 | 6 | // Convenience array of status values 7 | var cacheStatusValues = []; 8 | cacheStatusValues[0] = 'uncached'; 9 | cacheStatusValues[1] = 'idle'; 10 | cacheStatusValues[2] = 'checking'; 11 | cacheStatusValues[3] = 'downloading'; 12 | cacheStatusValues[4] = 'updateready'; 13 | cacheStatusValues[5] = 'obsolete'; 14 | 15 | // Listeners for all possible events 16 | var cache = window.applicationCache; 17 | cache.addEventListener('cached', logEvent, false); 18 | cache.addEventListener('checking', logEvent, false); 19 | cache.addEventListener('downloading', logEvent, false); 20 | cache.addEventListener('error', logEvent, false); 21 | cache.addEventListener('noupdate', logEvent, false); 22 | cache.addEventListener('obsolete', logEvent, false); 23 | cache.addEventListener('progress', logEvent, false); 24 | cache.addEventListener('updateready', logEvent, false); 25 | 26 | // Log every event to the console 27 | function logEvent(e) { 28 | var online, status, type, message; 29 | online = (isOnline()) ? 'yes' : 'no'; 30 | status = cacheStatusValues[cache.status]; 31 | type = e.type; 32 | message = 'online: ' + online; 33 | message+= ', event: ' + type; 34 | message+= ', status: ' + status; 35 | if (type == 'error' && navigator.onLine) { 36 | message+= ' There was an unknown error, check your Cache Manifest.'; 37 | } 38 | console.log(message); 39 | } 40 | 41 | function isOnline() { 42 | return navigator.onLine; 43 | } 44 | 45 | if (!$('html').attr('manifest')) { 46 | console.log('No Cache Manifest listed on the tag.'); 47 | } 48 | 49 | // Swap in newly download files when update is ready 50 | cache.addEventListener('updateready', function(e){ 51 | // Don't perform "swap" if this is the first cache 52 | if (cacheStatusValues[cache.status] != 'idle') { 53 | cache.swapCache(); 54 | console.log('Swapped/updated the Cache Manifest.'); 55 | } 56 | }, false); 57 | 58 | // These two functions check for updates to the manifest file 59 | function checkForUpdates(){ 60 | cache.update(); 61 | } 62 | function autoCheckForUpdates(){ 63 | setInterval(function(){cache.update();}, 10000); 64 | } 65 | 66 | return { 67 | isOnline: isOnline, 68 | checkForUpdates: checkForUpdates, 69 | autoCheckForUpdates: autoCheckForUpdates 70 | }; 71 | }); 72 | } 73 | })($); -------------------------------------------------------------------------------- /extensions/jqt.themeswitcher.coffee: -------------------------------------------------------------------------------- 1 | if $.jQT 2 | $.jQT.addExtension (jQT) -> 3 | 4 | $('[data-switch-stylesheet]').live 'tap', -> 5 | switchStyleSheet $(this).attr('data-stylesheet-title'), $(this).attr('data-switch-stylesheet') 6 | 7 | # Manage buttons/links set for changing stylesheet 8 | $('[data-switch-stylesheet]').removeClass('selected') 9 | $(this).addClass('selected') 10 | 11 | false 12 | 13 | switchStyleSheet = (newStyleTitle, newStyle) -> 14 | 15 | $link = $("""link[title="#{newStyleTitle}"]""") 16 | 17 | newHref = if $link.length # Using a link title to change stylesheet 18 | $link.attr('href') 19 | else # Using a direct path 20 | newStyle 21 | 22 | $('link[data-jqt-theme]').attr('href', newHref) 23 | 24 | $('#jqt').attr('data-jqt-theme', newStyleTitle) 25 | 26 | # Extend jQT object 27 | switchStyleSheet: switchStyleSheet -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "David Kaneda", 3 | "name": "jqt", 4 | "description": "Create powerful mobile apps with just HTML, CSS, and Zepto.js (or jQuery).", 5 | "version": "1.0.1", 6 | "versionId": "", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/senchalabs/jQTouch.git" 10 | }, 11 | "contributors": [ 12 | { 13 | "name": "David Kaneda", 14 | "email": "dk@morfunk.com" 15 | }, 16 | { 17 | "name": "Jonathan Stark" 18 | }, 19 | { 20 | "name": "Thomas Yip", 21 | "email": "thomasleaf@gmail.com" 22 | } 23 | ], 24 | "licenses": [ 25 | { 26 | "type": "MIT" 27 | } 28 | ], 29 | "engines": { 30 | "node": "~0.10" 31 | }, 32 | "dependencies": {}, 33 | "devDependencies": { 34 | "grunt": "~0.4.2", 35 | "grunt-contrib-clean": "~0.5.0", 36 | "grunt-contrib-coffee": "~0.10.1", 37 | "grunt-contrib-compass": "~0.7.2", 38 | "grunt-contrib-compress": "~0.6.1", 39 | "grunt-contrib-concat": "~0.3.0", 40 | "grunt-contrib-copy": "~0.5.0", 41 | "grunt-contrib-cssmin": "~0.7.0", 42 | "grunt-contrib-jshint": "~0.8.0", 43 | "grunt-contrib-qunit": "~0.4.0", 44 | "grunt-contrib-uglify": "~0.3.2", 45 | "grunt-contrib-watch": "~0.5.3", 46 | "grunt-coverjs": "~0.1.0", 47 | "grunt-update-submodules": "~0.2.0", 48 | "load-grunt-tasks": "^0.5.0" 49 | }, 50 | "optionalDependencies": {}, 51 | "scripts": { 52 | "test": "grunt test --verbose", 53 | "prepublish": "grunt dist --verbose" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/jqtouch-jquery2.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | var touch = {}, touchTimeout; 3 | var jQT; 4 | var touchSelector = 'a, .touch'; 5 | 6 | function parentIfText(node){ 7 | return 'tagName' in node ? node : node.parentNode; 8 | } 9 | 10 | function swipeDirection(x1, x2, y1, y2){ 11 | var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2); 12 | if (xDelta >= yDelta) { 13 | return (x1 - x2 > 0 ? 'Left' : 'Right'); 14 | } else { 15 | return (y1 - y2 > 0 ? 'Up' : 'Down'); 16 | } 17 | } 18 | 19 | var longTapDelay = 750; 20 | function longTap(){ 21 | if (touch.last && (Date.now() - touch.last >= longTapDelay)) { 22 | touch.el.trigger('longTap'); 23 | touch = {}; 24 | } 25 | } 26 | 27 | if ($.jQT) { 28 | $.jQT.addExtension(function GetInstance(jqt) { 29 | jQT = jqt; 30 | touchSelector = jQT.settings.touchSelector; 31 | }); 32 | } else { 33 | console.warn('Error: jQT not found.'); 34 | } 35 | 36 | $(document).ready(function(){ 37 | var SUPPORT_TOUCH = 'ontouchstart' in window; 38 | console.log('==== SUPPORT_TOUCH? ' + SUPPORT_TOUCH); 39 | var START_EVENT = SUPPORT_TOUCH? 'touchstart' : 'mousedown'; 40 | var MOVE_EVENT = SUPPORT_TOUCH? 'touchmove' : 'mousemove'; 41 | var END_EVENT = SUPPORT_TOUCH? 'touchend' : 'mouseup'; 42 | var CANCEL_EVENT = SUPPORT_TOUCH? 'touchcancel' : 'mouseout'; // mouseout on document 43 | 44 | function isRightClick(e) { 45 | var rightclick = false; 46 | 47 | if (!SUPPORT_TOUCH) { 48 | // http://www.quirksmode.org/js/events_properties.html 49 | if (!e) var e = window.event; 50 | if (e.which) rightclick = (e.which == 3); 51 | else if (e.button) rightclick = (e.button == 2); 52 | } 53 | return rightclick; 54 | } 55 | 56 | function touchstartHandler(e) { 57 | console.warn('touch started'); 58 | try { 59 | var $oel, $el, $marked; 60 | var elX, elY; 61 | 62 | if (isRightClick(e)) { 63 | return; 64 | } 65 | 66 | $oel = $(e.target); 67 | $el = $oel; 68 | elStartY = $el.offset().top; 69 | elStartX = $el.offset().left; 70 | 71 | var hovertimeout = null; 72 | var presstimeout = null; 73 | var startX, startY, startTime; 74 | var deltaX, deltaY, deltaT; 75 | var endX, endY, endTime; 76 | var swipped = false, tapped = false, moved = false, inprogress = false, pressed = false; 77 | 78 | function bindEvents($el) { 79 | $el.bind(MOVE_EVENT, handlemove).bind(END_EVENT, handleend); 80 | if (SUPPORT_TOUCH) { 81 | $el.bind(CANCEL_EVENT, handlecancel); 82 | } else { 83 | $(document).bind('mouseout', handleend); 84 | } 85 | } 86 | 87 | function unbindEvents($el) { 88 | $el.unbind(MOVE_EVENT, handlemove).unbind(END_EVENT, handleend); 89 | if (SUPPORT_TOUCH) { 90 | $el.unbind(CANCEL_EVENT, handlecancel); 91 | } else { 92 | $(document).unbind('mouseout', handlecancel); 93 | } 94 | } 95 | 96 | function updateChanges(e) { 97 | var point = e.originalEvent; 98 | var first = SUPPORT_TOUCH? point.changedTouches[0]: point; 99 | deltaX = first.pageX - startX; 100 | deltaY = first.pageY - startY; 101 | deltaT = (new Date).getTime() - startTime; 102 | var absElOffset = $el.offset(); 103 | elX = absElOffset.left - elStartX; 104 | elY = absElOffset.top - elStartY; 105 | } 106 | 107 | function handlestart(e) { 108 | var point; 109 | 110 | inprogress = true, swipped = false, tapped = false, 111 | moved = false, timed = false, pressed = false; 112 | point = e.originalEvent; 113 | startX = SUPPORT_TOUCH? point.changedTouches[0].pageX: point.pageX; 114 | startY = SUPPORT_TOUCH? point.changedTouches[0].pageY: point.pageY; 115 | startTime = (new Date).getTime(); 116 | endX = null, endY = null, endTime = null; 117 | deltaX = 0; 118 | deltaY = 0; 119 | deltaT = 0; 120 | 121 | // Let's bind these after the fact, so we can keep some internal values 122 | bindEvents($el); 123 | 124 | setTimeout(function() { 125 | $marked = $el; 126 | var mySelectors = touchSelector; 127 | while ($marked.parent().is(mySelectors)) { 128 | $marked = $marked.parent(); 129 | } 130 | 131 | handlehover(); 132 | }, 50); 133 | 134 | setTimeout(function() { 135 | $el.trigger("touch"); 136 | }, 50); 137 | 138 | setTimeout(function() { 139 | handlepress(e); 140 | }, 1000); 141 | }; 142 | 143 | function handlemove(e) { 144 | updateChanges(e); 145 | 146 | if (!inprogress) 147 | return; 148 | 149 | var absX = Math.abs(deltaX); 150 | var absY = Math.abs(deltaY); 151 | 152 | if (absX > 1 || absY > 1) { 153 | moved = true; 154 | } 155 | if (absY <= 5 && elX === 0 && elY === 0) { 156 | if (absX > (3 * absY) && (absX > 10) && deltaT < 1000) { 157 | inprogress = false; 158 | if ($marked) $marked.removeClass('active'); 159 | unbindEvents($el); 160 | 161 | swipped = true; 162 | $el.trigger('swipe', {direction: (deltaX < 0) ? 'left' : 'right', deltaX: deltaX, deltaY: deltaY }); 163 | } else if (absY > (3 * absX) && (absY > 10) && deltaT < 1000) { 164 | inprogress = false; 165 | if ($marked) $marked.removeClass('active'); 166 | unbindEvents($el); 167 | 168 | swipped = true; 169 | $el.trigger('swipe', {direction: (deltaY < 0) ? 'up' : 'down', deltaX: deltaX, deltaY: deltaY }); 170 | } 171 | } else { 172 | // moved too much, can't swipe anymore 173 | inprogress = false; 174 | if ($marked) $marked.removeClass('active'); 175 | unbindEvents($el); 176 | } 177 | }; 178 | 179 | function handleend(e) { 180 | updateChanges(e); 181 | var absX = Math.abs(deltaX); 182 | var absY = Math.abs(deltaY); 183 | 184 | inprogress = false; 185 | unbindEvents($el); 186 | if (!tapped && (absX <= 1 && absY <= 1) && (elX === 0 && elY === 0)) { 187 | tapped = true; 188 | $oel.trigger('tap'); 189 | setTimeout(function() { 190 | if ($marked) $marked.removeClass('active'); 191 | }, 1000); 192 | } else { 193 | if ($marked) $marked.removeClass('active'); 194 | //e.preventDefault(); 195 | } 196 | }; 197 | 198 | function handlecancel(e) { 199 | inprogress = false; 200 | if ($marked) $marked.removeClass('active'); 201 | unbindEvents(); 202 | }; 203 | 204 | function handlehover() { 205 | timed = true; 206 | if (tapped) { 207 | // flash the selection 208 | $marked.addClass('active'); 209 | hovertimeout = setTimeout(function() { 210 | $marked.removeClass('active'); 211 | }, 1000); 212 | } else if (inprogress && !moved) { 213 | $marked.addClass('active'); 214 | } 215 | }; 216 | 217 | function handlepress(e) { 218 | if (inprogress && !tapped && !moved) { 219 | pressed = true; 220 | tapped = true; 221 | $el.trigger('press'); 222 | } 223 | } 224 | 225 | handlestart(e); 226 | } catch (err) { 227 | console.error('tap error: ' + err); 228 | } 229 | 230 | } // End touch handler 231 | 232 | $(document.body).bind(START_EVENT, touchstartHandler); 233 | }); 234 | 235 | ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){ 236 | $.fn[m] = function(callback){ return this.bind(m, callback) } 237 | }); 238 | })($); 239 | -------------------------------------------------------------------------------- /test/runner/overlay-report.css: -------------------------------------------------------------------------------- 1 | #test-report { 2 | position: fixed; 3 | display: block; 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 15px; 7 | left: 0; right: 0; 8 | top: auto; 9 | bottom: 0; 10 | max-height: 50%; 11 | overflow-x: hidden; 12 | overflow-y: scroll; 13 | box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.3); 14 | box-shadow: inset 1px 1px 5px rgba(255, 255, 255, 0.7); 15 | opacity: 0.9; 16 | background-color: rgba(127, 127, 127, 0.7); 17 | z-index: 10; 18 | } 19 | #test-report > div, ol { 20 | overflow: hidden; 21 | } 22 | .hide { 23 | display: none; 24 | } 25 | -------------------------------------------------------------------------------- /test/unit/basic-initialization.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQTouch with Zepto 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |

jQTouch with Zepto

23 |

24 |
25 |

26 |
    27 |
    28 | 29 | 30 | 31 | 32 |
    33 |
    34 |
    35 |

    Animations

    36 | Home 37 |
    38 |
    39 |

    Most Popular

    40 | 46 |

    3d Transitions

    47 | 53 |
    54 |
    55 | Custom animations are also easy to write.
    View the source in demos/customanimation to see how. 56 |
    57 |
    58 |
    59 |
    60 |

    Buttons!

    61 | Home 62 |
    63 |
    64 | White 65 |
    66 | Gray 67 |
    68 | Red 69 |
    70 | Green 71 |
    72 | Blue 73 |
    74 |
    75 |
    76 | 77 | 78 | 79 | 80 | 81 | 82 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /test/unit/disabled/jquery-jqtouch2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | jQTouch's touch unit tests 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

    jQTouch's touch unit tests

    17 |

    18 |
    19 |

    20 |
      21 | 22 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /test/unit/initialization-variety.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQTouch with Zepto 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
      22 |

      jQTouch with Zepto

      23 |

      24 |
      25 |

      26 |
        27 |
        28 | 29 | 30 | 31 | 32 |
        33 |
        34 |
        35 |

        Animations

        36 | Home 37 |
        38 |
        39 |

        Most Popular

        40 | 46 |

        3d Transitions

        47 | 53 |
        54 |
        55 | Custom animations are also easy to write.
        View the source in demos/customanimation to see how. 56 |
        57 |
        58 |
        59 |
        60 | Pretty smooth, eh? 61 |
        62 | Go back 63 |
        64 |
        65 |
        66 |

        Buttons!

        67 | Home 68 |
        69 |
        70 | White 71 |
        72 | Gray 73 |
        74 | Red 75 |
        76 | Green 77 |
        78 | Blue 79 |
        80 |
        81 |
        82 | 83 | 84 | 85 | 86 | 87 | 88 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /test/unit/page-animation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQTouch Tests 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
        22 |

        jQTouch Tests

        23 |

        24 |
        25 |

        26 |
          27 |
          28 | 29 | 30 | 31 | 32 |
          33 |
          34 |
          35 |

          Animations

          36 | Home 37 |
          38 |
          39 |

          Most Popular

          40 | 46 |

          Slide

          47 | 53 |

          3d Transitions

          54 | 62 |
          63 |
          64 | Custom animations are also easy to write.
          View the source in demos/customanimation to see how. 65 |
          66 |
          67 |
          68 |
          69 | Pretty smooth, eh? 70 |
          71 | Go back 72 |
          73 |
          74 | 75 | 76 | 77 | 78 | 79 | 80 | 248 | 249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /test/unit/touch/jquery-jqtouch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | jQTouch’s touch unit tests 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

          jQTouch's touch unit tests

          17 |

          18 |
          19 |

          20 |
            21 | 22 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /test/unit/touch/test-touch.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // Fire a simulated touch event. 4 | // While it is possible to fire real touch events, 5 | // there are cross-browser issues, and this way we 6 | // can test touch events in browsers that don't 7 | // actually support touch input (like desktop Safari). 8 | // 9 | // Zepto's touch module only uses the `pageX/Y` and `target` 10 | // properties of the first touch in the `touches` TouchList 11 | function fire(type, element, x, y) { 12 | var event = document.createEvent('Event'), touch = { 13 | pageX: x, 14 | pageY: y, 15 | target: element 16 | } 17 | 18 | event.initEvent('touch' + type, true, true) 19 | event.touches = [touch] 20 | 21 | element.dispatchEvent(event) 22 | } 23 | 24 | function down(element, x, y) { 25 | fire('start', element, x, y) 26 | } 27 | function move(element, x, y) { 28 | fire('move', element, x, y) 29 | } 30 | function up(element) { 31 | fire('end', element) 32 | } 33 | 34 | module('TouchTest', { 35 | setup: function() { 36 | $('TEST ELEMENT
            ').appendTo('body') 37 | }, 38 | 39 | teardown: function() { 40 | $('#test').off() 41 | $('#test').remove() 42 | } 43 | }); 44 | 45 | asyncTest('testTap', function(t) { 46 | expect(1) 47 | 48 | var count = 0, element = $('#test').get(0) 49 | 50 | $('#test').on('tap', function() { 51 | count++ 52 | }) 53 | 54 | down(element, 10, 10) 55 | up(element) 56 | 57 | setTimeout(function() { 58 | start(); 59 | equal(1, count); 60 | }, 50) 61 | }); 62 | 63 | asyncTest('testSingleTapDoesNotInterfereWithTappingTwice', function(t) { 64 | expect(1) 65 | 66 | var count = 0, element = $('#test').get(0) 67 | 68 | $('#test').on('tap', function() { 69 | count++ 70 | }) 71 | 72 | down(element, 10, 10) 73 | up(element) 74 | 75 | setTimeout(function() { 76 | 77 | down(element, 10, 10) 78 | up(element) 79 | 80 | setTimeout(function() { 81 | start() 82 | 83 | equal(2, count) 84 | }, 200) 85 | }, 200) 86 | }); 87 | 88 | // should be fired if there is one tap within 250ms 89 | asyncTest('testSingleTap', function(t) { 90 | expect(2) 91 | 92 | var singleCount = 0, doubleCount = 0, element = $('#test').get(0) 93 | 94 | setTimeout(function() { 95 | $('#test').on('singleTap', function() { 96 | singleCount++ 97 | }).on('doubleTap', function() { 98 | doubleCount++ 99 | }) 100 | 101 | down(element, 10, 10) 102 | up(element) 103 | 104 | setTimeout(function() { 105 | start() 106 | 107 | equal(1, singleCount, 'expect a singleTap') 108 | equal(0, doubleCount, 'expect no doubleTap') 109 | }, 300) 110 | }, 300); // ensure last test won't affect this one 111 | }); 112 | 113 | // should be fired if there are two taps within 250ms 114 | asyncTest('testDoubleTap', function(t) { 115 | expect(2) 116 | 117 | var singleCount = 0, doubleCount = 0, element = $('#test').get(0) 118 | 119 | $('#test').on('singleTap', function() { 120 | singleCount++ 121 | }).on('doubleTap', function() { 122 | doubleCount++ 123 | }) 124 | 125 | down(element, 10, 10) 126 | up(element) 127 | 128 | setTimeout(function() { 129 | down(element, 12, 12) 130 | up(element) 131 | 132 | setTimeout(function() { 133 | start() 134 | 135 | equal(0, singleCount) 136 | equal(1, doubleCount) 137 | }, 100) 138 | }, 100) 139 | }); 140 | 141 | // should be fired if the finger is down in the same location for >750ms 142 | asyncTest('testLongTap', function(t) { 143 | var count = 0, element = $('#test').get(0) 144 | 145 | $('#test').on('longTap', function() { 146 | count++ 147 | }) 148 | 149 | down(element, 10, 10) 150 | 151 | setTimeout(function() { 152 | start(); 153 | 154 | up(element) 155 | 156 | equal(1, count) 157 | }, 900) 158 | }); 159 | 160 | asyncTest('testLongTapDoesNotFireIfFingerIsMoved', function(t) { 161 | expect(1) 162 | 163 | var count = 0, element = $('#test').get(0) 164 | 165 | setTimeout(function() { 166 | $('#test').on('longTap', function() { 167 | count++ 168 | }) 169 | down(element, 10, 10) 170 | 171 | setTimeout(function() { 172 | move(element, 50, 10) 173 | 174 | setTimeout(function() { 175 | start(); 176 | 177 | up(element) 178 | equal(0, count, 'expect moved long tap does not trigger longTap.') 179 | }, 450) 180 | }, 450) 181 | }, 1000) 182 | }); 183 | 184 | asyncTest('testSwipe', function(t) { 185 | expect(1) 186 | 187 | var swipeCount = 0, element = $('#test').get(0) 188 | 189 | $('#test').on('swipe', function() { 190 | swipeCount++ 191 | }) 192 | 193 | down(element, 10, 10) 194 | 195 | setTimeout(function() { 196 | 197 | move(element, 70, 10) 198 | up(element) 199 | 200 | setTimeout(function() { 201 | start(); 202 | equal(1, swipeCount) 203 | }, 50) 204 | }, 50) 205 | }); 206 | })(); 207 | -------------------------------------------------------------------------------- /themes/img/apple/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/apple/loading.gif -------------------------------------------------------------------------------- /themes/img/apple/on_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/apple/on_off.png -------------------------------------------------------------------------------- /themes/img/innsbruck/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/innsbruck/loading.gif -------------------------------------------------------------------------------- /themes/img/innsbruck/on_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/innsbruck/on_off.png -------------------------------------------------------------------------------- /themes/img/jqt/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/jqt/loading.gif -------------------------------------------------------------------------------- /themes/img/jqt/on_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/jqt/on_off.png -------------------------------------------------------------------------------- /themes/img/vanilla/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/vanilla/loading.gif -------------------------------------------------------------------------------- /themes/img/vanilla/on_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/senchalabs/jQTouch/8a462395772ff2d4420d2127706f08aa07e0c5ff/themes/img/vanilla/on_off.png -------------------------------------------------------------------------------- /themes/scss/apple.scss: -------------------------------------------------------------------------------- 1 | $base-color: #768BA7; 2 | $page-background-color: #CBD2D8; 3 | $highlight-color: #3366CC; 4 | $theme: apple; 5 | 6 | $list-background-color: #fff; 7 | 8 | $toolbar-background-color: $base-color; 9 | $toolbar-button-color: saturate(darken($base-color, 10), 10); 10 | 11 | @import 'include/core'; 12 | 13 | #jqt { 14 | > * { 15 | @include background-striped( 16 | $angle: left, 17 | $minorsize: 1px, 18 | $majorsize: 7px, 19 | $bgcolor: $page-background-color, 20 | $stripe-color: darken($page-background-color, 2) 21 | ) 22 | } 23 | 24 | .toolbar { 25 | @include background-image( 26 | linear-gradient(rgba(#fff, .15), rgba(#fff, 0)), 27 | glossy-gradient($toolbar-background-color, $contrast: .6) 28 | ); 29 | @include box-shadow(rgba(#fff, .3) 0 1px 0 inset); 30 | } 31 | 32 | ul { 33 | 34 | li { 35 | input[type="checkbox"], input[type="radio"] { 36 | color: rgb(50,79,133); 37 | } 38 | } 39 | 40 | .toggle input[type="checkbox"] { 41 | background: transparent url(../img/apple/on_off.png) 0 0 no-repeat; 42 | } 43 | 44 | input[type='submit'] { 45 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(238,238,238,1)), to(rgba(156,158,160,1))); 46 | border: 1px outset #aaa; 47 | } 48 | 49 | // Edge to edge 50 | &.edgetoedge li.sep { 51 | @include background-gradient($page-background-color, recessed); 52 | @include color-by-background($page-background-color); 53 | border-bottom: 1px solid #b5c1c9; 54 | border-top: 1px solid #b5c1c9; 55 | } 56 | } 57 | 58 | ul.edgetoedge li, .metal li { 59 | @include border-radius(0); 60 | } 61 | 62 | ul.edgetoedge li em { 63 | font-weight: normal; 64 | font-style: normal; 65 | } 66 | 67 | ul.metal li { 68 | border-top: 1px solid rgb(238,238,238); 69 | border-bottom: 1px solid rgb(156,158,165); 70 | font-size: 26px; 71 | text-shadow: #fff 0 1px 0; 72 | 73 | a:hover { 74 | color: #000; 75 | } 76 | em { 77 | color: #444; 78 | } 79 | } 80 | 81 | .info { 82 | background: #dce1eb; 83 | text-shadow: rgba(255,255,255,.8) 0 1px 0; 84 | color: rgb(76, 86, 108); 85 | border-top: 1px solid rgba(76, 86, 108, .3); 86 | } 87 | } -------------------------------------------------------------------------------- /themes/scss/config.rb: -------------------------------------------------------------------------------- 1 | # Manually bring in Compass Recipes for styling shortcuts 2 | require File.join(File.dirname(__FILE__), '..', 'compass-recipes', 'lib', 'compass-recipes') 3 | 4 | sass_path = File.dirname(__FILE__) 5 | css_path = File.join(sass_path, "..", "css") 6 | 7 | output_style = :expanded # nested/expanded/compact/compressed 8 | environment = :development # development/production 9 | 10 | # Rebuilt automatically with production settings in Ant build 11 | 12 | # for repeating-linear-gradient 13 | # https://github.com/chriseppstein/compass/issues/401 14 | Compass::BrowserSupport.add_support('repeating-linear-gradient', 'webkit', 'moz', 'o', 'ms') -------------------------------------------------------------------------------- /themes/scss/include/_animations.scss: -------------------------------------------------------------------------------- 1 | /* Fade */ 2 | 3 | #jqt .fade.in { 4 | -webkit-animation-name: fadeIn; 5 | } 6 | 7 | #jqt .fade.out { 8 | z-index: 10; 9 | -webkit-animation-name: fadeOut; 10 | } 11 | 12 | @-webkit-keyframes fadeIn { 13 | 0% { 14 | opacity: 0; 15 | } 16 | 100% { 17 | opacity: 1; 18 | } 19 | } 20 | 21 | @-webkit-keyframes fadeOut { 22 | 0% { 23 | opacity: 1; 24 | } 25 | 100% { 26 | opacity: 1; 27 | } 28 | } 29 | 30 | 31 | 32 | /* Disolve */ 33 | 34 | #jqt .dissolve.in { 35 | -webkit-animation-name: dissolveIn; 36 | } 37 | 38 | #jqt .dissolve.out { 39 | -webkit-animation-name: dissolveOut; 40 | } 41 | 42 | @-webkit-keyframes dissolveIn { 43 | 0% { 44 | opacity: 0; 45 | } 46 | 5% { 47 | opacity: 0; 48 | } 49 | 100% { 50 | opacity: 1; 51 | } 52 | } 53 | 54 | @-webkit-keyframes dissolveOut { 55 | 5% { 56 | opacity: 1; 57 | } 58 | 100% { 59 | opacity: 0; 60 | } 61 | } 62 | 63 | 64 | 65 | /* #Popin' */ 66 | 67 | #jqt .pop.in { 68 | -webkit-animation-name: popIn; 69 | } 70 | 71 | #jqt .pop.out { 72 | -webkit-animation-name: popOut; 73 | } 74 | 75 | @-webkit-keyframes popIn { 76 | 0% { 77 | opacity: 0; 78 | } 79 | 5% { 80 | -webkit-transform: scale(.2); 81 | opacity: 0; 82 | } 83 | 100% { 84 | -webkit-transform: scale(1); 85 | opacity: 1; 86 | } 87 | } 88 | 89 | @-webkit-keyframes popOut { 90 | 5% { 91 | -webkit-transform: scale(1); 92 | opacity: 1; 93 | } 94 | 100% { 95 | -webkit-transform: scale(.2); 96 | opacity: 0; 97 | } 98 | } 99 | 100 | 101 | 102 | /* Slide Left */ 103 | 104 | #jqt .slideleft.in { 105 | -webkit-animation-name: slideLeftIn; 106 | } 107 | 108 | #jqt .slideleft.out { 109 | -webkit-animation-name: slideLeftOut; 110 | } 111 | 112 | @-webkit-keyframes slideLeftIn { 113 | 0% { 114 | -webkit-transform: translateX(90%); 115 | } 116 | 100% { 117 | -webkit-transform: translateX(0); 118 | } 119 | } 120 | 121 | @-webkit-keyframes slideLeftOut { 122 | 0% { 123 | -webkit-transform: translateX(-10%); 124 | } 125 | 100% { 126 | -webkit-transform: translateX(-100%); 127 | } 128 | } 129 | 130 | 131 | 132 | /* Slide Right */ 133 | 134 | #jqt .slideright.in { 135 | -webkit-animation-name: slideRightIn; 136 | } 137 | 138 | #jqt .slideright.out { 139 | -webkit-animation-name: slideRightOut; 140 | } 141 | 142 | @-webkit-keyframes slideRightIn { 143 | 0% { 144 | -webkit-transform: translateX(-90%); 145 | } 146 | 100% { 147 | -webkit-transform: translateX(0); 148 | } 149 | } 150 | 151 | @-webkit-keyframes slideRightOut { 152 | 0% { 153 | -webkit-transform: translateX(10%); 154 | } 155 | 100% { 156 | -webkit-transform: translateX(100%); 157 | } 158 | } 159 | 160 | 161 | /* Slide Up */ 162 | 163 | #jqt .slideup.in { 164 | -webkit-animation-name: slideUpIn; 165 | } 166 | #jqt .slideup.out { 167 | -webkit-animation-name: slideUpOut; 168 | } 169 | 170 | @-webkit-keyframes slideUpIn { 171 | 20% { 172 | -webkit-transform: translateY(80%); 173 | } 174 | 100% { 175 | -webkit-transform: translateY(0%); 176 | } 177 | } 178 | 179 | @-webkit-keyframes slideUpOut { 180 | 20% { 181 | -webkit-transform: translateY(-20%); 182 | } 183 | 100% { 184 | -webkit-transform: translateY(-100%); 185 | } 186 | } 187 | 188 | 189 | 190 | /* Slide Down */ 191 | 192 | #jqt .slidedown.in { 193 | -webkit-animation-name: slideDownIn; 194 | } 195 | #jqt .slidedown.out { 196 | -webkit-animation-name: slideDownOut; 197 | } 198 | 199 | @-webkit-keyframes slideDownIn { 200 | 0% { 201 | -webkit-transform: translateY(-80%); 202 | } 203 | 100% { 204 | -webkit-transform: translateY(0%); 205 | } 206 | } 207 | 208 | @-webkit-keyframes slideDownOut { 209 | 0% { 210 | -webkit-transform: translateY(20%); 211 | } 212 | 100% { 213 | -webkit-transform: translateY(100%); 214 | } 215 | } 216 | 217 | #jqt .slideleft, #jqt .slideright, #jqt .slideup, #jqt .slidedown { 218 | -webkit-animation-timing-function: ease-in-out; 219 | } 220 | 221 | @if $include-3d-animations { 222 | 223 | /* Flip Left */ 224 | 225 | #jqt .flipleft { 226 | -webkit-backface-visibility: hidden; 227 | } 228 | 229 | #jqt .flipleft.in { 230 | -webkit-animation-name: flipLeftIn; 231 | } 232 | 233 | #jqt .flipleft.out { 234 | -webkit-animation-name: flipLeftOut; 235 | } 236 | 237 | @-webkit-keyframes flipLeftIn { 238 | 0% { 239 | opacity: 0; 240 | } 241 | 5% { 242 | opacity: 1; 243 | -webkit-transform: rotateY(180deg) scale(.8); 244 | } 245 | 100% { 246 | -webkit-transform: rotateY(0deg) scale(1); 247 | } 248 | } 249 | 250 | @-webkit-keyframes flipLeftOut { 251 | 5% { 252 | -webkit-transform: rotateY(0deg) scale(1); 253 | } 254 | 100% { 255 | -webkit-transform: rotateY(-180deg) scale(.8); 256 | } 257 | } 258 | 259 | 260 | 261 | /* Flip Right */ 262 | 263 | #jqt .flipright { 264 | -webkit-backface-visibility: hidden; 265 | } 266 | 267 | #jqt .flipright.in { 268 | -webkit-animation-name: flipRightIn; 269 | } 270 | 271 | #jqt .flipright.out { 272 | -webkit-animation-name: flipRightOut; 273 | } 274 | 275 | @-webkit-keyframes flipRightIn { 276 | 0% { 277 | opacity: 0; 278 | } 279 | 5% { 280 | -webkit-transform: rotateY(-180deg) scale(.8); 281 | } 282 | 100% { 283 | -webkit-transform: rotateY(0deg) scale(1); 284 | } 285 | } 286 | 287 | @-webkit-keyframes flipRightOut { 288 | 5% { 289 | -webkit-transform: rotateY(0deg) scale(1); 290 | } 291 | 100% { 292 | -webkit-transform: rotateY(180deg) scale(.8); 293 | } 294 | } 295 | 296 | 297 | 298 | /* Swap Right */ 299 | 300 | #jqt .swapright { 301 | -webkit-animation-duration: .7s; 302 | -webkit-transform: perspective(800); 303 | -webkit-animation-timing-function: ease-out; 304 | } 305 | #jqt .swapright.in { 306 | -webkit-animation-name: swapRightIn; 307 | } 308 | #jqt .swapright.out { 309 | -webkit-animation-name: swapRightOut; 310 | } 311 | 312 | @-webkit-keyframes swapRightIn { 313 | 0% { 314 | opacity: 0; 315 | } 316 | 5% { 317 | -webkit-transform: translate3d(0px, 0px, -800px) rotateY(70deg); 318 | opacity: 0; 319 | } 320 | 35% { 321 | -webkit-transform: translate3d(-180px, 0px, -400px) rotateY(20deg); 322 | opacity: 1; 323 | } 324 | 95% { 325 | -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg); 326 | opacity: 1; 327 | } 328 | } 329 | 330 | @-webkit-keyframes swapRightOut { 331 | 5% { 332 | -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg); 333 | opacity: 1; 334 | } 335 | 35% { 336 | -webkit-transform: translate3d(180px, 0px, -400px) rotateY(-20deg); 337 | opacity: .5; 338 | } 339 | 95% { 340 | -webkit-transform: translate3d(0px, 0px, -800px) rotateY(-70deg); 341 | opacity: 0; 342 | } 343 | } 344 | 345 | /* Swap Left */ 346 | 347 | #jqt .swapleft { 348 | -webkit-animation-duration: .7s; 349 | -webkit-transform: perspective(800); 350 | -webkit-animation-timing-function: ease-out; 351 | } 352 | #jqt .swapleft.in { 353 | -webkit-animation-name: swapLeftIn; 354 | } 355 | #jqt .swapleft.out { 356 | -webkit-animation-name: swapLeftOut; 357 | } 358 | 359 | @-webkit-keyframes swapLeftIn { 360 | 0% { 361 | opacity: 0; 362 | } 363 | 5% { 364 | -webkit-transform: translate3d(0px, 0px, -800px) rotateY(-70deg); 365 | opacity: 0; 366 | } 367 | 35% { 368 | -webkit-transform: translate3d(180px, 0px, -400px) rotateY(-20deg); 369 | opacity: 1; 370 | } 371 | 95% { 372 | opacity: 1; 373 | -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg); 374 | } 375 | } 376 | 377 | @-webkit-keyframes swapLeftOut { 378 | 5% { 379 | -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg); 380 | opacity: 1; 381 | } 382 | 35% { 383 | -webkit-transform: translate3d(-180px, 0px, -400px) rotateY(20deg); 384 | opacity: .5; 385 | } 386 | 95% { 387 | -webkit-transform: translate3d(0px, 0px, -800px) rotateY(70deg); 388 | opacity: 0; 389 | } 390 | } 391 | 392 | 393 | // Cubes 394 | /* Cube Left */ 395 | 396 | // Unfortunately, to acheive a proper cube effect, 397 | // we need the page width. Assuming 320px here. 398 | 399 | #jqt .cubeleft, #jqt .cuberight { 400 | &.in, &.out { 401 | -webkit-animation-duration: .6s; 402 | // -webkit-animation-timing-function: linear; 403 | -webkit-transform: perspective(800); 404 | } 405 | } 406 | 407 | #jqt .cubeleft.in { 408 | -webkit-transform-origin: 0% 50%; 409 | -webkit-animation-name: cubeLeftIn; 410 | } 411 | 412 | #jqt .cubeleft.out { 413 | -webkit-transform-origin: 100% 50%; 414 | -webkit-animation-name: cubeLeftOut; 415 | } 416 | 417 | @-webkit-keyframes cubeLeftIn { 418 | 0% { 419 | opacity: 0; 420 | } 421 | 5% { 422 | -webkit-transform: rotateY(90deg) translateZ(320px); 423 | opacity: .5; 424 | } 425 | 95% { 426 | -webkit-transform: rotateY(0deg) translateZ(0) translateX(0); 427 | opacity: 1; 428 | } 429 | } 430 | 431 | @-webkit-keyframes cubeLeftOut { 432 | 5% { 433 | -webkit-transform: rotateY(0deg) translateZ(0) translateX(0); 434 | opacity: 1; 435 | } 436 | 95% { 437 | -webkit-transform: rotateY(-90deg) translateZ(320px); 438 | opacity: .5; 439 | } 440 | } 441 | 442 | /* Cube Right */ 443 | 444 | #jqt .cuberight.in { 445 | -webkit-transform-origin: 100% 50%; 446 | -webkit-animation-name: cubeRightIn; 447 | } 448 | 449 | #jqt .cuberight.out { 450 | -webkit-transform-origin: 0% 50%; 451 | -webkit-animation-name: cubeRightOut; 452 | } 453 | 454 | @-webkit-keyframes cubeRightIn { 455 | 0% { 456 | opacity: 0; 457 | } 458 | 5% { 459 | -webkit-transform: rotateY(-90deg) translateZ(320px); 460 | opacity: .5; 461 | } 462 | 95% { 463 | -webkit-transform: rotateY(0deg) translateZ(0) translateX(0); 464 | opacity: 1; 465 | } 466 | } 467 | 468 | @-webkit-keyframes cubeRightOut { 469 | 5% { 470 | -webkit-transform: rotateY(0deg) translateZ(0) translateX(0); 471 | opacity: 1; 472 | } 473 | 95% { 474 | -webkit-transform: rotateY(90deg) translateZ(320px); 475 | opacity: .5; 476 | } 477 | } 478 | 479 | } 480 | -------------------------------------------------------------------------------- /themes/scss/include/_base.scss: -------------------------------------------------------------------------------- 1 | @import "compass/css3/flexbox"; 2 | @import "compass/support"; 3 | 4 | * { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | -webkit-tap-highlight-color: rgba(0,0,0,0); 11 | -webkit-touch-callout: none; 12 | } 13 | 14 | #jqt { 15 | -webkit-text-size-adjust: none; 16 | @include user-select(none); 17 | font-family: $base-font-family; 18 | position: absolute; 19 | right: 0; 20 | top: 0; 21 | left: 0; 22 | bottom: 0; 23 | 24 | a { 25 | -webkit-tap-highlight-color: rgba(0,0,0,0); 26 | -webkit-user-drag: none; 27 | } 28 | 29 | .selectable, input, textarea { 30 | -webkit-user-select: auto; 31 | } 32 | 33 | &.notransform { 34 | -webkit-transform: none !important; 35 | } 36 | 37 | // "Views" 38 | > * { 39 | display: block; 40 | left: 0; 41 | top: 0; 42 | min-height: 100%; 43 | width: 100%; 44 | overflow-x: hidden; 45 | position: absolute; 46 | z-index: 0; 47 | display: -webkit-box; 48 | display: box; 49 | -webkit-box-orient: vertical; 50 | box-orient: vertical; 51 | } 52 | 53 | > .current { 54 | z-index: 10; 55 | } 56 | 57 | > *:not(.current):not(.in):not(.out) { 58 | display: none; 59 | } 60 | 61 | &.touchscroll:not(.animating3d), &.autoscroll:not(.animating3d) { 62 | overflow-y: auto; 63 | -webkit-overflow-scrolling: touch; 64 | 65 | > * { 66 | height: 100%; 67 | } 68 | .scroll { 69 | position: relative; 70 | -webkit-box-flex: 1; 71 | box-flex: 1; 72 | overflow-y: auto; 73 | -webkit-overflow-scrolling: touch; 74 | } 75 | } 76 | 77 | &.touchscroll:not(.animating3d) { 78 | .scroll { 79 | overflow-y: scroll; 80 | } 81 | } 82 | 83 | // Ensure margins don't collapse 84 | .scroll { 85 | -webkit-margin-collapse: separate; 86 | } 87 | 88 | .in, .out { 89 | -webkit-animation-duration: 375ms; 90 | -webkit-animation-fill-mode: both; 91 | -webkit-animation-timing-function: ease-in-out; 92 | 93 | // Make sure elements that are animating are not tapable 94 | &:after { 95 | @include pseudo-element($width: auto); 96 | top: 0; 97 | left: 0; 98 | bottom: 0; 99 | right: 0; 100 | } 101 | 102 | input, a { 103 | pointer-events: none; 104 | } 105 | } 106 | 107 | .in { 108 | z-index: 10; 109 | } 110 | .out { 111 | z-index: 0 !important; 112 | } 113 | 114 | &.supports3d { 115 | -webkit-perspective: 1000; 116 | 117 | > * { 118 | -webkit-transform: translate3d(0,0,0) rotate(0) scale(1); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /themes/scss/include/_core.scss: -------------------------------------------------------------------------------- 1 | // Disable everything but WebKit 2 | $experimental-support-for-mozilla: false; 3 | $experimental-support-for-opera: false; 4 | $experimental-support-for-microsoft: false; 5 | $experimental-support-for-khtml: false; 6 | 7 | // iOS5 only: 8 | // $support-for-original-webkit-gradients: false; 9 | 10 | // Color tests 11 | $red-color: #D83B38 !default; 12 | $green-color: #53b401 !default; 13 | $gray-color: #444 !default; 14 | $white-color: #eee !default; 15 | $blue-color: #2F7CE3 !default; 16 | 17 | // Default colors 18 | $base-color: #555658 !default; 19 | $body-color: rgb(0,0,0) !default; 20 | $highlight-color: #53b401 !default; // bright green 21 | $toolbar-background-color: darken($base-color, 15%) !default; 22 | $page-background-color: $base-color !default; 23 | $list-background-color: $page-background-color !default; 24 | $toolbar-button-color: darken($toolbar-background-color, 15%) !default; 25 | $toolbar-button-active-color: darken($toolbar-button-color, 5%) !default; 26 | $base-font-family: "Helvetica Neue", Helvetica !default; 27 | $base-font: bold 18px $base-font-family !default; 28 | $base-button-gradient: glossy !default; 29 | $default-border-radius: 8px !default; 30 | 31 | // Optimization variables 32 | $include-metal-lists: true !default; 33 | $include-plastic-lists: true !default; 34 | $include-forms: true !default; 35 | $include-edge-lists: true !default; 36 | $include-animations: true !default; 37 | $include-3d-animations: true !default; 38 | $include-highlights: true !default; 39 | $include-back-arrow: true !default; 40 | 41 | @import 'compass'; 42 | @import 'recipes'; 43 | @import 'include/base'; 44 | @import 'include/animations'; 45 | @import 'include/skeleton'; -------------------------------------------------------------------------------- /themes/scss/include/_widgets.scss: -------------------------------------------------------------------------------- 1 | 2 | @mixin pseudo-chervon($size: 0.6em, $thickness: 0.2em, $ratio: 1, $direction: 0, $top: 30%, $left: false) { 3 | border-style: solid; 4 | border-width: $thickness $thickness 0 0; 5 | position: relative; 6 | display: inline-block; 7 | @if $top != false { 8 | top: $top; 9 | } 10 | @if $left != false { 11 | left: $left; 12 | } 13 | content: ''; 14 | height: $size; 15 | width: $size; 16 | -webkit-transform: scale($ratio, 1) rotate($direction * 90deg - 45deg) ; 17 | vertical-align: top; 18 | } 19 | 20 | @mixin pseudo-circle($size: 24px, $border-width: 2px, $color: #fff, $content: '›', 21 | $include-highlights: true, $include-gradient: true) { 22 | @include pseudo-element($size, $size, $content); 23 | @include circle($size); 24 | top: 50%; 25 | right: 6px; 26 | margin-top: -$size/2; 27 | border: $border-width solid $color; 28 | -webkit-box-sizing: border-box; 29 | padding: 0; 30 | z-index: 10; 31 | line-height: $size - 11; 32 | color: $color; 33 | text-indent: 5px; 34 | pointer-events: none; 35 | 36 | @if $include-gradient { 37 | @include background-gradient($highlight-color, $base-button-gradient); 38 | } @else { 39 | @include background-image(none); 40 | background-color: transparent; 41 | } 42 | @if $include-highlights { 43 | @include box-shadow(0 1px 2px rgba(#000, .3)); 44 | } @else { 45 | @include box-shadow(none); 46 | } 47 | } 48 | 49 | @mixin bordered-button($include-highlights: true) { 50 | display: block; 51 | font-size: 20px; 52 | font-weight: bold; 53 | margin: 10px 20px; 54 | padding: 10px; 55 | text-align: center; 56 | text-decoration: inherit; 57 | @include border-radius; 58 | 59 | @if $include-highlights { 60 | @include box-shadow( 61 | rgba(#000, .4) 0 1px 3px, 62 | rgba(#000, .4) 0 0 0 5px, 63 | rgba(#fff, .3) 0 1px 0 5px 64 | ); 65 | } @else { 66 | border: 1px solid darken($base-color, 10); 67 | } 68 | 69 | &.active, &:active { 70 | $active-color: darken($highlight-color, 10); 71 | @include background-gradient($active-color, $base-button-gradient); 72 | @include color-by-background($active-color); 73 | } 74 | } 75 | 76 | @mixin toggle-button($height: 32px, $width: 52px) { 77 | position: relative; 78 | appearance: none; 79 | -webkit-appearance: none; 80 | display: inline-block; 81 | border-radius: $height / 2; 82 | background-color: #fff; 83 | padding: 1px; 84 | width: $width; 85 | height: $height; 86 | cursor: pointer; 87 | margin: 0px; 88 | vertical-align: middle; 89 | border: 0px solid transparent; 90 | box-shadow: inset 0px 0px 0px 1px #e6e6e6; 91 | transition: all .3s ease-out; 92 | 93 | &:before { 94 | content: ''; 95 | position: absolute; 96 | width: $height - 2; 97 | height: $height - 2; 98 | border-radius: ($height - 3 / 2); 99 | top: 1px; 100 | box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,.2), -1px 2px 5px rgba(0, 0, 0, 0.1); 101 | border: 0px solid transparent; 102 | cursor: pointer; 103 | background-color: #fff; 104 | transition: left 0.1s ease-in .1s, box-shadow 0.2s ease-in .2s; 105 | } 106 | 107 | &:checked { 108 | box-shadow: inset 0px 0px 0px 20px #53d76a, -1px 2px 5px rgba(0, 0, 0, 0.1); 109 | 110 | &:before { 111 | left: 22px; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /themes/scss/innsbruck.scss: -------------------------------------------------------------------------------- 1 | $base-color: white; 2 | $body-color: #efeff4; 3 | $page-background-color: #efeff4; 4 | $toolbar-background-color: #f7f7f8; 5 | $highlight-color: #d9d9d9; 6 | $theme: innsbruck; 7 | $base-font-family: Helvetica Neue Ultra Light, Helvetica Neue Interface M3, Helvetica; 8 | $base-font: normal 17px $base-font-family; 9 | $base-button-gradient: flat; 10 | $include-back-arrow: false; 11 | 12 | $list-background-color: #fff; 13 | $include-highlights: false; 14 | 15 | $toolbar-background-color: $base-color; 16 | $toolbar-button-color: saturate(darken($base-color, 10), 10); 17 | 18 | @import 'include/core'; 19 | @import 'include/widgets'; 20 | 21 | #jqt { 22 | 23 | > * { 24 | background-color: $page-background-color; 25 | } 26 | 27 | h1, h2 { 28 | color: #4d4d4d; 29 | } 30 | 31 | h2 { 32 | text-transform: uppercase; 33 | font-size: 0.9em; 34 | } 35 | 36 | .toolbar { 37 | border-bottom: 1px solid #a7a7ab; 38 | font-weight: bold; 39 | @include box-shadow(rgba(#fff, .3) 0 1px 0 inset); 40 | 41 | .button, .back, .cancel, .add { 42 | background-image: none; 43 | background-color: transparent; 44 | border: 0px solid transparent; 45 | box-shadow: none; 46 | color: #007aff; 47 | font-weight: lighter; 48 | font-size: 15px; 49 | text-shadow: none; 50 | padding: 0 7px; 51 | margin: 0 0px; 52 | 53 | &.active, &:active { 54 | color: lighten(#007aff, 30); 55 | background-image: none; 56 | background-color: transparent; 57 | } 58 | } 59 | 60 | .back, .cancel { 61 | left: 2px; 62 | 63 | &::before { 64 | @include pseudo-chervon($direction: 3, $thickness: 0.2em, $ratio: 0.9); 65 | margin-right: 5px; 66 | } 67 | } 68 | 69 | h1 { 70 | font-size: 17px; 71 | } 72 | } 73 | 74 | ul { 75 | overflow: hidden; 76 | 77 | li { 78 | overflow: visible; 79 | padding-right: 10px; 80 | box-sizing: border-box; 81 | 82 | input[type="checkbox"], input[type="radio"] { 83 | color: rgb(50,79,133); 84 | } 85 | 86 | &.forward::after { 87 | @include pseudo-circle( 88 | $color: #007aff, $size: 20px, $border-width: 1px, $content: 'i', 89 | $include-highlights: false, $include-gradient: false 90 | ); 91 | font-size: 13px; 92 | font-weight: bold; 93 | text-indent: 7.5px; 94 | line-height: 19px; 95 | right: 13px; 96 | } 97 | 98 | a { 99 | color: #040404; 100 | 101 | &.active, &.selected { 102 | background-image: none; 103 | color: #222; 104 | margin-left: -20px; 105 | padding-left: 20px; 106 | margin-right: -16px; 107 | padding-right: 16px; 108 | text-shadow: none; 109 | box-shadow: none; 110 | -webkit-box-shadow: none; 111 | } 112 | } 113 | 114 | &.arrow small { 115 | margin-right: 14px; 116 | } 117 | &.forward small { 118 | margin-right: 25px; 119 | 120 | &.counter { 121 | margin-right: 32px; 122 | } 123 | } 124 | } 125 | 126 | input[type='submit'] { 127 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(238,238,238,1)), to(rgba(156,158,160,1))); 128 | border: 1px outset #aaa; 129 | } 130 | 131 | // Edge to edge 132 | &.edgetoedge li.sep { 133 | color: black; 134 | background-color: #f7f7f7; 135 | } 136 | 137 | &.rounded { 138 | margin: 20px 0; 139 | padding: 0 0; 140 | border-radius: 0; 141 | 142 | li { 143 | padding-left: 0; 144 | margin-left: 20px; 145 | padding-right: 16px; 146 | 147 | &:first-child, &:last-child { 148 | a.active { 149 | border-top-left-radius: 0; 150 | border-top-right-radius: 0; 151 | border-bottom-left-radius: 0; 152 | border-bottom-right-radius: 0; 153 | } 154 | } 155 | 156 | a.active { 157 | border-radius: 0; 158 | } 159 | } 160 | } 161 | &.edgetoedge li, 162 | &.metal li { 163 | @include border-radius(0); 164 | 165 | &.arrow small.counter { 166 | margin-right: 20px; 167 | } 168 | } 169 | 170 | &.plastic li { 171 | a.active, a:active { 172 | background-color: #c9c9c9; 173 | } 174 | } 175 | 176 | &.edgetoedge li em { 177 | font-weight: normal; 178 | font-style: normal; 179 | } 180 | 181 | &.metal li { 182 | border-top: 1px solid rgb(238,238,238); 183 | border-bottom: 1px solid rgb(156,158,165); 184 | font-size: 26px; 185 | text-shadow: #fff 0 1px 0; 186 | 187 | a:hover { 188 | color: #000; 189 | } 190 | em { 191 | color: #444; 192 | } 193 | } 194 | 195 | li input[type="checkbox"].toggle { 196 | margin-top: 4px; 197 | right: 16px; 198 | } 199 | } 200 | 201 | h1 + ul.rounded, h2 + ul.rounded { 202 | margin-top: 0; 203 | } 204 | 205 | .whiteButton, .grayButton, .redButton, .blueButton, .greenButton { 206 | font-weight: normal; 207 | font-size: 22px; 208 | line-height: 66px; 209 | padding: 0; 210 | text-shadow: none; 211 | margin: 0 20px; 212 | 213 | &.active, &:active { 214 | text-shadow: none; 215 | } 216 | } 217 | 218 | .whiteButton { 219 | background-color: rgba(255, 255, 255, 0.95); 220 | 221 | &.active, &:active { 222 | $active-color: #dcdcdd; 223 | color: black; 224 | @include background-gradient($active-color, $base-button-gradient); 225 | } 226 | } 227 | 228 | .grayButton { 229 | background-color: #1d1e1d; 230 | 231 | &.active, &:active { 232 | $active-color: black; 233 | color: white; 234 | @include background-gradient($active-color, $base-button-gradient); 235 | } 236 | } 237 | 238 | .redButton { 239 | background-color: #e0544c; 240 | 241 | &.active, &:active { 242 | $active-color: darken(#e0544c, 16); 243 | @include background-gradient($active-color, $base-button-gradient); 244 | } 245 | } 246 | 247 | .blueButton { 248 | } 249 | 250 | .greenButton { 251 | background-color: #4cd964; 252 | 253 | &.active, &:active { 254 | $active-color: darken(#4cd964, 16); 255 | @include background-gradient($active-color, $base-button-gradient); 256 | } 257 | } 258 | 259 | 260 | .info { 261 | background: #dcdcdf; 262 | text-shadow: rgba(255,255,255,.8) 0 1px 0; 263 | color: rgb(108, 108, 108); 264 | border-top: 1px solid rgba(86, 86, 89, .3); 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /themes/scss/jqtouch.scss: -------------------------------------------------------------------------------- 1 | // $toolbar-background-color: #485021; 2 | // $base-color: #485021; // Army green 3 | // $base-color: #3387CC; // Sky blue 4 | // $highlight-color: #CFD085; // Yellow 5 | // $highlight-color: #0175C4; 6 | // $toolbar-background-color: #3387CC; 7 | // $base-color: #D9D9D9; 8 | // $highlight-color: #000; 9 | 10 | $base-font-family: 'Avenir Next', "Avenir"; 11 | $theme: jqt; 12 | 13 | @import 'include/core'; 14 | 15 | #jqt { 16 | > * { 17 | @include background-image( 18 | background_noise($size: 60, $opacity: .07), 19 | bevel-gradient($base-color) 20 | ); 21 | } 22 | 23 | .toolbar { 24 | @include background-carbon-fiber( 25 | $background-color: $toolbar-background-color 26 | ); 27 | } 28 | 29 | /* Lists */ 30 | 31 | ul { 32 | li { 33 | border-top: 1px solid darken($base-color, 5); 34 | @include background-gradient(rgba($base-color, .2), matte); 35 | 36 | a { 37 | @include color-by-background($base-color); 38 | } 39 | 40 | .toggle input[type="checkbox"] { 41 | @include border-radius(5px); 42 | background: #fff url(../img/jqt/on_off.png) 0 0 no-repeat; 43 | } 44 | 45 | input[type='submit'] { 46 | @include background-gradient(color-by-background($list-background-color), glossy); 47 | border: 1px outset black; 48 | } 49 | 50 | small.counter { 51 | @include box-shadow(rgba(#fff,.1) 0 1px 0); 52 | } 53 | 54 | } // /li 55 | 56 | &.metal { 57 | li { 58 | background-image: none; 59 | border-top: 1px solid #fff; 60 | border-bottom: 1px solid #666; 61 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(238,238,238,1)), to(rgba(156,158,160,1))); 62 | 63 | a { 64 | text-shadow: #fff 0 1px 0; 65 | &.active { color: #000; } 66 | } 67 | 68 | em { 69 | color: #444; 70 | } 71 | } 72 | } // ul.metal 73 | 74 | &.edgetoedge li { 75 | @include background-gradient(darken($base-color, 10), color-stops(darken($base-color, 18), darken($base-color, 15))); 76 | border-bottom: 1px solid darken($base-color, 22); 77 | border-top: 1px solid darken($base-color, 13); 78 | 79 | &.sep { 80 | @include background-gradient(rgba(#000, .3), bevel); 81 | @include color-by-background(darken($base-color, 25), 50); 82 | } 83 | } 84 | } 85 | 86 | .info { 87 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ccc), to(#aaa), color-stop(.6,#CCCCCC)); 88 | text-shadow: rgba(255,255,255,.8) 0 1px 0; 89 | color: #444; 90 | border-top: 1px solid rgba(255,255,255,.2); 91 | } 92 | } -------------------------------------------------------------------------------- /themes/scss/reference/default.old.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #000; 3 | color: #ddd; 4 | } 5 | #jqt > * { 6 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#333), to(#5e5e65)); 7 | } 8 | #jqt h1, #jqt h2 { 9 | font: bold 18px "Helvetica Neue", Helvetica; 10 | text-shadow: rgba(255,255,255,.2) 0 1px 1px; 11 | color: #000; 12 | margin: 10px 20px 5px; 13 | } 14 | /* @group Toolbar */ 15 | #jqt .toolbar { 16 | -webkit-box-sizing: border-box; 17 | border-bottom: 1px solid #000; 18 | padding: 10px; 19 | height: 45px; 20 | background: url(img/toolbarBackground.png) #000000 repeat-x; 21 | position: relative; 22 | } 23 | #jqt .black-translucent .toolbar { 24 | margin-top: 20px; 25 | } 26 | #jqt .toolbar > h1 { 27 | position: absolute; 28 | overflow: hidden; 29 | left: 50%; 30 | top: 10px; 31 | line-height: 1em; 32 | margin: 1px 0 0 -75px; 33 | height: 40px; 34 | font-size: 20px; 35 | width: 150px; 36 | font-weight: bold; 37 | text-shadow: rgba(0,0,0,1) 0 -1px 1px; 38 | text-align: center; 39 | text-overflow: ellipsis; 40 | white-space: nowrap; 41 | color: #fff; 42 | } 43 | #jqt.landscape .toolbar > h1 { 44 | margin-left: -125px; 45 | width: 250px; 46 | } 47 | #jqt .button, #jqt .back, #jqt .cancel, #jqt .add { 48 | position: absolute; 49 | overflow: hidden; 50 | top: 8px; 51 | right: 10px; 52 | margin: 0; 53 | border-width: 0 5px; 54 | padding: 0 3px; 55 | width: auto; 56 | height: 30px; 57 | line-height: 30px; 58 | font-family: inherit; 59 | font-size: 12px; 60 | font-weight: bold; 61 | color: #fff; 62 | text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0; 63 | text-overflow: ellipsis; 64 | text-decoration: none; 65 | white-space: nowrap; 66 | background: none; 67 | -webkit-border-image: url(img/button.png) 0 5 0 5; 68 | } 69 | #jqt .button.active, 70 | #jqt .cancel.active, 71 | #jqt .add.active { 72 | -webkit-border-image: url(img/buttonActive.png) 0 5 0 5; 73 | } 74 | #jqt .back { 75 | left: 6px; 76 | right: auto; 77 | padding: 0; 78 | max-width: 55px; 79 | border-width: 0 8px 0 14px; 80 | -webkit-border-image: url(img/backButton.png) 0 8 0 14; 81 | } 82 | #jqt .back.active { 83 | -webkit-border-image: url(img/backButtonActive.png) 0 8 0 14; 84 | } 85 | #jqt .leftButton, #jqt .cancel { 86 | left: 6px; 87 | right: auto; 88 | } 89 | #jqt .add { 90 | font-size: 24px; 91 | line-height: 24px; 92 | font-weight: bold; 93 | } 94 | #jqt .bigButton { 95 | -webkit-border-image: url(img/bigButton.png) 0 12 0 12; 96 | border-width: 0 12px; 97 | color: #000000; 98 | display: block; 99 | font-size: 20px; 100 | font-weight: bold; 101 | line-height: 46px; 102 | margin: 0 10px; 103 | text-align: center; 104 | text-decoration: inherit; 105 | text-shadow: rgba(255,255,255,.8) 0 1px 0; 106 | } 107 | #jqt .bigButton.active { 108 | -webkit-border-image: url(img/bigButtonActive.png) 0 12 0 12; 109 | color: #000000; 110 | } 111 | 112 | 113 | /* @end */ 114 | /* @group Lists */ 115 | #jqt h1 + ul, #jqt h2 + ul, #jqt h3 + ul, #jqt h4 + ul, #jqt h5 + ul, #jqt h6 + ul { 116 | margin-top: 0; 117 | } 118 | #jqt ul { 119 | color: #aaa; 120 | border: 1px solid #333333; 121 | font: bold 18px "Helvetica Neue", Helvetica; 122 | padding: 0; 123 | margin: 15px 10px 17px 10px; 124 | } 125 | #jqt ul.rounded { 126 | -webkit-border-radius: 8px; 127 | -webkit-box-shadow: rgba(0,0,0,.3) 1px 1px 3px; 128 | } 129 | #jqt ul.rounded li:first-child, #jqt ul.rounded li:first-child a { 130 | border-top: 0; 131 | -webkit-border-top-left-radius: 8px; 132 | -webkit-border-top-right-radius: 8px; 133 | } 134 | #jqt ul.rounded li:last-child, #jqt ul.rounded li:last-child a { 135 | -webkit-border-bottom-left-radius: 8px; 136 | -webkit-border-bottom-right-radius: 8px; 137 | } 138 | #jqt ul li { 139 | color: #666; 140 | border-top: 1px solid #333; 141 | border-bottom: #555858; 142 | list-style-type: none; 143 | padding: 10px 10px 10px 10px; 144 | background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4c4d4e), to(#404142)); 145 | overflow: hidden; 146 | } 147 | #jqt ul li.arrow { 148 | background-color: #4c4d4e !important; 149 | background-image: url(img/chevron.png), -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4c4d4e), to(#404142)); 150 | background-position: right center !important; 151 | background-repeat: no-repeat !important; 152 | } 153 | 154 | #jqt ul li.arrow a { 155 | padding: 12px 22px 12px 10px; 156 | } 157 | 158 | #jqt ul li.forward { 159 | background-image: url(img/chevronCircle.png), -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4c4d4e), to(#404142)); 160 | background-position: right center; 161 | background-repeat: no-repeat; 162 | } 163 | /* universal links on list */ 164 | #jqt ul li a, #jqt li.img a + a { 165 | color: #fff; 166 | text-decoration: none; 167 | text-overflow: ellipsis; 168 | white-space: nowrap; 169 | overflow: hidden; 170 | display: block; 171 | padding: 12px 10px 12px 10px; 172 | margin: -10px; 173 | -webkit-tap-highlight-color: rgba(0,0,0,0); 174 | text-shadow: rgba(0,0,0,.2) 0 1px 1px; 175 | } 176 | #jqt ul li a.active, 177 | #jqt ul li a.button { 178 | background-color: #53b401; 179 | color: #fff; 180 | } 181 | #jqt ul li a.active.loading { 182 | background-image: url(img/loading.gif); 183 | background-position: 95% center; 184 | background-repeat: no-repeat; 185 | } 186 | #jqt ul li.arrow a.active { 187 | background-image: url(img/chevronActive.png); 188 | background-position: right center; 189 | background-repeat: no-repeat; 190 | } 191 | #jqt ul li.forward a.active { 192 | background-image: url(img/chevronCircleActive.png); 193 | background-position: right center; 194 | background-repeat: no-repeat; 195 | } 196 | #jqt ul li.img a + a { 197 | margin: -10px 10px -20px -5px; 198 | font-size: 17px; 199 | font-weight: bold; 200 | } 201 | #jqt ul li.img a + a + a { 202 | font-size: 14px; 203 | font-weight: normal; 204 | margin-left: -10px; 205 | margin-bottom: -10px; 206 | margin-top: 0; 207 | } 208 | #jqt ul li.img a + small + a { 209 | margin-left: -5px; 210 | } 211 | #jqt ul li.img a + small + a + a { 212 | margin-left: -10px; 213 | margin-top: -20px; 214 | margin-bottom: -10px; 215 | font-size: 14px; 216 | font-weight: normal; 217 | } 218 | #jqt ul li.img a + small + a + a + a { 219 | margin-left: 0px !important; 220 | margin-bottom: 0; 221 | } 222 | #jqt ul li a + a { 223 | color: #000; 224 | font: 14px "Helvetica Neue", Helvetica; 225 | text-overflow: ellipsis; 226 | white-space: nowrap; 227 | overflow: hidden; 228 | display: block; 229 | margin: 0; 230 | padding: 0; 231 | } 232 | #jqt ul li a + a + a, #jqt ul li.img a + a + a + a, #jqt ul li.img a + small + a + a + a { 233 | color: #666; 234 | font: 13px "Helvetica Neue", Helvetica; 235 | margin: 0; 236 | text-overflow: ellipsis; 237 | white-space: nowrap; 238 | overflow: hidden; 239 | display: block; 240 | padding: 0; 241 | } 242 | /* 243 | @end */ 244 | /* @group Forms */ 245 | #jqt ul.form li { 246 | padding: 7px 10px; 247 | } 248 | #jqt ul.form li.error { 249 | border: 2px solid red; 250 | } 251 | #jqt ul.form li.error + li.error { 252 | border-top: 0; 253 | } 254 | #jqt ul li input[type="text"], 255 | #jqt ul li input[type="password"], 256 | #jqt ul li input[type="tel"], 257 | #jqt ul li input[type="number"], 258 | #jqt ul li input[type="search"], 259 | #jqt ul li input[type="email"], 260 | #jqt ul li input[type="url"], 261 | #jqt ul li textarea, 262 | #jqt ul li select { 263 | color: #777; 264 | background: transparent url('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='); 265 | border: 0; 266 | font: normal 17px "Helvetica Neue", Helvetica; 267 | padding: 0; 268 | display: inline-block; 269 | margin-left: 0px; 270 | width: 100%; 271 | -webkit-appearance: textarea; 272 | } 273 | #jqt ul li textarea { 274 | height: 120px; 275 | padding: 0; 276 | text-indent: -2px; 277 | } 278 | #jqt ul li select { 279 | text-indent: 0px; 280 | background: transparent url(img/chevron.png) no-repeat right center; 281 | -webkit-appearance: textfield; 282 | margin-left: -6px; 283 | width: 104%; 284 | } 285 | #jqt ul li input[type="checkbox"], #jqt ul li input[type="radio"] { 286 | margin: 0; 287 | padding: 10px 10px; 288 | } 289 | #jqt ul li input[type="checkbox"]:after, #jqt ul li input[type="radio"]:after { 290 | content: attr(title); 291 | font: 17px "Helvetica Neue", Helvetica; 292 | display: block; 293 | width: 246px; 294 | color: #777; 295 | margin: -12px 0 0 17px; 296 | } 297 | /* @end */ 298 | /* @group Mini Label */ 299 | #jqt ul li small { 300 | color: #64c114; 301 | font: 17px "Helvetica Neue", Helvetica; 302 | text-align: right; 303 | text-overflow: ellipsis; 304 | white-space: nowrap; 305 | overflow: hidden; 306 | display: block; 307 | width: 23%; 308 | float: right; 309 | padding: 0; 310 | } 311 | #jqt ul li.arrow small { 312 | padding: 0 15px; 313 | } 314 | #jqt ul li small.counter { 315 | font-size: 17px; 316 | line-height: 13px; 317 | font-weight: bold; 318 | background: rgba(0,0,0,.15); 319 | color: #fff; 320 | -webkit-border-radius: 11px; 321 | padding: 4px 10px 5px 10px; 322 | display: block; 323 | width: auto; 324 | margin-top: -22px; 325 | -webkit-box-shadow: rgba(255,255,255,.1) 0 1px 0; 326 | } 327 | #jqt ul li.arrow small.counter { 328 | margin-right: 15px; 329 | } 330 | /* @end */ 331 | /* @group Individual */ 332 | #jqt ul.individual { 333 | border: 0; 334 | background: none; 335 | clear: both; 336 | overflow: hidden; 337 | padding-bottom: 3px; 338 | -webkit-box-shadow: none; 339 | } 340 | #jqt ul.individual li { 341 | background: #4c4d4e; 342 | border: 1px solid #333; 343 | font-size: 14px; 344 | text-align: center; 345 | -webkit-border-radius: 8px; 346 | -webkit-box-sizing: border-box; 347 | width: 48%; 348 | float: left; 349 | display: block; 350 | padding: 11px 10px 14px 10px; 351 | -webkit-box-shadow: rgba(0,0,0,.2) 1px 1px 3px; 352 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4c4d4e), to(#404142)); 353 | } 354 | #jqt ul.individual li + li { 355 | float: right; 356 | } 357 | #jqt ul.individual li a { 358 | color: #fff; 359 | line-height: 16px; 360 | margin: -11px -10px -14px -10px; 361 | padding: 11px 10px 14px 10px; 362 | -webkit-border-radius: 8px; 363 | } 364 | /* @end */ 365 | /* @group Toggle */ 366 | #jqt .toggle { 367 | width: 94px; 368 | position: relative; 369 | height: 27px; 370 | display: block; 371 | overflow: hidden; 372 | float: right; 373 | } 374 | #jqt .toggle input[type="checkbox"]:checked { 375 | left: 0px; 376 | } 377 | #jqt .toggle input[type="checkbox"] { 378 | -webkit-appearance: textarea; 379 | -webkit-border-radius: 5px; 380 | -webkit-tap-highlight-color: rgba(0,0,0,0); 381 | -webkit-transition: left .15s; 382 | background-color: transparent; 383 | background: #fff url(img/toggleSwitch.png) 0 0 no-repeat; 384 | border: 0; 385 | height: 27px; 386 | left: -55px; 387 | margin: 0; 388 | overflow: hidden; 389 | position: absolute; 390 | top: 0; 391 | width: 149px; 392 | } 393 | /* @end */ 394 | /* @group Info */ 395 | #jqt .info { 396 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ccc), to(#aaa), color-stop(.6,#CCCCCC)); 397 | border-top: 1px solid rgba(255,255,255,.2); 398 | color: #444; 399 | font-size: 12px; 400 | font-weight: bold; 401 | line-height: 16px; 402 | padding: 15px; 403 | text-align: center; 404 | text-shadow: rgba(255,255,255,.8) 0 1px 0; 405 | } 406 | /* @end */ 407 | /* @group Edge to edge */ 408 | #jqt ul.edgetoedge { 409 | border-width: 1px 0; 410 | margin: 0; 411 | padding: 0; 412 | } 413 | #jqt ul.edgetoedge li { 414 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#1e1f21), to(#272729)); 415 | border-bottom: 2px solid #000; 416 | border-top: 1px solid #4a4b4d; 417 | font-size: 20px; 418 | margin-bottom: -1px; 419 | } 420 | #jqt ul.edgetoedge li.arrow { 421 | background-color: #404142 !important; 422 | background-image: url(img/chevron.png), -webkit-gradient(linear, 0% 0%, 0% 100%, from(#1e1f21), to(#272729)); 423 | background-position: right center; 424 | background-repeat: no-repeat; 425 | } 426 | #jqt ul.edgetoedge li.sep { 427 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(0,0,0,0)), to(rgba(0,0,0,.5))); 428 | border-bottom: 1px solid #111113; 429 | border-top: 1px solid #666; 430 | color: #3e9ac3; 431 | font-size: 16px; 432 | margin: 1px 0 0 0; 433 | padding: 2px 10px; 434 | text-shadow: #000 0 1px 0; 435 | } 436 | #jqt ul.edgetoedge li em { 437 | font-weight: normal; 438 | font-style: normal; 439 | } 440 | /* @end */ 441 | /* @group Plastic */ 442 | #jqt #plastic { 443 | background: #17181a; 444 | } 445 | #jqt ul.plastic { 446 | background: #17181a; 447 | color: #aaa; 448 | font: bold 18px "Helvetica Neue", Helvetica; 449 | margin: 0; 450 | padding: 0; 451 | border-width: 0 0 1px 0; 452 | } 453 | #jqt ul.plastic li { 454 | border-width: 1px 0; 455 | border-style: solid; 456 | border-top-color: #222; 457 | border-bottom-color: #000; 458 | color: #666; 459 | list-style-type: none; 460 | overflow: hidden; 461 | padding: 10px 10px 10px 10px; 462 | } 463 | #jqt ul.plastic li a.active.loading { 464 | background-image: url(img/loading.gif); 465 | background-position: 95% center; 466 | background-repeat: no-repeat; 467 | } 468 | #jqt ul.plastic li small { 469 | color: #888; 470 | font-size: 13px; 471 | font-weight: bold; 472 | line-height: 24px; 473 | text-transform: uppercase; 474 | } 475 | #jqt ul.plastic li:nth-child(odd) { 476 | background-color: #1c1c1f; 477 | } 478 | #jqt ul.plastic li.arrow { 479 | background-image: url(img/chevron.png); 480 | background-position: right center; 481 | background-repeat: no-repeat; 482 | } 483 | #jqt ul.plastic li.arrow a.active { 484 | background-image: url(img/chevron.png); 485 | background-position: right center; 486 | background-repeat: no-repeat; 487 | } 488 | #jqt ul.plastic li.forward { 489 | background-image: url(img/chevronCircle.png); 490 | background-position: right center; 491 | background-repeat: no-repeat; 492 | } 493 | #jqt ul.plastic li.forward a.active { 494 | background-image: url(img/chevronCircle.png); 495 | background-position: right center; 496 | background-repeat: no-repeat; 497 | } 498 | /* @group Metal */ 499 | #jqt ul.metal { 500 | border-bottom: 0; 501 | border-left: 0; 502 | border-right: 0; 503 | border-top: 0; 504 | margin: 0; 505 | } 506 | #jqt ul.metal li { 507 | background-image: none; 508 | border-top: 1px solid #fff; 509 | border-bottom: 1px solid #666; 510 | font-size: 26px; 511 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(238,238,238,1)), to(rgba(156,158,160,1))); 512 | } 513 | #jqt ul.metal li a { 514 | line-height: 26px; 515 | margin: 0; 516 | text-shadow: #fff 0 1px 0; 517 | padding: 13px 0; 518 | } 519 | #jqt ul.metal li a em { 520 | display: block; 521 | font-size: 14px; 522 | font-style: normal; 523 | color: #444; 524 | width: 50%; 525 | line-height: 14px; 526 | } 527 | #jqt ul.metal li a.active { 528 | color: rgb(0,0,0); 529 | } 530 | #jqt ul.metal li small { 531 | float: right; 532 | position: relative; 533 | margin-top: 10px; 534 | font-weight: bold; 535 | } 536 | #jqt ul.metal li.arrow { 537 | background-image: url(img/chevron.png); 538 | background-position: right center; 539 | background-repeat: no-repeat; 540 | background-image: url(img/chevron.png), -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(238,238,238,1)), to(rgba(156,158,160,1))); 541 | background-repeat: no-repeat; 542 | background-position: right center; 543 | } 544 | #jqt ul.metal li.arrow a small { 545 | padding-right: 15px; 546 | line-height: 17px; 547 | } 548 | /* @end */ 549 | input[type='submit'] { 550 | -webkit-border-radius: 4px; 551 | background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(238,238,238,1)), to(rgba(156,158,160,1))); 552 | border: 1px outset black; 553 | display: block; 554 | font-size: inherit; 555 | font-weight: inherit; 556 | padding: 10px; 557 | } 558 | -------------------------------------------------------------------------------- /themes/scss/vanilla.scss: -------------------------------------------------------------------------------- 1 | $base-color: #eee; 2 | $highlight-color: #f6f6f6; 3 | $base-button-gradient: flat; 4 | $include-highlights: false; 5 | $include-back-arrow: false; 6 | // $default-border-radius: 0; 7 | $theme: vanilla; 8 | 9 | @import 'include/core'; 10 | --------------------------------------------------------------------------------