jquery-historyjs 0.1.0 → 0.2.1

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.
@@ -1,8 +1,7 @@
1
1
  module Historyjs
2
2
  module Rails
3
- VERSION = "0.1.0"
4
- HISTORYJS_VERSION = "1.7.0"
3
+ VERSION = "0.2.1"
4
+ HISTORYJS_VERSION = "1.7.1-r2"
5
5
  JSON2_VERSION = "8e0b15cb492f63067a88"
6
- AMPLIFY_STORE_VERSION = "1.0beta"
7
6
  end
8
7
  end
@@ -1,5 +1,4 @@
1
1
  //= require json2
2
- //= require amplify_store
3
2
  //= require history_core
4
3
  //= require history_adapter_jquery
5
4
  //= require history_html4
@@ -7,6 +7,8 @@
7
7
 
8
8
  // Closure
9
9
  (function(window,undefined){
10
+ "use strict";
11
+
10
12
  // Localise Globals
11
13
  var
12
14
  History = window.History = window.History||{},
@@ -21,10 +23,10 @@
21
23
  History.Adapter = {
22
24
  /**
23
25
  * History.Adapter.bind(el,event,callback)
24
- * @param {Element|Selector} el
25
- * @param {String} event - custom and standard events
26
- * @param {Function} callback
27
- * @return
26
+ * @param {Element|string} el
27
+ * @param {string} event - custom and standard events
28
+ * @param {function} callback
29
+ * @return {void}
28
30
  */
29
31
  bind: function(el,event,callback){
30
32
  jQuery(el).bind(event,callback);
@@ -32,18 +34,34 @@
32
34
 
33
35
  /**
34
36
  * History.Adapter.trigger(el,event)
35
- * @param {Element|Selector} el
36
- * @param {String} event - custom and standard events
37
- * @return
37
+ * @param {Element|string} el
38
+ * @param {string} event - custom and standard events
39
+ * @param {Object=} extra - a object of extra event data (optional)
40
+ * @return {void}
38
41
  */
39
- trigger: function(el,event){
40
- jQuery(el).trigger(event);
42
+ trigger: function(el,event,extra){
43
+ jQuery(el).trigger(event,extra);
41
44
  },
42
45
 
43
46
  /**
44
- * History.Adapter.trigger(el,event,data)
45
- * @param {Function} callback
46
- * @return
47
+ * History.Adapter.extractEventData(key,event,extra)
48
+ * @param {string} key - key for the event data to extract
49
+ * @param {string} event - custom and standard events
50
+ * @param {Object=} extra - a object of extra event data (optional)
51
+ * @return {mixed}
52
+ */
53
+ extractEventData: function(key,event,extra){
54
+ // jQuery Native then jQuery Custom
55
+ var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined;
56
+
57
+ // Return
58
+ return result;
59
+ },
60
+
61
+ /**
62
+ * History.Adapter.onDomLoad(callback)
63
+ * @param {function} callback
64
+ * @return {void}
47
65
  */
48
66
  onDomLoad: function(callback) {
49
67
  jQuery(callback);
@@ -56,3 +74,4 @@
56
74
  }
57
75
 
58
76
  })(window);
77
+
@@ -8,7 +8,7 @@
8
8
  (function(window,undefined){
9
9
  "use strict";
10
10
 
11
- // --------------------------------------------------------------------------
11
+ // ========================================================================
12
12
  // Initialise
13
13
 
14
14
  // Localise Globals
@@ -16,12 +16,13 @@
16
16
  console = window.console||undefined, // Prevent a JSLint complain
17
17
  document = window.document, // Make sure we are using the correct document
18
18
  navigator = window.navigator, // Make sure we are using the correct navigator
19
- amplify = window.amplify||false, // Amplify.js
19
+ sessionStorage = window.sessionStorage||false, // sessionStorage
20
20
  setTimeout = window.setTimeout,
21
21
  clearTimeout = window.clearTimeout,
22
22
  setInterval = window.setInterval,
23
23
  clearInterval = window.clearInterval,
24
24
  JSON = window.JSON,
25
+ alert = window.alert,
25
26
  History = window.History = window.History||{}, // Public History Object
26
27
  history = window.history; // Old History Object
27
28
 
@@ -55,7 +56,8 @@
55
56
  return true;
56
57
  };
57
58
 
58
- // --------------------------------------------------------------------------
59
+
60
+ // ========================================================================
59
61
  // Initialise Core
60
62
 
61
63
  // Initialise Core
@@ -69,7 +71,8 @@
69
71
  History.initCore.initialized = true;
70
72
  }
71
73
 
72
- // ----------------------------------------------------------------------
74
+
75
+ // ====================================================================
73
76
  // Options
74
77
 
75
78
  /**
@@ -121,7 +124,7 @@
121
124
  History.options.initialTitle = History.options.initialTitle || document.title;
122
125
 
123
126
 
124
- // ----------------------------------------------------------------------
127
+ // ====================================================================
125
128
  // Interval record
126
129
 
127
130
  /**
@@ -143,11 +146,9 @@
143
146
  History.intervalList = null;
144
147
  }
145
148
  };
146
- History.Adapter.bind(window,"beforeunload",History.clearAllIntervals);
147
- History.Adapter.bind(window,"unload",History.clearAllIntervals);
148
149
 
149
150
 
150
- // ----------------------------------------------------------------------
151
+ // ====================================================================
151
152
  // Debug
152
153
 
153
154
  /**
@@ -170,12 +171,13 @@
170
171
  consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'),
171
172
  textarea = document.getElementById('log'),
172
173
  message,
173
- i,n
174
+ i,n,
175
+ args,arg
174
176
  ;
175
177
 
176
178
  // Write to Console
177
179
  if ( consoleExists ) {
178
- var args = Array.prototype.slice.call(arguments);
180
+ args = Array.prototype.slice.call(arguments);
179
181
  message = args.shift();
180
182
  if ( typeof console.debug !== 'undefined' ) {
181
183
  console.debug.apply(console,[message,args]);
@@ -190,7 +192,7 @@
190
192
 
191
193
  // Write to log
192
194
  for ( i=1,n=arguments.length; i<n; ++i ) {
193
- var arg = arguments[i];
195
+ arg = arguments[i];
194
196
  if ( typeof arg === 'object' && typeof JSON !== 'undefined' ) {
195
197
  try {
196
198
  arg = JSON.stringify(arg);
@@ -216,7 +218,8 @@
216
218
  return true;
217
219
  };
218
220
 
219
- // ----------------------------------------------------------------------
221
+
222
+ // ====================================================================
220
223
  // Emulated Status
221
224
 
222
225
  /**
@@ -327,7 +330,7 @@
327
330
 
328
331
  /**
329
332
  * History.cloneObject(obj)
330
- * Clones a object
333
+ * Clones a object and eliminate all references to the original contexts
331
334
  * @param {Object} obj
332
335
  * @return {Object}
333
336
  */
@@ -343,7 +346,8 @@
343
346
  return newObj;
344
347
  };
345
348
 
346
- // ----------------------------------------------------------------------
349
+
350
+ // ====================================================================
347
351
  // URL Helpers
348
352
 
349
353
  /**
@@ -412,10 +416,11 @@
412
416
  // Fetch
413
417
  var
414
418
  State = History.getState(false,false),
415
- stateUrl = (State||{}).url||document.location.href;
419
+ stateUrl = (State||{}).url||document.location.href,
420
+ pageUrl;
416
421
 
417
422
  // Create
418
- var pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){
423
+ pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){
419
424
  return (/\./).test(part) ? part : part+'/';
420
425
  });
421
426
 
@@ -517,17 +522,15 @@
517
522
  return shortUrl;
518
523
  };
519
524
 
520
- // ----------------------------------------------------------------------
525
+
526
+ // ====================================================================
521
527
  // State Storage
522
528
 
523
529
  /**
524
530
  * History.store
525
531
  * The store for all session specific data
526
532
  */
527
- History.store = amplify ? (amplify.store('History.store')||{}) : {};
528
- History.store.idToState = History.store.idToState||{};
529
- History.store.urlToId = History.store.urlToId||{};
530
- History.store.stateToId = History.store.stateToId||{};
533
+ History.store = {};
531
534
 
532
535
  /**
533
536
  * History.idToState
@@ -559,6 +562,16 @@
559
562
  */
560
563
  History.savedStates = History.savedStates||[];
561
564
 
565
+ /**
566
+ * History.noramlizeStore()
567
+ * Noramlize the store by adding necessary values
568
+ */
569
+ History.normalizeStore = function(){
570
+ History.store.idToState = History.store.idToState||{};
571
+ History.store.urlToId = History.store.urlToId||{};
572
+ History.store.stateToId = History.store.stateToId||{};
573
+ };
574
+
562
575
  /**
563
576
  * History.getState()
564
577
  * Get an object containing the data, title and url of the current state
@@ -598,10 +611,12 @@
598
611
  History.getIdByState = function(newState){
599
612
 
600
613
  // Fetch ID
601
- var id = History.extractId(newState.url);
614
+ var id = History.extractId(newState.url),
615
+ str;
616
+
602
617
  if ( !id ) {
603
618
  // Find ID via State String
604
- var str = History.getStateString(newState);
619
+ str = History.getStateString(newState);
605
620
  if ( typeof History.stateToId[str] !== 'undefined' ) {
606
621
  id = History.stateToId[str];
607
622
  }
@@ -611,7 +626,7 @@
611
626
  else {
612
627
  // Generate a new ID
613
628
  while ( true ) {
614
- id = String(Math.floor(Math.random()*1000));
629
+ id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,'');
615
630
  if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) {
616
631
  break;
617
632
  }
@@ -634,6 +649,9 @@
634
649
  * @return {object}
635
650
  */
636
651
  History.normalizeState = function(oldState){
652
+ // Variables
653
+ var newState, dataNotEmpty;
654
+
637
655
  // Prepare
638
656
  if ( !oldState || (typeof oldState !== 'object') ) {
639
657
  oldState = {};
@@ -649,10 +667,10 @@
649
667
  oldState.data = {};
650
668
  }
651
669
 
652
- // ----------------------------------------------------------------------
670
+ // ----------------------------------------------------------------
653
671
 
654
672
  // Create
655
- var newState = {};
673
+ newState = {};
656
674
  newState.normalized = true;
657
675
  newState.title = oldState.title||'';
658
676
  newState.url = History.getFullUrl(History.unescapeString(oldState.url||document.location.href));
@@ -662,14 +680,14 @@
662
680
  // Fetch ID
663
681
  newState.id = History.getIdByState(newState);
664
682
 
665
- // ----------------------------------------------------------------------
683
+ // ----------------------------------------------------------------
666
684
 
667
685
  // Clean the URL
668
686
  newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,'');
669
687
  newState.url = newState.cleanUrl;
670
688
 
671
689
  // Check to see if we have more than just a url
672
- var dataNotEmpty = !History.isEmptyObject(newState.data);
690
+ dataNotEmpty = !History.isEmptyObject(newState.data);
673
691
 
674
692
  // Apply
675
693
  if ( newState.title || dataNotEmpty ) {
@@ -684,14 +702,14 @@
684
702
  // Create the Hashed URL
685
703
  newState.hashedUrl = History.getFullUrl(newState.hash);
686
704
 
687
- // ----------------------------------------------------------------------
705
+ // ----------------------------------------------------------------
688
706
 
689
707
  // Update the URL if we have a duplicate
690
708
  if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) {
691
709
  newState.url = newState.hashedUrl;
692
710
  }
693
711
 
694
- // ----------------------------------------------------------------------
712
+ // ----------------------------------------------------------------
695
713
 
696
714
  // Return
697
715
  return newState;
@@ -742,17 +760,20 @@
742
760
  */
743
761
  History.getStateString = function(passedState){
744
762
  // Prepare
745
- var State = History.normalizeState(passedState);
763
+ var State, cleanedState, str;
764
+
765
+ // Fetch
766
+ State = History.normalizeState(passedState);
746
767
 
747
768
  // Clean
748
- var cleanedState = {
769
+ cleanedState = {
749
770
  data: State.data,
750
771
  title: passedState.title,
751
772
  url: passedState.url
752
773
  };
753
774
 
754
775
  // Fetch
755
- var str = JSON.stringify(cleanedState);
776
+ str = JSON.stringify(cleanedState);
756
777
 
757
778
  // Return
758
779
  return str;
@@ -765,10 +786,13 @@
765
786
  */
766
787
  History.getStateId = function(passedState){
767
788
  // Prepare
768
- var State = History.normalizeState(passedState);
789
+ var State, id;
790
+
791
+ // Fetch
792
+ State = History.normalizeState(passedState);
769
793
 
770
794
  // Fetch
771
- var id = State.id;
795
+ id = State.id;
772
796
 
773
797
  // Return
774
798
  return id;
@@ -782,9 +806,12 @@
782
806
  */
783
807
  History.getHashByState = function(passedState){
784
808
  // Prepare
785
- var hash, State = History.normalizeState(passedState);
786
-
809
+ var State, hash;
810
+
787
811
  // Fetch
812
+ State = History.normalizeState(passedState);
813
+
814
+ // Hash
788
815
  hash = State.hash;
789
816
 
790
817
  // Return
@@ -799,10 +826,9 @@
799
826
  */
800
827
  History.extractId = function ( url_or_hash ) {
801
828
  // Prepare
802
- var id;
829
+ var id,parts,url;
803
830
 
804
831
  // Extract
805
- var parts,url;
806
832
  parts = /(.*)\&_suid=([0-9]+)$/.exec(url_or_hash);
807
833
  url = parts ? (parts[1]||url_or_hash) : url_or_hash;
808
834
  id = parts ? String(parts[2]||'') : '';
@@ -833,11 +859,11 @@
833
859
  */
834
860
  History.extractState = function(url_or_hash,create){
835
861
  // Prepare
836
- var State = null;
862
+ var State = null, id, url;
837
863
  create = create||false;
838
864
 
839
865
  // Fetch SUID
840
- var id = History.extractId(url_or_hash);
866
+ id = History.extractId(url_or_hash);
841
867
  if ( id ) {
842
868
  State = History.getStateById(id);
843
869
  }
@@ -845,7 +871,7 @@
845
871
  // Fetch SUID returned no State
846
872
  if ( !State ) {
847
873
  // Fetch URL
848
- var url = History.getFullUrl(url_or_hash);
874
+ url = History.getFullUrl(url_or_hash);
849
875
 
850
876
  // Check URL
851
877
  id = History.getIdByUrl(url)||false;
@@ -901,10 +927,11 @@
901
927
  */
902
928
  History.hasUrlDuplicate = function(newState) {
903
929
  // Prepare
904
- var hasDuplicate = false;
930
+ var hasDuplicate = false,
931
+ oldState;
905
932
 
906
933
  // Fetch
907
- var oldState = History.extractState(newState.url);
934
+ oldState = History.extractState(newState.url);
908
935
 
909
936
  // Check
910
937
  hasDuplicate = oldState && oldState.id !== newState.id;
@@ -938,14 +965,14 @@
938
965
  */
939
966
  History.isLastSavedState = function(newState){
940
967
  // Prepare
941
- var isLast = false;
968
+ var isLast = false,
969
+ newId, oldState, oldId;
942
970
 
943
971
  // Check
944
972
  if ( History.savedStates.length ) {
945
- var
946
- newId = newState.id,
947
- oldState = History.getLastSavedState(),
948
- oldId = oldState.id;
973
+ newId = newState.id;
974
+ oldState = History.getLastSavedState();
975
+ oldId = oldState.id;
949
976
 
950
977
  // Check
951
978
  isLast = (newId === oldId);
@@ -1002,7 +1029,8 @@
1002
1029
  return State;
1003
1030
  };
1004
1031
 
1005
- // ----------------------------------------------------------------------
1032
+
1033
+ // ====================================================================
1006
1034
  // Hash Helpers
1007
1035
 
1008
1036
  /**
@@ -1023,10 +1051,10 @@
1023
1051
  */
1024
1052
  History.unescapeString = function(str){
1025
1053
  // Prepare
1026
- var result = str;
1054
+ var result = str,
1055
+ tmp;
1027
1056
 
1028
1057
  // Unescape hash
1029
- var tmp;
1030
1058
  while ( true ) {
1031
1059
  tmp = window.unescape(result);
1032
1060
  if ( tmp === result ) {
@@ -1062,6 +1090,7 @@
1062
1090
  * @return {string}
1063
1091
  */
1064
1092
  History.normalizeHash = function(hash){
1093
+ // Prepare
1065
1094
  var result = hash.replace(/[^#]*#/,'').replace(/#.*/, '');
1066
1095
 
1067
1096
  // Return result
@@ -1075,6 +1104,9 @@
1075
1104
  * @return {History}
1076
1105
  */
1077
1106
  History.setHash = function(hash,queue){
1107
+ // Prepare
1108
+ var adjustedHash, State, pageUrl;
1109
+
1078
1110
  // Handle Queueing
1079
1111
  if ( queue !== false && History.busy() ) {
1080
1112
  // Wait + Push to Queue
@@ -1092,13 +1124,13 @@
1092
1124
  //History.debug('History.setHash: called',hash);
1093
1125
 
1094
1126
  // Prepare
1095
- var adjustedHash = History.escapeHash(hash);
1127
+ adjustedHash = History.escapeHash(hash);
1096
1128
 
1097
1129
  // Make Busy + Continue
1098
1130
  History.busy(true);
1099
1131
 
1100
1132
  // Check if hash is a state
1101
- var State = History.extractState(hash,true);
1133
+ State = History.extractState(hash,true);
1102
1134
  if ( State && !History.emulated.pushState ) {
1103
1135
  // Hash is a state so skip the setHash
1104
1136
  //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments);
@@ -1114,7 +1146,7 @@
1114
1146
  // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249
1115
1147
 
1116
1148
  // Fetch the base page
1117
- var pageUrl = History.getPageUrl();
1149
+ pageUrl = History.getPageUrl();
1118
1150
 
1119
1151
  // Safari hash apply
1120
1152
  History.pushState(null,null,pageUrl+'#'+adjustedHash,false);
@@ -1135,6 +1167,7 @@
1135
1167
  * @return {string}
1136
1168
  */
1137
1169
  History.escapeHash = function(hash){
1170
+ // Prepare
1138
1171
  var result = History.normalizeHash(hash);
1139
1172
 
1140
1173
  // Escape hash
@@ -1181,11 +1214,12 @@
1181
1214
  */
1182
1215
  History.setTitle = function(newState){
1183
1216
  // Prepare
1184
- var title = newState.title;
1217
+ var title = newState.title,
1218
+ firstState;
1185
1219
 
1186
1220
  // Initial
1187
1221
  if ( !title ) {
1188
- var firstState = History.getStateByIndex(0);
1222
+ firstState = History.getStateByIndex(0);
1189
1223
  if ( firstState && firstState.url === newState.url ) {
1190
1224
  title = firstState.title||History.options.initialTitle;
1191
1225
  }
@@ -1202,7 +1236,8 @@
1202
1236
  return History;
1203
1237
  };
1204
1238
 
1205
- // ----------------------------------------------------------------------
1239
+
1240
+ // ====================================================================
1206
1241
  // Queueing
1207
1242
 
1208
1243
  /**
@@ -1233,11 +1268,12 @@
1233
1268
  // Execute the next item in the queue
1234
1269
  clearTimeout(History.busy.timeout);
1235
1270
  var fireNext = function(){
1271
+ var i, queue, item;
1236
1272
  if ( History.busy.flag ) return;
1237
- for ( var i=History.queues.length-1; i >= 0; --i ) {
1238
- var queue = History.queues[i];
1273
+ for ( i=History.queues.length-1; i >= 0; --i ) {
1274
+ queue = History.queues[i];
1239
1275
  if ( queue.length === 0 ) continue;
1240
- var item = queue.shift();
1276
+ item = queue.shift();
1241
1277
  History.fireQueueItem(item);
1242
1278
  History.busy.timeout = setTimeout(fireNext,History.options.busyDelay);
1243
1279
  }
@@ -1249,6 +1285,11 @@
1249
1285
  return History.busy.flag;
1250
1286
  };
1251
1287
 
1288
+ /**
1289
+ * History.busy.flag
1290
+ */
1291
+ History.busy.flag = false;
1292
+
1252
1293
  /**
1253
1294
  * History.fireQueueItem(item)
1254
1295
  * Fire a Queue Item
@@ -1312,7 +1353,7 @@
1312
1353
  };
1313
1354
 
1314
1355
 
1315
- // ----------------------------------------------------------------------
1356
+ // ====================================================================
1316
1357
  // IE Bug Fix
1317
1358
 
1318
1359
  /**
@@ -1391,7 +1432,8 @@
1391
1432
  return History;
1392
1433
  };
1393
1434
 
1394
- // ----------------------------------------------------------------------
1435
+
1436
+ // ====================================================================
1395
1437
  // Safari Bug Fix
1396
1438
 
1397
1439
  /**
@@ -1430,7 +1472,8 @@
1430
1472
  return History;
1431
1473
  };
1432
1474
 
1433
- // ----------------------------------------------------------------------
1475
+
1476
+ // ====================================================================
1434
1477
  // State Aliases
1435
1478
 
1436
1479
  /**
@@ -1538,67 +1581,10 @@
1538
1581
  };
1539
1582
 
1540
1583
 
1541
- // ----------------------------------------------------------------------
1542
- // Initialise
1543
-
1544
- /**
1545
- * Create the initial State
1546
- */
1547
- History.saveState(History.storeState(History.extractState(document.location.href,true)));
1548
-
1549
- /**
1550
- * Bind for Saving Store
1551
- */
1552
- if ( amplify ) {
1553
- History.onUnload = function(){
1554
- // Prepare
1555
- var
1556
- currentStore = amplify.store('History.store')||{},
1557
- item;
1558
-
1559
- // Ensure
1560
- currentStore.idToState = currentStore.idToState || {};
1561
- currentStore.urlToId = currentStore.urlToId || {};
1562
- currentStore.stateToId = currentStore.stateToId || {};
1563
-
1564
- // Sync
1565
- for ( item in History.idToState ) {
1566
- if ( !History.idToState.hasOwnProperty(item) ) {
1567
- continue;
1568
- }
1569
- currentStore.idToState[item] = History.idToState[item];
1570
- }
1571
- for ( item in History.urlToId ) {
1572
- if ( !History.urlToId.hasOwnProperty(item) ) {
1573
- continue;
1574
- }
1575
- currentStore.urlToId[item] = History.urlToId[item];
1576
- }
1577
- for ( item in History.stateToId ) {
1578
- if ( !History.stateToId.hasOwnProperty(item) ) {
1579
- continue;
1580
- }
1581
- currentStore.stateToId[item] = History.stateToId[item];
1582
- }
1583
-
1584
- // Update
1585
- History.store = currentStore;
1586
-
1587
- // Store
1588
- amplify.store('History.store',currentStore);
1589
- };
1590
- // For Internet Explorer
1591
- History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval));
1592
- // For Other Browsers
1593
- History.Adapter.bind(window,'beforeunload',History.onUnload);
1594
- History.Adapter.bind(window,'unload',History.onUnload);
1595
- // Both are enabled for consistency
1596
- }
1597
-
1598
-
1599
- // ----------------------------------------------------------------------
1584
+ // ====================================================================
1600
1585
  // HTML5 State Support
1601
1586
 
1587
+ // Non-Native pushState Implementation
1602
1588
  if ( History.emulated.pushState ) {
1603
1589
  /*
1604
1590
  * Provide Skeleton for HTML4 Browsers
@@ -1608,7 +1594,9 @@
1608
1594
  var emptyFunction = function(){};
1609
1595
  History.pushState = History.pushState||emptyFunction;
1610
1596
  History.replaceState = History.replaceState||emptyFunction;
1611
- }
1597
+ } // History.emulated.pushState
1598
+
1599
+ // Native pushState Implementation
1612
1600
  else {
1613
1601
  /*
1614
1602
  * Use native HTML5 History API Implementation
@@ -1618,15 +1606,18 @@
1618
1606
  * History.onPopState(event,extra)
1619
1607
  * Refresh the Current State
1620
1608
  */
1621
- History.onPopState = function(event){
1609
+ History.onPopState = function(event,extra){
1610
+ // Prepare
1611
+ var stateId = false, newState = false, currentHash, currentState;
1612
+
1622
1613
  // Reset the double check
1623
1614
  History.doubleCheckComplete();
1624
1615
 
1625
1616
  // Check for a Hash, and handle apporiatly
1626
- var currentHash = History.getHash();
1617
+ currentHash = History.getHash();
1627
1618
  if ( currentHash ) {
1628
1619
  // Expand Hash
1629
- var currentState = History.extractState(currentHash||document.location.href,true);
1620
+ currentState = History.extractState(currentHash||document.location.href,true);
1630
1621
  if ( currentState ) {
1631
1622
  // We were able to parse it, it must be a State!
1632
1623
  // Let's forward to replaceState
@@ -1645,29 +1636,13 @@
1645
1636
  return false;
1646
1637
  }
1647
1638
 
1648
- // Prepare
1649
- var newState = false;
1650
-
1651
- // Prepare
1652
- event = event||{};
1653
- if ( typeof event.state === 'undefined' ) {
1654
- // jQuery
1655
- if ( typeof event.originalEvent !== 'undefined' && typeof event.originalEvent.state !== 'undefined' ) {
1656
- event.state = event.originalEvent.state||false;
1657
- }
1658
- // MooTools
1659
- else if ( typeof event.event !== 'undefined' && typeof event.event.state !== 'undefined' ) {
1660
- event.state = event.event.state||false;
1661
- }
1662
- }
1663
-
1664
1639
  // Ensure
1665
- event.state = (event.state||false);
1640
+ stateId = History.Adapter.extractEventData('state',event,extra) || false;
1666
1641
 
1667
1642
  // Fetch State
1668
- if ( event.state ) {
1643
+ if ( stateId ) {
1669
1644
  // Vanilla: Back/forward button was used
1670
- newState = History.getStateById(event.state);
1645
+ newState = History.getStateById(stateId);
1671
1646
  }
1672
1647
  else if ( History.expectedStateId ) {
1673
1648
  // Vanilla: A new state was pushed, and popstate was called manually
@@ -1825,6 +1800,106 @@
1825
1800
  return true;
1826
1801
  };
1827
1802
 
1803
+ } // !History.emulated.pushState
1804
+
1805
+
1806
+ // ====================================================================
1807
+ // Initialise
1808
+
1809
+ /**
1810
+ * Load the Store
1811
+ */
1812
+ if ( sessionStorage ) {
1813
+ // Fetch
1814
+ try {
1815
+ History.store = JSON.parse(sessionStorage.getItem('History.store'))||{};
1816
+ }
1817
+ catch ( err ) {
1818
+ History.store = {};
1819
+ }
1820
+
1821
+ // Normalize
1822
+ History.normalizeStore();
1823
+ }
1824
+ else {
1825
+ // Default Load
1826
+ History.store = {};
1827
+ History.normalizeStore();
1828
+ }
1829
+
1830
+ /**
1831
+ * Clear Intervals on exit to prevent memory leaks
1832
+ */
1833
+ History.Adapter.bind(window,"beforeunload",History.clearAllIntervals);
1834
+ History.Adapter.bind(window,"unload",History.clearAllIntervals);
1835
+
1836
+ /**
1837
+ * Create the initial State
1838
+ */
1839
+ History.saveState(History.storeState(History.extractState(document.location.href,true)));
1840
+
1841
+ /**
1842
+ * Bind for Saving Store
1843
+ */
1844
+ if ( sessionStorage ) {
1845
+ // When the page is closed
1846
+ History.onUnload = function(){
1847
+ // Prepare
1848
+ var currentStore, item;
1849
+
1850
+ // Fetch
1851
+ try {
1852
+ currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{};
1853
+ }
1854
+ catch ( err ) {
1855
+ currentStore = {};
1856
+ }
1857
+
1858
+ // Ensure
1859
+ currentStore.idToState = currentStore.idToState || {};
1860
+ currentStore.urlToId = currentStore.urlToId || {};
1861
+ currentStore.stateToId = currentStore.stateToId || {};
1862
+
1863
+ // Sync
1864
+ for ( item in History.idToState ) {
1865
+ if ( !History.idToState.hasOwnProperty(item) ) {
1866
+ continue;
1867
+ }
1868
+ currentStore.idToState[item] = History.idToState[item];
1869
+ }
1870
+ for ( item in History.urlToId ) {
1871
+ if ( !History.urlToId.hasOwnProperty(item) ) {
1872
+ continue;
1873
+ }
1874
+ currentStore.urlToId[item] = History.urlToId[item];
1875
+ }
1876
+ for ( item in History.stateToId ) {
1877
+ if ( !History.stateToId.hasOwnProperty(item) ) {
1878
+ continue;
1879
+ }
1880
+ currentStore.stateToId[item] = History.stateToId[item];
1881
+ }
1882
+
1883
+ // Update
1884
+ History.store = currentStore;
1885
+ History.normalizeStore();
1886
+
1887
+ // Store
1888
+ sessionStorage.setItem('History.store',JSON.stringify(currentStore));
1889
+ };
1890
+
1891
+ // For Internet Explorer
1892
+ History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval));
1893
+
1894
+ // For Other Browsers
1895
+ History.Adapter.bind(window,'beforeunload',History.onUnload);
1896
+ History.Adapter.bind(window,'unload',History.onUnload);
1897
+
1898
+ // Both are enabled for consistency
1899
+ }
1900
+
1901
+ // Non-Native pushState Implementation
1902
+ if ( !History.emulated.pushState ) {
1828
1903
  // Be aware, the following is only for native pushState implementations
1829
1904
  // If you are wanting to include something for all browsers
1830
1905
  // Then include it above this if block
@@ -1859,6 +1934,7 @@
1859
1934
 
1860
1935
  } // !History.emulated.pushState
1861
1936
 
1937
+
1862
1938
  }; // History.initCore
1863
1939
 
1864
1940
  // Try and Initialise History