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