compass-jquery-plugin 0.3.2.3 → 0.3.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (235) hide show
  1. data/README.md +54 -37
  2. data/VERSION.yml +1 -1
  3. data/lib/handle_attributes.rb +4 -4
  4. data/lib/handle_js_files.rb +5 -5
  5. data/lib/jqtouch_theme.rb +2 -2
  6. data/lib/jquery/dynatree.rb +2 -2
  7. data/lib/jquery/emulators.rb +1 -1
  8. data/lib/jquery/flash_messages.rb +6 -6
  9. data/lib/jquery/graphics.rb +5 -0
  10. data/lib/jquery/gridify/assertions.rb +1 -1
  11. data/lib/jquery/gridify/grid.rb +76 -59
  12. data/lib/jquery/gridify/grid_column.rb +73 -67
  13. data/lib/jquery/gridify/grid_finder.rb +79 -79
  14. data/lib/jquery/gridify/grid_options.rb +154 -149
  15. data/lib/jquery/gridify/grid_view.rb +143 -143
  16. data/lib/jquery/gridify.rb +25 -25
  17. data/lib/jquery/ical/calendar.rb +2 -2
  18. data/lib/jquery/ical/event.rb +48 -44
  19. data/lib/jquery/ical/helpers/ui_event_helper.rb +3 -3
  20. data/lib/jquery/jqgrid/jqgrid.rb +58 -58
  21. data/lib/jquery/jqgrid.rb +1 -1
  22. data/lib/jquery/jqtouch.rb +1 -1
  23. data/lib/jquery/jquery.rb +117 -117
  24. data/lib/jquery/jquery_auto_complete.rb +9 -9
  25. data/lib/jquery/jquery_json_response.rb +12 -12
  26. data/lib/jquery/jquery_selector_assertions.rb +55 -53
  27. data/lib/jquery/jstree.rb +2 -2
  28. data/lib/jquery/mobile.rb +1 -1
  29. data/lib/jquery/ribbon.rb +2 -2
  30. data/lib/jquery/secret_sauce/controller/ui_dialog_controls.rb +5 -5
  31. data/lib/jquery/secret_sauce/controller/ui_grid_controls.rb +5 -5
  32. data/lib/jquery/secret_sauce/helpers/ui_dialog_helper.rb +1 -1
  33. data/lib/jquery/secret_sauce/helpers/ui_form_helper.rb +39 -39
  34. data/lib/jquery/secret_sauce/helpers/ui_grid_helper.rb +74 -74
  35. data/lib/jquery/secret_sauce/model/find_for_grid.rb +21 -21
  36. data/lib/jquery/secret_sauce.rb +1 -1
  37. data/lib/jquery/tools.rb +1 -1
  38. data/lib/jquery_mobile_theme.rb +2 -2
  39. data/lib/jquery_ui_theme.rb +12 -12
  40. data/templates/dynatree/config/initializers/dynatree.rb +3 -3
  41. data/templates/dynatree/jquery/dynatree/aero.scss +16 -16
  42. data/templates/dynatree/jquery/dynatree/aqua.scss +16 -16
  43. data/templates/dynatree/jquery/dynatree/crystal.scss +16 -16
  44. data/templates/dynatree/jquery/dynatree/xp.scss +17 -17
  45. data/templates/dynatree/jquery.dynatree.js +2926 -2912
  46. data/templates/emulators/config/initializers/emulators.rb +6 -6
  47. data/templates/graphics/config/initializers/graphics.rb +5 -0
  48. data/templates/graphics/jquery/ganttView.scss +89 -0
  49. data/templates/graphics/jquery.ganttView.js +1669 -0
  50. data/templates/graphics/jquery.ganttView.min.js +70 -0
  51. data/templates/{jquery → graphics}/jquery.sparkline.js +466 -438
  52. data/templates/{jquery → graphics}/jquery.sparkline.min.js +0 -0
  53. data/templates/graphics/manifest.rb +9 -0
  54. data/templates/jqgrid/config/initializers/jqgrid.rb +1 -1
  55. data/templates/jqgrid/i18n/jqgrid/locale-ar.js +131 -125
  56. data/templates/jqgrid/i18n/jqgrid/locale-bg.js +135 -131
  57. data/templates/jqgrid/i18n/jqgrid/locale-bg1251.js +135 -131
  58. data/templates/jqgrid/i18n/jqgrid/locale-cat.js +132 -126
  59. data/templates/jqgrid/i18n/jqgrid/locale-cn.js +137 -131
  60. data/templates/jqgrid/i18n/jqgrid/locale-cs.js +133 -127
  61. data/templates/jqgrid/i18n/jqgrid/locale-da.js +132 -126
  62. data/templates/jqgrid/i18n/jqgrid/locale-de.js +138 -132
  63. data/templates/jqgrid/i18n/jqgrid/locale-el.js +131 -125
  64. data/templates/jqgrid/i18n/jqgrid/locale-en.js +133 -127
  65. data/templates/jqgrid/i18n/jqgrid/locale-es.js +133 -127
  66. data/templates/jqgrid/i18n/jqgrid/locale-fa.js +19 -16
  67. data/templates/jqgrid/i18n/jqgrid/locale-fi.js +132 -126
  68. data/templates/jqgrid/i18n/jqgrid/locale-fr.js +131 -125
  69. data/templates/jqgrid/i18n/jqgrid/locale-gl.js +131 -125
  70. data/templates/jqgrid/i18n/jqgrid/locale-he.js +132 -126
  71. data/templates/jqgrid/i18n/jqgrid/locale-hu.js +133 -127
  72. data/templates/jqgrid/i18n/jqgrid/locale-is.js +131 -125
  73. data/templates/jqgrid/i18n/jqgrid/locale-it.js +8 -1
  74. data/templates/jqgrid/i18n/jqgrid/locale-ja.js +139 -136
  75. data/templates/jqgrid/i18n/jqgrid/locale-nl.js +4 -1
  76. data/templates/jqgrid/i18n/jqgrid/locale-no.js +14 -1
  77. data/templates/jqgrid/i18n/jqgrid/locale-pl.js +132 -126
  78. data/templates/jqgrid/i18n/jqgrid/locale-pt-br.js +132 -126
  79. data/templates/jqgrid/i18n/jqgrid/locale-pt.js +130 -124
  80. data/templates/jqgrid/i18n/jqgrid/locale-ro.js +144 -138
  81. data/templates/jqgrid/i18n/jqgrid/locale-ru.js +132 -126
  82. data/templates/jqgrid/i18n/jqgrid/locale-sk.js +132 -126
  83. data/templates/jqgrid/i18n/jqgrid/locale-sr.js +133 -127
  84. data/templates/jqgrid/i18n/jqgrid/locale-sv.js +132 -126
  85. data/templates/jqgrid/i18n/jqgrid/locale-tr.js +131 -125
  86. data/templates/jqgrid/i18n/jqgrid/locale-ua.js +132 -126
  87. data/templates/jqgrid/jquery.jqGrid.js +12735 -10444
  88. data/templates/jqgrid/jquery.jqGrid.min.js +477 -469
  89. data/templates/jqgrid/public/stylesheets/ellipsis-xbl.xml +12 -10
  90. data/templates/jqtouch/config/initializers/jqtouch.rb +3 -3
  91. data/templates/jqtouch/jquery/touch/jqtouch.scss +1 -1
  92. data/templates/jqtouch/jquery.jqtouch.js +10025 -10043
  93. data/templates/jquery/config/initializers/jquery.rb +2 -4
  94. data/templates/jquery/history.adapter.jquery.js +71 -0
  95. data/templates/jquery/history.adapter.jquery.min.js +4 -0
  96. data/templates/jquery/history.html4.js +690 -0
  97. data/templates/jquery/history.html4.min.js +21 -0
  98. data/templates/jquery/history.js +1297 -0
  99. data/templates/jquery/history.min.js +29 -0
  100. data/templates/jquery/i18n/jquery.ui/datepicker-af.js +20 -20
  101. data/templates/jquery/i18n/jquery.ui/datepicker-ar-DZ.js +19 -19
  102. data/templates/jquery/i18n/jquery.ui/datepicker-ar.js +19 -19
  103. data/templates/jquery/i18n/jquery.ui/datepicker-az.js +19 -19
  104. data/templates/jquery/i18n/jquery.ui/datepicker-bg.js +8 -8
  105. data/templates/jquery/i18n/jquery.ui/datepicker-bs.js +20 -20
  106. data/templates/jquery/i18n/jquery.ui/datepicker-ca.js +20 -20
  107. data/templates/jquery/i18n/jquery.ui/datepicker-cs.js +20 -20
  108. data/templates/jquery/i18n/jquery.ui/datepicker-da.js +14 -14
  109. data/templates/jquery/i18n/jquery.ui/datepicker-de.js +20 -20
  110. data/templates/jquery/i18n/jquery.ui/datepicker-el.js +20 -20
  111. data/templates/jquery/i18n/jquery.ui/datepicker-en-AU.js +20 -20
  112. data/templates/jquery/i18n/jquery.ui/datepicker-en-GB.js +20 -20
  113. data/templates/jquery/i18n/jquery.ui/datepicker-en-NZ.js +20 -20
  114. data/templates/jquery/i18n/jquery.ui/datepicker-eo.js +20 -20
  115. data/templates/jquery/i18n/jquery.ui/datepicker-es.js +20 -20
  116. data/templates/jquery/i18n/jquery.ui/datepicker-et.js +20 -20
  117. data/templates/jquery/i18n/jquery.ui/datepicker-eu.js +20 -20
  118. data/templates/jquery/i18n/jquery.ui/datepicker-fa.js +18 -18
  119. data/templates/jquery/i18n/jquery.ui/datepicker-fi.js +15 -15
  120. data/templates/jquery/i18n/jquery.ui/datepicker-fo.js +20 -20
  121. data/templates/jquery/i18n/jquery.ui/datepicker-fr-CH.js +20 -20
  122. data/templates/jquery/i18n/jquery.ui/datepicker-fr.js +22 -22
  123. data/templates/jquery/i18n/jquery.ui/datepicker-gl.js +20 -20
  124. data/templates/jquery/i18n/jquery.ui/datepicker-he.js +20 -20
  125. data/templates/jquery/i18n/jquery.ui/datepicker-hr.js +20 -20
  126. data/templates/jquery/i18n/jquery.ui/datepicker-hu.js +20 -20
  127. data/templates/jquery/i18n/jquery.ui/datepicker-hu.min.js +1 -1
  128. data/templates/jquery/i18n/jquery.ui/datepicker-hy.js +20 -20
  129. data/templates/jquery/i18n/jquery.ui/datepicker-id.js +20 -20
  130. data/templates/jquery/i18n/jquery.ui/datepicker-is.js +20 -20
  131. data/templates/jquery/i18n/jquery.ui/datepicker-it.js +20 -20
  132. data/templates/jquery/i18n/jquery.ui/datepicker-ja.js +20 -20
  133. data/templates/jquery/i18n/jquery.ui/datepicker-ko.js +20 -20
  134. data/templates/jquery/i18n/jquery.ui/datepicker-kz.js +20 -20
  135. data/templates/jquery/i18n/jquery.ui/datepicker-lt.js +20 -20
  136. data/templates/jquery/i18n/jquery.ui/datepicker-lv.js +20 -20
  137. data/templates/jquery/i18n/jquery.ui/datepicker-ml.js +20 -20
  138. data/templates/jquery/i18n/jquery.ui/datepicker-ms.js +20 -20
  139. data/templates/jquery/i18n/jquery.ui/datepicker-nl.js +20 -20
  140. data/templates/jquery/i18n/jquery.ui/datepicker-no.js +16 -16
  141. data/templates/jquery/i18n/jquery.ui/datepicker-no.min.js +2 -2
  142. data/templates/jquery/i18n/jquery.ui/datepicker-pl.js +20 -20
  143. data/templates/jquery/i18n/jquery.ui/datepicker-pt-BR.js +20 -20
  144. data/templates/jquery/i18n/jquery.ui/datepicker-pt.js +20 -20
  145. data/templates/jquery/i18n/jquery.ui/datepicker-rm.js +18 -18
  146. data/templates/jquery/i18n/jquery.ui/datepicker-ro.js +20 -20
  147. data/templates/jquery/i18n/jquery.ui/datepicker-ru.js +20 -20
  148. data/templates/jquery/i18n/jquery.ui/datepicker-sk.js +20 -20
  149. data/templates/jquery/i18n/jquery.ui/datepicker-sl.js +20 -20
  150. data/templates/jquery/i18n/jquery.ui/datepicker-sq.js +20 -20
  151. data/templates/jquery/i18n/jquery.ui/datepicker-sr-SR.js +20 -20
  152. data/templates/jquery/i18n/jquery.ui/datepicker-sr.js +20 -20
  153. data/templates/jquery/i18n/jquery.ui/datepicker-sv.js +14 -14
  154. data/templates/jquery/i18n/jquery.ui/datepicker-ta.js +20 -20
  155. data/templates/jquery/i18n/jquery.ui/datepicker-th.js +20 -20
  156. data/templates/jquery/i18n/jquery.ui/datepicker-tr.js +20 -20
  157. data/templates/jquery/i18n/jquery.ui/datepicker-uk.js +20 -20
  158. data/templates/jquery/i18n/jquery.ui/datepicker-vi.js +20 -20
  159. data/templates/jquery/i18n/jquery.ui/datepicker-zh-CN.js +20 -20
  160. data/templates/jquery/i18n/jquery.ui/datepicker-zh-HK.js +20 -20
  161. data/templates/jquery/i18n/jquery.ui/datepicker-zh-TW.js +20 -20
  162. data/templates/jquery/{partials → jquery/ui}/_flash_messages.scss +0 -0
  163. data/templates/jquery/jquery/ui/_theme.scss +14 -13
  164. data/templates/jquery/jquery/ui/contextMenu/configure.png +0 -0
  165. data/templates/jquery/jquery/ui/contextMenu/copy.png +0 -0
  166. data/templates/jquery/jquery/ui/contextMenu/cut.png +0 -0
  167. data/templates/jquery/jquery/ui/contextMenu/delete.png +0 -0
  168. data/templates/jquery/jquery/ui/contextMenu/edit.png +0 -0
  169. data/templates/jquery/jquery/ui/contextMenu/exit.png +0 -0
  170. data/templates/jquery/jquery/ui/contextMenu/new.png +0 -0
  171. data/templates/jquery/jquery/ui/contextMenu/paste.png +0 -0
  172. data/templates/jquery/jquery/ui/contextMenu/rename.png +0 -0
  173. data/templates/jquery/jquery/ui/contextMenu/show.png +0 -0
  174. data/templates/jquery/jquery/ui/contextMenu/trash.png +0 -0
  175. data/templates/jquery/jquery/ui/contextMenu.scss +16 -10
  176. data/templates/jquery/jquery-ui.js +11839 -23066
  177. data/templates/jquery/jquery-ui.min.js +401 -795
  178. data/templates/jquery/jquery.bgiframe.js +27 -25
  179. data/templates/jquery/jquery.contextMenu.js +209 -196
  180. data/templates/jquery/jquery.cookie.js +3 -1
  181. data/templates/jquery/jquery.dotimeout.js +236 -228
  182. data/templates/jquery/jquery.dst.js +154 -151
  183. data/templates/jquery/jquery.farbtastic.js +293 -293
  184. data/templates/jquery/jquery.flashMessages.js +26 -0
  185. data/templates/jquery/jquery.flashMessages.min.js +1 -0
  186. data/templates/jquery/jquery.form.js +803 -786
  187. data/templates/jquery/jquery.haml.js +248 -247
  188. data/templates/jquery/jquery.hotkeys.js +89 -89
  189. data/templates/jquery/jquery.js +8141 -8106
  190. data/templates/jquery/jquery.layout.js +2451 -2415
  191. data/templates/jquery/jquery.min.js +167 -166
  192. data/templates/jquery/jquery.mousewheel.js +62 -54
  193. data/templates/jquery/jquery.offline.js +171 -171
  194. data/templates/jquery/jquery.pngFix.js +76 -76
  195. data/templates/jquery/jquery.replacetext.js +83 -83
  196. data/templates/jquery/jquery.themeswitchertool.js +202 -177
  197. data/templates/jquery/jquery.tmpl.js +478 -473
  198. data/templates/jquery/jquery.tmplPlus.js +82 -81
  199. data/templates/jquery/jrails.js +178 -175
  200. data/templates/jquery/json.js +77 -7
  201. data/templates/jquery/json2.js +480 -0
  202. data/templates/jquery/json2.min.js +7 -0
  203. data/templates/jquery/lib/tasks/haml.rake +2 -2
  204. data/templates/jquery/manifest.rb +21 -17
  205. data/templates/jstree/jquery.jstree.js +5967 -4536
  206. data/templates/mobile/config/initializers/mobile.rb +1 -1
  207. data/templates/mobile/jquery/mobile/_base.scss +944 -927
  208. data/templates/mobile/jquery/mobile/default.scss +61 -48
  209. data/templates/mobile/jquery/mobile/valencia.scss +56 -42
  210. data/templates/mobile/jquery.mobile.js +4461 -4347
  211. data/templates/mobile/jquery.mobile.min.js +11 -2
  212. data/templates/mobile/lib/tasks/jquery.mobile.rake +12 -12
  213. data/templates/ribbon/config/initializers/ribbon.rb +2 -2
  214. data/templates/ribbon/jquery.ribbon.js +50 -29
  215. data/templates/secret_sauce/secret_sauce.js +8 -8
  216. data/templates/tools/flowplayer.js +945 -1
  217. data/templates/tools/jquery.tools.js +4645 -4335
  218. data/templates/tools/jquery.tools.min.js +37 -37
  219. data/templates/tools/lib/tasks/jquery.tools.rake +4 -4
  220. data/templates/tools/swfobject.js +813 -773
  221. metadata +33 -21
  222. data/templates/jquery/haml.js +0 -506
  223. data/templates/jquery/haml.min.js +0 -5
  224. data/templates/jquery/jquery/ui/contextMenu/door.png +0 -0
  225. data/templates/jquery/jquery/ui/contextMenu/page_white_copy.png +0 -0
  226. data/templates/jquery/jquery/ui/contextMenu/page_white_delete.png +0 -0
  227. data/templates/jquery/jquery/ui/contextMenu/page_white_edit.png +0 -0
  228. data/templates/jquery/jquery/ui/contextMenu/page_white_new.png +0 -0
  229. data/templates/jquery/jquery/ui/contextMenu/page_white_paste.png +0 -0
  230. data/templates/jquery/jquery.compat-1.3.js +0 -291
  231. data/templates/jquery/jquery.compat-1.3.min.js +0 -6
  232. data/templates/jquery/jquery.flash_messages.js +0 -5
  233. data/templates/jquery/jquery.flash_messages.min.js +0 -1
  234. data/templates/jquery/jquery.history.js +0 -194
  235. data/templates/jquery/jquery.history.min.js +0 -5
@@ -0,0 +1,21 @@
1
+ /*
2
+ New BSD License <http://creativecommons.org/licenses/BSD/>
3
+ Public Domain
4
+ @author Benjamin Arthur Lupton <contact@balupton.com>
5
+ @author James Padolsey <https://gist.github.com/527683>
6
+ Public Domain
7
+ @author Benjamin Arthur Lupton <contact@balupton.com>
8
+ */
9
+ (function(h){h.History=h.History||{};h._History=h._History||{};var i=h.document,b=h._History,a=h.History;if(typeof a.initHtml4!=="undefined")throw Error("History.js HTML4 Support has already been loaded...");a.initHtml4=function(){if(typeof a.initHtml5==="undefined"||typeof a.Adapter==="undefined")return false;b.getInternetExplorerMajorVersion=function(){return b.getInternetExplorerMajorVersion.cached=typeof b.getInternetExplorerMajorVersion.cached!=="undefined"?b.getInternetExplorerMajorVersion.cached:
10
+ function(){for(var c=3,d=i.createElement("div"),f=d.getElementsByTagName("i");d.innerHTML="<!--[if gt IE "+ ++c+"]><i></i><![endif]--\>",f[0];);return c>4?c:void 0}()};b.isInternetExplorer=function(){return b.isInternetExplorer.cached=typeof b.isInternetExplorer.cached!=="undefined"?b.isInternetExplorer.cached:b.getInternetExplorerMajorVersion()!==0};a.emulated.hashChange=Boolean(!("onhashchange"in h||"onhashchange"in i)||b.isInternetExplorer()&&b.getInternetExplorerMajorVersion()<8);b.savedHashes=
11
+ [];b.isLastHash=function(c){var d=b.getHashByIndex();return c===d};b.saveHash=function(c){if(b.isLastHash(c))return false;b.savedHashes.push(c);return true};b.getHashByIndex=function(c){var d=null;return d=typeof c==="undefined"?b.savedHashes[b.savedHashes.length-1]:c<0?b.savedHashes[b.savedHashes.length+c]:b.savedHashes[c]};b.stateHashExists=function(c){return typeof b.statesByHash[c]!=="undefined"};b.discardedHashes={};b.discardedStates={};b.discardState=function(c,d,f){a.debug("History.discardState",
12
+ this,arguments);var j=a.contractState(c);b.discardedStates[j]={discardedState:c,backState:f,forwardState:d};return true};b.discardHash=function(c,d,f){a.debug("History.discardState",this,arguments);b.discardedHashes[c]={discardedHash:c,backState:f,forwardState:d};return true};b.discardedState=function(c){c=a.contractState(c);return b.discardedStates[c]||false};b.discardedHash=function(c){return b.discardedHashes[c]||false};b.recycleState=function(c){a.debug("History.recycleState",this,arguments);
13
+ var d=a.contractState(c);b.discardedState(c)&&delete b.discardedStates[d];return true};a.emulated.hashChange&&a.Adapter.onDomLoad(function(){b.checkerFunction=null;if(b.isInternetExplorer()){var c=i.createElement("iframe");c.setAttribute("id","historyjs-iframe");c.style.display="none";i.body.appendChild(c);c.contentWindow.document.open();c.contentWindow.document.close();var d=null,f=null,j=false;b.checkerFunction=function(){if(j){a.debug("hashchange.checker: checker is running");return false}j=true;
14
+ var e=a.getHash(),g=b.unescapeHash(c.contentWindow.document.location.hash);if(e!==d){d=e;if(g!==e){a.debug("hashchange.checker: iframe hash change","documentHash (new):",e,"iframeHash (old):",g);f=e;c.contentWindow.document.open();c.contentWindow.document.close();c.contentWindow.document.location.hash=b.escapeHash(e)}a.Adapter.trigger(h,"hashchange")}else if(g!==f){a.debug("hashchange.checker: iframe hash out of sync","iframeHash (new):",g,"documentHash (old):",e);f=g;a.setHash(g,false)}j=false;return true}}else{d=
15
+ null;b.checkerFunction=function(){var e=a.getHash();if(e!==d){d=e;a.Adapter.trigger(h,"hashchange")}return true}}setInterval(b.checkerFunction,a.options.hashChangeCheckerDelay);return true});if(a.emulated.pushState){b.onHashChange=function(c){a.debug("_History.onHashChange",this,arguments);currentHash=unescape(a.extractHashFromUrl(c&&c.newURL||i.location.href));currentStateHashExits=currentStateHash=currentState=null;if(b.isLastHash(currentHash)){a.debug("_History.onHashChange: no change");a.busy(false);
16
+ return false}b.saveHash(currentHash);currentState=a.expandHash(currentHash);if(!currentState){a.debug("_History.onHashChange: traditional anchor");a.Adapter.trigger(h,"anchorchange");a.busy(false);return false}if(b.isLastState(currentState)){a.debug("_History.onHashChange: no change");a.busy(false);return false}currentStateHash=a.contractState(currentState);a.debug("_History.onHashChange: ","currentStateHash",currentStateHash,"Hash -1",b.getHashByIndex(-1),"Hash -2",b.getHashByIndex(-2),"Hash -3",
17
+ b.getHashByIndex(-3),"Hash -4",b.getHashByIndex(-4),"Hash -5",b.getHashByIndex(-5),"Hash -6",b.getHashByIndex(-6),"Hash -7",b.getHashByIndex(-7));var d=b.discardedState(currentState);if(d){a.debug("forwardState:",a.contractState(d.forwardState),"backState:",a.contractState(d.backState));if(b.getHashByIndex(-2)===a.contractState(d.forwardState)){a.debug("_History.onHashChange: go backwards");a.back(false)}else{a.debug("_History.onHashChange: go forwards");a.forward(false)}a.busy(false);return false}a.debug("_History.onHashChange: success hashchange");
18
+ a.pushState(currentState.data,currentState.title,currentState.url,false);return true};a.Adapter.bind(h,"hashchange",b.onHashChange);a.pushState=function(c,d,f,j){a.debug("History.pushState",this,arguments);if(a.extractHashFromUrl(f))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(j!==false&&a.busy()){a.debug("History.pushState: we must wait",arguments);a.pushQueue({scope:a,callback:a.pushState,args:arguments,queue:j});return false}a.busy(true);var e=
19
+ a.createStateObject(c,d,f),g=a.contractState(e);a.getState();var k=a.getStateHash(),l=unescape(a.getHash());b.storeState(e);b.recycleState(e);if(i.title!==e.title){i.title=e.title;try{i.getElementsByTagName("title")[0].innerHTML=e.title}catch(m){}}a.debug("History.pushState: details","newStateHash:",g,"oldStateHash:",k,"html4Hash:",l);if(g===k){a.debug("History.pushState: no change",g);return false}if(g!==l){a.debug("History.pushState: update hash",g);a.setHash(g,false);return false}b.saveState(e);
20
+ a.debug("History.pushState: trigger popstate");a.Adapter.trigger(h,"statechange");a.busy(false);return true};a.replaceState=function(c,d,f,j){a.debug("History.replaceState",this,arguments);if(a.extractHashFromUrl(f))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(j!==false&&a.busy()){a.debug("History.replaceState: we must wait",arguments);a.pushQueue({scope:a,callback:a.replaceState,args:arguments,queue:j});return false}a.busy(true);var e=a.createStateObject(c,
21
+ d,f),g=a.getState(),k=b.getStateByIndex(-2);b.discardState(g,e,k);a.pushState(e.data,e.title,e.url,false);return true};if(!i.location.hash||i.location.hash==="#")a.Adapter.onDomLoad(function(){a.debug("Internet Explorer Initial State Change Fix");var c=a.createStateObject({},"",i.location.href);a.pushState(c.data,c.title,c.url)});else if(!a.emulated.hashChange){a.debug("Firefox Initial State Change Fix");a.Adapter.onDomLoad(function(){b.onHashChange()})}}};a.initHtml4()})(window);
@@ -0,0 +1,1297 @@
1
+ /**
2
+ * History.js HTML5 Support
3
+ * @author Benjamin Arthur Lupton <contact@balupton.com>
4
+ * @copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
5
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
6
+ */
7
+
8
+ (function(window,undefined){
9
+
10
+ // --------------------------------------------------------------------------
11
+ // Initialise
12
+
13
+ // History Object
14
+ window.History = window.History||{};
15
+ window._History = window._History||{};
16
+
17
+ // Localise Globals
18
+ var
19
+ console = window.console||undefined, // Prevent a JSLint complain
20
+ document = window.document, // Make sure we are using the correct document
21
+ _History = window._History, // Private History Object
22
+ History = window.History, // Public History Object
23
+ history = window.history; // Old History Object
24
+
25
+ // Check Existence of History.js
26
+ if ( typeof History.initHtml5 !== 'undefined' ) {
27
+ throw new Error('History.js HTML5 Support has already been loaded...');
28
+ }
29
+
30
+ // Initialise
31
+ History.initHtml5 = function(){
32
+
33
+ // ----------------------------------------------------------------------
34
+ // Check Status
35
+
36
+ if ( typeof History.Adapter === 'undefined' ) {
37
+ return false;
38
+ }
39
+
40
+ // ----------------------------------------------------------------------
41
+ // Debug Helpers
42
+
43
+ /**
44
+ * History.options
45
+ * Configurable options
46
+ */
47
+ History.options = {
48
+ /**
49
+ * History.options.hashChangeCheckerDelay
50
+ * How long should the interval be before hashchange checks
51
+ */
52
+ hashChangeCheckerDelay: 100,
53
+ /**
54
+ * History.options.busyDelay
55
+ * How long should we wait between busy events
56
+ */
57
+ busyDelay: 250
58
+ };
59
+
60
+ // ----------------------------------------------------------------------
61
+ // Debug Helpers
62
+
63
+ /**
64
+ * History.debug(message,...)
65
+ * Logs the passed arguments if debug enabled
66
+ */
67
+ History.debug = function(){
68
+ if ( (History.debug.enable||false) ) {
69
+ History.log.apply(History,arguments);
70
+ }
71
+ };
72
+ History.debug.enable = false;
73
+
74
+ /**
75
+ * History.log(message,...)
76
+ * Logs the passed arguments
77
+ */
78
+ History.log = function(){
79
+ // Prepare
80
+ var
81
+ consoleExists = (typeof console !== 'undefined'),
82
+ textarea = document.getElementById('log'),
83
+ message = ("\n"+arguments[0]+"\n"),
84
+ i
85
+ ;
86
+
87
+ // Write to Console
88
+ if ( consoleExists ) {
89
+ var
90
+ args = Array.prototype.slice.call(arguments),
91
+ message = args.shift();
92
+ if ( typeof console.debug !== 'undefined' ) {
93
+ console.debug.apply(console,[message,args]);
94
+ }
95
+ else {
96
+ console.log.apply(console,[message,args]);
97
+ }
98
+ }
99
+
100
+ // Write to log
101
+ for ( i=1,n=arguments.length; i<n; ++i ) {
102
+ var arg = arguments[i];
103
+ if ( typeof arg === 'object' && typeof JSON !== 'undefined' ) {
104
+ try {
105
+ arg = JSON.stringify(arg);
106
+ }
107
+ catch ( Exception ) {
108
+ // Recursive Object
109
+ }
110
+ }
111
+ message += "\n"+arg+"\n";
112
+ }
113
+
114
+ // Textarea
115
+ if ( textarea ) {
116
+ textarea.value += message+"\n-----\n";
117
+ textarea.scrollTop = textarea.scrollHeight - textarea.clientHeight;
118
+ }
119
+ // No Textarea, No Console
120
+ else if ( !consoleExists ) {
121
+ alert(message);
122
+ }
123
+
124
+ // Return true
125
+ return true;
126
+ };
127
+
128
+ // ----------------------------------------------------------------------
129
+ // Emulated Status
130
+
131
+ /**
132
+ * _History.getInternetExplorerMajorVersion()
133
+ * Get's the major version of Internet Explorer
134
+ * @return {integer}
135
+ * @license Public Domain
136
+ * @author Benjamin Arthur Lupton <contact@balupton.com>
137
+ * @author James Padolsey <https://gist.github.com/527683>
138
+ */
139
+ _History.getInternetExplorerMajorVersion = function(){
140
+ var result = _History.getInternetExplorerMajorVersion.cached =
141
+ (typeof _History.getInternetExplorerMajorVersion.cached !== 'undefined')
142
+ ? _History.getInternetExplorerMajorVersion.cached
143
+ : (function(){
144
+ var undef,
145
+ v = 3,
146
+ div = document.createElement('div'),
147
+ all = div.getElementsByTagName('i');
148
+ while (
149
+ div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
150
+ all[0]
151
+ );
152
+ return v > 4 ? v : undef;
153
+ })()
154
+ ;
155
+ return result;
156
+ };
157
+
158
+ /**
159
+ * _History.isInternetExplorer()
160
+ * Are we using Internet Explorer?
161
+ * @return {boolean}
162
+ * @license Public Domain
163
+ * @author Benjamin Arthur Lupton <contact@balupton.com>
164
+ */
165
+ _History.isInternetExplorer = function(){
166
+ var result = _History.isInternetExplorer.cached =
167
+ (typeof _History.isInternetExplorer.cached !== 'undefined')
168
+ ? _History.isInternetExplorer.cached
169
+ : (_History.getInternetExplorerMajorVersion() !== 0)
170
+ ;
171
+ return result;
172
+ };
173
+
174
+ /**
175
+ * History.emulated
176
+ * Which features require emulating?
177
+ */
178
+ History.emulated = {
179
+ pushState: !Boolean(window.history && window.history.pushState && window.history.replaceState)
180
+ };
181
+
182
+ /**
183
+ * _History.isEmptyObject(obj)
184
+ * Checks to see if the Object is Empty
185
+ * @param {Object} obj
186
+ * @return {boolean}
187
+ */
188
+ _History.isEmptyObject = function(obj) {
189
+ for ( var key in obj ) {
190
+ if ( !this.hasOwnProperty(key) ) {
191
+ continue;
192
+ }
193
+ return false;
194
+ }
195
+ return true;
196
+ };
197
+
198
+ /**
199
+ * _History.cloneObject(obj)
200
+ * Clones a object
201
+ * @param {Object} obj
202
+ * @return {Object}
203
+ */
204
+ _History.cloneObject = function(obj) {
205
+ var hash,newObj;
206
+ if ( obj ) {
207
+ hash = JSON.stringify(obj);
208
+ newObj = JSON.parse(hash);
209
+ }
210
+ else {
211
+ newObj = {};
212
+ }
213
+ return newObj;
214
+ };
215
+
216
+ // ----------------------------------------------------------------------
217
+ // State Object Helpers
218
+
219
+ /**
220
+ * History.contractUrl(url)
221
+ * Ensures that we have a relative URL and not a absolute URL
222
+ * @param {string} url
223
+ * @return {string} url
224
+ */
225
+ History.contractUrl = function(url){
226
+ // Prepare
227
+ url = History.expandUrl(url);
228
+
229
+ // Prepare for Base Domain
230
+ var baseDomain = document.location.protocol+'//'+(document.location.hostname||document.location.host);
231
+ if ( document.location.port||false ) {
232
+ baseDomain += ':'+document.location.port;
233
+ }
234
+ baseDomain += '/';
235
+
236
+ // Adjust for Base Domain
237
+ url = url.replace(baseDomain,'/');
238
+
239
+ // Return url
240
+ return url;
241
+ };
242
+
243
+ /**
244
+ * History.expandUrl(url)
245
+ * Ensures that we have an absolute URL and not a relative URL
246
+ * @param {string} url
247
+ * @return {string} url
248
+ */
249
+ History.expandUrl = function(url){
250
+ // Prepare
251
+ url = url||'';
252
+
253
+ // Test for Full URL
254
+ if ( /[a-z]+\:\/\//.test(url) ) {
255
+ // We have a Full URL
256
+ }
257
+
258
+ // Relative URL
259
+ else {
260
+ // Test for Base Page
261
+ if ( url.length === 0 || url.substring(0,1) === '?' ) {
262
+ // Fetch Base Page
263
+ var basePage = document.location.href.replace(/[#\?].*/,'');
264
+
265
+ // Adjust Page
266
+ url = basePage+url;
267
+ }
268
+
269
+ // No Base Page
270
+ else {
271
+
272
+ // Prepare for Base Element
273
+ var
274
+ baseElements = document.getElementsByTagName('base'),
275
+ baseElement = null,
276
+ baseHref = '';
277
+
278
+ // Test for Base Element
279
+ if ( baseElements.length === 1 ) {
280
+ // Prepare for Base Element
281
+ baseElement = baseElements[0];
282
+ baseHref = baseElement.href;
283
+ if ( baseHref[baseHref.length-1] !== '/' ) baseHref += '/';
284
+
285
+ // Adjust for Base Element
286
+ url = baseHref+url.replace(/^\//,'');
287
+ }
288
+
289
+ // No Base Element
290
+ else {
291
+ // Test for Base URL
292
+ if ( url.substring(0,1) === '.' ) {
293
+ // Prepare for Base URL
294
+ var baseUrl = document.location.href.replace(/[#\?].*/,'').replace(/[^\/]+$/,'');
295
+ if ( baseUrl[baseUrl.length-1] !== '/' ) baseUrl += '/';
296
+
297
+ // Adjust for Base URL
298
+ url = baseUrl + url;
299
+ }
300
+
301
+ // No Base URL
302
+ else {
303
+ // Prepare for Base Domain
304
+ var baseDomain = document.location.protocol+'//'+(document.location.hostname||document.location.host);
305
+ if ( document.location.port||false ) {
306
+ baseDomain += ':'+document.location.port;
307
+ }
308
+ baseDomain += '/';
309
+
310
+ // Adjust for Base Domain
311
+ url = baseDomain+url.replace(/^\//,'');
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ // Return url
318
+ return url;
319
+ };
320
+
321
+ /**
322
+ * History.expandState(State)
323
+ * Expands a State Object
324
+ * @param {object} State
325
+ * @return {object}
326
+ */
327
+ History.expandState = function(oldState){
328
+ oldState = oldState||{};
329
+ var newState = {
330
+ 'data': oldState.data||{},
331
+ 'url': History.expandUrl(oldState.url||''),
332
+ 'title': oldState.title||''
333
+ };
334
+ newState.data.title = newState.data.title||newState.title;
335
+ newState.data.url = newState.data.url||newState.url;
336
+ return newState;
337
+ };
338
+
339
+ /**
340
+ * History.createStateObject(data,title,url)
341
+ * Creates a object based on the data, title and url state params
342
+ * @param {object} data
343
+ * @param {string} title
344
+ * @param {string} url
345
+ * @return {object}
346
+ */
347
+ History.createStateObject = function(data,title,url){
348
+ // Hashify
349
+ var State = {
350
+ 'data': data,
351
+ 'title': title,
352
+ 'url': url
353
+ };
354
+
355
+ // Expand the State
356
+ State = History.expandState(State);
357
+
358
+ // Return object
359
+ return State;
360
+ };
361
+
362
+ /**
363
+ * History.expandHash(hash)
364
+ * Expands a Hash into a StateHash if applicable
365
+ * @param {string} hash
366
+ * @return {Object|null} State
367
+ */
368
+ History.expandHash = function(hash){
369
+ // Prepare
370
+ var State = null;
371
+
372
+ // JSON
373
+ try {
374
+ State = JSON.parse(hash);
375
+ }
376
+ catch ( Exception ) {
377
+ var
378
+ parts = /(.*)\/uid=([0-9]+)$/.exec(hash),
379
+ url = parts ? (parts[1]||hash) : hash,
380
+ uid = parts ? String(parts[2]||'') : '';
381
+
382
+ if ( uid ) {
383
+ State = _History.getStateByUid(uid)||null;
384
+ }
385
+
386
+ if ( !State && /\//.test(hash) ) {
387
+ // Is a URL
388
+ var expandedUrl = History.expandUrl(hash);
389
+ State = History.createStateObject(null,null,expandedUrl);
390
+ }
391
+ else {
392
+ // Non State Hash
393
+ // do nothing
394
+ }
395
+ }
396
+
397
+ // Expand
398
+ State = State ? History.expandState(State) : null;
399
+
400
+ // Return State
401
+ return State;
402
+ };
403
+
404
+ /**
405
+ * History.contractState(State)
406
+ * Creates a Hash for the State Object
407
+ * @param {object} passedState
408
+ * @return {string} hash
409
+ */
410
+ History.contractState = function(passedState){
411
+ // Check
412
+ if ( !passedState ) {
413
+ return null;
414
+ }
415
+
416
+ // Prepare
417
+ var
418
+ hash = null,
419
+ State = _History.cloneObject(passedState);
420
+
421
+ // Ensure State
422
+ if ( State ) {
423
+ // Clean
424
+ State.data = State.data||{};
425
+ delete State.data.title;
426
+ delete State.data.url;
427
+
428
+ // Handle
429
+ if ( _History.isEmptyObject(State) && !State.title ) {
430
+ hash = History.contractUrl(State.url);
431
+ }
432
+ else {
433
+ // Serialised Hash
434
+ hash = JSON.stringify(State);
435
+
436
+ // Has it been associated with a UID?
437
+ var uid;
438
+ if ( typeof _History.hashesToUids[hash] !== 'undefined' ) {
439
+ uid = _History.hashesToUids[hash];
440
+ }
441
+ else {
442
+ while ( true ) {
443
+ uid = String(Math.floor(Math.random()*1000));
444
+ if ( typeof _History.uidsToStates[uid] === 'undefined' ) {
445
+ break;
446
+ }
447
+ }
448
+ }
449
+
450
+ // Associate UID with Hash
451
+ _History.hashesToUids[hash] = uid;
452
+ _History.uidsToStates[uid] = State;
453
+
454
+ // Simplified Hash
455
+ hash = History.contractUrl(State.url)+'/uid='+uid;
456
+ }
457
+ }
458
+
459
+ // Return hash
460
+ return hash;
461
+ };
462
+
463
+ /**
464
+ * _History.uidsToStates
465
+ * UIDs to States
466
+ */
467
+ _History.uidsToStates = {};
468
+
469
+ /**
470
+ * _History.hashesToUids
471
+ * Serialised States to UIDs
472
+ */
473
+ _History.hashesToUids = {};
474
+
475
+ /**
476
+ * _History.getStateByUid(uid)
477
+ * Get a state by it's UID
478
+ * @param {string} uid
479
+ */
480
+ _History.getStateByUid = function(uid){
481
+ uid = String(uid);
482
+ var State = _History.uidsToStates[uid]||undefined;
483
+ return State;
484
+ };
485
+
486
+
487
+ // ----------------------------------------------------------------------
488
+ // State Storage
489
+
490
+ /**
491
+ * _History.statesByUrl
492
+ * Store the states indexed by their URLs
493
+ */
494
+ _History.statesByUrl = {};
495
+
496
+ /**
497
+ * _History.duplicateStateUrls
498
+ * Which urls have duplicate states (indexed by url)
499
+ */
500
+ _History.duplicateStateUrls = {};
501
+
502
+ /**
503
+ * _History.statesByHash
504
+ * Store the states indexed by their Hashes
505
+ */
506
+ _History.statesByHash = {};
507
+
508
+ /**
509
+ * _History.savedStates
510
+ * Store the states in an array
511
+ */
512
+ _History.savedStates = [];
513
+
514
+ /**
515
+ * History.getState()
516
+ * Get an object containing the data, title and url of the current state
517
+ * @return {Object} State
518
+ */
519
+ History.getState = function(){
520
+ return _History.getStateByIndex();
521
+ };
522
+
523
+ /**
524
+ * History.getStateHash()
525
+ * Get the hash of the current state
526
+ * @return {string} hash
527
+ */
528
+ History.getStateHash = function(){
529
+ return History.contractState(History.getState());
530
+ };
531
+
532
+ /**
533
+ * _History.getStateByUrl
534
+ * Get a state by it's url
535
+ * @param {string} stateUrl
536
+ */
537
+ _History.getStateByUrl = function(stateUrl){
538
+ var State = _History.statesByUrl[stateUrl]||undefined;
539
+ return State;
540
+ };
541
+
542
+ /**
543
+ * _History.getStateByHash
544
+ * Get a state by it's hash
545
+ * @param {string} stateHash
546
+ */
547
+ _History.getStateByHash = function(stateHash){
548
+ var State = _History.statesByHash[stateHash]||undefined;
549
+ return State;
550
+ };
551
+
552
+ /**
553
+ * _History.storeState
554
+ * Store a State
555
+ * @param {object} State
556
+ * @return {boolean} true
557
+ */
558
+ _History.storeState = function(newState){
559
+ // Prepare
560
+ var
561
+ newStateHash = History.contractState(newState),
562
+ oldState = _History.getStateByUrl(newState.url);
563
+
564
+ // Check for Conflict
565
+ if ( typeof oldState !== 'undefined' ) {
566
+ // Compare Hashes
567
+ var oldStateHash = History.contractState(oldState);
568
+ if ( oldStateHash !== newStateHash ) {
569
+ // We have a conflict
570
+ _History.duplicateStateUrls[newState.url] = true;
571
+ }
572
+ }
573
+
574
+ // Store the State
575
+ _History.statesByUrl[newState.url] = _History.statesByHash[newStateHash] = newState;
576
+
577
+ // Return true
578
+ return true;
579
+ };
580
+
581
+ /**
582
+ * _History.isLastState(newState)
583
+ * Tests to see if the state is the last state
584
+ * @param {Object} newState
585
+ * @return {boolean} isLast
586
+ */
587
+ _History.isLastState = function(newState){
588
+ // Prepare
589
+ var
590
+ newStateHash = History.contractState(newState),
591
+ oldStateHash = History.getStateHash();
592
+
593
+ // Check
594
+ var isLast = _History.savedStates.length && newStateHash === oldStateHash;
595
+
596
+ // Return isLast
597
+ return isLast;
598
+ };
599
+
600
+ /**
601
+ * _History.saveState
602
+ * Push a State
603
+ * @param {Object} newState
604
+ * @return {boolean} changed
605
+ */
606
+ _History.saveState = function(newState){
607
+ // Check Hash
608
+ if ( _History.isLastState(newState) ) {
609
+ return false;
610
+ }
611
+
612
+ // Push the State
613
+ _History.savedStates.push(newState);
614
+
615
+ // Return true
616
+ return true;
617
+ };
618
+
619
+ /**
620
+ * _History.getStateByIndex()
621
+ * Gets a state by the index
622
+ * @param {integer} index
623
+ * @return {Object}
624
+ */
625
+ _History.getStateByIndex = function(index){
626
+ // Prepare
627
+ var State = null;
628
+
629
+ // Handle
630
+ if ( typeof index === 'undefined' ) {
631
+ // Get the last inserted
632
+ State = _History.savedStates[_History.savedStates.length-1];
633
+ }
634
+ else if ( index < 0 ) {
635
+ // Get from the end
636
+ State = _History.savedStates[_History.savedStates.length+index];
637
+ }
638
+ else {
639
+ // Get from the beginning
640
+ State = _History.savedStates[index];
641
+ }
642
+
643
+ // Return State
644
+ return State;
645
+ };
646
+
647
+ /**
648
+ * _History.stateUrlExists
649
+ * Checks if the State Url Exists
650
+ * @param {string} stateUrl
651
+ * @return {boolean} exists
652
+ */
653
+ _History.stateUrlExists = function(stateUrl){
654
+ // Prepare
655
+ var exists = typeof _History.statesByUrl[stateUrl] !== 'undefined';
656
+
657
+ // Return exists
658
+ return exists;
659
+ };
660
+
661
+ /**
662
+ * _History.urlDuplicateExists
663
+ * Check if the url has multiple states associated to it
664
+ * @param {string} stateUrl
665
+ * @return {boolean} exists
666
+ */
667
+ _History.urlDuplicateExists = function(stateUrl){
668
+ var exists = typeof _History.duplicateStateUrls[stateUrl] !== 'undefined';
669
+ return exists;
670
+ };
671
+
672
+
673
+ // ----------------------------------------------------------------------
674
+ // Hash Helpers
675
+
676
+ /**
677
+ * History.getHash()
678
+ * Gets the current document hash
679
+ * @return {string}
680
+ */
681
+ History.getHash = function(){
682
+ var hash = _History.unescapeHash(document.location.hash);
683
+ return hash;
684
+ };
685
+
686
+ /**
687
+ * _History.unescapeHash()
688
+ * Normalise and Unescape a Hash
689
+ * @return {string}
690
+ */
691
+ _History.unescapeHash = function(hash){
692
+ var result = _History.normalizeHash(hash);
693
+
694
+ // Unescape hash
695
+ if ( /[\%]/.test(result) ) {
696
+ result = unescape(result);
697
+ }
698
+
699
+ // Return result
700
+ return result;
701
+ };
702
+
703
+ /**
704
+ * _History.normalizeHash()
705
+ * Normalise a hash across browsers
706
+ * @return {string}
707
+ */
708
+ _History.normalizeHash = function(hash){
709
+ var result = hash.replace(/[^#]*#/,'').replace(/#.*/, '');
710
+
711
+ // Return result
712
+ return result;
713
+ };
714
+
715
+ /**
716
+ * History.setHash(hash)
717
+ * Sets the document hash
718
+ * @param {string} hash
719
+ * @return {string}
720
+ */
721
+ History.setHash = function(hash,queue){
722
+ // Handle Queueing
723
+ if ( queue !== false && History.busy() ) {
724
+ // Wait + Push to Queue
725
+ History.debug('History.setHash: we must wait', arguments);
726
+ History.pushQueue({
727
+ scope: History,
728
+ callback: History.setHash,
729
+ args: arguments,
730
+ queue: queue
731
+ });
732
+ return false;
733
+ }
734
+
735
+ // Prepare
736
+ var adjustedHash = _History.escapeHash(hash);
737
+
738
+ // Log hash
739
+ History.debug('History.setHash',this,arguments,'hash:',hash,'adjustedHash:',adjustedHash,'oldHash:',document.location.hash);
740
+
741
+ // Make Busy + Continue
742
+ History.busy(true);
743
+
744
+ // Apply hash
745
+ document.location.hash = adjustedHash;
746
+
747
+ // Return hash
748
+ return hash;
749
+ };
750
+
751
+ /**
752
+ * _History.escape()
753
+ * Normalise and Escape a Hash
754
+ * @return {string}
755
+ */
756
+ _History.escapeHash = function(hash){
757
+ var result = _History.normalizeHash(hash);
758
+
759
+ // Escape hash
760
+ if ( /[^a-zA-Z0-9\/\-\_\%\.]/.test(result) ) {
761
+ result = escape(result);
762
+ }
763
+
764
+ // Return result
765
+ return result;
766
+ };
767
+
768
+ /**
769
+ * History.extractHashFromUrl(url)
770
+ * Extracts the Hash from a URL
771
+ * @param {string} url
772
+ * @return {string} url
773
+ */
774
+ History.extractHashFromUrl = function(url){
775
+ // Extract the hash
776
+ var hash = String(url)
777
+ .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2')
778
+ ;
779
+
780
+ // Unescape hash
781
+ hash = _History.unescapeHash(hash);
782
+
783
+ // Return hash
784
+ return hash;
785
+ };
786
+
787
+ /**
788
+ * History.isTraditionalAnchor(url)
789
+ * Checks to see if the url is a traditional anchor
790
+ * @param {string} url
791
+ * @return {boolean}
792
+ */
793
+ History.isTraditionalAnchor = function(url){
794
+ var
795
+ hash = History.extractHashFromUrl(url),
796
+ el = document.getElementById(hash),
797
+ isTraditionalAnchor = typeof el !== 'undefined';
798
+
799
+ // Return isTraditionalAnchor
800
+ return isTraditionalAnchor;
801
+ };
802
+
803
+ // ----------------------------------------------------------------------
804
+ // Queueing
805
+
806
+ /**
807
+ * History.queues
808
+ * The list of queues to use
809
+ * First In, First Out
810
+ */
811
+ History.queues = [];
812
+
813
+ /**
814
+ * History.busy(value)
815
+ * @param {boolean} value [optional]
816
+ * @return {boolean} busy
817
+ */
818
+ History.busy = function(value){
819
+ History.debug('History.busy: called: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues);
820
+
821
+ // Apply
822
+ if ( typeof value !== 'undefined' ) {
823
+ History.busy.flag = value;
824
+ }
825
+ // Default
826
+ else if ( typeof History.busy.flag === 'undefined' ) {
827
+ History.busy.flag = false;
828
+ }
829
+
830
+ // Queue
831
+ if ( !History.busy.flag ) {
832
+ // Execute the next item in the queue
833
+ clearTimeout(History.busy.timeout);
834
+ var fireNext = function(){
835
+ if ( History.busy.flag ) return;
836
+ for ( var i=History.queues.length-1; i >= 0; --i ) {
837
+ var queue = History.queues[i];
838
+ if ( queue.length === 0 ) continue;
839
+ var item = queue.shift();
840
+ History.debug('History.busy: firing', item);
841
+ History.fireQueueItem(item);
842
+ History.busy.timeout = setTimeout(fireNext,History.options.busyDelay);
843
+ }
844
+ };
845
+ History.busy.timeout = setTimeout(fireNext,History.options.busyDelay);
846
+ }
847
+
848
+ // Return
849
+ return History.busy.flag;
850
+ };
851
+
852
+ /**
853
+ * History.fireQueueItem(item)
854
+ * Fire a Queue Item
855
+ * @param {Object} item
856
+ * @return {Mixed} result
857
+ */
858
+ History.fireQueueItem = function(item){
859
+ return item.callback.apply(item.scope||History,item.args||[]);
860
+ };
861
+
862
+ /**
863
+ * History.pushQueue(callback,args)
864
+ * Add an item to the queue
865
+ * @param {Object} item [scope,callback,args,queue]
866
+ */
867
+ History.pushQueue = function(item){
868
+ History.debug('History.pushQueue: called', arguments);
869
+
870
+ // Prepare the queue
871
+ History.queues[item.queue||0] = History.queues[item.queue||0]||[];
872
+
873
+ // Add to the queue
874
+ History.queues[item.queue||0].push(item);
875
+
876
+ // End pushQueue closure
877
+ return true;
878
+ };
879
+
880
+ /**
881
+ * History.queue (item,queue), (func,queue), (func), (item)
882
+ * Either firs the item now if not busy, or adds it to the queue
883
+ */
884
+ History.queue = function(item,queue){
885
+ // Prepare
886
+ if ( typeof item === 'function' ) {
887
+ item = {
888
+ callback: item
889
+ };
890
+ }
891
+ if ( typeof queue !== 'undefined' ) {
892
+ item.queue = queue;
893
+ }
894
+
895
+ // Handle
896
+ if ( History.busy() ) {
897
+ History.pushQueue(item);
898
+ } else {
899
+ History.fireQueueItem(item);
900
+ }
901
+
902
+ // End queue closure
903
+ return true;
904
+ };
905
+
906
+
907
+ // ----------------------------------------------------------------------
908
+ // State Aliases
909
+
910
+ /**
911
+ * History.back(queue)
912
+ * Send the browser history back one item
913
+ * @param {Integer} queue [optional]
914
+ */
915
+ History.back = function(queue){
916
+ History.debug('History.back: called', arguments);
917
+
918
+ // Handle Queueing
919
+ if ( queue !== false && History.busy() ) {
920
+ // Wait + Push to Queue
921
+ History.debug('History.back: we must wait', arguments);
922
+ History.pushQueue({
923
+ scope: History,
924
+ callback: History.back,
925
+ args: arguments,
926
+ queue: queue
927
+ });
928
+ return false;
929
+ }
930
+
931
+ // Make Busy + Continue
932
+ History.busy(true);
933
+
934
+ // Fix a bug in IE6,IE7
935
+ if ( History.emulated.hashChange && _History.isInternetExplorer() ) {
936
+ // Prepare
937
+ var currentHash = History.getHash();
938
+
939
+ // Apply Check
940
+ setTimeout(function(){
941
+ var newHash = History.getHash();
942
+ if ( newHash === currentHash ) {
943
+ // No change occurred, try again
944
+ History.debug('History.back: trying again');
945
+ return History.back(false);
946
+ }
947
+ return true;
948
+ },History.options.hashChangeCheckerDelay*5);
949
+ }
950
+
951
+ // Go back
952
+ history.go(-1);
953
+
954
+ // End back closure
955
+ return true;
956
+ };
957
+
958
+ /**
959
+ * History.forward(queue)
960
+ * Send the browser history forward one item
961
+ * @param {Integer} queue [optional]
962
+ */
963
+ History.forward = function(queue){
964
+ History.debug('History.forward: called', arguments);
965
+
966
+ // Handle Queueing
967
+ if ( queue !== false && History.busy() ) {
968
+ // Wait + Push to Queue
969
+ History.debug('History.forward: we must wait', arguments);
970
+ History.pushQueue({
971
+ scope: History,
972
+ callback: History.forward,
973
+ args: arguments,
974
+ queue: queue
975
+ });
976
+ return false;
977
+ }
978
+
979
+ // Make Busy + Continue
980
+ History.busy(true);
981
+
982
+ // Fix a bug in IE6,IE7
983
+ if ( History.emulated.hashChange && _History.isInternetExplorer() ) {
984
+ // Prepare
985
+ var currentHash = History.getHash();
986
+
987
+ // Apply Check
988
+ setTimeout(function(){
989
+ var newHash = History.getHash();
990
+ if ( newHash === currentHash ) {
991
+ // No change occurred, try again
992
+ History.debug('History.forward: trying again');
993
+ return History.forward(false);
994
+ }
995
+ return true;
996
+ },History.options.hashChangeCheckerDelay*5);
997
+ }
998
+
999
+ // Go forward
1000
+ history.go(1);
1001
+
1002
+ // End forward closure
1003
+ return true;
1004
+ };
1005
+
1006
+ /**
1007
+ * History.go(index,queue)
1008
+ * Send the browser history back or forward index times
1009
+ * @param {Integer} queue [optional]
1010
+ */
1011
+ History.go = function(index,queue){
1012
+ History.debug('History.go: called', arguments);
1013
+
1014
+ // Handle
1015
+ if ( index > 0 ) {
1016
+ // Forward
1017
+ for ( var i=1; i<=index; ++i ) {
1018
+ History.forward(queue);
1019
+ }
1020
+ }
1021
+ else if ( index < 0 ) {
1022
+ // Backward
1023
+ for ( var i=-1; i>=index; --i ) {
1024
+ History.back(queue);
1025
+ }
1026
+ }
1027
+ else {
1028
+ throw new Error('History.go: History.go requires a positive or negative integer passed.');
1029
+ }
1030
+
1031
+ // End go closure
1032
+ return true;
1033
+ };
1034
+
1035
+
1036
+ // ----------------------------------------------------------------------
1037
+ // HTML5 State Support
1038
+
1039
+ if ( !History.emulated.pushState ) {
1040
+ /*
1041
+ * Use native HTML5 History API Implementation
1042
+ */
1043
+
1044
+ /**
1045
+ * _History.onPopState(event,extra)
1046
+ * Refresh the Current State
1047
+ */
1048
+ _History.onPopState = function(event){
1049
+ History.debug('_History.onPopState',this,arguments);
1050
+
1051
+ // Check for a Hash, and handle apporiatly
1052
+ var currentHash = unescape(History.getHash());
1053
+ if ( currentHash ) {
1054
+ // Expand Hash
1055
+ var currentState = History.expandHash(currentHash);
1056
+ if ( currentState ) {
1057
+ // We were able to parse it, it must be a State!
1058
+ // Let's forward to replaceState
1059
+ History.debug('_History.onPopState: state anchor', currentHash, currentState);
1060
+ History.replaceState(currentState.data, currentState.tite, currentState.url, false);
1061
+ }
1062
+ else {
1063
+ // Traditional Anchor
1064
+ History.debug('_History.onPopState: traditional anchor', currentHash);
1065
+ History.Adapter.trigger(window,'anchorchange');
1066
+ History.busy(false);
1067
+ }
1068
+
1069
+ // We don't care for hashes
1070
+ return false;
1071
+ }
1072
+
1073
+ // Prepare
1074
+ var
1075
+ currentStateHashExits = null,
1076
+ stateData = {},
1077
+ stateTitle = null,
1078
+ stateUrl = null,
1079
+ newState = null;
1080
+
1081
+ // Prepare
1082
+ event = event||{};
1083
+ if ( typeof event.state === 'undefined' ) {
1084
+ // jQuery
1085
+ if ( typeof event.originalEvent !== 'undefined' && typeof event.originalEvent.state !== 'undefined' ) {
1086
+ event.state = event.originalEvent.state;
1087
+ }
1088
+ // MooTools
1089
+ else if ( typeof event.event !== 'undefined' && typeof event.event.state !== 'undefined' ) {
1090
+ event.state = event.event.state;
1091
+ }
1092
+ }
1093
+
1094
+ // Fetch Data
1095
+ if ( event.state === null ) {
1096
+ // Vanilla: State has no data (new state, not pushed)
1097
+ stateData = event.state;
1098
+ }
1099
+ else if ( typeof event.state !== 'undefined' ) {
1100
+ // Vanilla: Back/forward button was used
1101
+
1102
+ // Using Chrome Fix
1103
+ var
1104
+ newStateUrl = History.expandUrl(document.location.href),
1105
+ oldState = _History.getStateByUrl(newStateUrl),
1106
+ duplicateExists = _History.urlDuplicateExists(newStateUrl);
1107
+
1108
+ // Does oldState Exist?
1109
+ if ( typeof oldState !== 'undefined' && !duplicateExists ) {
1110
+ stateData = oldState.data;
1111
+ }
1112
+ else {
1113
+ stateData = event.state;
1114
+ }
1115
+
1116
+ // Use the way that should work
1117
+ // stateData = event.state;
1118
+ }
1119
+ else {
1120
+ // Vanilla: A new state was pushed, and popstate was called manually
1121
+
1122
+ // Get State object from the last state
1123
+ var
1124
+ newStateUrl = History.expandUrl(document.location.href),
1125
+ oldState = _History.getStateByUrl(newStateUrl);
1126
+
1127
+ // Check if the URLs match
1128
+ if ( oldState && newStateUrl == oldState.url ) {
1129
+ stateData = oldState.data;
1130
+ }
1131
+ else {
1132
+ throw new Error('Unknown state');
1133
+ }
1134
+ }
1135
+
1136
+ // Resolve newState
1137
+ stateData = (typeof stateData !== 'object' || stateData === null) ? {} : stateData;
1138
+ stateTitle = stateData.title||'',
1139
+ stateUrl = stateData.url||document.location.href,
1140
+ newState = History.createStateObject(stateData,stateTitle,stateUrl);
1141
+
1142
+ // Check if we are the same state
1143
+ if ( _History.isLastState(newState) ) {
1144
+ // There has been no change (just the page's hash has finally propagated)
1145
+ History.debug('_History.onPopState: no change', newState, _History.savedStates);
1146
+ History.busy(false);
1147
+ return false;
1148
+ }
1149
+
1150
+ // Log
1151
+ History.debug(
1152
+ '_History.onPopState',
1153
+ 'newState:', newState,
1154
+ 'oldState:', _History.getStateByUrl(History.expandUrl(document.location.href)),
1155
+ 'duplicateExists:', _History.urlDuplicateExists(History.expandUrl(document.location.href))
1156
+ );
1157
+
1158
+ // Store the State
1159
+ _History.storeState(newState);
1160
+ _History.saveState(newState);
1161
+
1162
+ // Force update of the title
1163
+ if ( newState.title ) {
1164
+ document.title = newState.title
1165
+ }
1166
+
1167
+ // Fire Our Event
1168
+ History.Adapter.trigger(window,'statechange');
1169
+ History.busy(false);
1170
+
1171
+ // Return true
1172
+ return true;
1173
+ };
1174
+ History.Adapter.bind(window,'popstate',_History.onPopState);
1175
+
1176
+ /**
1177
+ * History.pushState(data,title,url)
1178
+ * Add a new State to the history object, become it, and trigger onpopstate
1179
+ * We have to trigger for HTML4 compatibility
1180
+ * @param {object} data
1181
+ * @param {string} title
1182
+ * @param {string} url
1183
+ * @return {true}
1184
+ */
1185
+ History.pushState = function(data,title,url,queue){
1186
+ // Check the State
1187
+ if ( History.extractHashFromUrl(url) ) {
1188
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
1189
+ }
1190
+
1191
+ // Handle Queueing
1192
+ if ( queue !== false && History.busy() ) {
1193
+ // Wait + Push to Queue
1194
+ History.debug('History.pushState: we must wait', arguments);
1195
+ History.pushQueue({
1196
+ scope: History,
1197
+ callback: History.pushState,
1198
+ args: arguments,
1199
+ queue: queue
1200
+ });
1201
+ return false;
1202
+ }
1203
+
1204
+ // Make Busy + Continue
1205
+ History.busy(true);
1206
+
1207
+ // Create the newState
1208
+ var newState = History.createStateObject(data,title,url);
1209
+
1210
+ // Store the newState
1211
+ _History.storeState(newState);
1212
+
1213
+ // Push the newState
1214
+ history.pushState(newState.data,newState.title,newState.url);
1215
+
1216
+ // Fire HTML5 Event
1217
+ History.Adapter.trigger(window,'popstate');
1218
+
1219
+ // End pushState closure
1220
+ return true;
1221
+ }
1222
+
1223
+ /**
1224
+ * History.replaceState(data,title,url)
1225
+ * Replace the State and trigger onpopstate
1226
+ * We have to trigger for HTML4 compatibility
1227
+ * @param {object} data
1228
+ * @param {string} title
1229
+ * @param {string} url
1230
+ * @return {true}
1231
+ */
1232
+ History.replaceState = function(data,title,url,queue){
1233
+ // Check the State
1234
+ if ( History.extractHashFromUrl(url) ) {
1235
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
1236
+ }
1237
+
1238
+ // Handle Queueing
1239
+ if ( queue !== false && History.busy() ) {
1240
+ // Wait + Push to Queue
1241
+ History.debug('History.replaceState: we must wait', arguments);
1242
+ History.pushQueue({
1243
+ scope: History,
1244
+ callback: History.replaceState,
1245
+ args: arguments,
1246
+ queue: queue
1247
+ });
1248
+ return false;
1249
+ }
1250
+
1251
+ // Make Busy + Continue
1252
+ History.busy(true);
1253
+
1254
+ // Create the newState
1255
+ var newState = History.createStateObject(data,title,url);
1256
+
1257
+ // Store the newState
1258
+ _History.storeState(newState);
1259
+
1260
+ // Push the newState
1261
+ history.replaceState(newState.data,newState.title,newState.url);
1262
+
1263
+ // Fire HTML5 Event
1264
+ History.Adapter.trigger(window,'popstate');
1265
+
1266
+ // End replaceState closure
1267
+ return true;
1268
+ }
1269
+
1270
+
1271
+ /**
1272
+ * Ensure Cross Browser Compatibility
1273
+ */
1274
+ if ( navigator.vendor === 'Apple Computer, Inc.' ) {
1275
+ /**
1276
+ * Fix Safari Initial State Issue
1277
+ */
1278
+ History.Adapter.onDomLoad(function(){
1279
+ History.debug('Safari Initial State Change Fix');
1280
+ var currentState = History.createStateObject({},'',document.location.href);
1281
+ History.pushState(currentState.data,currentState.title,currentState.url);
1282
+ });
1283
+
1284
+ /**
1285
+ * Fix Safari HashChange Issue
1286
+ */
1287
+ History.Adapter.bind(window,'hashchange',function(){
1288
+ History.Adapter.trigger(window,'popstate');
1289
+ });
1290
+ }
1291
+ }
1292
+ }; // init
1293
+
1294
+ // Try Load HTML5 Support
1295
+ History.initHtml5();
1296
+
1297
+ })(window);