historyjs-rails 1.0.0 → 1.0.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.
- data/README.md +8 -6
- data/historyjs-rails.gemspec +2 -2
- data/lib/historyjs/rails/version.rb +2 -2
- data/spec/historyjs/rails/version_spec.rb +2 -2
- data/vendor/assets/javascripts/history_adapter_jquery.js +77 -77
- data/vendor/assets/javascripts/history_adapter_mootools.js +84 -84
- data/vendor/assets/javascripts/history_adapter_native.js +121 -121
- data/vendor/assets/javascripts/history_adapter_right.js +78 -78
- data/vendor/assets/javascripts/history_adapter_zepto.js +74 -74
- data/vendor/assets/javascripts/history_core.js +1943 -1943
- data/vendor/assets/javascripts/history_html4.js +621 -621
- data/vendor/assets/javascripts/json2.js +480 -480
- metadata +18 -8
@@ -1,621 +1,621 @@
|
|
1
|
-
/**
|
2
|
-
* History.js HTML4 Support
|
3
|
-
* Depends on the HTML5 Support
|
4
|
-
* @author Benjamin Arthur Lupton <contact@balupton.com>
|
5
|
-
* @copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
|
6
|
-
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
|
7
|
-
*/
|
8
|
-
|
9
|
-
(function(window,undefined){
|
10
|
-
"use strict";
|
11
|
-
|
12
|
-
// ========================================================================
|
13
|
-
// Initialise
|
14
|
-
|
15
|
-
// Localise Globals
|
16
|
-
var
|
17
|
-
document = window.document, // Make sure we are using the correct document
|
18
|
-
setTimeout = window.setTimeout||setTimeout,
|
19
|
-
clearTimeout = window.clearTimeout||clearTimeout,
|
20
|
-
setInterval = window.setInterval||setInterval,
|
21
|
-
History = window.History = window.History||{}; // Public History Object
|
22
|
-
|
23
|
-
// Check Existence
|
24
|
-
if ( typeof History.initHtml4 !== 'undefined' ) {
|
25
|
-
throw new Error('History.js HTML4 Support has already been loaded...');
|
26
|
-
}
|
27
|
-
|
28
|
-
|
29
|
-
// ========================================================================
|
30
|
-
// Initialise HTML4 Support
|
31
|
-
|
32
|
-
// Initialise HTML4 Support
|
33
|
-
History.initHtml4 = function(){
|
34
|
-
// Initialise
|
35
|
-
if ( typeof History.initHtml4.initialized !== 'undefined' ) {
|
36
|
-
// Already Loaded
|
37
|
-
return false;
|
38
|
-
}
|
39
|
-
else {
|
40
|
-
History.initHtml4.initialized = true;
|
41
|
-
}
|
42
|
-
|
43
|
-
|
44
|
-
// ====================================================================
|
45
|
-
// Properties
|
46
|
-
|
47
|
-
/**
|
48
|
-
* History.enabled
|
49
|
-
* Is History enabled?
|
50
|
-
*/
|
51
|
-
History.enabled = true;
|
52
|
-
|
53
|
-
|
54
|
-
// ====================================================================
|
55
|
-
// Hash Storage
|
56
|
-
|
57
|
-
/**
|
58
|
-
* History.savedHashes
|
59
|
-
* Store the hashes in an array
|
60
|
-
*/
|
61
|
-
History.savedHashes = [];
|
62
|
-
|
63
|
-
/**
|
64
|
-
* History.isLastHash(newHash)
|
65
|
-
* Checks if the hash is the last hash
|
66
|
-
* @param {string} newHash
|
67
|
-
* @return {boolean} true
|
68
|
-
*/
|
69
|
-
History.isLastHash = function(newHash){
|
70
|
-
// Prepare
|
71
|
-
var oldHash = History.getHashByIndex(),
|
72
|
-
isLast;
|
73
|
-
|
74
|
-
// Check
|
75
|
-
isLast = newHash === oldHash;
|
76
|
-
|
77
|
-
// Return isLast
|
78
|
-
return isLast;
|
79
|
-
};
|
80
|
-
|
81
|
-
/**
|
82
|
-
* History.saveHash(newHash)
|
83
|
-
* Push a Hash
|
84
|
-
* @param {string} newHash
|
85
|
-
* @return {boolean} true
|
86
|
-
*/
|
87
|
-
History.saveHash = function(newHash){
|
88
|
-
// Check Hash
|
89
|
-
if ( History.isLastHash(newHash) ) {
|
90
|
-
return false;
|
91
|
-
}
|
92
|
-
|
93
|
-
// Push the Hash
|
94
|
-
History.savedHashes.push(newHash);
|
95
|
-
|
96
|
-
// Return true
|
97
|
-
return true;
|
98
|
-
};
|
99
|
-
|
100
|
-
/**
|
101
|
-
* History.getHashByIndex()
|
102
|
-
* Gets a hash by the index
|
103
|
-
* @param {integer} index
|
104
|
-
* @return {string}
|
105
|
-
*/
|
106
|
-
History.getHashByIndex = function(index){
|
107
|
-
// Prepare
|
108
|
-
var hash = null;
|
109
|
-
|
110
|
-
// Handle
|
111
|
-
if ( typeof index === 'undefined' ) {
|
112
|
-
// Get the last inserted
|
113
|
-
hash = History.savedHashes[History.savedHashes.length-1];
|
114
|
-
}
|
115
|
-
else if ( index < 0 ) {
|
116
|
-
// Get from the end
|
117
|
-
hash = History.savedHashes[History.savedHashes.length+index];
|
118
|
-
}
|
119
|
-
else {
|
120
|
-
// Get from the beginning
|
121
|
-
hash = History.savedHashes[index];
|
122
|
-
}
|
123
|
-
|
124
|
-
// Return hash
|
125
|
-
return hash;
|
126
|
-
};
|
127
|
-
|
128
|
-
|
129
|
-
// ====================================================================
|
130
|
-
// Discarded States
|
131
|
-
|
132
|
-
/**
|
133
|
-
* History.discardedHashes
|
134
|
-
* A hashed array of discarded hashes
|
135
|
-
*/
|
136
|
-
History.discardedHashes = {};
|
137
|
-
|
138
|
-
/**
|
139
|
-
* History.discardedStates
|
140
|
-
* A hashed array of discarded states
|
141
|
-
*/
|
142
|
-
History.discardedStates = {};
|
143
|
-
|
144
|
-
/**
|
145
|
-
* History.discardState(State)
|
146
|
-
* Discards the state by ignoring it through History
|
147
|
-
* @param {object} State
|
148
|
-
* @return {true}
|
149
|
-
*/
|
150
|
-
History.discardState = function(discardedState,forwardState,backState){
|
151
|
-
//History.debug('History.discardState', arguments);
|
152
|
-
// Prepare
|
153
|
-
var discardedStateHash = History.getHashByState(discardedState),
|
154
|
-
discardObject;
|
155
|
-
|
156
|
-
// Create Discard Object
|
157
|
-
discardObject = {
|
158
|
-
'discardedState': discardedState,
|
159
|
-
'backState': backState,
|
160
|
-
'forwardState': forwardState
|
161
|
-
};
|
162
|
-
|
163
|
-
// Add to DiscardedStates
|
164
|
-
History.discardedStates[discardedStateHash] = discardObject;
|
165
|
-
|
166
|
-
// Return true
|
167
|
-
return true;
|
168
|
-
};
|
169
|
-
|
170
|
-
/**
|
171
|
-
* History.discardHash(hash)
|
172
|
-
* Discards the hash by ignoring it through History
|
173
|
-
* @param {string} hash
|
174
|
-
* @return {true}
|
175
|
-
*/
|
176
|
-
History.discardHash = function(discardedHash,forwardState,backState){
|
177
|
-
//History.debug('History.discardState', arguments);
|
178
|
-
// Create Discard Object
|
179
|
-
var discardObject = {
|
180
|
-
'discardedHash': discardedHash,
|
181
|
-
'backState': backState,
|
182
|
-
'forwardState': forwardState
|
183
|
-
};
|
184
|
-
|
185
|
-
// Add to discardedHash
|
186
|
-
History.discardedHashes[discardedHash] = discardObject;
|
187
|
-
|
188
|
-
// Return true
|
189
|
-
return true;
|
190
|
-
};
|
191
|
-
|
192
|
-
/**
|
193
|
-
* History.discardState(State)
|
194
|
-
* Checks to see if the state is discarded
|
195
|
-
* @param {object} State
|
196
|
-
* @return {bool}
|
197
|
-
*/
|
198
|
-
History.discardedState = function(State){
|
199
|
-
// Prepare
|
200
|
-
var StateHash = History.getHashByState(State),
|
201
|
-
discarded;
|
202
|
-
|
203
|
-
// Check
|
204
|
-
discarded = History.discardedStates[StateHash]||false;
|
205
|
-
|
206
|
-
// Return true
|
207
|
-
return discarded;
|
208
|
-
};
|
209
|
-
|
210
|
-
/**
|
211
|
-
* History.discardedHash(hash)
|
212
|
-
* Checks to see if the state is discarded
|
213
|
-
* @param {string} State
|
214
|
-
* @return {bool}
|
215
|
-
*/
|
216
|
-
History.discardedHash = function(hash){
|
217
|
-
// Check
|
218
|
-
var discarded = History.discardedHashes[hash]||false;
|
219
|
-
|
220
|
-
// Return true
|
221
|
-
return discarded;
|
222
|
-
};
|
223
|
-
|
224
|
-
/**
|
225
|
-
* History.recycleState(State)
|
226
|
-
* Allows a discarded state to be used again
|
227
|
-
* @param {object} data
|
228
|
-
* @param {string} title
|
229
|
-
* @param {string} url
|
230
|
-
* @return {true}
|
231
|
-
*/
|
232
|
-
History.recycleState = function(State){
|
233
|
-
//History.debug('History.recycleState', arguments);
|
234
|
-
// Prepare
|
235
|
-
var StateHash = History.getHashByState(State);
|
236
|
-
|
237
|
-
// Remove from DiscardedStates
|
238
|
-
if ( History.discardedState(State) ) {
|
239
|
-
delete History.discardedStates[StateHash];
|
240
|
-
}
|
241
|
-
|
242
|
-
// Return true
|
243
|
-
return true;
|
244
|
-
};
|
245
|
-
|
246
|
-
|
247
|
-
// ====================================================================
|
248
|
-
// HTML4 HashChange Support
|
249
|
-
|
250
|
-
if ( History.emulated.hashChange ) {
|
251
|
-
/*
|
252
|
-
* We must emulate the HTML4 HashChange Support by manually checking for hash changes
|
253
|
-
*/
|
254
|
-
|
255
|
-
/**
|
256
|
-
* History.hashChangeInit()
|
257
|
-
* Init the HashChange Emulation
|
258
|
-
*/
|
259
|
-
History.hashChangeInit = function(){
|
260
|
-
// Define our Checker Function
|
261
|
-
History.checkerFunction = null;
|
262
|
-
|
263
|
-
// Define some variables that will help in our checker function
|
264
|
-
var lastDocumentHash = '',
|
265
|
-
iframeId, iframe,
|
266
|
-
lastIframeHash, checkerRunning;
|
267
|
-
|
268
|
-
// Handle depending on the browser
|
269
|
-
if ( History.isInternetExplorer() ) {
|
270
|
-
// IE6 and IE7
|
271
|
-
// We need to use an iframe to emulate the back and forward buttons
|
272
|
-
|
273
|
-
// Create iFrame
|
274
|
-
iframeId = 'historyjs-iframe';
|
275
|
-
iframe = document.createElement('iframe');
|
276
|
-
|
277
|
-
// Adjust iFarme
|
278
|
-
iframe.setAttribute('id', iframeId);
|
279
|
-
iframe.style.display = 'none';
|
280
|
-
|
281
|
-
// Append iFrame
|
282
|
-
document.body.appendChild(iframe);
|
283
|
-
|
284
|
-
// Create initial history entry
|
285
|
-
iframe.contentWindow.document.open();
|
286
|
-
iframe.contentWindow.document.close();
|
287
|
-
|
288
|
-
// Define some variables that will help in our checker function
|
289
|
-
lastIframeHash = '';
|
290
|
-
checkerRunning = false;
|
291
|
-
|
292
|
-
// Define the checker function
|
293
|
-
History.checkerFunction = function(){
|
294
|
-
// Check Running
|
295
|
-
if ( checkerRunning ) {
|
296
|
-
return false;
|
297
|
-
}
|
298
|
-
|
299
|
-
// Update Running
|
300
|
-
checkerRunning = true;
|
301
|
-
|
302
|
-
// Fetch
|
303
|
-
var documentHash = History.getHash()||'',
|
304
|
-
iframeHash = History.unescapeHash(iframe.contentWindow.document.location.hash)||'';
|
305
|
-
|
306
|
-
// The Document Hash has changed (application caused)
|
307
|
-
if ( documentHash !== lastDocumentHash ) {
|
308
|
-
// Equalise
|
309
|
-
lastDocumentHash = documentHash;
|
310
|
-
|
311
|
-
// Create a history entry in the iframe
|
312
|
-
if ( iframeHash !== documentHash ) {
|
313
|
-
//History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash);
|
314
|
-
|
315
|
-
// Equalise
|
316
|
-
lastIframeHash = iframeHash = documentHash;
|
317
|
-
|
318
|
-
// Create History Entry
|
319
|
-
iframe.contentWindow.document.open();
|
320
|
-
iframe.contentWindow.document.close();
|
321
|
-
|
322
|
-
// Update the iframe's hash
|
323
|
-
iframe.contentWindow.document.location.hash = History.escapeHash(documentHash);
|
324
|
-
}
|
325
|
-
|
326
|
-
// Trigger Hashchange Event
|
327
|
-
History.Adapter.trigger(window,'hashchange');
|
328
|
-
}
|
329
|
-
|
330
|
-
// The iFrame Hash has changed (back button caused)
|
331
|
-
else if ( iframeHash !== lastIframeHash ) {
|
332
|
-
//History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash);
|
333
|
-
|
334
|
-
// Equalise
|
335
|
-
lastIframeHash = iframeHash;
|
336
|
-
|
337
|
-
// Update the Hash
|
338
|
-
History.setHash(iframeHash,false);
|
339
|
-
}
|
340
|
-
|
341
|
-
// Reset Running
|
342
|
-
checkerRunning = false;
|
343
|
-
|
344
|
-
// Return true
|
345
|
-
return true;
|
346
|
-
};
|
347
|
-
}
|
348
|
-
else {
|
349
|
-
// We are not IE
|
350
|
-
// Firefox 1 or 2, Opera
|
351
|
-
|
352
|
-
// Define the checker function
|
353
|
-
History.checkerFunction = function(){
|
354
|
-
// Prepare
|
355
|
-
var documentHash = History.getHash();
|
356
|
-
|
357
|
-
// The Document Hash has changed (application caused)
|
358
|
-
if ( documentHash !== lastDocumentHash ) {
|
359
|
-
// Equalise
|
360
|
-
lastDocumentHash = documentHash;
|
361
|
-
|
362
|
-
// Trigger Hashchange Event
|
363
|
-
History.Adapter.trigger(window,'hashchange');
|
364
|
-
}
|
365
|
-
|
366
|
-
// Return true
|
367
|
-
return true;
|
368
|
-
};
|
369
|
-
}
|
370
|
-
|
371
|
-
// Apply the checker function
|
372
|
-
History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval));
|
373
|
-
|
374
|
-
// Done
|
375
|
-
return true;
|
376
|
-
}; // History.hashChangeInit
|
377
|
-
|
378
|
-
// Bind hashChangeInit
|
379
|
-
History.Adapter.onDomLoad(History.hashChangeInit);
|
380
|
-
|
381
|
-
} // History.emulated.hashChange
|
382
|
-
|
383
|
-
|
384
|
-
// ====================================================================
|
385
|
-
// HTML5 State Support
|
386
|
-
|
387
|
-
// Non-Native pushState Implementation
|
388
|
-
if ( History.emulated.pushState ) {
|
389
|
-
/*
|
390
|
-
* We must emulate the HTML5 State Management by using HTML4 HashChange
|
391
|
-
*/
|
392
|
-
|
393
|
-
/**
|
394
|
-
* History.onHashChange(event)
|
395
|
-
* Trigger HTML5's window.onpopstate via HTML4 HashChange Support
|
396
|
-
*/
|
397
|
-
History.onHashChange = function(event){
|
398
|
-
//History.debug('History.onHashChange', arguments);
|
399
|
-
|
400
|
-
// Prepare
|
401
|
-
var currentUrl = ((event && event.newURL) || document.location.href),
|
402
|
-
currentHash = History.getHashByUrl(currentUrl),
|
403
|
-
currentState = null,
|
404
|
-
currentStateHash = null,
|
405
|
-
currentStateHashExits = null,
|
406
|
-
discardObject;
|
407
|
-
|
408
|
-
// Check if we are the same state
|
409
|
-
if ( History.isLastHash(currentHash) ) {
|
410
|
-
// There has been no change (just the page's hash has finally propagated)
|
411
|
-
//History.debug('History.onHashChange: no change');
|
412
|
-
History.busy(false);
|
413
|
-
return false;
|
414
|
-
}
|
415
|
-
|
416
|
-
// Reset the double check
|
417
|
-
History.doubleCheckComplete();
|
418
|
-
|
419
|
-
// Store our location for use in detecting back/forward direction
|
420
|
-
History.saveHash(currentHash);
|
421
|
-
|
422
|
-
// Expand Hash
|
423
|
-
if ( currentHash && History.isTraditionalAnchor(currentHash) ) {
|
424
|
-
//History.debug('History.onHashChange: traditional anchor', currentHash);
|
425
|
-
// Traditional Anchor Hash
|
426
|
-
History.Adapter.trigger(window,'anchorchange');
|
427
|
-
History.busy(false);
|
428
|
-
return false;
|
429
|
-
}
|
430
|
-
|
431
|
-
// Create State
|
432
|
-
currentState = History.extractState(History.getFullUrl(currentHash||document.location.href,false),true);
|
433
|
-
|
434
|
-
// Check if we are the same state
|
435
|
-
if ( History.isLastSavedState(currentState) ) {
|
436
|
-
//History.debug('History.onHashChange: no change');
|
437
|
-
// There has been no change (just the page's hash has finally propagated)
|
438
|
-
History.busy(false);
|
439
|
-
return false;
|
440
|
-
}
|
441
|
-
|
442
|
-
// Create the state Hash
|
443
|
-
currentStateHash = History.getHashByState(currentState);
|
444
|
-
|
445
|
-
// Check if we are DiscardedState
|
446
|
-
discardObject = History.discardedState(currentState);
|
447
|
-
if ( discardObject ) {
|
448
|
-
// Ignore this state as it has been discarded and go back to the state before it
|
449
|
-
if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) {
|
450
|
-
// We are going backwards
|
451
|
-
//History.debug('History.onHashChange: go backwards');
|
452
|
-
History.back(false);
|
453
|
-
} else {
|
454
|
-
// We are going forwards
|
455
|
-
//History.debug('History.onHashChange: go forwards');
|
456
|
-
History.forward(false);
|
457
|
-
}
|
458
|
-
return false;
|
459
|
-
}
|
460
|
-
|
461
|
-
// Push the new HTML5 State
|
462
|
-
//History.debug('History.onHashChange: success hashchange');
|
463
|
-
History.pushState(currentState.data,currentState.title,currentState.url,false);
|
464
|
-
|
465
|
-
// End onHashChange closure
|
466
|
-
return true;
|
467
|
-
};
|
468
|
-
History.Adapter.bind(window,'hashchange',History.onHashChange);
|
469
|
-
|
470
|
-
/**
|
471
|
-
* History.pushState(data,title,url)
|
472
|
-
* Add a new State to the history object, become it, and trigger onpopstate
|
473
|
-
* We have to trigger for HTML4 compatibility
|
474
|
-
* @param {object} data
|
475
|
-
* @param {string} title
|
476
|
-
* @param {string} url
|
477
|
-
* @return {true}
|
478
|
-
*/
|
479
|
-
History.pushState = function(data,title,url,queue){
|
480
|
-
//History.debug('History.pushState: called', arguments);
|
481
|
-
|
482
|
-
// Check the State
|
483
|
-
if ( History.getHashByUrl(url) ) {
|
484
|
-
throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
|
485
|
-
}
|
486
|
-
|
487
|
-
// Handle Queueing
|
488
|
-
if ( queue !== false && History.busy() ) {
|
489
|
-
// Wait + Push to Queue
|
490
|
-
//History.debug('History.pushState: we must wait', arguments);
|
491
|
-
History.pushQueue({
|
492
|
-
scope: History,
|
493
|
-
callback: History.pushState,
|
494
|
-
args: arguments,
|
495
|
-
queue: queue
|
496
|
-
});
|
497
|
-
return false;
|
498
|
-
}
|
499
|
-
|
500
|
-
// Make Busy
|
501
|
-
History.busy(true);
|
502
|
-
|
503
|
-
// Fetch the State Object
|
504
|
-
var newState = History.createStateObject(data,title,url),
|
505
|
-
newStateHash = History.getHashByState(newState),
|
506
|
-
oldState = History.getState(false),
|
507
|
-
oldStateHash = History.getHashByState(oldState),
|
508
|
-
html4Hash = History.getHash();
|
509
|
-
|
510
|
-
// Store the newState
|
511
|
-
History.storeState(newState);
|
512
|
-
History.expectedStateId = newState.id;
|
513
|
-
|
514
|
-
// Recycle the State
|
515
|
-
History.recycleState(newState);
|
516
|
-
|
517
|
-
// Force update of the title
|
518
|
-
History.setTitle(newState);
|
519
|
-
|
520
|
-
// Check if we are the same State
|
521
|
-
if ( newStateHash === oldStateHash ) {
|
522
|
-
//History.debug('History.pushState: no change', newStateHash);
|
523
|
-
History.busy(false);
|
524
|
-
return false;
|
525
|
-
}
|
526
|
-
|
527
|
-
// Update HTML4 Hash
|
528
|
-
if ( newStateHash !== html4Hash && newStateHash !== History.getShortUrl(document.location.href) ) {
|
529
|
-
//History.debug('History.pushState: update hash', newStateHash, html4Hash);
|
530
|
-
History.setHash(newStateHash,false);
|
531
|
-
return false;
|
532
|
-
}
|
533
|
-
|
534
|
-
// Update HTML5 State
|
535
|
-
History.saveState(newState);
|
536
|
-
|
537
|
-
// Fire HTML5 Event
|
538
|
-
//History.debug('History.pushState: trigger popstate');
|
539
|
-
History.Adapter.trigger(window,'statechange');
|
540
|
-
History.busy(false);
|
541
|
-
|
542
|
-
// End pushState closure
|
543
|
-
return true;
|
544
|
-
};
|
545
|
-
|
546
|
-
/**
|
547
|
-
* History.replaceState(data,title,url)
|
548
|
-
* Replace the State and trigger onpopstate
|
549
|
-
* We have to trigger for HTML4 compatibility
|
550
|
-
* @param {object} data
|
551
|
-
* @param {string} title
|
552
|
-
* @param {string} url
|
553
|
-
* @return {true}
|
554
|
-
*/
|
555
|
-
History.replaceState = function(data,title,url,queue){
|
556
|
-
//History.debug('History.replaceState: called', arguments);
|
557
|
-
|
558
|
-
// Check the State
|
559
|
-
if ( History.getHashByUrl(url) ) {
|
560
|
-
throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
|
561
|
-
}
|
562
|
-
|
563
|
-
// Handle Queueing
|
564
|
-
if ( queue !== false && History.busy() ) {
|
565
|
-
// Wait + Push to Queue
|
566
|
-
//History.debug('History.replaceState: we must wait', arguments);
|
567
|
-
History.pushQueue({
|
568
|
-
scope: History,
|
569
|
-
callback: History.replaceState,
|
570
|
-
args: arguments,
|
571
|
-
queue: queue
|
572
|
-
});
|
573
|
-
return false;
|
574
|
-
}
|
575
|
-
|
576
|
-
// Make Busy
|
577
|
-
History.busy(true);
|
578
|
-
|
579
|
-
// Fetch the State Objects
|
580
|
-
var newState = History.createStateObject(data,title,url),
|
581
|
-
oldState = History.getState(false),
|
582
|
-
previousState = History.getStateByIndex(-2);
|
583
|
-
|
584
|
-
// Discard Old State
|
585
|
-
History.discardState(oldState,newState,previousState);
|
586
|
-
|
587
|
-
// Alias to PushState
|
588
|
-
History.pushState(newState.data,newState.title,newState.url,false);
|
589
|
-
|
590
|
-
// End replaceState closure
|
591
|
-
return true;
|
592
|
-
};
|
593
|
-
|
594
|
-
} // History.emulated.pushState
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
// ====================================================================
|
599
|
-
// Initialise
|
600
|
-
|
601
|
-
// Non-Native pushState Implementation
|
602
|
-
if ( History.emulated.pushState ) {
|
603
|
-
/**
|
604
|
-
* Ensure initial state is handled correctly
|
605
|
-
*/
|
606
|
-
if ( History.getHash() && !History.emulated.hashChange ) {
|
607
|
-
History.Adapter.onDomLoad(function(){
|
608
|
-
History.Adapter.trigger(window,'hashchange');
|
609
|
-
});
|
610
|
-
}
|
611
|
-
|
612
|
-
} // History.emulated.pushState
|
613
|
-
|
614
|
-
}; // History.initHtml4
|
615
|
-
|
616
|
-
// Try and Initialise History
|
617
|
-
if ( typeof History.init !== 'undefined' ) {
|
618
|
-
History.init();
|
619
|
-
}
|
620
|
-
|
621
|
-
})(window);
|
1
|
+
/**
|
2
|
+
* History.js HTML4 Support
|
3
|
+
* Depends on the HTML5 Support
|
4
|
+
* @author Benjamin Arthur Lupton <contact@balupton.com>
|
5
|
+
* @copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
|
6
|
+
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
|
7
|
+
*/
|
8
|
+
|
9
|
+
(function(window,undefined){
|
10
|
+
"use strict";
|
11
|
+
|
12
|
+
// ========================================================================
|
13
|
+
// Initialise
|
14
|
+
|
15
|
+
// Localise Globals
|
16
|
+
var
|
17
|
+
document = window.document, // Make sure we are using the correct document
|
18
|
+
setTimeout = window.setTimeout||setTimeout,
|
19
|
+
clearTimeout = window.clearTimeout||clearTimeout,
|
20
|
+
setInterval = window.setInterval||setInterval,
|
21
|
+
History = window.History = window.History||{}; // Public History Object
|
22
|
+
|
23
|
+
// Check Existence
|
24
|
+
if ( typeof History.initHtml4 !== 'undefined' ) {
|
25
|
+
throw new Error('History.js HTML4 Support has already been loaded...');
|
26
|
+
}
|
27
|
+
|
28
|
+
|
29
|
+
// ========================================================================
|
30
|
+
// Initialise HTML4 Support
|
31
|
+
|
32
|
+
// Initialise HTML4 Support
|
33
|
+
History.initHtml4 = function(){
|
34
|
+
// Initialise
|
35
|
+
if ( typeof History.initHtml4.initialized !== 'undefined' ) {
|
36
|
+
// Already Loaded
|
37
|
+
return false;
|
38
|
+
}
|
39
|
+
else {
|
40
|
+
History.initHtml4.initialized = true;
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
// ====================================================================
|
45
|
+
// Properties
|
46
|
+
|
47
|
+
/**
|
48
|
+
* History.enabled
|
49
|
+
* Is History enabled?
|
50
|
+
*/
|
51
|
+
History.enabled = true;
|
52
|
+
|
53
|
+
|
54
|
+
// ====================================================================
|
55
|
+
// Hash Storage
|
56
|
+
|
57
|
+
/**
|
58
|
+
* History.savedHashes
|
59
|
+
* Store the hashes in an array
|
60
|
+
*/
|
61
|
+
History.savedHashes = [];
|
62
|
+
|
63
|
+
/**
|
64
|
+
* History.isLastHash(newHash)
|
65
|
+
* Checks if the hash is the last hash
|
66
|
+
* @param {string} newHash
|
67
|
+
* @return {boolean} true
|
68
|
+
*/
|
69
|
+
History.isLastHash = function(newHash){
|
70
|
+
// Prepare
|
71
|
+
var oldHash = History.getHashByIndex(),
|
72
|
+
isLast;
|
73
|
+
|
74
|
+
// Check
|
75
|
+
isLast = newHash === oldHash;
|
76
|
+
|
77
|
+
// Return isLast
|
78
|
+
return isLast;
|
79
|
+
};
|
80
|
+
|
81
|
+
/**
|
82
|
+
* History.saveHash(newHash)
|
83
|
+
* Push a Hash
|
84
|
+
* @param {string} newHash
|
85
|
+
* @return {boolean} true
|
86
|
+
*/
|
87
|
+
History.saveHash = function(newHash){
|
88
|
+
// Check Hash
|
89
|
+
if ( History.isLastHash(newHash) ) {
|
90
|
+
return false;
|
91
|
+
}
|
92
|
+
|
93
|
+
// Push the Hash
|
94
|
+
History.savedHashes.push(newHash);
|
95
|
+
|
96
|
+
// Return true
|
97
|
+
return true;
|
98
|
+
};
|
99
|
+
|
100
|
+
/**
|
101
|
+
* History.getHashByIndex()
|
102
|
+
* Gets a hash by the index
|
103
|
+
* @param {integer} index
|
104
|
+
* @return {string}
|
105
|
+
*/
|
106
|
+
History.getHashByIndex = function(index){
|
107
|
+
// Prepare
|
108
|
+
var hash = null;
|
109
|
+
|
110
|
+
// Handle
|
111
|
+
if ( typeof index === 'undefined' ) {
|
112
|
+
// Get the last inserted
|
113
|
+
hash = History.savedHashes[History.savedHashes.length-1];
|
114
|
+
}
|
115
|
+
else if ( index < 0 ) {
|
116
|
+
// Get from the end
|
117
|
+
hash = History.savedHashes[History.savedHashes.length+index];
|
118
|
+
}
|
119
|
+
else {
|
120
|
+
// Get from the beginning
|
121
|
+
hash = History.savedHashes[index];
|
122
|
+
}
|
123
|
+
|
124
|
+
// Return hash
|
125
|
+
return hash;
|
126
|
+
};
|
127
|
+
|
128
|
+
|
129
|
+
// ====================================================================
|
130
|
+
// Discarded States
|
131
|
+
|
132
|
+
/**
|
133
|
+
* History.discardedHashes
|
134
|
+
* A hashed array of discarded hashes
|
135
|
+
*/
|
136
|
+
History.discardedHashes = {};
|
137
|
+
|
138
|
+
/**
|
139
|
+
* History.discardedStates
|
140
|
+
* A hashed array of discarded states
|
141
|
+
*/
|
142
|
+
History.discardedStates = {};
|
143
|
+
|
144
|
+
/**
|
145
|
+
* History.discardState(State)
|
146
|
+
* Discards the state by ignoring it through History
|
147
|
+
* @param {object} State
|
148
|
+
* @return {true}
|
149
|
+
*/
|
150
|
+
History.discardState = function(discardedState,forwardState,backState){
|
151
|
+
//History.debug('History.discardState', arguments);
|
152
|
+
// Prepare
|
153
|
+
var discardedStateHash = History.getHashByState(discardedState),
|
154
|
+
discardObject;
|
155
|
+
|
156
|
+
// Create Discard Object
|
157
|
+
discardObject = {
|
158
|
+
'discardedState': discardedState,
|
159
|
+
'backState': backState,
|
160
|
+
'forwardState': forwardState
|
161
|
+
};
|
162
|
+
|
163
|
+
// Add to DiscardedStates
|
164
|
+
History.discardedStates[discardedStateHash] = discardObject;
|
165
|
+
|
166
|
+
// Return true
|
167
|
+
return true;
|
168
|
+
};
|
169
|
+
|
170
|
+
/**
|
171
|
+
* History.discardHash(hash)
|
172
|
+
* Discards the hash by ignoring it through History
|
173
|
+
* @param {string} hash
|
174
|
+
* @return {true}
|
175
|
+
*/
|
176
|
+
History.discardHash = function(discardedHash,forwardState,backState){
|
177
|
+
//History.debug('History.discardState', arguments);
|
178
|
+
// Create Discard Object
|
179
|
+
var discardObject = {
|
180
|
+
'discardedHash': discardedHash,
|
181
|
+
'backState': backState,
|
182
|
+
'forwardState': forwardState
|
183
|
+
};
|
184
|
+
|
185
|
+
// Add to discardedHash
|
186
|
+
History.discardedHashes[discardedHash] = discardObject;
|
187
|
+
|
188
|
+
// Return true
|
189
|
+
return true;
|
190
|
+
};
|
191
|
+
|
192
|
+
/**
|
193
|
+
* History.discardState(State)
|
194
|
+
* Checks to see if the state is discarded
|
195
|
+
* @param {object} State
|
196
|
+
* @return {bool}
|
197
|
+
*/
|
198
|
+
History.discardedState = function(State){
|
199
|
+
// Prepare
|
200
|
+
var StateHash = History.getHashByState(State),
|
201
|
+
discarded;
|
202
|
+
|
203
|
+
// Check
|
204
|
+
discarded = History.discardedStates[StateHash]||false;
|
205
|
+
|
206
|
+
// Return true
|
207
|
+
return discarded;
|
208
|
+
};
|
209
|
+
|
210
|
+
/**
|
211
|
+
* History.discardedHash(hash)
|
212
|
+
* Checks to see if the state is discarded
|
213
|
+
* @param {string} State
|
214
|
+
* @return {bool}
|
215
|
+
*/
|
216
|
+
History.discardedHash = function(hash){
|
217
|
+
// Check
|
218
|
+
var discarded = History.discardedHashes[hash]||false;
|
219
|
+
|
220
|
+
// Return true
|
221
|
+
return discarded;
|
222
|
+
};
|
223
|
+
|
224
|
+
/**
|
225
|
+
* History.recycleState(State)
|
226
|
+
* Allows a discarded state to be used again
|
227
|
+
* @param {object} data
|
228
|
+
* @param {string} title
|
229
|
+
* @param {string} url
|
230
|
+
* @return {true}
|
231
|
+
*/
|
232
|
+
History.recycleState = function(State){
|
233
|
+
//History.debug('History.recycleState', arguments);
|
234
|
+
// Prepare
|
235
|
+
var StateHash = History.getHashByState(State);
|
236
|
+
|
237
|
+
// Remove from DiscardedStates
|
238
|
+
if ( History.discardedState(State) ) {
|
239
|
+
delete History.discardedStates[StateHash];
|
240
|
+
}
|
241
|
+
|
242
|
+
// Return true
|
243
|
+
return true;
|
244
|
+
};
|
245
|
+
|
246
|
+
|
247
|
+
// ====================================================================
|
248
|
+
// HTML4 HashChange Support
|
249
|
+
|
250
|
+
if ( History.emulated.hashChange ) {
|
251
|
+
/*
|
252
|
+
* We must emulate the HTML4 HashChange Support by manually checking for hash changes
|
253
|
+
*/
|
254
|
+
|
255
|
+
/**
|
256
|
+
* History.hashChangeInit()
|
257
|
+
* Init the HashChange Emulation
|
258
|
+
*/
|
259
|
+
History.hashChangeInit = function(){
|
260
|
+
// Define our Checker Function
|
261
|
+
History.checkerFunction = null;
|
262
|
+
|
263
|
+
// Define some variables that will help in our checker function
|
264
|
+
var lastDocumentHash = '',
|
265
|
+
iframeId, iframe,
|
266
|
+
lastIframeHash, checkerRunning;
|
267
|
+
|
268
|
+
// Handle depending on the browser
|
269
|
+
if ( History.isInternetExplorer() ) {
|
270
|
+
// IE6 and IE7
|
271
|
+
// We need to use an iframe to emulate the back and forward buttons
|
272
|
+
|
273
|
+
// Create iFrame
|
274
|
+
iframeId = 'historyjs-iframe';
|
275
|
+
iframe = document.createElement('iframe');
|
276
|
+
|
277
|
+
// Adjust iFarme
|
278
|
+
iframe.setAttribute('id', iframeId);
|
279
|
+
iframe.style.display = 'none';
|
280
|
+
|
281
|
+
// Append iFrame
|
282
|
+
document.body.appendChild(iframe);
|
283
|
+
|
284
|
+
// Create initial history entry
|
285
|
+
iframe.contentWindow.document.open();
|
286
|
+
iframe.contentWindow.document.close();
|
287
|
+
|
288
|
+
// Define some variables that will help in our checker function
|
289
|
+
lastIframeHash = '';
|
290
|
+
checkerRunning = false;
|
291
|
+
|
292
|
+
// Define the checker function
|
293
|
+
History.checkerFunction = function(){
|
294
|
+
// Check Running
|
295
|
+
if ( checkerRunning ) {
|
296
|
+
return false;
|
297
|
+
}
|
298
|
+
|
299
|
+
// Update Running
|
300
|
+
checkerRunning = true;
|
301
|
+
|
302
|
+
// Fetch
|
303
|
+
var documentHash = History.getHash()||'',
|
304
|
+
iframeHash = History.unescapeHash(iframe.contentWindow.document.location.hash)||'';
|
305
|
+
|
306
|
+
// The Document Hash has changed (application caused)
|
307
|
+
if ( documentHash !== lastDocumentHash ) {
|
308
|
+
// Equalise
|
309
|
+
lastDocumentHash = documentHash;
|
310
|
+
|
311
|
+
// Create a history entry in the iframe
|
312
|
+
if ( iframeHash !== documentHash ) {
|
313
|
+
//History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash);
|
314
|
+
|
315
|
+
// Equalise
|
316
|
+
lastIframeHash = iframeHash = documentHash;
|
317
|
+
|
318
|
+
// Create History Entry
|
319
|
+
iframe.contentWindow.document.open();
|
320
|
+
iframe.contentWindow.document.close();
|
321
|
+
|
322
|
+
// Update the iframe's hash
|
323
|
+
iframe.contentWindow.document.location.hash = History.escapeHash(documentHash);
|
324
|
+
}
|
325
|
+
|
326
|
+
// Trigger Hashchange Event
|
327
|
+
History.Adapter.trigger(window,'hashchange');
|
328
|
+
}
|
329
|
+
|
330
|
+
// The iFrame Hash has changed (back button caused)
|
331
|
+
else if ( iframeHash !== lastIframeHash ) {
|
332
|
+
//History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash);
|
333
|
+
|
334
|
+
// Equalise
|
335
|
+
lastIframeHash = iframeHash;
|
336
|
+
|
337
|
+
// Update the Hash
|
338
|
+
History.setHash(iframeHash,false);
|
339
|
+
}
|
340
|
+
|
341
|
+
// Reset Running
|
342
|
+
checkerRunning = false;
|
343
|
+
|
344
|
+
// Return true
|
345
|
+
return true;
|
346
|
+
};
|
347
|
+
}
|
348
|
+
else {
|
349
|
+
// We are not IE
|
350
|
+
// Firefox 1 or 2, Opera
|
351
|
+
|
352
|
+
// Define the checker function
|
353
|
+
History.checkerFunction = function(){
|
354
|
+
// Prepare
|
355
|
+
var documentHash = History.getHash();
|
356
|
+
|
357
|
+
// The Document Hash has changed (application caused)
|
358
|
+
if ( documentHash !== lastDocumentHash ) {
|
359
|
+
// Equalise
|
360
|
+
lastDocumentHash = documentHash;
|
361
|
+
|
362
|
+
// Trigger Hashchange Event
|
363
|
+
History.Adapter.trigger(window,'hashchange');
|
364
|
+
}
|
365
|
+
|
366
|
+
// Return true
|
367
|
+
return true;
|
368
|
+
};
|
369
|
+
}
|
370
|
+
|
371
|
+
// Apply the checker function
|
372
|
+
History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval));
|
373
|
+
|
374
|
+
// Done
|
375
|
+
return true;
|
376
|
+
}; // History.hashChangeInit
|
377
|
+
|
378
|
+
// Bind hashChangeInit
|
379
|
+
History.Adapter.onDomLoad(History.hashChangeInit);
|
380
|
+
|
381
|
+
} // History.emulated.hashChange
|
382
|
+
|
383
|
+
|
384
|
+
// ====================================================================
|
385
|
+
// HTML5 State Support
|
386
|
+
|
387
|
+
// Non-Native pushState Implementation
|
388
|
+
if ( History.emulated.pushState ) {
|
389
|
+
/*
|
390
|
+
* We must emulate the HTML5 State Management by using HTML4 HashChange
|
391
|
+
*/
|
392
|
+
|
393
|
+
/**
|
394
|
+
* History.onHashChange(event)
|
395
|
+
* Trigger HTML5's window.onpopstate via HTML4 HashChange Support
|
396
|
+
*/
|
397
|
+
History.onHashChange = function(event){
|
398
|
+
//History.debug('History.onHashChange', arguments);
|
399
|
+
|
400
|
+
// Prepare
|
401
|
+
var currentUrl = ((event && event.newURL) || document.location.href),
|
402
|
+
currentHash = History.getHashByUrl(currentUrl),
|
403
|
+
currentState = null,
|
404
|
+
currentStateHash = null,
|
405
|
+
currentStateHashExits = null,
|
406
|
+
discardObject;
|
407
|
+
|
408
|
+
// Check if we are the same state
|
409
|
+
if ( History.isLastHash(currentHash) ) {
|
410
|
+
// There has been no change (just the page's hash has finally propagated)
|
411
|
+
//History.debug('History.onHashChange: no change');
|
412
|
+
History.busy(false);
|
413
|
+
return false;
|
414
|
+
}
|
415
|
+
|
416
|
+
// Reset the double check
|
417
|
+
History.doubleCheckComplete();
|
418
|
+
|
419
|
+
// Store our location for use in detecting back/forward direction
|
420
|
+
History.saveHash(currentHash);
|
421
|
+
|
422
|
+
// Expand Hash
|
423
|
+
if ( currentHash && History.isTraditionalAnchor(currentHash) ) {
|
424
|
+
//History.debug('History.onHashChange: traditional anchor', currentHash);
|
425
|
+
// Traditional Anchor Hash
|
426
|
+
History.Adapter.trigger(window,'anchorchange');
|
427
|
+
History.busy(false);
|
428
|
+
return false;
|
429
|
+
}
|
430
|
+
|
431
|
+
// Create State
|
432
|
+
currentState = History.extractState(History.getFullUrl(currentHash||document.location.href,false),true);
|
433
|
+
|
434
|
+
// Check if we are the same state
|
435
|
+
if ( History.isLastSavedState(currentState) ) {
|
436
|
+
//History.debug('History.onHashChange: no change');
|
437
|
+
// There has been no change (just the page's hash has finally propagated)
|
438
|
+
History.busy(false);
|
439
|
+
return false;
|
440
|
+
}
|
441
|
+
|
442
|
+
// Create the state Hash
|
443
|
+
currentStateHash = History.getHashByState(currentState);
|
444
|
+
|
445
|
+
// Check if we are DiscardedState
|
446
|
+
discardObject = History.discardedState(currentState);
|
447
|
+
if ( discardObject ) {
|
448
|
+
// Ignore this state as it has been discarded and go back to the state before it
|
449
|
+
if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) {
|
450
|
+
// We are going backwards
|
451
|
+
//History.debug('History.onHashChange: go backwards');
|
452
|
+
History.back(false);
|
453
|
+
} else {
|
454
|
+
// We are going forwards
|
455
|
+
//History.debug('History.onHashChange: go forwards');
|
456
|
+
History.forward(false);
|
457
|
+
}
|
458
|
+
return false;
|
459
|
+
}
|
460
|
+
|
461
|
+
// Push the new HTML5 State
|
462
|
+
//History.debug('History.onHashChange: success hashchange');
|
463
|
+
History.pushState(currentState.data,currentState.title,currentState.url,false);
|
464
|
+
|
465
|
+
// End onHashChange closure
|
466
|
+
return true;
|
467
|
+
};
|
468
|
+
History.Adapter.bind(window,'hashchange',History.onHashChange);
|
469
|
+
|
470
|
+
/**
|
471
|
+
* History.pushState(data,title,url)
|
472
|
+
* Add a new State to the history object, become it, and trigger onpopstate
|
473
|
+
* We have to trigger for HTML4 compatibility
|
474
|
+
* @param {object} data
|
475
|
+
* @param {string} title
|
476
|
+
* @param {string} url
|
477
|
+
* @return {true}
|
478
|
+
*/
|
479
|
+
History.pushState = function(data,title,url,queue){
|
480
|
+
//History.debug('History.pushState: called', arguments);
|
481
|
+
|
482
|
+
// Check the State
|
483
|
+
if ( History.getHashByUrl(url) ) {
|
484
|
+
throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
|
485
|
+
}
|
486
|
+
|
487
|
+
// Handle Queueing
|
488
|
+
if ( queue !== false && History.busy() ) {
|
489
|
+
// Wait + Push to Queue
|
490
|
+
//History.debug('History.pushState: we must wait', arguments);
|
491
|
+
History.pushQueue({
|
492
|
+
scope: History,
|
493
|
+
callback: History.pushState,
|
494
|
+
args: arguments,
|
495
|
+
queue: queue
|
496
|
+
});
|
497
|
+
return false;
|
498
|
+
}
|
499
|
+
|
500
|
+
// Make Busy
|
501
|
+
History.busy(true);
|
502
|
+
|
503
|
+
// Fetch the State Object
|
504
|
+
var newState = History.createStateObject(data,title,url),
|
505
|
+
newStateHash = History.getHashByState(newState),
|
506
|
+
oldState = History.getState(false),
|
507
|
+
oldStateHash = History.getHashByState(oldState),
|
508
|
+
html4Hash = History.getHash();
|
509
|
+
|
510
|
+
// Store the newState
|
511
|
+
History.storeState(newState);
|
512
|
+
History.expectedStateId = newState.id;
|
513
|
+
|
514
|
+
// Recycle the State
|
515
|
+
History.recycleState(newState);
|
516
|
+
|
517
|
+
// Force update of the title
|
518
|
+
History.setTitle(newState);
|
519
|
+
|
520
|
+
// Check if we are the same State
|
521
|
+
if ( newStateHash === oldStateHash ) {
|
522
|
+
//History.debug('History.pushState: no change', newStateHash);
|
523
|
+
History.busy(false);
|
524
|
+
return false;
|
525
|
+
}
|
526
|
+
|
527
|
+
// Update HTML4 Hash
|
528
|
+
if ( newStateHash !== html4Hash && newStateHash !== History.getShortUrl(document.location.href) ) {
|
529
|
+
//History.debug('History.pushState: update hash', newStateHash, html4Hash);
|
530
|
+
History.setHash(newStateHash,false);
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
|
534
|
+
// Update HTML5 State
|
535
|
+
History.saveState(newState);
|
536
|
+
|
537
|
+
// Fire HTML5 Event
|
538
|
+
//History.debug('History.pushState: trigger popstate');
|
539
|
+
History.Adapter.trigger(window,'statechange');
|
540
|
+
History.busy(false);
|
541
|
+
|
542
|
+
// End pushState closure
|
543
|
+
return true;
|
544
|
+
};
|
545
|
+
|
546
|
+
/**
|
547
|
+
* History.replaceState(data,title,url)
|
548
|
+
* Replace the State and trigger onpopstate
|
549
|
+
* We have to trigger for HTML4 compatibility
|
550
|
+
* @param {object} data
|
551
|
+
* @param {string} title
|
552
|
+
* @param {string} url
|
553
|
+
* @return {true}
|
554
|
+
*/
|
555
|
+
History.replaceState = function(data,title,url,queue){
|
556
|
+
//History.debug('History.replaceState: called', arguments);
|
557
|
+
|
558
|
+
// Check the State
|
559
|
+
if ( History.getHashByUrl(url) ) {
|
560
|
+
throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).');
|
561
|
+
}
|
562
|
+
|
563
|
+
// Handle Queueing
|
564
|
+
if ( queue !== false && History.busy() ) {
|
565
|
+
// Wait + Push to Queue
|
566
|
+
//History.debug('History.replaceState: we must wait', arguments);
|
567
|
+
History.pushQueue({
|
568
|
+
scope: History,
|
569
|
+
callback: History.replaceState,
|
570
|
+
args: arguments,
|
571
|
+
queue: queue
|
572
|
+
});
|
573
|
+
return false;
|
574
|
+
}
|
575
|
+
|
576
|
+
// Make Busy
|
577
|
+
History.busy(true);
|
578
|
+
|
579
|
+
// Fetch the State Objects
|
580
|
+
var newState = History.createStateObject(data,title,url),
|
581
|
+
oldState = History.getState(false),
|
582
|
+
previousState = History.getStateByIndex(-2);
|
583
|
+
|
584
|
+
// Discard Old State
|
585
|
+
History.discardState(oldState,newState,previousState);
|
586
|
+
|
587
|
+
// Alias to PushState
|
588
|
+
History.pushState(newState.data,newState.title,newState.url,false);
|
589
|
+
|
590
|
+
// End replaceState closure
|
591
|
+
return true;
|
592
|
+
};
|
593
|
+
|
594
|
+
} // History.emulated.pushState
|
595
|
+
|
596
|
+
|
597
|
+
|
598
|
+
// ====================================================================
|
599
|
+
// Initialise
|
600
|
+
|
601
|
+
// Non-Native pushState Implementation
|
602
|
+
if ( History.emulated.pushState ) {
|
603
|
+
/**
|
604
|
+
* Ensure initial state is handled correctly
|
605
|
+
*/
|
606
|
+
if ( History.getHash() && !History.emulated.hashChange ) {
|
607
|
+
History.Adapter.onDomLoad(function(){
|
608
|
+
History.Adapter.trigger(window,'hashchange');
|
609
|
+
});
|
610
|
+
}
|
611
|
+
|
612
|
+
} // History.emulated.pushState
|
613
|
+
|
614
|
+
}; // History.initHtml4
|
615
|
+
|
616
|
+
// Try and Initialise History
|
617
|
+
if ( typeof History.init !== 'undefined' ) {
|
618
|
+
History.init();
|
619
|
+
}
|
620
|
+
|
621
|
+
})(window);
|