compass-jquery-plugin 0.3.2.6 → 0.3.2.7.nil

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. data/README.md +2 -1
  2. data/VERSION.yml +2 -2
  3. data/lib/handle_js_files.rb +21 -2
  4. data/templates/dynatree/jquery.dynatree.js +23 -20
  5. data/templates/dynatree/jquery.dynatree.min.js +38 -38
  6. data/templates/dynatree/jquery/dynatree/aero.scss +1 -1
  7. data/templates/dynatree/jquery/dynatree/aqua.scss +1 -1
  8. data/templates/dynatree/jquery/dynatree/crystal.scss +1 -1
  9. data/templates/dynatree/jquery/dynatree/xp.scss +2 -2
  10. data/templates/ical/jquery/ical.scss +10 -10
  11. data/templates/jqgrid/i18n/jqgrid/locale-lt.js +134 -0
  12. data/templates/jqgrid/i18n/jqgrid/locale-lt.min.js +7 -0
  13. data/templates/jqgrid/jquery.jqGrid.js +155 -65
  14. data/templates/jqgrid/jquery.jqGrid.min.js +396 -393
  15. data/templates/jqgrid/manifest.rb +2 -0
  16. data/templates/jqtouch/jquery.jqtouch.js +166 -195
  17. data/templates/jqtouch/jquery.jqtouch.min.js +1 -1
  18. data/templates/jqtouch/jquery/touch/apple.scss +5 -5
  19. data/templates/jqtouch/jquery/touch/default.scss +5 -5
  20. data/templates/jqtouch/jquery/touch/jqt.scss +12 -7
  21. data/templates/jqtouch/jquery/touch/jqtouch.scss +11 -13
  22. data/templates/jquery/history.adapter.jquery.js +54 -67
  23. data/templates/jquery/history.adapter.jquery.min.js +2 -2
  24. data/templates/jquery/history.html4.js +587 -680
  25. data/templates/jquery/history.html4.min.js +8 -18
  26. data/templates/jquery/history.js +1670 -1289
  27. data/templates/jquery/history.min.js +25 -21
  28. data/templates/jquery/i18n/jquery.ui/datepicker-ar.js +1 -1
  29. data/templates/jquery/i18n/jquery.ui/datepicker-ar.min.js +1 -1
  30. data/templates/jquery/i18n/jquery.ui/datepicker-tj.js +23 -0
  31. data/templates/jquery/i18n/jquery.ui/datepicker-tj.min.js +2 -0
  32. data/templates/jquery/jquery-ui.js +97 -61
  33. data/templates/jquery/jquery-ui.min.js +175 -175
  34. data/templates/jquery/jquery.dst.js +86 -151
  35. data/templates/jquery/jquery/ui/_theme.scss +13 -13
  36. data/templates/jquery/json2.js +214 -214
  37. data/templates/jquery/manifest.rb +2 -0
  38. data/templates/mobile/jquery.mobile.js +324 -225
  39. data/templates/mobile/jquery.mobile.min.js +4 -4
  40. data/templates/mobile/jquery/mobile/_base.scss +60 -48
  41. data/templates/mobile/jquery/mobile/default.scss +57 -80
  42. data/templates/mobile/jquery/mobile/default/icons-18-black.png +0 -0
  43. data/templates/mobile/jquery/mobile/default/icons-18-white.png +0 -0
  44. data/templates/mobile/jquery/mobile/default/icons-36-black.png +0 -0
  45. data/templates/mobile/jquery/mobile/default/icons-36-white.png +0 -0
  46. data/templates/mobile/jquery/mobile/valencia.scss +61 -73
  47. data/templates/mobile/jquery/mobile/valencia/icons-18-black.png +0 -0
  48. data/templates/mobile/jquery/mobile/valencia/icons-18-white.png +0 -0
  49. data/templates/mobile/jquery/mobile/valencia/icons-36-black.png +0 -0
  50. data/templates/mobile/jquery/mobile/valencia/icons-36-white.png +0 -0
  51. data/templates/mobile/manifest.rb +0 -8
  52. data/templates/ribbon/jquery/ribbon/office.scss +12 -12
  53. data/templates/ribbon/jquery/ribbon/windows7.scss +12 -12
  54. data/templates/tiny_mce/manifest.rb +16 -0
  55. data/templates/tiny_mce/tiny_mce/jquery.tinymce.js +1 -1
  56. data/templates/tiny_mce/tiny_mce/langs/de.js +1 -0
  57. data/templates/tiny_mce/tiny_mce/langs/en.js +1 -222
  58. data/templates/tiny_mce/tiny_mce/plugins/advhr/css/advhr.css +1 -5
  59. data/templates/tiny_mce/tiny_mce/plugins/advhr/editor_plugin.js +1 -1
  60. data/templates/tiny_mce/tiny_mce/plugins/advhr/editor_plugin_src.js +1 -57
  61. data/templates/tiny_mce/tiny_mce/plugins/advhr/js/rule.js +1 -43
  62. data/templates/tiny_mce/tiny_mce/plugins/advhr/langs/de_dlg.js +1 -0
  63. data/templates/tiny_mce/tiny_mce/plugins/advhr/langs/en_dlg.js +1 -7
  64. data/templates/tiny_mce/tiny_mce/plugins/advhr/rule.htm +1 -58
  65. data/templates/tiny_mce/tiny_mce/plugins/advimage/css/advimage.css +1 -13
  66. data/templates/tiny_mce/tiny_mce/plugins/advimage/editor_plugin.js +1 -1
  67. data/templates/tiny_mce/tiny_mce/plugins/advimage/editor_plugin_src.js +1 -50
  68. data/templates/tiny_mce/tiny_mce/plugins/advimage/image.htm +1 -235
  69. data/templates/tiny_mce/tiny_mce/plugins/advimage/js/image.js +1 -445
  70. data/templates/tiny_mce/tiny_mce/plugins/advimage/langs/de_dlg.js +1 -0
  71. data/templates/tiny_mce/tiny_mce/plugins/advimage/langs/en_dlg.js +1 -45
  72. data/templates/tiny_mce/tiny_mce/plugins/advlink/css/advlink.css +1 -8
  73. data/templates/tiny_mce/tiny_mce/plugins/advlink/editor_plugin.js +1 -1
  74. data/templates/tiny_mce/tiny_mce/plugins/advlink/editor_plugin_src.js +1 -61
  75. data/templates/tiny_mce/tiny_mce/plugins/advlink/js/advlink.js +1 -525
  76. data/templates/tiny_mce/tiny_mce/plugins/advlink/langs/de_dlg.js +1 -0
  77. data/templates/tiny_mce/tiny_mce/plugins/advlink/langs/en_dlg.js +1 -54
  78. data/templates/tiny_mce/tiny_mce/plugins/advlink/link.htm +1 -338
  79. data/templates/tiny_mce/tiny_mce/plugins/advlist/editor_plugin.js +1 -1
  80. data/templates/tiny_mce/tiny_mce/plugins/advlist/editor_plugin_src.js +1 -154
  81. data/templates/tiny_mce/tiny_mce/plugins/autoresize/editor_plugin.js +1 -1
  82. data/templates/tiny_mce/tiny_mce/plugins/autoresize/editor_plugin_src.js +1 -119
  83. data/templates/tiny_mce/tiny_mce/plugins/autosave/editor_plugin.js +1 -1
  84. data/templates/tiny_mce/tiny_mce/plugins/autosave/editor_plugin_src.js +1 -431
  85. data/templates/tiny_mce/tiny_mce/plugins/autosave/langs/en.js +1 -4
  86. data/templates/tiny_mce/tiny_mce/plugins/bbcode/editor_plugin.js +1 -1
  87. data/templates/tiny_mce/tiny_mce/plugins/bbcode/editor_plugin_src.js +1 -120
  88. data/templates/tiny_mce/tiny_mce/plugins/contextmenu/editor_plugin.js +1 -1
  89. data/templates/tiny_mce/tiny_mce/plugins/contextmenu/editor_plugin_src.js +1 -154
  90. data/templates/tiny_mce/tiny_mce/plugins/directionality/editor_plugin.js +1 -1
  91. data/templates/tiny_mce/tiny_mce/plugins/directionality/editor_plugin_src.js +1 -82
  92. data/templates/tiny_mce/tiny_mce/plugins/emotions/editor_plugin.js +1 -1
  93. data/templates/tiny_mce/tiny_mce/plugins/emotions/editor_plugin_src.js +1 -43
  94. data/templates/tiny_mce/tiny_mce/plugins/emotions/emotions.htm +1 -41
  95. data/templates/tiny_mce/tiny_mce/plugins/emotions/js/emotions.js +1 -22
  96. data/templates/tiny_mce/tiny_mce/plugins/emotions/langs/de_dlg.js +1 -0
  97. data/templates/tiny_mce/tiny_mce/plugins/emotions/langs/en_dlg.js +1 -20
  98. data/templates/tiny_mce/tiny_mce/plugins/example/dialog.htm +1 -22
  99. data/templates/tiny_mce/tiny_mce/plugins/example/editor_plugin.js +1 -1
  100. data/templates/tiny_mce/tiny_mce/plugins/example/editor_plugin_src.js +1 -84
  101. data/templates/tiny_mce/tiny_mce/plugins/example/js/dialog.js +1 -19
  102. data/templates/tiny_mce/tiny_mce/plugins/example/langs/en.js +1 -3
  103. data/templates/tiny_mce/tiny_mce/plugins/example/langs/en_dlg.js +1 -3
  104. data/templates/tiny_mce/tiny_mce/plugins/fullpage/css/fullpage.css +1 -182
  105. data/templates/tiny_mce/tiny_mce/plugins/fullpage/editor_plugin.js +1 -1
  106. data/templates/tiny_mce/tiny_mce/plugins/fullpage/editor_plugin_src.js +1 -166
  107. data/templates/tiny_mce/tiny_mce/plugins/fullpage/fullpage.htm +1 -571
  108. data/templates/tiny_mce/tiny_mce/plugins/fullpage/js/fullpage.js +1 -492
  109. data/templates/tiny_mce/tiny_mce/plugins/fullpage/langs/de_dlg.js +1 -0
  110. data/templates/tiny_mce/tiny_mce/plugins/fullpage/langs/en_dlg.js +1 -85
  111. data/templates/tiny_mce/tiny_mce/plugins/fullscreen/editor_plugin.js +1 -1
  112. data/templates/tiny_mce/tiny_mce/plugins/fullscreen/editor_plugin_src.js +1 -159
  113. data/templates/tiny_mce/tiny_mce/plugins/fullscreen/fullscreen.htm +1 -109
  114. data/templates/tiny_mce/tiny_mce/plugins/iespell/editor_plugin.js +1 -1
  115. data/templates/tiny_mce/tiny_mce/plugins/iespell/editor_plugin_src.js +1 -54
  116. data/templates/tiny_mce/tiny_mce/plugins/inlinepopups/editor_plugin.js +1 -1
  117. data/templates/tiny_mce/tiny_mce/plugins/inlinepopups/editor_plugin_src.js +1 -696
  118. data/templates/tiny_mce/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css +1 -90
  119. data/templates/tiny_mce/tiny_mce/plugins/inlinepopups/template.htm +1 -387
  120. data/templates/tiny_mce/tiny_mce/plugins/insertdatetime/editor_plugin.js +1 -1
  121. data/templates/tiny_mce/tiny_mce/plugins/insertdatetime/editor_plugin_src.js +1 -83
  122. data/templates/tiny_mce/tiny_mce/plugins/layer/editor_plugin.js +1 -1
  123. data/templates/tiny_mce/tiny_mce/plugins/layer/editor_plugin_src.js +1 -214
  124. data/templates/tiny_mce/tiny_mce/plugins/legacyoutput/editor_plugin.js +1 -1
  125. data/templates/tiny_mce/tiny_mce/plugins/legacyoutput/editor_plugin_src.js +1 -139
  126. data/templates/tiny_mce/tiny_mce/plugins/media/css/media.css +1 -17
  127. data/templates/tiny_mce/tiny_mce/plugins/media/editor_plugin.js +1 -1
  128. data/templates/tiny_mce/tiny_mce/plugins/media/editor_plugin_src.js +1 -770
  129. data/templates/tiny_mce/tiny_mce/plugins/media/js/embed.js +1 -73
  130. data/templates/tiny_mce/tiny_mce/plugins/media/js/media.js +1 -340
  131. data/templates/tiny_mce/tiny_mce/plugins/media/langs/de_dlg.js +1 -0
  132. data/templates/tiny_mce/tiny_mce/plugins/media/langs/en_dlg.js +1 -109
  133. data/templates/tiny_mce/tiny_mce/plugins/media/media.htm +1 -812
  134. data/templates/tiny_mce/tiny_mce/plugins/nonbreaking/editor_plugin.js +1 -1
  135. data/templates/tiny_mce/tiny_mce/plugins/nonbreaking/editor_plugin_src.js +1 -53
  136. data/templates/tiny_mce/tiny_mce/plugins/noneditable/editor_plugin.js +1 -1
  137. data/templates/tiny_mce/tiny_mce/plugins/noneditable/editor_plugin_src.js +1 -90
  138. data/templates/tiny_mce/tiny_mce/plugins/pagebreak/editor_plugin.js +1 -1
  139. data/templates/tiny_mce/tiny_mce/plugins/pagebreak/editor_plugin_src.js +1 -74
  140. data/templates/tiny_mce/tiny_mce/plugins/paste/editor_plugin.js +1 -1
  141. data/templates/tiny_mce/tiny_mce/plugins/paste/editor_plugin_src.js +1 -899
  142. data/templates/tiny_mce/tiny_mce/plugins/paste/js/pastetext.js +1 -36
  143. data/templates/tiny_mce/tiny_mce/plugins/paste/js/pasteword.js +1 -51
  144. data/templates/tiny_mce/tiny_mce/plugins/paste/langs/de_dlg.js +1 -0
  145. data/templates/tiny_mce/tiny_mce/plugins/paste/langs/en_dlg.js +1 -5
  146. data/templates/tiny_mce/tiny_mce/plugins/paste/pastetext.htm +1 -27
  147. data/templates/tiny_mce/tiny_mce/plugins/paste/pasteword.htm +1 -21
  148. data/templates/tiny_mce/tiny_mce/plugins/preview/editor_plugin.js +1 -1
  149. data/templates/tiny_mce/tiny_mce/plugins/preview/editor_plugin_src.js +1 -53
  150. data/templates/tiny_mce/tiny_mce/plugins/preview/example.html +17 -16
  151. data/templates/tiny_mce/tiny_mce/plugins/preview/jscripts/embed.js +1 -73
  152. data/templates/tiny_mce/tiny_mce/plugins/preview/preview.html +10 -9
  153. data/templates/tiny_mce/tiny_mce/plugins/print/editor_plugin.js +1 -1
  154. data/templates/tiny_mce/tiny_mce/plugins/print/editor_plugin_src.js +1 -34
  155. data/templates/tiny_mce/tiny_mce/plugins/save/editor_plugin.js +1 -1
  156. data/templates/tiny_mce/tiny_mce/plugins/save/editor_plugin_src.js +1 -101
  157. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/css/searchreplace.css +1 -6
  158. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/editor_plugin.js +1 -1
  159. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/editor_plugin_src.js +1 -61
  160. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/js/searchreplace.js +1 -140
  161. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/langs/de_dlg.js +1 -0
  162. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/langs/en_dlg.js +1 -16
  163. data/templates/tiny_mce/tiny_mce/plugins/searchreplace/searchreplace.htm +1 -100
  164. data/templates/tiny_mce/tiny_mce/plugins/spellchecker/css/content.css +1 -1
  165. data/templates/tiny_mce/tiny_mce/plugins/spellchecker/editor_plugin.js +1 -1
  166. data/templates/tiny_mce/tiny_mce/plugins/spellchecker/editor_plugin_src.js +1 -415
  167. data/templates/tiny_mce/tiny_mce/plugins/style/css/props.css +1 -13
  168. data/templates/tiny_mce/tiny_mce/plugins/style/editor_plugin.js +1 -1
  169. data/templates/tiny_mce/tiny_mce/plugins/style/editor_plugin_src.js +1 -55
  170. data/templates/tiny_mce/tiny_mce/plugins/style/js/props.js +1 -635
  171. data/templates/tiny_mce/tiny_mce/plugins/style/langs/de_dlg.js +1 -0
  172. data/templates/tiny_mce/tiny_mce/plugins/style/langs/en_dlg.js +1 -70
  173. data/templates/tiny_mce/tiny_mce/plugins/style/props.htm +1 -838
  174. data/templates/tiny_mce/tiny_mce/plugins/tabfocus/editor_plugin.js +1 -1
  175. data/templates/tiny_mce/tiny_mce/plugins/tabfocus/editor_plugin_src.js +1 -114
  176. data/templates/tiny_mce/tiny_mce/plugins/table/cell.htm +1 -178
  177. data/templates/tiny_mce/tiny_mce/plugins/table/css/cell.css +1 -17
  178. data/templates/tiny_mce/tiny_mce/plugins/table/css/row.css +1 -25
  179. data/templates/tiny_mce/tiny_mce/plugins/table/css/table.css +1 -13
  180. data/templates/tiny_mce/tiny_mce/plugins/table/editor_plugin.js +1 -1
  181. data/templates/tiny_mce/tiny_mce/plugins/table/editor_plugin_src.js +1 -1183
  182. data/templates/tiny_mce/tiny_mce/plugins/table/js/cell.js +1 -284
  183. data/templates/tiny_mce/tiny_mce/plugins/table/js/merge_cells.js +1 -27
  184. data/templates/tiny_mce/tiny_mce/plugins/table/js/row.js +1 -232
  185. data/templates/tiny_mce/tiny_mce/plugins/table/js/table.js +1 -450
  186. data/templates/tiny_mce/tiny_mce/plugins/table/langs/de_dlg.js +1 -0
  187. data/templates/tiny_mce/tiny_mce/plugins/table/langs/en_dlg.js +1 -74
  188. data/templates/tiny_mce/tiny_mce/plugins/table/merge_cells.htm +1 -32
  189. data/templates/tiny_mce/tiny_mce/plugins/table/row.htm +1 -157
  190. data/templates/tiny_mce/tiny_mce/plugins/table/table.htm +1 -188
  191. data/templates/tiny_mce/tiny_mce/plugins/template/blank.htm +1 -12
  192. data/templates/tiny_mce/tiny_mce/plugins/template/css/template.css +1 -23
  193. data/templates/tiny_mce/tiny_mce/plugins/template/editor_plugin.js +1 -1
  194. data/templates/tiny_mce/tiny_mce/plugins/template/editor_plugin_src.js +1 -159
  195. data/templates/tiny_mce/tiny_mce/plugins/template/js/template.js +1 -106
  196. data/templates/tiny_mce/tiny_mce/plugins/template/langs/de_dlg.js +1 -0
  197. data/templates/tiny_mce/tiny_mce/plugins/template/langs/en_dlg.js +1 -15
  198. data/templates/tiny_mce/tiny_mce/plugins/template/template.htm +1 -31
  199. data/templates/tiny_mce/tiny_mce/plugins/visualchars/editor_plugin.js +1 -1
  200. data/templates/tiny_mce/tiny_mce/plugins/visualchars/editor_plugin_src.js +1 -83
  201. data/templates/tiny_mce/tiny_mce/plugins/wordcount/editor_plugin.js +1 -1
  202. data/templates/tiny_mce/tiny_mce/plugins/wordcount/editor_plugin_src.js +1 -114
  203. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/abbr.htm +1 -142
  204. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/acronym.htm +1 -142
  205. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/attributes.htm +1 -149
  206. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/cite.htm +1 -142
  207. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/css/attributes.css +1 -11
  208. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/css/popup.css +1 -9
  209. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/del.htm +1 -162
  210. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/editor_plugin.js +1 -1
  211. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js +1 -132
  212. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/ins.htm +1 -162
  213. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/abbr.js +1 -28
  214. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/acronym.js +1 -28
  215. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/attributes.js +1 -125
  216. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/cite.js +1 -28
  217. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/del.js +1 -53
  218. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/element_common.js +1 -229
  219. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/js/ins.js +1 -53
  220. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/langs/de_dlg.js +1 -0
  221. data/templates/tiny_mce/tiny_mce/plugins/xhtmlxtras/langs/en_dlg.js +1 -32
  222. data/templates/tiny_mce/tiny_mce/themes/advanced/about.htm +1 -52
  223. data/templates/tiny_mce/tiny_mce/themes/advanced/anchor.htm +1 -26
  224. data/templates/tiny_mce/tiny_mce/themes/advanced/charmap.htm +1 -51
  225. data/templates/tiny_mce/tiny_mce/themes/advanced/color_picker.htm +1 -74
  226. data/templates/tiny_mce/tiny_mce/themes/advanced/editor_template.js +1 -1
  227. data/templates/tiny_mce/tiny_mce/themes/advanced/editor_template_src.js +1 -1328
  228. data/templates/tiny_mce/tiny_mce/themes/advanced/image.htm +1 -80
  229. data/templates/tiny_mce/tiny_mce/themes/advanced/js/about.js +1 -73
  230. data/templates/tiny_mce/tiny_mce/themes/advanced/js/anchor.js +1 -42
  231. data/templates/tiny_mce/tiny_mce/themes/advanced/js/charmap.js +1 -354
  232. data/templates/tiny_mce/tiny_mce/themes/advanced/js/color_picker.js +1 -329
  233. data/templates/tiny_mce/tiny_mce/themes/advanced/js/image.js +1 -247
  234. data/templates/tiny_mce/tiny_mce/themes/advanced/js/link.js +1 -153
  235. data/templates/tiny_mce/tiny_mce/themes/advanced/js/source_editor.js +1 -56
  236. data/templates/tiny_mce/tiny_mce/themes/advanced/langs/de.js +1 -0
  237. data/templates/tiny_mce/tiny_mce/themes/advanced/langs/de_dlg.js +1 -0
  238. data/templates/tiny_mce/tiny_mce/themes/advanced/langs/en.js +1 -68
  239. data/templates/tiny_mce/tiny_mce/themes/advanced/langs/en_dlg.js +1 -54
  240. data/templates/tiny_mce/tiny_mce/themes/advanced/link.htm +1 -57
  241. data/templates/tiny_mce/tiny_mce/themes/advanced/shortcuts.htm +1 -47
  242. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/default/content.css +1 -47
  243. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/default/dialog.css +1 -117
  244. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/default/ui.css +1 -213
  245. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/highcontrast/content.css +1 -23
  246. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +1 -105
  247. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/highcontrast/ui.css +1 -101
  248. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/o2k7/content.css +1 -46
  249. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/o2k7/dialog.css +1 -116
  250. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/o2k7/ui.css +1 -215
  251. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +1 -8
  252. data/templates/tiny_mce/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +1 -5
  253. data/templates/tiny_mce/tiny_mce/themes/advanced/source_editor.htm +1 -25
  254. data/templates/tiny_mce/tiny_mce/themes/simple/editor_template.js +1 -1
  255. data/templates/tiny_mce/tiny_mce/themes/simple/editor_template_src.js +1 -84
  256. data/templates/tiny_mce/tiny_mce/themes/simple/langs/de.js +1 -0
  257. data/templates/tiny_mce/tiny_mce/themes/simple/langs/en.js +1 -11
  258. data/templates/tiny_mce/tiny_mce/themes/simple/skins/default/content.css +1 -25
  259. data/templates/tiny_mce/tiny_mce/themes/simple/skins/default/ui.css +1 -32
  260. data/templates/tiny_mce/tiny_mce/themes/simple/skins/o2k7/content.css +1 -17
  261. data/templates/tiny_mce/tiny_mce/themes/simple/skins/o2k7/ui.css +1 -35
  262. data/templates/tiny_mce/tiny_mce/tiny_mce.js +1 -1
  263. data/templates/tiny_mce/tiny_mce/tiny_mce_popup.js +1 -5
  264. data/templates/tiny_mce/tiny_mce/utils/editable_selects.js +1 -70
  265. data/templates/tiny_mce/tiny_mce/utils/form_utils.js +1 -207
  266. data/templates/tiny_mce/tiny_mce/utils/mctabs.js +1 -162
  267. data/templates/tiny_mce/tiny_mce/utils/validate.js +1 -252
  268. metadata +32 -17
  269. data/templates/mobile/jquery/mobile/default/form-check-off.png +0 -0
  270. data/templates/mobile/jquery/mobile/default/form-check-on.png +0 -0
  271. data/templates/mobile/jquery/mobile/default/form-radio-off.png +0 -0
  272. data/templates/mobile/jquery/mobile/default/form-radio-on.png +0 -0
  273. data/templates/mobile/jquery/mobile/valencia/form-check-off.png +0 -0
  274. data/templates/mobile/jquery/mobile/valencia/form-check-on.png +0 -0
  275. data/templates/mobile/jquery/mobile/valencia/form-radio-off.png +0 -0
  276. data/templates/mobile/jquery/mobile/valencia/form-radio-on.png +0 -0
@@ -1,21 +1,11 @@
1
1
  /*
2
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
3
  */
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);
4
+ (function(h){var i=h.document,a=h.History=h.History||{};if(typeof a.initHtml4!=="undefined")throw Error("History.js HTML4 Support has already been loaded...");a.initHtml4=function(){if(typeof a.initHtml4.initialized!=="undefined")return false;else a.initHtml4.initialized=true;a.savedHashes=[];a.isLastHash=function(b){var c=a.getHashByIndex();return b===c};a.saveHash=function(b){if(a.isLastHash(b))return false;a.savedHashes.push(b);return true};a.getHashByIndex=function(b){var c=null;return c=typeof b===
5
+ "undefined"?a.savedHashes[a.savedHashes.length-1]:b<0?a.savedHashes[a.savedHashes.length+b]:a.savedHashes[b]};a.discardedHashes={};a.discardedStates={};a.discardState=function(b,c,e){var f=a.getHashByState(b);a.discardedStates[f]={discardedState:b,backState:e,forwardState:c};return true};a.discardHash=function(b,c,e){a.discardedHashes[b]={discardedHash:b,backState:e,forwardState:c};return true};a.discardedState=function(b){b=a.getHashByState(b);return a.discardedStates[b]||false};a.discardedHash=
6
+ function(b){return a.discardedHashes[b]||false};a.recycleState=function(b){var c=a.getHashByState(b);a.discardedState(b)&&delete a.discardedStates[c];return true};if(a.emulated.hashChange){a.hashChangeInit=function(){a.checkerFunction=null;var b="";if(a.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 e="",f=false;a.checkerFunction=function(){if(f)return false;
7
+ f=true;var d=a.getHash()||"",g=a.unescapeHash(c.contentWindow.document.location.hash)||"";if(d!==b){b=d;if(g!==d){e=d;c.contentWindow.document.open();c.contentWindow.document.close();c.contentWindow.document.location.hash=a.escapeHash(d)}a.Adapter.trigger(h,"hashchange")}else if(g!==e){e=g;a.setHash(g,false)}f=false;return true}}else a.checkerFunction=function(){var d=a.getHash();if(d!==b){b=d;a.Adapter.trigger(h,"hashchange")}return true};setInterval(a.checkerFunction,a.options.hashChangeInterval);
8
+ return true};a.Adapter.onDomLoad(a.hashChangeInit)}if(a.emulated.pushState){a.onHashChange=function(b){var c=a.getHashByUrl(b&&b.newURL||i.location.href);b=null;if(a.isLastHash(c)){a.busy(false);return false}a.doubleCheckComplete();a.saveHash(c);b=a.extractState(c||i.location.href);if(!b){a.Adapter.trigger(h,"anchorchange");a.busy(false);return false}if(a.isLastSavedState(b)){a.busy(false);return false}a.getHashByState(b);if(c=a.discardedState(b)){a.getHashByIndex(-2)===a.getHashByState(c.forwardState)?
9
+ a.back(false):a.forward(false);a.busy(false);return false}a.pushState(b.data,b.title,b.url,false);return true};a.Adapter.bind(h,"hashchange",a.onHashChange);a.pushState=function(b,c,e,f){if(a.getHashByUrl(e))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==false&&a.busy()){a.pushQueue({scope:a,callback:a.pushState,args:arguments,queue:f});return false}a.busy(true);var d=a.createStateObject(b,c,e),g=a.getHashByState(d),j=a.getState(false);j=a.getHashByState(j);
10
+ var k=a.getHash();a.storeState(d);a.expectedStateId=d.id;a.recycleState(d);a.setTitle(d);if(g===j){a.busy(false);return false}if(g!==k&&g!==a.getShortUrl(i.location.href)){a.setHash(g,false);return false}a.saveState(d);a.Adapter.trigger(h,"statechange");a.busy(false);return true};a.replaceState=function(b,c,e,f){if(a.getHashByUrl(e))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==false&&a.busy()){a.pushQueue({scope:a,callback:a.replaceState,args:arguments,
11
+ queue:f});return false}a.busy(true);var d=a.createStateObject(b,c,e),g=a.getState(false),j=a.getStateByIndex(-2);a.discardState(g,d,j);a.pushState(d.data,d.title,d.url,false);return true};a.saveState(a.storeState(a.createStateObject({},"",i.location.href)));a.getHash()&&!a.emulated.hashChange&&a.Adapter.onDomLoad(function(){a.Adapter.trigger(h,"hashchange")})}};a.init()})(window);
@@ -1,1297 +1,1678 @@
1
1
  /**
2
- * History.js HTML5 Support
2
+ * History.js Core
3
3
  * @author Benjamin Arthur Lupton <contact@balupton.com>
4
4
  * @copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
5
5
  * @license New BSD License <http://creativecommons.org/licenses/BSD/>
6
6
  */
7
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();
8
+ (function(window,undefined){
9
+ "use strict";
10
+
11
+ // --------------------------------------------------------------------------
12
+ // Initialise
13
+
14
+ // Localise Globals
15
+ var
16
+ console = window.console||undefined, // Prevent a JSLint complain
17
+ document = window.document, // Make sure we are using the correct document
18
+ navigator = window.navigator, // Make sure we are using the correct navigator
19
+ History = window.History = window.History||{}, // Public History Object
20
+ history = window.history; // Old History Object
21
+
22
+ // Check Existence
23
+ if ( typeof History.init !== 'undefined' ) {
24
+ throw new Error('History.js Core has already been loaded...');
25
+ }
26
+
27
+ // Initialise History
28
+ History.init = function(){
29
+ // Check Load Status of Adapter
30
+ if ( typeof History.Adapter === 'undefined' ) {
31
+ return false;
32
+ }
33
+
34
+ // Check Load Status of Core
35
+ if ( typeof History.initCore !== 'undefined' ) {
36
+ History.initCore();
37
+ }
38
+
39
+ // Check Load Status of HTML4 Support
40
+ if ( typeof History.initHtml4 !== 'undefined' ) {
41
+ History.initHtml4();
42
+ }
43
+
44
+ // Return true
45
+ return true;
46
+ };
47
+
48
+ // --------------------------------------------------------------------------
49
+ // Initialise Core
50
+
51
+ // Initialise Core
52
+ History.initCore = function(){
53
+ // Initialise
54
+ if ( typeof History.initCore.initialized !== 'undefined' ) {
55
+ // Already Loaded
56
+ return false;
57
+ }
58
+ else {
59
+ History.initCore.initialized = true;
60
+ }
61
+
62
+ // ----------------------------------------------------------------------
63
+ // Options
64
+
65
+ /**
66
+ * History.options
67
+ * Configurable options
68
+ */
69
+ History.options = History.options||{};
70
+
71
+ /**
72
+ * History.options.hashChangeInterval
73
+ * How long should the interval be before hashchange checks
74
+ */
75
+ History.options.hashChangeInterval = History.options.hashChangeInterval || 100;
76
+
77
+ /**
78
+ * History.options.safariPollInterval
79
+ * How long should the interval be before safari poll checks
80
+ */
81
+ History.options.safariPollInterval = History.options.safariPollInterval || 500;
82
+
83
+ /**
84
+ * History.options.doubleCheckInterval
85
+ * How long should the interval be before we perform a double check
86
+ */
87
+ History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500;
88
+
89
+ /**
90
+ * History.options.busyDelay
91
+ * How long should we wait between busy events
92
+ */
93
+ History.options.busyDelay = History.options.busyDelay || 250;
94
+
95
+ /**
96
+ * History.options.debug
97
+ * If true will enable debug messages to be logged
98
+ */
99
+ History.options.debug = History.options.debug || false;
100
+
101
+ /**
102
+ * History.options.initialTitle
103
+ * What is the title of the initial state
104
+ */
105
+ History.options.initialTitle = History.options.initialTitle || document.title;
106
+
107
+
108
+ // ----------------------------------------------------------------------
109
+ // Debug
110
+
111
+ /**
112
+ * History.debug(message,...)
113
+ * Logs the passed arguments if debug enabled
114
+ */
115
+ History.debug = function(){
116
+ if ( (History.options.debug||false) ) {
117
+ History.log.apply(History,arguments);
118
+ }
119
+ };
120
+
121
+ /**
122
+ * History.log(message,...)
123
+ * Logs the passed arguments
124
+ */
125
+ History.log = function(){
126
+ // Prepare
127
+ var
128
+ consoleExists = (typeof console !== 'undefined' && typeof console.log !== 'undefined' && typeof console.log.apply !== 'undefined'),
129
+ textarea = document.getElementById('log'),
130
+ message,
131
+ i,n
132
+ ;
133
+
134
+ // Write to Console
135
+ if ( consoleExists ) {
136
+ var args = Array.prototype.slice.call(arguments);
137
+ message = args.shift();
138
+ if ( typeof console.debug !== 'undefined' ) {
139
+ console.debug.apply(console,[message,args]);
140
+ }
141
+ else {
142
+ console.log.apply(console,[message,args]);
143
+ }
144
+ }
145
+ else {
146
+ message = ("\n"+arguments[0]+"\n");
147
+ }
148
+
149
+ // Write to log
150
+ for ( i=1,n=arguments.length; i<n; ++i ) {
151
+ var arg = arguments[i];
152
+ if ( typeof arg === 'object' && typeof JSON !== 'undefined' ) {
153
+ try {
154
+ arg = JSON.stringify(arg);
155
+ }
156
+ catch ( Exception ) {
157
+ // Recursive Object
158
+ }
159
+ }
160
+ message += "\n"+arg+"\n";
161
+ }
162
+
163
+ // Textarea
164
+ if ( textarea ) {
165
+ textarea.value += message+"\n-----\n";
166
+ textarea.scrollTop = textarea.scrollHeight - textarea.clientHeight;
167
+ }
168
+ // No Textarea, No Console
169
+ else if ( !consoleExists ) {
170
+ alert(message);
171
+ }
172
+
173
+ // Return true
174
+ return true;
175
+ };
176
+
177
+ // ----------------------------------------------------------------------
178
+ // Emulated Status
179
+
180
+ /**
181
+ * History.getInternetExplorerMajorVersion()
182
+ * Get's the major version of Internet Explorer
183
+ * @return {integer}
184
+ * @license Public Domain
185
+ * @author Benjamin Arthur Lupton <contact@balupton.com>
186
+ * @author James Padolsey <https://gist.github.com/527683>
187
+ */
188
+ History.getInternetExplorerMajorVersion = function(){
189
+ var result = History.getInternetExplorerMajorVersion.cached =
190
+ (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined')
191
+ ? History.getInternetExplorerMajorVersion.cached
192
+ : (function(){
193
+ var v = 3,
194
+ div = document.createElement('div'),
195
+ all = div.getElementsByTagName('i');
196
+ while ( (div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->') && all[0] ) {}
197
+ return (v > 4) ? v : false;
198
+ })()
199
+ ;
200
+ return result;
201
+ };
202
+
203
+ /**
204
+ * History.isInternetExplorer()
205
+ * Are we using Internet Explorer?
206
+ * @return {boolean}
207
+ * @license Public Domain
208
+ * @author Benjamin Arthur Lupton <contact@balupton.com>
209
+ */
210
+ History.isInternetExplorer = function(){
211
+ var result =
212
+ History.isInternetExplorer.cached =
213
+ (typeof History.isInternetExplorer.cached !== 'undefined')
214
+ ? History.isInternetExplorer.cached
215
+ : Boolean(History.getInternetExplorerMajorVersion())
216
+ ;
217
+ return result;
218
+ };
219
+
220
+ /**
221
+ * History.emulated
222
+ * Which features require emulating?
223
+ */
224
+ History.emulated = {
225
+ pushState: !Boolean(
226
+ window.history && window.history.pushState && window.history.replaceState
227
+ && !(/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */
228
+ ),
229
+ hashChange: Boolean(
230
+ !(('onhashchange' in window) || ('onhashchange' in document))
231
+ ||
232
+ (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8)
233
+ )
234
+ };
235
+
236
+ /**
237
+ * History.bugs
238
+ * Which bugs are present
239
+ */
240
+ History.bugs = {
241
+ /**
242
+ * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call
243
+ * https://bugs.webkit.org/show_bug.cgi?id=56249
244
+ */
245
+ setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2][0-9]|3[0-3])/.test(navigator.userAgent)),
246
+
247
+ /**
248
+ * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions
249
+ * https://bugs.webkit.org/show_bug.cgi?id=42940
250
+ */
251
+ safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2][0-9]|3[0-3])/.test(navigator.userAgent)),
252
+
253
+ /**
254
+ * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function)
255
+ */
256
+ ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8),
257
+
258
+ /**
259
+ * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event
260
+ */
261
+ hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7)
262
+ };
263
+
264
+ /**
265
+ * History.isEmptyObject(obj)
266
+ * Checks to see if the Object is Empty
267
+ * @param {Object} obj
268
+ * @return {boolean}
269
+ */
270
+ History.isEmptyObject = function(obj) {
271
+ for ( var name in obj ) {
272
+ return false;
273
+ }
274
+ return true;
275
+ };
276
+
277
+ /**
278
+ * History.cloneObject(obj)
279
+ * Clones a object
280
+ * @param {Object} obj
281
+ * @return {Object}
282
+ */
283
+ History.cloneObject = function(obj) {
284
+ var hash,newObj;
285
+ if ( obj ) {
286
+ hash = JSON.stringify(obj);
287
+ newObj = JSON.parse(hash);
288
+ }
289
+ else {
290
+ newObj = {};
291
+ }
292
+ return newObj;
293
+ };
294
+
295
+ // ----------------------------------------------------------------------
296
+ // URL Helpers
297
+
298
+ /**
299
+ * History.getRootUrl()
300
+ * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com"
301
+ * @return {String} rootUrl
302
+ */
303
+ History.getRootUrl = function(){
304
+ // Create
305
+ var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host);
306
+ if ( document.location.port||false ) {
307
+ rootUrl += ':'+document.location.port;
308
+ }
309
+ rootUrl += '/';
310
+
311
+ // Return
312
+ return rootUrl;
313
+ };
314
+
315
+ /**
316
+ * History.getBaseHref()
317
+ * Fetches the `href` attribute of the `<base href="...">` element if it exists
318
+ * @return {String} baseHref
319
+ */
320
+ History.getBaseHref = function(){
321
+ // Create
322
+ var
323
+ baseElements = document.getElementsByTagName('base'),
324
+ baseElement = null,
325
+ baseHref = '';
326
+
327
+ // Test for Base Element
328
+ if ( baseElements.length === 1 ) {
329
+ // Prepare for Base Element
330
+ baseElement = baseElements[0];
331
+ baseHref = baseElement.href.replace(/[^\/]+$/,'');
332
+ }
333
+
334
+ // Adjust trailing slash
335
+ baseHref = baseHref.replace(/\/+$/,'');
336
+ if ( baseHref ) baseHref += '/';
337
+
338
+ // Return
339
+ return baseHref;
340
+ };
341
+
342
+ /**
343
+ * History.getBaseUrl()
344
+ * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first)
345
+ * @return {String} baseUrl
346
+ */
347
+ History.getBaseUrl = function(){
348
+ // Create
349
+ var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl();
350
+
351
+ // Return
352
+ return baseUrl;
353
+ };
354
+
355
+ /**
356
+ * History.getPageUrl()
357
+ * Fetches the URL of the current page
358
+ * @return {String} pageUrl
359
+ */
360
+ History.getPageUrl = function(){
361
+ // Fetch
362
+ var
363
+ State = History.getState(),
364
+ stateUrl = State.url||document.location.href;
365
+
366
+ // Create
367
+ var pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){
368
+ return (/\./).test(part) ? part : part+'/';
369
+ });
370
+
371
+ // Return
372
+ return pageUrl;
373
+ };
374
+
375
+ /**
376
+ * History.getBasePageUrl()
377
+ * Fetches the Url of the directory of the current page
378
+ * @return {String} basePageUrl
379
+ */
380
+ History.getBasePageUrl = function(){
381
+ // Create
382
+ var basePageUrl = document.location.href.replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){
383
+ return (/\./).test(part) ? '' : part;
384
+ }).replace(/\/+$/,'')+'/';
385
+
386
+ // Return
387
+ return basePageUrl;
388
+ };
389
+
390
+ /**
391
+ * History.getFullUrl(url)
392
+ * Ensures that we have an absolute URL and not a relative URL
393
+ * @param {string} url
394
+ * @return {string} fullUrl
395
+ */
396
+ History.getFullUrl = function(url){
397
+ // Prepare
398
+ var fullUrl = url, firstChar = url.substring(0,1);
399
+
400
+ // Check
401
+ if ( /[a-z]+\:\/\//.test(url) ) {
402
+ // Full URL
403
+ }
404
+ else if ( firstChar === '/' ) {
405
+ // Root URL
406
+ fullUrl = History.getRootUrl()+url.replace(/^\/+/,'');
407
+ }
408
+ else if ( firstChar === '#' ) {
409
+ // Anchor URL
410
+ fullUrl = History.getPageUrl().replace(/#.*/,'')+url;
411
+ }
412
+ else if ( firstChar === '?' ) {
413
+ // Query URL
414
+ fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url;
415
+ }
416
+ else {
417
+ // Relative URL
418
+ fullUrl = History.getBaseUrl()+url;
419
+ }
420
+
421
+ // Return
422
+ return fullUrl.replace(/\#$/,'');
423
+ };
424
+
425
+ /**
426
+ * History.getShortUrl(url)
427
+ * Ensures that we have a relative URL and not a absolute URL
428
+ * @param {string} url
429
+ * @return {string} url
430
+ */
431
+ History.getShortUrl = function(url){
432
+ // Prepare
433
+ var shortUrl, rootUrl = History.getRootUrl(); // History.getBaseHref()||History.getBasePageUrl()
434
+
435
+ // Adjust
436
+ shortUrl = url.replace(rootUrl,'/');
437
+
438
+ // Return
439
+ return shortUrl.replace(/\#$/,'');
440
+ };
441
+
442
+ // ----------------------------------------------------------------------
443
+ // State Storage
444
+
445
+ /**
446
+ * History.idToState
447
+ * 1-1: State ID to State Object
448
+ */
449
+ History.idToState = {};
450
+
451
+ /**
452
+ * History.stateToId
453
+ * 1-1: State String to State ID
454
+ */
455
+ History.stateToId = {};
456
+
457
+ /**
458
+ * History.urlToId
459
+ * 1-1: State URL to State ID
460
+ */
461
+ History.urlToId = {};
462
+
463
+ /**
464
+ * History.storedStates
465
+ * Store the states in an array
466
+ */
467
+ History.storedStates = [];
468
+
469
+ /**
470
+ * History.savedStates
471
+ * Saved the states in an array
472
+ */
473
+ History.savedStates = [];
474
+
475
+ /**
476
+ * History.getState()
477
+ * Get an object containing the data, title and url of the current state
478
+ * @return {Object} State
479
+ */
480
+ History.getState = function(friendly){
481
+ // Prepare
482
+ if ( typeof friendly === 'undefined' ) { friendly = true; }
483
+
484
+ // Fetch
485
+ var State = History.getLastSavedState()||History.createStateObject();
486
+
487
+ // Adjust
488
+ if ( friendly ) {
489
+ State = History.cloneObject(State);
490
+ State.url = State.cleanUrl||State.url;
491
+ }
492
+
493
+ // Return
494
+ return State;
495
+ };
496
+
497
+ /**
498
+ * History.getIdByState(State)
499
+ * Gets a ID for a State
500
+ * @param {State} newState
501
+ * @return {String} id
502
+ */
503
+ History.getIdByState = function(newState){
504
+
505
+ // Fetch ID
506
+ var id = History.extractId(newState.url);
507
+ if ( !id ) {
508
+ // Find ID via State String
509
+ var str = History.getStateString(newState);
510
+ if ( typeof History.stateToId[str] !== 'undefined' ) {
511
+ id = History.stateToId[str];
512
+ }
513
+ else {
514
+ // Generate a new ID
515
+ while ( true ) {
516
+ id = String(Math.floor(Math.random()*1000));
517
+ if ( typeof History.idToState[id] === 'undefined' ) {
518
+ break;
519
+ }
520
+ }
521
+
522
+ // Apply the new State to the ID
523
+ History.stateToId[str] = id;
524
+ History.idToState[id] = newState;
525
+ }
526
+ }
527
+
528
+ // Return ID
529
+ return id;
530
+ };
531
+
532
+ /**
533
+ * History.normalizeState(State)
534
+ * Expands a State Object
535
+ * @param {object} State
536
+ * @return {object}
537
+ */
538
+ History.normalizeState = function(oldState){
539
+ // Prepare
540
+ if ( !oldState || (typeof oldState !== 'object') ) {
541
+ oldState = {};
542
+ }
543
+
544
+ // Check
545
+ if ( typeof oldState.normalized !== 'undefined' ) {
546
+ return oldState;
547
+ }
548
+
549
+ // Adjust
550
+ if ( !oldState.data || (typeof oldState.data !== 'object') ) {
551
+ oldState.data = {};
552
+ }
553
+
554
+ // ----------------------------------------------------------------------
555
+
556
+ // Create
557
+ var newState = {};
558
+ newState.normalized = true;
559
+ newState.title = oldState.title||'';
560
+ newState.url = History.getFullUrl(oldState.url||document.location.href);
561
+ newState.hash = History.getShortUrl(newState.url);
562
+ newState.data = History.cloneObject(oldState.data);
563
+
564
+ // Fetch ID
565
+ newState.id = History.getIdByState(newState);
566
+
567
+ // ----------------------------------------------------------------------
568
+
569
+ // Check to see if we have more than just a url
570
+ var dataNotEmpty = !History.isEmptyObject(newState.data);
571
+
572
+ // Apply
573
+ if ( newState.title || dataNotEmpty ) {
574
+ // Add ID to Hash
575
+ newState.hash = History.getShortUrl(newState.url).replace(/\&_suid.*/,'');
576
+ if ( !/\?/.test(newState.hash) ) {
577
+ newState.hash += '?';
578
+ }
579
+ newState.hash += '&_suid='+newState.id;
580
+ }
581
+
582
+ // Create the Hashed URL
583
+ newState.hashedUrl = History.getFullUrl(newState.hash);
584
+ newState.cleanUrl = newState.url.replace(/\&_suid.*/,'');
585
+
586
+ // ----------------------------------------------------------------------
587
+
588
+ // Update the URL if we have a duplicate
589
+ if ( History.hasUrlDuplicate(newState) ) {
590
+ newState.url = newState.hashedUrl;
591
+ }
592
+
593
+ // ----------------------------------------------------------------------
594
+
595
+ // Return
596
+ return newState;
597
+ };
598
+
599
+ /**
600
+ * History.createStateObject(data,title,url)
601
+ * Creates a object based on the data, title and url state params
602
+ * @param {object} data
603
+ * @param {string} title
604
+ * @param {string} url
605
+ * @return {object}
606
+ */
607
+ History.createStateObject = function(data,title,url){
608
+ // Hashify
609
+ var State = {
610
+ 'data': data,
611
+ 'title': title,
612
+ 'url': url
613
+ };
614
+
615
+ // Expand the State
616
+ State = History.normalizeState(State);
617
+
618
+ // Return object
619
+ return State;
620
+ };
621
+
622
+ /**
623
+ * History.getStateById(id)
624
+ * Get a state by it's UID
625
+ * @param {String} id
626
+ */
627
+ History.getStateById = function(id){
628
+ id = String(id);
629
+ var State = History.idToState[id]||undefined;
630
+ return State;
631
+ };
632
+
633
+ /**
634
+ * Get a State's String
635
+ * @param {State} passedState
636
+ */
637
+ History.getStateString = function(passedState){
638
+ // Prepare
639
+ var State = History.normalizeState(passedState);
640
+
641
+ // Clean
642
+ var cleanedState = {
643
+ data: State.data,
644
+ title: passedState.title,
645
+ url: passedState.url
646
+ };
647
+
648
+ // Fetch
649
+ var str = JSON.stringify(cleanedState);
650
+
651
+ // Return
652
+ return str;
653
+ };
654
+
655
+ /**
656
+ * Get a State's ID
657
+ * @param {State} passedState
658
+ * @return {String} id
659
+ */
660
+ History.getStateId = function(passedState){
661
+ // Prepare
662
+ var State = History.normalizeState(passedState);
663
+
664
+ // Fetch
665
+ var id = State.id;
666
+
667
+ // Return
668
+ return id;
669
+ };
670
+
671
+ /**
672
+ * History.getHashByState(State)
673
+ * Creates a Hash for the State Object
674
+ * @param {State} passedState
675
+ * @return {String} hash
676
+ */
677
+ History.getHashByState = function(passedState){
678
+ // Prepare
679
+ var hash, State = History.normalizeState(passedState);
680
+
681
+ // Fetch
682
+ hash = State.hash;
683
+
684
+ // Return
685
+ return hash;
686
+ };
687
+
688
+ /**
689
+ * History.extractId(url_or_hash)
690
+ * Get a State ID by it's URL or Hash
691
+ * @param {string} url_or_hash
692
+ * @return {string} id
693
+ */
694
+ History.extractId = function ( url_or_hash ) {
695
+ // Prepare
696
+ var id;
697
+
698
+ // Extract
699
+ var parts,url;
700
+ parts = /(.*)\&_suid=([0-9]+)$/.exec(url_or_hash);
701
+ url = parts ? (parts[1]||url_or_hash) : url_or_hash;
702
+ id = parts ? String(parts[2]||'') : '';
703
+
704
+ // Return
705
+ return id||false;
706
+ };
707
+
708
+ /**
709
+ * History.extractState
710
+ * Get a State by it's URL or Hash
711
+ */
712
+ History.extractState = function(url_or_hash,create){
713
+ // Prepare
714
+ var State = null;
715
+ create = create||false;
716
+
717
+ // Fetch SUID
718
+ var id = History.extractId(url_or_hash);
719
+ if ( id ) {
720
+ State = History.getStateById(id);
721
+ }
722
+
723
+ // Fetch SUID returned no State
724
+ if ( !State ) {
725
+ // Fetch URL
726
+ var url = History.getFullUrl(url_or_hash);
727
+
728
+ // Check URL
729
+ id = History.getIdByUrl(url)||false;
730
+ if ( id ) {
731
+ State = History.getStateById(id);
732
+ }
733
+ // Create State
734
+ else if ( create && /\//.test(url_or_hash) ) {
735
+ State = History.createStateObject(null,null,url.replace(/\&_suid.*/,''));
736
+ }
737
+ }
738
+
739
+ // Return
740
+ return State;
741
+ };
742
+
743
+ /**
744
+ * History.getIdByUrl()
745
+ * Get a State ID by a State URL
746
+ */
747
+ History.getIdByUrl = function(url){
748
+ var id = History.urlToId[url]||false;
749
+ return id;
750
+ };
751
+
752
+ /**
753
+ * History.getLastSavedState()
754
+ * Get an object containing the data, title and url of the current state
755
+ * @return {Object} State
756
+ */
757
+ History.getLastSavedState = function(){
758
+ return History.savedStates[History.savedStates.length-1]||undefined;
759
+ };
760
+
761
+ /**
762
+ * History.getLastStoredState()
763
+ * Get an object containing the data, title and url of the current state
764
+ * @return {Object} State
765
+ */
766
+ History.getLastStoredState = function(){
767
+ return History.storedStates[History.storedStates.length-1]||undefined;
768
+ };
769
+
770
+ /**
771
+ * History.hasUrlDuplicate
772
+ * Checks if a Url will have a url conflict
773
+ * @param {Object} newState
774
+ * @return {Boolean} hasDuplicate
775
+ */
776
+ History.hasUrlDuplicate = function(newState) {
777
+ // Prepare
778
+ var hasDuplicate = false;
779
+
780
+ // Fetch
781
+ var oldState = History.extractState(newState.url);
782
+
783
+ // Check
784
+ hasDuplicate = oldState && oldState.id !== newState.id;
785
+
786
+ // Return
787
+ return hasDuplicate;
788
+ };
789
+
790
+ /**
791
+ * History.storeState
792
+ * Store a State
793
+ * @param {Object} newState
794
+ * @return {Object} newState
795
+ */
796
+ History.storeState = function(newState){
797
+ // Store the State
798
+ History.urlToId[newState.url] = newState.id;
799
+
800
+ // Push the State
801
+ History.storedStates.push(History.cloneObject(newState));
802
+
803
+ // Return newState
804
+ return newState;
805
+ };
806
+
807
+ /**
808
+ * History.isLastSavedState(newState)
809
+ * Tests to see if the state is the last state
810
+ * @param {Object} newState
811
+ * @return {boolean} isLast
812
+ */
813
+ History.isLastSavedState = function(newState){
814
+ // Prepare
815
+ var isLast = false;
816
+
817
+ // Check
818
+ if ( History.savedStates.length ) {
819
+ var
820
+ newId = newState.id,
821
+ oldState = History.getLastSavedState(),
822
+ oldId = oldState.id;
823
+
824
+ // Check
825
+ isLast = (newId === oldId);
826
+ }
827
+
828
+ // Return
829
+ return isLast;
830
+ };
831
+
832
+ /**
833
+ * History.saveState
834
+ * Push a State
835
+ * @param {Object} newState
836
+ * @return {boolean} changed
837
+ */
838
+ History.saveState = function(newState){
839
+ // Check Hash
840
+ if ( History.isLastSavedState(newState) ) {
841
+ return false;
842
+ }
843
+
844
+ // Push the State
845
+ History.savedStates.push(History.cloneObject(newState));
846
+
847
+ // Return true
848
+ return true;
849
+ };
850
+
851
+ /**
852
+ * History.getStateByIndex()
853
+ * Gets a state by the index
854
+ * @param {integer} index
855
+ * @return {Object}
856
+ */
857
+ History.getStateByIndex = function(index){
858
+ // Prepare
859
+ var State = null;
860
+
861
+ // Handle
862
+ if ( typeof index === 'undefined' ) {
863
+ // Get the last inserted
864
+ State = History.savedStates[History.savedStates.length-1];
865
+ }
866
+ else if ( index < 0 ) {
867
+ // Get from the end
868
+ State = History.savedStates[History.savedStates.length+index];
869
+ }
870
+ else {
871
+ // Get from the beginning
872
+ State = History.savedStates[index];
873
+ }
874
+
875
+ // Return State
876
+ return State;
877
+ };
878
+
879
+ // ----------------------------------------------------------------------
880
+ // Hash Helpers
881
+
882
+ /**
883
+ * History.getHash()
884
+ * Gets the current document hash
885
+ * @return {string}
886
+ */
887
+ History.getHash = function(){
888
+ var hash = History.unescapeHash(document.location.hash);
889
+ return hash;
890
+ };
891
+
892
+ /**
893
+ * History.unescapeHash()
894
+ * normalize and Unescape a Hash
895
+ * @return {string}
896
+ */
897
+ History.unescapeHash = function(hash){
898
+ var result = History.normalizeHash(hash);
899
+
900
+ // Unescape hash
901
+ if ( /\%[^2][^5]/.test(result) ) {
902
+ result = window.unescape(result);
903
+ }
904
+
905
+ // Return result
906
+ return result;
907
+ };
908
+
909
+ /**
910
+ * History.normalizeHash()
911
+ * normalize a hash across browsers
912
+ * @return {string}
913
+ */
914
+ History.normalizeHash = function(hash){
915
+ var result = hash.replace(/[^#]*#/,'').replace(/#.*/, '');
916
+
917
+ // Return result
918
+ return result;
919
+ };
920
+
921
+ /**
922
+ * History.setHash(hash)
923
+ * Sets the document hash
924
+ * @param {string} hash
925
+ * @return {History}
926
+ */
927
+ History.setHash = function(hash,queue){
928
+ // Handle Queueing
929
+ if ( queue !== false && History.busy() ) {
930
+ // Wait + Push to Queue
931
+ //History.debug('History.setHash: we must wait', arguments);
932
+ History.pushQueue({
933
+ scope: History,
934
+ callback: History.setHash,
935
+ args: arguments,
936
+ queue: queue
937
+ });
938
+ return false;
939
+ }
940
+
941
+ // Log
942
+ //History.debug('History.setHash: called',hash);
943
+
944
+ // Prepare
945
+ var adjustedHash = History.escapeHash(hash);
946
+
947
+ // Make Busy + Continue
948
+ History.busy(true);
949
+
950
+ // Check if hash is a state
951
+ var State = History.extractState(hash,true);
952
+ if ( State && !History.emulated.pushState ) {
953
+ // Hash is a state so skip the setHash
954
+ //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments);
955
+
956
+ // PushState
957
+ History.pushState(State.data,State.title,State.url,false);
958
+ }
959
+ else if ( document.location.hash !== adjustedHash ) {
960
+ // Hash is a proper hash, so apply it
961
+
962
+ // Handle browser bugs
963
+ if ( History.bugs.setHash ) {
964
+ // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249
965
+
966
+ // Fetch the base page
967
+ var pageUrl = History.getPageUrl();
968
+
969
+ // Safari hash apply
970
+ History.pushState(null,null,pageUrl+'#'+adjustedHash,false);
971
+ }
972
+ else {
973
+ // Normal hash apply
974
+ document.location.hash = adjustedHash;
975
+ }
976
+ }
977
+
978
+ // Chain
979
+ return History;
980
+ };
981
+
982
+ /**
983
+ * History.escape()
984
+ * normalize and Escape a Hash
985
+ * @return {string}
986
+ */
987
+ History.escapeHash = function(hash){
988
+ var result = History.normalizeHash(hash);
989
+
990
+ // Escape hash
991
+ result = window.escape(result);
992
+
993
+ // IE6 Escape Bug
994
+ if ( !History.bugs.hashEscape ) {
995
+ // Restore common parts
996
+ result = result
997
+ .replace('%21','!')
998
+ .replace('%26','&')
999
+ .replace('%3D','=')
1000
+ .replace('%3F','?');
1001
+ }
1002
+
1003
+ // Return result
1004
+ return result;
1005
+ };
1006
+
1007
+ /**
1008
+ * History.getHashByUrl(url)
1009
+ * Extracts the Hash from a URL
1010
+ * @param {string} url
1011
+ * @return {string} url
1012
+ */
1013
+ History.getHashByUrl = function(url){
1014
+ // Extract the hash
1015
+ var hash = String(url)
1016
+ .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2')
1017
+ ;
1018
+
1019
+ // Unescape hash
1020
+ hash = History.unescapeHash(hash);
1021
+
1022
+ // Return hash
1023
+ return hash;
1024
+ };
1025
+
1026
+ /**
1027
+ * History.isTraditionalAnchor(url)
1028
+ * Checks to see if the url is a traditional anchor
1029
+ * @param {string} url
1030
+ * @return {boolean}
1031
+ */
1032
+ History.isTraditionalAnchor = function(url){
1033
+ var
1034
+ hash = History.getHashByUrl(url),
1035
+ el = document.getElementById(hash),
1036
+ isTraditionalAnchor = typeof el !== 'undefined';
1037
+
1038
+ // Return isTraditionalAnchor
1039
+ return isTraditionalAnchor;
1040
+ };
1041
+
1042
+ /**
1043
+ * History.setTitle(title)
1044
+ * Applies the title to the document
1045
+ * @param {State} newState
1046
+ * @return {Boolean}
1047
+ */
1048
+ History.setTitle = function(newState){
1049
+ // Prepare
1050
+ var title = newState.title;
1051
+
1052
+ // Initial
1053
+ if ( !title ) {
1054
+ var firstState = History.getStateByIndex(0);
1055
+ if ( firstState && firstState.url === newState.url ) {
1056
+ title = firstState.title||History.options.initialTitle;
1057
+ }
1058
+ }
1059
+
1060
+ // Apply
1061
+ try {
1062
+ document.getElementsByTagName('title')[0].innerHTML = title.replace('<','&lt;').replace('>','&gt;').replace(' & ',' &amp; ');
1063
+ }
1064
+ catch ( Exception ) { }
1065
+ document.title = title;
1066
+
1067
+ // Chain
1068
+ return History;
1069
+ };
1070
+
1071
+ // ----------------------------------------------------------------------
1072
+ // Queueing
1073
+
1074
+ /**
1075
+ * History.queues
1076
+ * The list of queues to use
1077
+ * First In, First Out
1078
+ */
1079
+ History.queues = [];
1080
+
1081
+ /**
1082
+ * History.busy(value)
1083
+ * @param {boolean} value [optional]
1084
+ * @return {boolean} busy
1085
+ */
1086
+ History.busy = function(value){
1087
+ // Apply
1088
+ if ( typeof value !== 'undefined' ) {
1089
+ //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length);
1090
+ History.busy.flag = value;
1091
+ }
1092
+ // Default
1093
+ else if ( typeof History.busy.flag === 'undefined' ) {
1094
+ History.busy.flag = false;
1095
+ }
1096
+
1097
+ // Queue
1098
+ if ( !History.busy.flag ) {
1099
+ // Execute the next item in the queue
1100
+ clearTimeout(History.busy.timeout);
1101
+ var fireNext = function(){
1102
+ if ( History.busy.flag ) return;
1103
+ for ( var i=History.queues.length-1; i >= 0; --i ) {
1104
+ var queue = History.queues[i];
1105
+ if ( queue.length === 0 ) continue;
1106
+ var item = queue.shift();
1107
+ History.fireQueueItem(item);
1108
+ History.busy.timeout = setTimeout(fireNext,History.options.busyDelay);
1109
+ }
1110
+ };
1111
+ History.busy.timeout = setTimeout(fireNext,History.options.busyDelay);
1112
+ }
1113
+
1114
+ // Return
1115
+ return History.busy.flag;
1116
+ };
1117
+
1118
+ /**
1119
+ * History.fireQueueItem(item)
1120
+ * Fire a Queue Item
1121
+ * @param {Object} item
1122
+ * @return {Mixed} result
1123
+ */
1124
+ History.fireQueueItem = function(item){
1125
+ return item.callback.apply(item.scope||History,item.args||[]);
1126
+ };
1127
+
1128
+ /**
1129
+ * History.pushQueue(callback,args)
1130
+ * Add an item to the queue
1131
+ * @param {Object} item [scope,callback,args,queue]
1132
+ */
1133
+ History.pushQueue = function(item){
1134
+ // Prepare the queue
1135
+ History.queues[item.queue||0] = History.queues[item.queue||0]||[];
1136
+
1137
+ // Add to the queue
1138
+ History.queues[item.queue||0].push(item);
1139
+
1140
+ // Chain
1141
+ return History;
1142
+ };
1143
+
1144
+ /**
1145
+ * History.queue (item,queue), (func,queue), (func), (item)
1146
+ * Either firs the item now if not busy, or adds it to the queue
1147
+ */
1148
+ History.queue = function(item,queue){
1149
+ // Prepare
1150
+ if ( typeof item === 'function' ) {
1151
+ item = {
1152
+ callback: item
1153
+ };
1154
+ }
1155
+ if ( typeof queue !== 'undefined' ) {
1156
+ item.queue = queue;
1157
+ }
1158
+
1159
+ // Handle
1160
+ if ( History.busy() ) {
1161
+ History.pushQueue(item);
1162
+ } else {
1163
+ History.fireQueueItem(item);
1164
+ }
1165
+
1166
+ // Chain
1167
+ return History;
1168
+ };
1169
+
1170
+ /**
1171
+ * History.clearQueue()
1172
+ * Clears the Queue
1173
+ */
1174
+ History.clearQueue = function(){
1175
+ History.busy.flag = false;
1176
+ History.queues = [];
1177
+ return History;
1178
+ };
1179
+
1180
+
1181
+ // ----------------------------------------------------------------------
1182
+ // IE Bug Fix
1183
+
1184
+ /**
1185
+ * History.stateChanged
1186
+ * States whether or not the state has changed since the last double check was initialised
1187
+ */
1188
+ History.stateChanged = false;
1189
+
1190
+ /**
1191
+ * History.doubleChecker
1192
+ * Contains the timeout used for the double checks
1193
+ */
1194
+ History.doubleChecker = false;
1195
+
1196
+ /**
1197
+ * History.doubleCheckComplete()
1198
+ * Complete a double check
1199
+ * @return {History}
1200
+ */
1201
+ History.doubleCheckComplete = function(){
1202
+ // Update
1203
+ History.stateChanged = true;
1204
+
1205
+ // Clear
1206
+ History.doubleCheckClear();
1207
+
1208
+ // Chain
1209
+ return History;
1210
+ };
1211
+
1212
+ /**
1213
+ * History.doubleCheckClear()
1214
+ * Clear a double check
1215
+ * @return {History}
1216
+ */
1217
+ History.doubleCheckClear = function(){
1218
+ // Clear
1219
+ if ( History.doubleChecker ) {
1220
+ clearTimeout(History.doubleChecker);
1221
+ History.doubleChecker = false;
1222
+ }
1223
+
1224
+ // Chain
1225
+ return History;
1226
+ };
1227
+
1228
+ /**
1229
+ * History.doubleCheck()
1230
+ * Create a double check
1231
+ * @return {History}
1232
+ */
1233
+ History.doubleCheck = function(tryAgain){
1234
+ // Reset
1235
+ History.stateChanged = false;
1236
+ History.doubleCheckClear();
1237
+
1238
+ // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does)
1239
+ // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940
1240
+ if ( History.bugs.ieDoubleCheck ) {
1241
+ // Apply Check
1242
+ History.doubleChecker = setTimeout(
1243
+ function(){
1244
+ History.doubleCheckClear();
1245
+ if ( !History.stateChanged ) {
1246
+ //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments);
1247
+ // Re-Attempt
1248
+ tryAgain();
1249
+ }
1250
+ return true;
1251
+ },
1252
+ History.options.doubleCheckInterval
1253
+ );
1254
+ }
1255
+
1256
+ // Chain
1257
+ return History;
1258
+ };
1259
+
1260
+ // ----------------------------------------------------------------------
1261
+ // Safari Bug Fix
1262
+
1263
+ /**
1264
+ * History.safariStatePoll()
1265
+ * Poll the current state
1266
+ * @return {History}
1267
+ */
1268
+ History.safariStatePoll = function(){
1269
+ // Poll the URL
1270
+
1271
+ // Get the Last State which has the new URL
1272
+ var
1273
+ urlState = History.extractState(document.location.href),
1274
+ newState;
1275
+
1276
+ // Check for a difference
1277
+ if ( !History.isLastSavedState(urlState) ) {
1278
+ newState = urlState;
1279
+ }
1280
+ else {
1281
+ return;
1282
+ }
1283
+
1284
+ // Check if we have a state with that url
1285
+ // If not create it
1286
+ if ( !newState ) {
1287
+ //History.debug('History.safariStatePoll: new');
1288
+ newState = History.createStateObject();
1289
+ }
1290
+
1291
+ // Apply the New State
1292
+ //History.debug('History.safariStatePoll: trigger');
1293
+ History.Adapter.trigger(window,'popstate');
1294
+
1295
+ // Chain
1296
+ return History;
1297
+ };
1298
+
1299
+ // ----------------------------------------------------------------------
1300
+ // State Aliases
1301
+
1302
+ /**
1303
+ * History.back(queue)
1304
+ * Send the browser history back one item
1305
+ * @param {Integer} queue [optional]
1306
+ */
1307
+ History.back = function(queue){
1308
+ //History.debug('History.back: called', arguments);
1309
+
1310
+ // Handle Queueing
1311
+ if ( queue !== false && History.busy() ) {
1312
+ // Wait + Push to Queue
1313
+ //History.debug('History.back: we must wait', arguments);
1314
+ History.pushQueue({
1315
+ scope: History,
1316
+ callback: History.back,
1317
+ args: arguments,
1318
+ queue: queue
1319
+ });
1320
+ return false;
1321
+ }
1322
+
1323
+ // Make Busy + Continue
1324
+ History.busy(true);
1325
+
1326
+ // Fix certain browser bugs that prevent the state from changing
1327
+ History.doubleCheck(function(){
1328
+ History.back(false);
1329
+ });
1330
+
1331
+ // Go back
1332
+ history.go(-1);
1333
+
1334
+ // End back closure
1335
+ return true;
1336
+ };
1337
+
1338
+ /**
1339
+ * History.forward(queue)
1340
+ * Send the browser history forward one item
1341
+ * @param {Integer} queue [optional]
1342
+ */
1343
+ History.forward = function(queue){
1344
+ //History.debug('History.forward: called', arguments);
1345
+
1346
+ // Handle Queueing
1347
+ if ( queue !== false && History.busy() ) {
1348
+ // Wait + Push to Queue
1349
+ //History.debug('History.forward: we must wait', arguments);
1350
+ History.pushQueue({
1351
+ scope: History,
1352
+ callback: History.forward,
1353
+ args: arguments,
1354
+ queue: queue
1355
+ });
1356
+ return false;
1357
+ }
1358
+
1359
+ // Make Busy + Continue
1360
+ History.busy(true);
1361
+
1362
+ // Fix certain browser bugs that prevent the state from changing
1363
+ History.doubleCheck(function(){
1364
+ History.forward(false);
1365
+ });
1366
+
1367
+ // Go forward
1368
+ history.go(1);
1369
+
1370
+ // End forward closure
1371
+ return true;
1372
+ };
1373
+
1374
+ /**
1375
+ * History.go(index,queue)
1376
+ * Send the browser history back or forward index times
1377
+ * @param {Integer} queue [optional]
1378
+ */
1379
+ History.go = function(index,queue){
1380
+ //History.debug('History.go: called', arguments);
1381
+
1382
+ // Prepare
1383
+ var i;
1384
+
1385
+ // Handle
1386
+ if ( index > 0 ) {
1387
+ // Forward
1388
+ for ( i=1; i<=index; ++i ) {
1389
+ History.forward(queue);
1390
+ }
1391
+ }
1392
+ else if ( index < 0 ) {
1393
+ // Backward
1394
+ for ( i=-1; i>=index; --i ) {
1395
+ History.back(queue);
1396
+ }
1397
+ }
1398
+ else {
1399
+ throw new Error('History.go: History.go requires a positive or negative integer passed.');
1400
+ }
1401
+
1402
+ // Chain
1403
+ return History;
1404
+ };
1405
+
1406
+
1407
+ // ----------------------------------------------------------------------
1408
+ // HTML5 State Support
1409
+
1410
+ if ( History.emulated.pushState ) {
1411
+ /*
1412
+ * Provide Skeleton for HTML4 Browsers
1413
+ */
1414
+
1415
+ // Prepare
1416
+ var emptyFunction = function(){};
1417
+ History.pushState = History.pushState||emptyFunction;
1418
+ History.replaceState = History.replaceState||emptyFunction;
1419
+ }
1420
+ else {
1421
+ /*
1422
+ * Use native HTML5 History API Implementation
1423
+ */
1424
+
1425
+ /**
1426
+ * History.onPopState(event,extra)
1427
+ * Refresh the Current State
1428
+ */
1429
+ History.onPopState = function(event){
1430
+ // Reset the double check
1431
+ History.doubleCheckComplete();
1432
+
1433
+ // Check for a Hash, and handle apporiatly
1434
+ var currentHash = History.getHash();
1435
+ if ( currentHash ) {
1436
+ // Expand Hash
1437
+ var currentState = History.extractState(currentHash||document.location.href,true);
1438
+ if ( currentState ) {
1439
+ // We were able to parse it, it must be a State!
1440
+ // Let's forward to replaceState
1441
+ //History.debug('History.onPopState: state anchor', currentHash, currentState);
1442
+ History.replaceState(currentState.data, currentState.title, currentState.url, false);
1443
+ }
1444
+ else {
1445
+ // Traditional Anchor
1446
+ //History.debug('History.onPopState: traditional anchor', currentHash);
1447
+ History.Adapter.trigger(window,'anchorchange');
1448
+ History.busy(false);
1449
+ }
1450
+
1451
+ // We don't care for hashes
1452
+ History.expectedStateId = false;
1453
+ return false;
1454
+ }
1455
+
1456
+ // Prepare
1457
+ var newState = null;
1458
+
1459
+ // Prepare
1460
+ event = event||{};
1461
+ if ( typeof event.state === 'undefined' ) {
1462
+ // jQuery
1463
+ if ( typeof event.originalEvent !== 'undefined' && typeof event.originalEvent.state !== 'undefined' ) {
1464
+ event.state = event.originalEvent.state||false;
1465
+ }
1466
+ // MooTools
1467
+ else if ( typeof event.event !== 'undefined' && typeof event.event.state !== 'undefined' ) {
1468
+ event.state = event.event.state||false;
1469
+ }
1470
+ }
1471
+
1472
+ // Ensure
1473
+ event.state = (event.state||false);
1474
+
1475
+ // Fetch State
1476
+ if ( event.state ) {
1477
+ // Vanilla: Back/forward button was used
1478
+ newState = History.getStateById(event.state);
1479
+ }
1480
+ else if ( History.expectedStateId ) {
1481
+ // Vanilla: A new state was pushed, and popstate was called manually
1482
+ newState = History.getStateById(History.expectedStateId);
1483
+ }
1484
+ else {
1485
+ // Initial State
1486
+ newState = History.extractState(document.location.href);
1487
+ }
1488
+
1489
+ // Clean
1490
+ History.expectedStateId = false;
1491
+
1492
+ // Check if we are the same state
1493
+ if ( History.isLastSavedState(newState) ) {
1494
+ // There has been no change (just the page's hash has finally propagated)
1495
+ //History.debug('History.onPopState: no change', newState, History.savedStates);
1496
+ History.busy(false);
1497
+ return false;
1498
+ }
1499
+
1500
+ // Store the State
1501
+ History.storeState(newState);
1502
+ History.saveState(newState);
1503
+
1504
+ // Force update of the title
1505
+ History.setTitle(newState);
1506
+
1507
+ // Fire Our Event
1508
+ History.Adapter.trigger(window,'statechange');
1509
+ History.busy(false);
1510
+
1511
+ // Return true
1512
+ return true;
1513
+ };
1514
+ History.Adapter.bind(window,'popstate',History.onPopState);
1515
+
1516
+ /**
1517
+ * History.pushState(data,title,url)
1518
+ * Add a new State to the history object, become it, and trigger onpopstate
1519
+ * We have to trigger for HTML4 compatibility
1520
+ * @param {object} data
1521
+ * @param {string} title
1522
+ * @param {string} url
1523
+ * @return {true}
1524
+ */
1525
+ History.pushState = function(data,title,url,queue){
1526
+ //History.debug('History.pushState: called', arguments);
1527
+
1528
+ // Check the State
1529
+ if ( History.getHashByUrl(url) && History.emulated.pushState ) {
1530
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
1531
+ }
1532
+
1533
+ // Handle Queueing
1534
+ if ( queue !== false && History.busy() ) {
1535
+ // Wait + Push to Queue
1536
+ //History.debug('History.pushState: we must wait', arguments);
1537
+ History.pushQueue({
1538
+ scope: History,
1539
+ callback: History.pushState,
1540
+ args: arguments,
1541
+ queue: queue
1542
+ });
1543
+ return false;
1544
+ }
1545
+
1546
+ // Make Busy + Continue
1547
+ History.busy(true);
1548
+
1549
+ // Create the newState
1550
+ var newState = History.createStateObject(data,title,url);
1551
+
1552
+ // Check it
1553
+ if ( History.isLastSavedState(newState) ) {
1554
+ // Won't be a change
1555
+ History.busy(false);
1556
+ }
1557
+ else {
1558
+ // Store the newState
1559
+ History.storeState(newState);
1560
+ History.expectedStateId = newState.id;
1561
+
1562
+ // Push the newState
1563
+ var pushUrl =
1564
+ (History.bugs.safariPoll && History.hasUrlDuplicate(newState))
1565
+ ? newState.hashedUrl
1566
+ : newState.url;
1567
+ history.pushState(newState.id,newState.title,pushUrl);
1568
+
1569
+ // Fire HTML5 Event
1570
+ History.Adapter.trigger(window,'popstate');
1571
+ }
1572
+
1573
+ // End pushState closure
1574
+ return true;
1575
+ };
1576
+
1577
+ /**
1578
+ * History.replaceState(data,title,url)
1579
+ * Replace the State and trigger onpopstate
1580
+ * We have to trigger for HTML4 compatibility
1581
+ * @param {object} data
1582
+ * @param {string} title
1583
+ * @param {string} url
1584
+ * @return {true}
1585
+ */
1586
+ History.replaceState = function(data,title,url,queue){
1587
+ //History.debug('History.replaceState: called', arguments);
1588
+
1589
+ // Check the State
1590
+ if ( History.getHashByUrl(url) && History.emulated.pushState ) {
1591
+ throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
1592
+ }
1593
+
1594
+ // Handle Queueing
1595
+ if ( queue !== false && History.busy() ) {
1596
+ // Wait + Push to Queue
1597
+ //History.debug('History.replaceState: we must wait', arguments);
1598
+ History.pushQueue({
1599
+ scope: History,
1600
+ callback: History.replaceState,
1601
+ args: arguments,
1602
+ queue: queue
1603
+ });
1604
+ return false;
1605
+ }
1606
+
1607
+ // Make Busy + Continue
1608
+ History.busy(true);
1609
+
1610
+ // Create the newState
1611
+ var newState = History.createStateObject(data,title,url);
1612
+
1613
+ // Check it
1614
+ if ( History.isLastSavedState(newState) ) {
1615
+ // Won't be a change
1616
+ History.busy(false);
1617
+ }
1618
+ else {
1619
+ // Store the newState
1620
+ History.storeState(newState);
1621
+ History.expectedStateId = newState.id;
1622
+
1623
+ // Push the newState
1624
+ var pushUrl =
1625
+ (History.bugs.safariPoll && History.hasUrlDuplicate(newState))
1626
+ ? newState.hashedUrl
1627
+ : newState.url;
1628
+ history.replaceState(newState.id,newState.title,pushUrl);
1629
+
1630
+ // Fire HTML5 Event
1631
+ History.Adapter.trigger(window,'popstate');
1632
+ }
1633
+
1634
+ // End replaceState closure
1635
+ return true;
1636
+ };
1637
+
1638
+ /**
1639
+ * Create the initial State
1640
+ */
1641
+ History.saveState(History.storeState(History.createStateObject({},'',document.location.href)));
1642
+
1643
+ /**
1644
+ * Setup Safari Fix
1645
+ */
1646
+ if ( History.bugs.safariPoll ) {
1647
+ setInterval(History.safariStatePoll, History.options.safariPollInterval);
1648
+ }
1649
+
1650
+ /**
1651
+ * Ensure Cross Browser Compatibility
1652
+ */
1653
+ if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) {
1654
+ /**
1655
+ * Fix Safari HashChange Issue
1656
+ */
1657
+
1658
+ // Setup Alias
1659
+ History.Adapter.bind(window,'hashchange',function(){
1660
+ History.Adapter.trigger(window,'popstate');
1661
+ });
1662
+
1663
+ // Initialise Alias
1664
+ if ( History.getHash() ) {
1665
+ History.Adapter.onDomLoad(function(){
1666
+ History.Adapter.trigger(window,'hashchange');
1667
+ });
1668
+ }
1669
+ }
1670
+
1671
+ } // !History.emulated.pushState
1672
+
1673
+ }; // History.initCore
1674
+
1675
+ // Try and Initialise History
1676
+ History.init();
1296
1677
 
1297
1678
  })(window);