Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

initial commit

  • Loading branch information...
commit eb05ab79dc4cdb61ac0d7e6b408481907ab65736 0 parents
Brandon Aaron authored

Showing 37 changed files with 23,402 additions and 0 deletions. Show diff stats Hide diff stats

  1. +20 0 LICENSE.txt
  2. +5 0 README.markdown
  3. BIN  _css/.DS_Store
  4. +59 0 _css/app.css
  5. +373 0 _css/jqtouch.css
  6. +200 0 _js/apidocs.js
  7. +55 0 _js/app.js
  8. +624 0 _js/jqtouch.js
  9. +97 0 _js/jqtouch.offline.js
  10. +6,078 0 _js/jquery.js
  11. +22 0 _js/jquery.template.js
  12. +341 0 _js/scrollable.js
  13. BIN  _themes/jqt/img/activeButton.png
  14. BIN  _themes/jqt/img/back_button.png
  15. BIN  _themes/jqt/img/back_button_clicked.png
  16. BIN  _themes/jqt/img/blueButton.png
  17. BIN  _themes/jqt/img/button.png
  18. BIN  _themes/jqt/img/button_clicked.png
  19. BIN  _themes/jqt/img/chevron.png
  20. BIN  _themes/jqt/img/chevron_circle.png
  21. BIN  _themes/jqt/img/grayButton.png
  22. BIN  _themes/jqt/img/greenButton.png
  23. BIN  _themes/jqt/img/loading.gif
  24. BIN  _themes/jqt/img/on_off.png
  25. BIN  _themes/jqt/img/redButton.png
  26. BIN  _themes/jqt/img/rowhead.png
  27. BIN  _themes/jqt/img/toggle.png
  28. BIN  _themes/jqt/img/toggleOn.png
  29. BIN  _themes/jqt/img/toolbar.png
  30. BIN  _themes/jqt/img/whiteButton.png
  31. +561 0 _themes/jqt/theme.css
  32. +14,763 0 api.xml
  33. +27 0 cache.manifest
  34. BIN  icon.png
  35. +134 0 index.html
  36. +43 0 sample.htaccess
  37. BIN  startup.png
20 LICENSE.txt
... ... @@ -0,0 +1,20 @@
  1 +Copyright 2010, Brandon Aaron (http://brandonaaron.net/)
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining
  4 +a copy of this software and associated documentation files (the
  5 +"Software"), to deal in the Software without restriction, including
  6 +without limitation the rights to use, copy, modify, merge, publish,
  7 +distribute, sublicense, and/or sell copies of the Software, and to
  8 +permit persons to whom the Software is furnished to do so, subject to
  9 +the following conditions:
  10 +
  11 +The above copyright notice and this permission notice shall be
  12 +included in all copies or substantial portions of the Software.
  13 +
  14 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5 README.markdown
Source Rendered
... ... @@ -0,0 +1,5 @@
  1 +A jQuery API browser for Mobile Safari.
  2 +
  3 +## License
  4 +
  5 +This work is Copyright 2010 [Brandon Aaron](http://brandonaaron.net/) and licensed under the MIT license (LICENSE.txt).
BIN  _css/.DS_Store
Binary file not shown
59 _css/app.css
... ... @@ -0,0 +1,59 @@
  1 +@import "jqtouch.css";
  2 +@import "../_themes/jqt/theme.css";
  3 +
  4 +/* hide fullscreen info when fullscreen */
  5 +#jqt.fullscreen #home .info { display: none; }
  6 +
  7 +
  8 +/* special styles for an entry to include a description */
  9 +#jqt li.entry a { font-size: 14px; color: #ccc; font-weight: normal; }
  10 + #jqt li.entry a span.name { font-size: 18px; color: #fff; font-weight: bold; }
  11 +
  12 +
  13 +/* content heavy styles */
  14 +#jqt .info.rounded {
  15 + margin: 15px 10px 17px 10px;
  16 + -webkit-border-radius: 8px;
  17 + text-align: left;
  18 + background: #ddd;
  19 + font-size: 13px;
  20 + line-height: 1.4em;
  21 + text-shadow: none;
  22 + color: #333;
  23 + padding: 15px;
  24 + border-top: none;
  25 + font-weight: normal;
  26 +}
  27 + #jqt .info.rounded h2 { margin: 0 0 10px; }
  28 + #jqt .info.rounded p { margin: 0 0 10px; padding: 0; }
  29 + #jqt .info.rounded pre { margin: 0 0 10px; font-size: 12px; word-wrap: break-word; white-space: pre-wrap; }
  30 + #jqt .info.rounded ul,
  31 + #jqt .info.rounded ol { margin: 10px; padding: 0; background: none; color: #333; font-size: 13px; font-weight: normal; border: 0; }
  32 + #jqt .info.rounded ul li,
  33 + #jqt .info.rounded ol li { padding: 0 0 5px 0; background: none; color: #333; font-size: 13px; font-weight: normal; border: 0; }
  34 +
  35 + dl.signature { margin-bottom: 17px; }
  36 + dl.signature dt { font-weight: bold; font-size: 14px; border-bottom: 1px solid #333; }
  37 +
  38 +
  39 +/* styles necessary for Scrollable */
  40 +.toolbar { z-index: 2; }
  41 +.scrollable { height: 372px; position: relative; padding-top: 1px; z-index: 1; -webkit-transform-style: preserve-3d; -webkit-transform: translate3d(0, 0, 0); -webkit-transition-property: -webkit-transform; -webkit-transition-timing-function: cubic-bezier(0,0,0,1); }
  42 +#jqt.landscape .scrollable { height: 227px; }
  43 +#jqt.fullscreen.black-translucent .scrollable { height: 432px; }
  44 +#jqt.fullscreen.landscape .scrollable { height: 258px; }
  45 +
  46 +/* force correct height for .page divs */
  47 +body #jqt .page {
  48 + min-height: 420px !important;
  49 + overflow: hidden;
  50 +}
  51 +body #jqt.fullscreen .page {
  52 + min-height: 460px !important;
  53 +}
  54 +body #jqt.fullscreen.black-translucent .page {
  55 + min-height: 480px !important;
  56 +}
  57 +body #jqt.landscape .page {
  58 + min-height: 320px !important;
  59 +}
373 _css/jqtouch.css
... ... @@ -0,0 +1,373 @@
  1 +* {
  2 + margin: 0;
  3 + padding: 0;
  4 +}
  5 +a {
  6 + -webkit-tap-highlight-color: rgba(0,0,0,0);
  7 +}
  8 +
  9 +div#jqt {
  10 + /*overflow-x: hidden;*/
  11 + -webkit-user-select: none;
  12 + -webkit-text-size-adjust: none;
  13 + font-family: "Helvetica Neue", Helvetica;
  14 + -webkit-perspective: 800;
  15 + -webkit-transform-style: preserve-3d;
  16 +}
  17 +#jqt .selectable, #jqt input, #jqt textarea {
  18 + -webkit-user-select: auto;
  19 +}
  20 +div#jqt > * {
  21 + -webkit-backface-visibility: hidden;
  22 + -webkit-box-sizing: border-box;
  23 + display: none;
  24 + position: absolute;
  25 + left: 0;
  26 + width: 100%;
  27 + -webkit-transform: translate3d(0,0,0) rotate(0) scale(1);
  28 + min-height: 420px !important;
  29 +}
  30 +#jqt.fullscreen > * {
  31 + min-height: 460px !important;
  32 +}
  33 +#jqt.fullscreen.black-translucent > * {
  34 + min-height: 480px !important;
  35 +}
  36 +#jqt.landscape > * {
  37 + min-height: 320px !important;
  38 +}
  39 +div#jqt > .current {
  40 + display: block !important;
  41 +}
  42 +
  43 +#jqt .in, #jqt .out {
  44 + -webkit-animation-timing-function: ease-in-out;
  45 + -webkit-animation-duration: 350ms;
  46 +}
  47 +
  48 +#jqt .slide.in {
  49 + -webkit-animation-name: slideinfromright;
  50 +}
  51 +
  52 +#jqt .slide.out {
  53 + -webkit-animation-name: slideouttoleft;
  54 +}
  55 +
  56 +#jqt .slide.in.reverse {
  57 + -webkit-animation-name: slideinfromleft;
  58 +}
  59 +
  60 +#jqt .slide.out.reverse {
  61 + -webkit-animation-name: slideouttoright;
  62 +}
  63 +
  64 +@-webkit-keyframes slideinfromright {
  65 + from { -webkit-transform: translateX(100%); }
  66 + to { -webkit-transform: translateX(0); }
  67 +}
  68 +
  69 +@-webkit-keyframes slideinfromleft {
  70 + from { -webkit-transform: translateX(-100%); }
  71 + to { -webkit-transform: translateX(0); }
  72 +}
  73 +
  74 +@-webkit-keyframes slideouttoleft {
  75 + from { -webkit-transform: translateX(0); }
  76 + to { -webkit-transform: translateX(-100%); }
  77 +}
  78 +
  79 +@-webkit-keyframes slideouttoright {
  80 + from { -webkit-transform: translateX(0); }
  81 + to { -webkit-transform: translateX(100%); }
  82 +}
  83 +
  84 +@-webkit-keyframes fadein {
  85 + from { opacity: 0; }
  86 + to { opacity: 1; }
  87 +}
  88 +
  89 +@-webkit-keyframes fadeout {
  90 + from { opacity: 1; }
  91 + to { opacity: 0; }
  92 +}
  93 +
  94 +#jqt .fade.in {
  95 + z-index: 10;
  96 + -webkit-animation-name: fadein;
  97 +}
  98 +#jqt .fade.out {
  99 + z-index: 0;
  100 +}
  101 +
  102 +#jqt .dissolve.in {
  103 + -webkit-animation-name: fadein;
  104 +}
  105 +
  106 +#jqt .dissolve.out {
  107 + -webkit-animation-name: fadeout;
  108 +}
  109 +
  110 +
  111 +
  112 +#jqt .flip {
  113 + -webkit-animation-duration: .65s;
  114 +}
  115 +
  116 +#jqt .flip.in {
  117 + -webkit-animation-name: flipinfromleft;
  118 +}
  119 +
  120 +#jqt .flip.out {
  121 + -webkit-animation-name: flipouttoleft;
  122 +}
  123 +
  124 +/* Shake it all about */
  125 +
  126 +#jqt .flip.in.reverse {
  127 + -webkit-animation-name: flipinfromright;
  128 +}
  129 +
  130 +#jqt .flip.out.reverse {
  131 + -webkit-animation-name: flipouttoright;
  132 +}
  133 +
  134 +@-webkit-keyframes flipinfromright {
  135 + from { -webkit-transform: rotateY(-180deg) scale(.8); }
  136 + to { -webkit-transform: rotateY(0) scale(1); }
  137 +}
  138 +
  139 +@-webkit-keyframes flipinfromleft {
  140 + from { -webkit-transform: rotateY(180deg) scale(.8); }
  141 + to { -webkit-transform: rotateY(0) scale(1); }
  142 +}
  143 +
  144 +@-webkit-keyframes flipouttoleft {
  145 + from { -webkit-transform: rotateY(0) scale(1); }
  146 + to { -webkit-transform: rotateY(-180deg) scale(.8); }
  147 +}
  148 +
  149 +@-webkit-keyframes flipouttoright {
  150 + from { -webkit-transform: rotateY(0) scale(1); }
  151 + to { -webkit-transform: rotateY(180deg) scale(.8); }
  152 +}
  153 +
  154 +#jqt .slideup.in {
  155 + -webkit-animation-name: slideup;
  156 + z-index: 10;
  157 +}
  158 +
  159 +#jqt .slideup.out {
  160 + -webkit-animation-name: dontmove;
  161 + z-index: 0;
  162 +}
  163 +
  164 +#jqt .slideup.out.reverse {
  165 + z-index: 10;
  166 + -webkit-animation-name: slidedown;
  167 +}
  168 +
  169 +#jqt .slideup.in.reverse {
  170 + z-index: 0;
  171 + -webkit-animation-name: dontmove;
  172 +}
  173 +
  174 +
  175 +@-webkit-keyframes slideup {
  176 + from { -webkit-transform: translateY(100%); }
  177 + to { -webkit-transform: translateY(0); }
  178 +}
  179 +
  180 +@-webkit-keyframes slidedown {
  181 + from { -webkit-transform: translateY(0); }
  182 + to { -webkit-transform: translateY(100%); }
  183 +}
  184 +
  185 +
  186 +
  187 +/* Hackish, but reliable. */
  188 +
  189 +@-webkit-keyframes dontmove {
  190 + from { opacity: 1; }
  191 + to { opacity: 1; }
  192 +}
  193 +
  194 +#jqt .swap {
  195 + -webkit-transform: perspective(800);
  196 + -webkit-animation-duration: .7s;
  197 +}
  198 +#jqt .swap.out {
  199 + -webkit-animation-name: swapouttoleft;
  200 +}
  201 +#jqt .swap.in {
  202 + -webkit-animation-name: swapinfromright;
  203 +}
  204 +#jqt .swap.out.reverse {
  205 + -webkit-animation-name: swapouttoright;
  206 +}
  207 +#jqt .swap.in.reverse {
  208 + -webkit-animation-name: swapinfromleft;
  209 +}
  210 +
  211 +
  212 +@-webkit-keyframes swapouttoright {
  213 + 0% {
  214 + -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg);
  215 + -webkit-animation-timing-function: ease-in-out;
  216 + }
  217 + 50% {
  218 + -webkit-transform: translate3d(-180px, 0px, -400px) rotateY(20deg);
  219 + -webkit-animation-timing-function: ease-in;
  220 + }
  221 + 100% {
  222 + -webkit-transform: translate3d(0px, 0px, -800px) rotateY(70deg);
  223 + }
  224 +}
  225 +
  226 +@-webkit-keyframes swapouttoleft {
  227 + 0% {
  228 + -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg);
  229 + -webkit-animation-timing-function: ease-in-out;
  230 + }
  231 + 50% {
  232 + -webkit-transform: translate3d(180px, 0px, -400px) rotateY(-20deg);
  233 + -webkit-animation-timing-function: ease-in;
  234 + }
  235 + 100% {
  236 + -webkit-transform: translate3d(0px, 0px, -800px) rotateY(-70deg);
  237 + }
  238 +}
  239 +
  240 +@-webkit-keyframes swapinfromright {
  241 + 0% {
  242 + -webkit-transform: translate3d(0px, 0px, -800px) rotateY(70deg);
  243 + -webkit-animation-timing-function: ease-out;
  244 + }
  245 + 50% {
  246 + -webkit-transform: translate3d(-180px, 0px, -400px) rotateY(20deg);
  247 + -webkit-animation-timing-function: ease-in-out;
  248 + }
  249 + 100% {
  250 + -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg);
  251 + }
  252 +}
  253 +
  254 +@-webkit-keyframes swapinfromleft {
  255 + 0% {
  256 + -webkit-transform: translate3d(0px, 0px, -800px) rotateY(-70deg);
  257 + -webkit-animation-timing-function: ease-out;
  258 + }
  259 + 50% {
  260 + -webkit-transform: translate3d(180px, 0px, -400px) rotateY(-20deg);
  261 + -webkit-animation-timing-function: ease-in-out;
  262 + }
  263 + 100% {
  264 + -webkit-transform: translate3d(0px, 0px, 0px) rotateY(0deg);
  265 + }
  266 +}
  267 +
  268 +#jqt .cube {
  269 + -webkit-animation-duration: .55s;
  270 +}
  271 +
  272 +#jqt .cube.in {
  273 + -webkit-animation-name: cubeinfromright;
  274 + -webkit-transform-origin: 0% 50%;
  275 +}
  276 +#jqt .cube.out {
  277 + -webkit-animation-name: cubeouttoleft;
  278 + -webkit-transform-origin: 100% 50%;
  279 +}
  280 +#jqt .cube.in.reverse {
  281 + -webkit-animation-name: cubeinfromleft;
  282 + -webkit-transform-origin: 100% 50%;
  283 +}
  284 +#jqt .cube.out.reverse {
  285 + -webkit-animation-name: cubeouttoright;
  286 + -webkit-transform-origin: 0% 50%;
  287 +
  288 +}
  289 +
  290 +@-webkit-keyframes cubeinfromleft {
  291 + from {
  292 + -webkit-transform: rotateY(-90deg) translateZ(320px);
  293 + opacity: .5;
  294 + }
  295 + to {
  296 + -webkit-transform: rotateY(0deg) translateZ(0);
  297 + opacity: 1;
  298 + }
  299 +}
  300 +@-webkit-keyframes cubeouttoright {
  301 + from {
  302 + -webkit-transform: rotateY(0deg) translateX(0);
  303 + opacity: 1;
  304 + }
  305 + to {
  306 + -webkit-transform: rotateY(90deg) translateZ(320px);
  307 + opacity: .5;
  308 + }
  309 +}
  310 +@-webkit-keyframes cubeinfromright {
  311 + from {
  312 + -webkit-transform: rotateY(90deg) translateZ(320px);
  313 + opacity: .5;
  314 + }
  315 + to {
  316 + -webkit-transform: rotateY(0deg) translateZ(0);
  317 + opacity: 1;
  318 + }
  319 +}
  320 +@-webkit-keyframes cubeouttoleft {
  321 + from {
  322 + -webkit-transform: rotateY(0deg) translateZ(0);
  323 + opacity: 1;
  324 + }
  325 + to {
  326 + -webkit-transform: rotateY(-90deg) translateZ(320px);
  327 + opacity: .5;
  328 + }
  329 +}
  330 +
  331 +
  332 +
  333 +
  334 +#jqt .pop {
  335 + -webkit-transform-origin: 50% 50%;
  336 +}
  337 +
  338 +#jqt .pop.in {
  339 + -webkit-animation-name: popin;
  340 + z-index: 10;
  341 +}
  342 +
  343 +#jqt .pop.out.reverse {
  344 + -webkit-animation-name: popout;
  345 + z-index: 10;
  346 +}
  347 +
  348 +#jqt .pop.in.reverse {
  349 + z-index: 0;
  350 + -webkit-animation-name: dontmove;
  351 +}
  352 +
  353 +@-webkit-keyframes popin {
  354 + from {
  355 + -webkit-transform: scale(.2);
  356 + opacity: 0;
  357 + }
  358 + to {
  359 + -webkit-transform: scale(1);
  360 + opacity: 1;
  361 + }
  362 +}
  363 +
  364 +@-webkit-keyframes popout {
  365 + from {
  366 + -webkit-transform: scale(1);
  367 + opacity: 1;
  368 + }
  369 + to {
  370 + -webkit-transform: scale(.2);
  371 + opacity: 0;
  372 + }
  373 +}
200 _js/apidocs.js
... ... @@ -0,0 +1,200 @@
  1 +/*!
  2 + * Copyright 2010, Brandon Aaron (http://brandonaaron.net/)
  3 + * Licensed under the MIT license: LICENSE.txt.
  4 + */
  5 +
  6 +function APIDocs(settings) {
  7 + this.url = '/api.xml';
  8 +}
  9 +
  10 +APIDocs.prototype = {
  11 + setup: function() {
  12 + this.categories = this.select('api/categories/category');
  13 + this.selectors = this.select('api/entries/entry[@type="selector"]');
  14 + this.versions = this.select('api/categories/category[@name="Version"]/category');
  15 + this.entries = this.select('api/entries/entry');
  16 +
  17 + this.templates = {
  18 + categories: $('#tpl-categories').template(),
  19 + entries: $('#tpl-entries').template(),
  20 + entry: $('#tpl-entry').template()
  21 + };
  22 + },
  23 +
  24 + select: function(selector, parent) {
  25 + return this._toArray(document.evaluate(selector, parent || this.xml, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null));
  26 + },
  27 +
  28 + getXML: function(obj) {
  29 + $.ajax({
  30 + url: this.url,
  31 + context: this,
  32 + dataType: 'xml',
  33 + beforeSend: function(xhr) {
  34 + xhr.overrideMimeType('text/xml');
  35 + },
  36 + success: function(data, status, xhr) {
  37 + this.xml = xhr.responseXML;
  38 + this.setup();
  39 + obj.success.call(obj.context || this, this);
  40 + },
  41 + error: function(xhr, status, error) {
  42 + this.error(error);
  43 + obj.error.call(obj.context || this, this);
  44 + },
  45 + });
  46 + },
  47 +
  48 + showCategory: function(name) {
  49 + var id = name && 'category'+this._sanitizeName(name) || 'categories',
  50 + $category = $('#'+id);
  51 + if (!$category.length) {
  52 + var html = this._generateCategory(name, id);
  53 + $(html).appendTo('#jqt').find('.scrollable').scrollable();
  54 + }
  55 + jqtouch.goTo('#'+id, 'slide');
  56 + },
  57 +
  58 + showEntry: function(name, index) {
  59 + $('#entry').remove();
  60 + var html = this._generateEntry(name, index);
  61 + $(html).appendTo('#jqt').find('.scrollable').scrollable();
  62 + jqtouch.goTo('#entry', 'slide');
  63 + },
  64 +
  65 + _generateCategory: function(name, id) {
  66 + var subcategories = name ?
  67 + this.select('/api/categories/category[@name="'+name+'"]/category') :
  68 + this.select('/api/categories/category'),
  69 + data = {
  70 + id: id,
  71 + title: name || 'Categories'
  72 + };
  73 + if (subcategories.length) {
  74 + data.categories = [];
  75 + subcategories.forEach(function(category) {
  76 + var name = category.getAttribute('name');
  77 + data.categories.push({
  78 + name: name
  79 + });
  80 + });
  81 + this._sortByName(data.categories);
  82 + return this.templates.categories(data, true);
  83 + } else {
  84 + return this._generateEntriesByCategory(name, id);
  85 + }
  86 + },
  87 +
  88 + _generateEntriesByCategory: function(name, id) {
  89 + var entries = this.select('/api/entries/entry/category[@name="'+name+'"]/..'),
  90 + data = {
  91 + id: id,
  92 + title: name,
  93 + entries: []
  94 + };
  95 + entries.forEach(function(entry, index) {
  96 + var type = entry.getAttribute('type'),
  97 + name = entry.getAttribute('name'), displayName = name;
  98 + if (type === 'method') displayName = name + '()';
  99 + if (type === 'selector') displayName = this._nodeValue(entry, 'sample');
  100 + data.entries.push({
  101 + index: this.entries.indexOf(entry),
  102 + type: type,
  103 + name: name,
  104 + displayName: displayName,
  105 + desc: this._sanitizeDescription(this._nodeValue(entry, 'desc', true))
  106 + });
  107 + }, this);
  108 + this._sortByName(data.entries)
  109 + return this.templates.entries(data, true);
  110 + },
  111 +
  112 + _generateEntry: function(name, index) {
  113 + var entry = this.entries[index],
  114 + type = entry.getAttribute('type'),
  115 + name = entry.getAttribute('name'),
  116 + displayName = type === 'selector' ? this._nodeValue(entry, 'sample') : type === 'method' ? name + '()' : name;
  117 + signatures = [].slice.call(entry.getElementsByTagName('signature')),
  118 + examples = [].slice.call(entry.getElementsByTagName('examples')),
  119 + data = {
  120 + id: 'entry',
  121 + title: displayName,
  122 + name: name,
  123 + displayName: displayName,
  124 + desc: this._nodeValue(entry, 'desc', true),
  125 + longdesc: this._nodeValue(entry, 'longdesc', true),
  126 + returns: entry.getAttribute('return'),
  127 + signatures: [],
  128 + examples: []
  129 + };
  130 +
  131 + if (type === 'method') {
  132 + signatures.forEach(function(signature, index) {
  133 + var sig = {
  134 + title: name + '(',
  135 + added: this._nodeValue(signature, 'added', true),
  136 + arguments: []
  137 + };
  138 + var arguments = [].slice.call(signature.getElementsByTagName('argument'));
  139 + arguments.forEach(function(argument, index) {
  140 + var sigName = argument.getAttribute('name'),
  141 + optional = !!argument.getAttribute('optional');
  142 + sig.arguments.push({
  143 + name: sigName,
  144 + type: argument.getAttribute('type'),
  145 + optional: optional,
  146 + desc: this._nodeValue(argument, 'desc', true)
  147 + });
  148 + if (optional) sig.title += '[';
  149 + sig.title += sigName;
  150 + if (optional) sig.title += ']';
  151 + sig.title += ', ';
  152 + }, this);
  153 + sig.title = sig.title.replace(/, $/, '') + ')';
  154 + data.signatures.push(sig);
  155 + }, this);
  156 + }
  157 + return this.templates.entry(data, true);
  158 + },
  159 +
  160 + _sortByName: function(array) {
  161 + return array.sort(function(a, b) {
  162 + a = a.name.replace(/^jQuery\./, '');
  163 + b = b.name.replace(/^jQuery\./, '');
  164 + if (a < b)
  165 + return -1;
  166 + if (a > b)
  167 + return 1;
  168 + return 0;
  169 + });
  170 + },
  171 +
  172 + _toArray: function(xpathresult) {
  173 + var nodes = [], node, index = 0;
  174 + while ((node = xpathresult.snapshotItem(index++)))
  175 + nodes.push(node);
  176 + return nodes;
  177 + },
  178 +
  179 + _nodeValue: function(parent, name, xpath) {
  180 + if (!parent) { return ''; }
  181 + var node = xpath ? this.select(name, parent)[0] : parent.getElementsByTagName(name)[0];
  182 + return node && node.firstChild && node.firstChild.nodeValue || '';
  183 + },
  184 +
  185 + _sanitizeName: function(name) {
  186 + return (name || '').replace(/\s+/g, '').replace(',', '').replace(/\./g, '');
  187 + },
  188 +
  189 + _sanitizeDescription: function(name) {
  190 + return (name || '').replace(/<\/?[^>]+(>|$)/g, "");
  191 + },
  192 +
  193 + error: function(msg) {
  194 + console.error(msg);
  195 + },
  196 +
  197 + notCompatible: function() {
  198 + return !('evaluate' in document) && !('localStorage' in window);
  199 + }
  200 +};
55 _js/app.js
... ... @@ -0,0 +1,55 @@
  1 +/*!
  2 + * Copyright 2010, Brandon Aaron (http://brandonaaron.net/)
  3 + * Licensed under the MIT license: LICENSE.txt.
  4 + */
  5 +
  6 +var jqtouch = new $.jQTouch({
  7 + icon: 'icon.png',
  8 + addGlossToIcon: false,
  9 + startupScreen: 'startup.png',
  10 + statusBar: 'black',
  11 + slideSelector: '#jqt .page ul a'
  12 +});
  13 +
  14 +$.fn.scrollable = function() {
  15 + return this.each(function() {
  16 + $.data(this, 'scrollable', new Scrollable(this));
  17 + });
  18 +};
  19 +
  20 +$(function(){
  21 + if (!('evaluate' in document) && !('localStorage' in window)) {
  22 + $('div.info').text('Sorry, your browser does not have the capabilities to run this web app.');
  23 + return;
  24 + }
  25 +
  26 + // jqtouch.autoCheckForUpdates();
  27 +
  28 + $('a').live('tap click', function(event) {
  29 + var $this = $(this);
  30 + if ($this.is('.entry')) {
  31 + var name = $this.attr('data-name'),
  32 + index = $this.attr('data-index');
  33 + apiDocs.showEntry(name, index);
  34 + return false;
  35 + }
  36 + if ($this.is('.category')) {
  37 + var name = $this.attr('data-name');
  38 + apiDocs.showCategory(name);
  39 + return false;
  40 + }
  41 + });
  42 +
  43 + $('#jqt').find('.scrollable').scrollable();
  44 +
  45 + window.apiDocs = new APIDocs();
  46 + apiDocs.getXML({
  47 + success: function() {
  48 + jqtouch.goTo('#home', 'fade');
  49 + },
  50 + error: function() {
  51 + jqtouch.goTo('#error', 'fade');
  52 + }
  53 + });
  54 +});
  55 +
624 _js/jqtouch.js
... ... @@ -0,0 +1,624 @@
  1 +/*
  2 +
  3 + _/ _/_/ _/_/_/_/_/ _/
  4 + _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/
  5 + _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/
  6 + _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/
  7 + _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/
  8 + _/
  9 + _/
  10 +
  11 + Created by David Kaneda <http://www.davidkaneda.com>
  12 + Documentation and issue tracking on Google Code <http://code.google.com/p/jqtouch/>
  13 +
  14 + Special thanks to Jonathan Stark <http://jonathanstark.com/>
  15 + and pinch/zoom <http://www.pinchzoom.com/>
  16 +
  17 + (c) 2009 by jQTouch project members.
  18 + See LICENSE.txt for license.
  19 +
  20 + $Revision: 133 $
  21 + $Date: 2010-01-15 15:08:54 -0600 (Fri, 15 Jan 2010) $
  22 + $LastChangedBy: RBoulanouar $
  23 +
  24 +*/
  25 +
  26 +(function($) {
  27 + $.jQTouch = function(options) {
  28 +
  29 + // Set support values
  30 + $.support.WebKitCSSMatrix = (typeof WebKitCSSMatrix == "object");
  31 + $.support.touch = (typeof Touch == "object");
  32 + $.support.WebKitAnimationEvent = (typeof WebKitTransitionEvent == "object");
  33 +
  34 + // Initialize internal variables
  35 + var $body,
  36 + $head=$('head'),
  37 + hist=[],
  38 + newPageCount=0,
  39 + jQTSettings={},
  40 + hashCheckInterval,
  41 + currentPage,
  42 + orientation,
  43 + isMobileWebKit = RegExp(" Mobile/").test(navigator.userAgent),
  44 + tapReady=true,
  45 + lastAnimationTime=0,
  46 + touchSelectors=[],
  47 + publicObj={},
  48 + extensions=$.jQTouch.prototype.extensions,
  49 + defaultAnimations=['slide','flip','slideup','swap','cube','pop','dissolve','fade','back'],
  50 + animations=[],
  51 + hairextensions='';
  52 + // Get the party started
  53 + init(options);
  54 +
  55 + function init(options) {
  56 +
  57 + var defaults = {
  58 + addGlossToIcon: true,
  59 + backSelector: '.back, .cancel, .goback',
  60 + cacheGetRequests: true,
  61 + cubeSelector: '.cube',
  62 + dissolveSelector: '.dissolve',
  63 + fadeSelector: '.fade',
  64 + fixedViewport: true,
  65 + flipSelector: '.flip',
  66 + formSelector: 'form',
  67 + fullScreen: true,
  68 + fullScreenClass: 'fullscreen',
  69 + icon: null,
  70 + touchSelector: 'a, .touch',
  71 + popSelector: '.pop',
  72 + preloadImages: false,
  73 + slideSelector: '#jqt > * > ul li a',
  74 + slideupSelector: '.slideup',
  75 + startupScreen: null,
  76 + statusBar: 'default', // other options: black-translucent, black
  77 + submitSelector: '.submit',
  78 + swapSelector: '.swap',
  79 + useAnimations: true,
  80 + useFastTouch: true // Experimental.
  81 + };
  82 + jQTSettings = $.extend({}, defaults, options);
  83 +
  84 + // Preload images
  85 + if (jQTSettings.preloadImages) {
  86 + for (var i = jQTSettings.preloadImages.length - 1; i >= 0; i--) {
  87 + (new Image()).src = jQTSettings.preloadImages[i];
  88 + };
  89 + }
  90 + // Set icon
  91 + if (jQTSettings.icon) {
  92 + var precomposed = (jQTSettings.addGlossToIcon) ? '' : '-precomposed';
  93 + hairextensions += '<link rel="apple-touch-icon' + precomposed + '" href="' + jQTSettings.icon + '" />';
  94 + }
  95 + // Set startup screen
  96 + if (jQTSettings.startupScreen) {
  97 + hairextensions += '<link rel="apple-touch-startup-image" href="' + jQTSettings.startupScreen + '" />';
  98 + }
  99 + // Set viewport
  100 + if (jQTSettings.fixedViewport) {
  101 + hairextensions += '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"/>';
  102 + }
  103 + // Set full-screen
  104 + if (jQTSettings.fullScreen) {
  105 + hairextensions += '<meta name="apple-mobile-web-app-capable" content="yes" />';
  106 + if (jQTSettings.statusBar) {
  107 + hairextensions += '<meta name="apple-mobile-web-app-status-bar-style" content="' + jQTSettings.statusBar + '" />';
  108 + }
  109 + }
  110 + if (hairextensions) {
  111 + $head.prepend(hairextensions);
  112 + }
  113 + }
  114 +
  115 + // PUBLIC FUNCTIONS
  116 + function goBack(to) {
  117 + // Init the param
  118 + var numberOfPages = Math.min(parseInt(to || 1, 10), hist.length-1),
  119 + curPage = hist[0];
  120 +
  121 + // Search through the history for an ID
  122 + if(isNaN(numberOfPages) && typeof(to) === "string" && to != '#' ) {
  123 + for( var i=1, length=hist.length; i < length; i++ ) {
  124 + if( '#' + hist[i].id === to ) {
  125 + numberOfPages = i;
  126 + break;
  127 + }
  128 + }
  129 + }
  130 +
  131 + // If still nothing, assume one
  132 + if(isNaN(numberOfPages) || numberOfPages < 1) {
  133 + numberOfPages = 1;
  134 + };
  135 +
  136 + if (hist.length > 1) {
  137 + // Remove all pages in front of the target page
  138 + hist.splice(0, numberOfPages);
  139 + animatePages(curPage.page, hist[0].page, curPage.animation, curPage.reverse === false);
  140 + } else {
  141 + location.hash = '#' + curPage.id;
  142 + }
  143 +
  144 + return publicObj;
  145 + }
  146 + function goTo(toPage, animation, reverse) {
  147 + var fromPage = hist[0].page;
  148 +
  149 + if (typeof(toPage) === 'string') {
  150 + toPage = $(toPage);
  151 + }
  152 + if (typeof(animation) === 'string') {
  153 + for (var i = animations.length - 1; i >= 0; i--) {
  154 + if (animations[i].name === animation) {
  155 + animation = animations[i];
  156 + break;
  157 + }
  158 + }
  159 + }
  160 + if (animatePages(fromPage, toPage, animation, reverse)) {
  161 + addPageToHistory(toPage, animation, reverse);
  162 + return publicObj;
  163 + } else {
  164 + console.error('Could not animate pages.');
  165 + return false;
  166 + }
  167 + }
  168 + function getOrientation() {
  169 + return orientation;
  170 + }
  171 +
  172 + // PRIVATE FUNCTIONS
  173 + function liveTap(e){
  174 +
  175 + // Grab the clicked element
  176 + var $el = $(e.target);
  177 +
  178 + if ($el.attr('nodeName')!=='A' && $el.attr('nodeName')!=='AREA') {
  179 + $el = $el.closest('a, area');
  180 + }
  181 +
  182 + var target = $el.attr('target'),
  183 + hash = $el.attr('hash'),
  184 + animation=null;
  185 +
  186 + if (tapReady == false || !$el.length) {
  187 + console.warn('Not able to tap element.');
  188 + return false;
  189 + }
  190 +
  191 + if ($el.isExternalLink()) {
  192 + $el.removeClass('active');
  193 + return true;
  194 + }
  195 +
  196 + // Figure out the animation to use
  197 + for (var i = animations.length - 1; i >= 0; i--) {
  198 + if ($el.is(animations[i].selector)) {
  199 + animation = animations[i];
  200 + break;
  201 + }
  202 + };
  203 +
  204 + // User clicked an internal link, fullscreen mode
  205 + if (target == '_webapp') {
  206 + window.location = $el.attr('href');
  207 + }
  208 + // User clicked a back button
  209 + else if ($el.is(jQTSettings.backSelector)) {
  210 + goBack(hash);
  211 + }
  212 + // Allow tap on item with no href
  213 + else if ($el.attr('href') == '#') {
  214 + $el.unselect();
  215 + return true;
  216 + }
  217 + // Branch on internal or external href
  218 + else if (hash && hash!='#') {
  219 + $el.addClass('active');
  220 + goTo($(hash).data('referrer', $el), animation, $(this).hasClass('reverse'));
  221 + } else {
  222 + $el.addClass('loading active');
  223 + showPageByHref($el.attr('href'), {
  224 + animation: animation,
  225 + callback: function() {
  226 + $el.removeClass('loading'); setTimeout($.fn.unselect, 250, $el);
  227 + },
  228 + $referrer: $el
  229 + });
  230 + }
  231 + return false;
  232 + }
  233 + function addPageToHistory(page, animation, reverse) {
  234 + // Grab some info
  235 + var pageId = page.attr('id');
  236 + // Prepend info to page history
  237 + hist.unshift({
  238 + page: page,
  239 + animation: animation,
  240 + reverse: reverse || false,
  241 + id: pageId
  242 + });
  243 + }
  244 + function animatePages(fromPage, toPage, animation, backwards) {
  245 + // Error check for target page
  246 + if (toPage.length === 0) {
  247 + $.fn.unselect();
  248 + console.error('Target element is missing.');
  249 + return false;
  250 + }
  251 +
  252 + // Error check for fromPage=toPage
  253 + if (toPage.hasClass('current')) {
  254 + $.fn.unselect();
  255 + console.error('Target element is the current page.');
  256 + return false;
  257 + }
  258 +
  259 + // Collapse the keyboard
  260 + $(':focus').blur();
  261 +
  262 + // Make sure we are scrolled up to hide location bar
  263 + scrollTo(0, 0);
  264 +
  265 + // Define callback to run after animation completes
  266 + var callback = function animationEnd(event) {
  267 + if (animation) {
  268 + toPage.removeClass('in ' + animation.name);
  269 + fromPage.removeClass('current out ' + animation.name);
  270 + if (backwards) {
  271 + toPage.toggleClass('reverse');
  272 + fromPage.toggleClass('reverse');
  273 + }
  274 + } else {
  275 + fromPage.removeClass('current');
  276 + }
  277 +
  278 + toPage.trigger('pageAnimationEnd', { direction: 'in' });
  279 + fromPage.trigger('pageAnimationEnd', { direction: 'out' });
  280 +
  281 + clearInterval(hashCheckInterval);
  282 + currentPage = toPage;
  283 + location.hash = '#' + currentPage.attr('id');
  284 + startHashCheck();
  285 +
  286 + var $originallink = toPage.data('referrer');
  287 + if ($originallink) {
  288 + $originallink.unselect();
  289 + }
  290 + lastAnimationTime = (new Date()).getTime();
  291 + tapReady = true;
  292 + }
  293 +
  294 + fromPage.trigger('pageAnimationStart', { direction: 'out' });
  295 + toPage.trigger('pageAnimationStart', { direction: 'in' });
  296 +
  297 + if ($.support.WebKitAnimationEvent && animation && jQTSettings.useAnimations) {
  298 + toPage.one('webkitAnimationEnd', callback);
  299 + tapReady = false;
  300 + if (backwards) {
  301 + toPage.toggleClass('reverse');
  302 + fromPage.toggleClass('reverse');
  303 + }
  304 + toPage.addClass(animation.name + ' in current ');
  305 + fromPage.addClass(animation.name + ' out');
  306 +
  307 + } else {
  308 + toPage.addClass('current');
  309 + callback();
  310 + }
  311 +
  312 + return true;
  313 + }
  314 + function hashCheck() {
  315 + var curid = currentPage.attr('id');
  316 + if (location.hash == '') {
  317 + location.hash = '#' + curid;
  318 + } else if (location.hash != '#' + curid) {
  319 + clearInterval(hashCheckInterval);
  320 + goBack(location.hash);
  321 + }
  322 + }
  323 + function startHashCheck() {
  324 + hashCheckInterval = setInterval(hashCheck, 100);
  325 + }
  326 + function insertPages(nodes, animation) {
  327 + var targetPage = null;
  328 + $(nodes).each(function(index, node) {
  329 + var $node = $(this);
  330 + if (!$node.attr('id')) {
  331 + $node.attr('id', 'page-' + (++newPageCount));
  332 + }
  333 +
  334 + $body.trigger('pageInserted', {page: $node.appendTo($body)});
  335 +
  336 + if ($node.hasClass('current') || !targetPage) {
  337 + targetPage = $node;
  338 + }
  339 + });
  340 + if (targetPage !== null) {
  341 + goTo(targetPage, animation);
  342 + return targetPage;
  343 + } else {
  344 + return false;
  345 + }
  346 + }
  347 + function showPageByHref(href, options) {
  348 + var defaults = {
  349 + data: null,
  350 + method: 'GET',
  351 + animation: null,
  352 + callback: null,
  353 + $referrer: null
  354 + };
  355 +
  356 + var settings = $.extend({}, defaults, options);
  357 +
  358 + if (href != '#') {
  359 + $.ajax({
  360 + url: href,
  361 + data: settings.data,
  362 + type: settings.method,
  363 + success: function (data, textStatus) {
  364 + var firstPage = insertPages(data, settings.animation);
  365 + if (firstPage) {
  366 + if (settings.method == 'GET' && jQTSettings.cacheGetRequests === true && settings.$referrer) {
  367 + settings.$referrer.attr('href', '#' + firstPage.attr('id'));
  368 + }
  369 + if (settings.callback) {
  370 + settings.callback(true);
  371 + }
  372 + }
  373 + },
  374 + error: function (data) {
  375 + if (settings.$referrer) {
  376 + settings.$referrer.unselect();
  377 + }
  378 + if (settings.callback) {
  379 + settings.callback(false);
  380 + }
  381 + }
  382 + });
  383 + }
  384 + else if (settings.$referrer) {
  385 + settings.$referrer.unselect();
  386 + }
  387 + }
  388 + function submitForm(e, callback) {
  389 + var $form = (typeof(e)==='string') ? $(e).eq(0) : (e.target ? $(e.target) : $(e));
  390 +
  391 + if ($form.length && $form.is(jQTSettings.formSelector)) {
  392 + showPageByHref($form.attr('action'), {
  393 + data: $form.serialize(),
  394 + method: $form.attr('method') || "POST",
  395 + animation: animations[0] || null,
  396 + callback: callback
  397 + });
  398 + return false;
  399 + }
  400 + return true;
  401 + }
  402 + function submitParentForm(e) {
  403 + var $form = $(this).closest('form');
  404 + if ($form.length) {
  405 + evt = jQuery.Event("submit");
  406 + evt.preventDefault();
  407 + $form.trigger(evt);
  408 + return false;
  409 + }
  410 + return true;
  411 + }
  412 + function addAnimation(animation) {
  413 + if (typeof(animation.selector) == 'string' && typeof(animation.name) == 'string') {
  414 + animations.push(animation);
  415 + $(animation.selector).tap(liveTap);
  416 + touchSelectors.push(animation.selector);
  417 + }
  418 + }
  419 + function updateOrientation() {
  420 + orientation = window.innerWidth < window.innerHeight ? 'profile' : 'landscape';
  421 + $body.removeClass('profile landscape').addClass(orientation).trigger('turn', {orientation: orientation});
  422 + // scrollTo(0, 0);
  423 + }
  424 + function handleTouch(e) {
  425 + var $el = $(e.target);
  426 +
  427 + // Only handle touchSelectors
  428 + if (!$(e.target).is(touchSelectors.join(', '))) {
  429 + var $link = $(e.target).closest('a, area');
  430 +
  431 + if ($link.length && $link.is(touchSelectors.join(', '))) {
  432 + $el = $link;
  433 + } else {
  434 + return;
  435 + }
  436 + }
  437 +
  438 + if (e) {
  439 + var hoverTimeout = null,
  440 + startX = event.changedTouches[0].clientX,
  441 + startY = event.changedTouches[0].clientY,
  442 + startTime = (new Date).getTime(),
  443 + deltaX = 0,
  444 + deltaY = 0,
  445 + deltaT = 0;
  446 +
  447 + // Let's bind these after the fact, so we can keep some internal values
  448 + $el.bind('touchmove', touchmove).bind('touchend', touchend);
  449 +
  450 + hoverTimeout = setTimeout(function() {
  451 + $el.makeActive();
  452 + }, 100);
  453 +
  454 + }
  455 +
  456 + // Private touch functions (TODO: insert dirty joke)
  457 + function touchmove(e) {
  458 +
  459 + updateChanges();
  460 + var absX = Math.abs(deltaX);
  461 + var absY = Math.abs(deltaY);
  462 +
  463 + // Check for swipe
  464 + if (absX > absY && (absX > 35) && deltaT < 1000) {
  465 + $el.trigger('swipe', {direction: (deltaX < 0) ? 'left' : 'right', deltaX: deltaX, deltaY: deltaY }).unbind('touchmove touchend');
  466 + } else if (absY > 1) {
  467 + $el.removeClass('active');
  468 + }
  469 +
  470 + clearTimeout(hoverTimeout);
  471 + }
  472 +
  473 + function touchend() {
  474 + updateChanges();
  475 +
  476 + if (deltaY === 0 && deltaX === 0) {
  477 + $el.makeActive();
  478 + $el.trigger('tap');
  479 + } else {
  480 + $el.removeClass('active');
  481 + }
  482 + $el.unbind('touchmove touchend');
  483 + clearTimeout(hoverTimeout);
  484 + }
  485 +
  486 + function updateChanges() {
  487 + var first = event.changedTouches[0] || null;
  488 + deltaX = first.pageX - startX;
  489 + deltaY = first.pageY - startY;
  490 + deltaT = (new Date).getTime() - startTime;
  491 + }
  492 +
  493 + } // End touch handler