7b520d428353283a56f54f84db03e816eb13426d
1 BrowserHistoryUtils
= {
2 addEvent: function(elm
, evType
, fn
, useCapture
) {
3 useCapture
= useCapture
|| false;
4 if (elm
.addEventListener
) {
5 elm
.addEventListener(evType
, fn
, useCapture
);
8 else if (elm
.attachEvent
) {
9 var r
= elm
.attachEvent('on' + evType
, fn
);
13 elm
['on' + evType
] = fn
;
18 BrowserHistory
= (function() {
28 // if setDefaultURL has been called, our first clue
29 // that the SWF is ready and listening
30 //var swfReady = false;
32 // the URL we'll send to the SWF once it is ready
33 //var pendingURL = '';
35 // Default app state URL to use when no fragment ID present
38 // Last-known app state URL
39 var currentHref
= document
.location
.href
;
41 // Initial URL (used only by IE)
42 var initialHref
= document
.location
.href
;
44 // Initial URL (used only by IE)
45 var initialHash
= document
.location
.hash
;
47 // History frame source URL prefix (used only by IE)
48 var historyFrameSourcePrefix
= 'history/historyFrame.html?';
50 // History maintenance (used only by Safari)
51 var currentHistoryLength
= -1;
55 var initialState
= createState(initialHref
, initialHref
+ '#' + initialHash
, initialHash
);
58 var forwardStack
= [];
60 var currentObjectId
= null;
63 var useragent
= navigator
.userAgent
.toLowerCase();
65 if (useragent
.indexOf("opera") != -1) {
67 } else if (useragent
.indexOf("msie") != -1) {
69 browser
.version
= parseFloat(useragent
.substring(useragent
.indexOf('msie') + 4));
70 } else if (useragent
.indexOf("safari") != -1) {
71 browser
.safari
= true;
72 browser
.version
= parseFloat(useragent
.substring(useragent
.indexOf('safari') + 7));
73 } else if (useragent
.indexOf("gecko") != -1) {
74 browser
.firefox
= true;
77 if (browser
.ie
== true && browser
.version
== 7) {
78 window
["_ie_firstload"] = false;
81 // Accessor functions for obtaining specific elements of the page.
82 function getHistoryFrame()
84 return document
.getElementById('ie_historyFrame');
87 function getAnchorElement()
89 return document
.getElementById('firefox_anchorDiv');
92 function getFormElement()
94 return document
.getElementById('safari_formDiv');
97 function getRememberElement()
99 return document
.getElementById("safari_remember_field");
102 // Get the Flash player object for performing ExternalInterface callbacks.
103 // Updated for changes to SWFObject2.
104 function getPlayer(id
) {
105 if (id
&& document
.getElementById(id
)) {
106 var r
= document
.getElementById(id
);
107 if (typeof r
.SetVariable
!= "undefined") {
111 var o
= r
.getElementsByTagName("object");
112 var e
= r
.getElementsByTagName("embed");
113 if (o
.length
> 0 && typeof o
[0].SetVariable
!= "undefined") {
116 else if (e
.length
> 0 && typeof e
[0].SetVariable
!= "undefined") {
122 var o
= document
.getElementsByTagName("object");
123 var e
= document
.getElementsByTagName("embed");
124 if (e
.length
> 0 && typeof e
[0].SetVariable
!= "undefined") {
127 else if (o
.length
> 0 && typeof o
[0].SetVariable
!= "undefined") {
130 else if (o
.length
> 1 && typeof o
[1].SetVariable
!= "undefined") {
137 function getPlayers() {
139 if (players
.length
== 0) {
140 var tmp
= document
.getElementsByTagName('object');
144 if (players
.length
== 0 || players
[0].object
== null) {
145 var tmp
= document
.getElementsByTagName('embed');
151 function getIframeHash() {
152 var doc
= getHistoryFrame().contentWindow
.document
;
153 var hash
= String(doc
.location
.search
);
154 if (hash
.length
== 1 && hash
.charAt(0) == "?") {
157 else if (hash
.length
>= 2 && hash
.charAt(0) == "?") {
158 hash
= hash
.substring(1);
163 /* Get the current location hash excluding the '#' symbol. */
165 // It would be nice if we could use document.location.hash here,
166 // but it's faulty sometimes.
167 var idx
= document
.location
.href
.indexOf('#');
168 return (idx
>= 0) ? document
.location
.href
.substr(idx
+1) : '';
171 /* Get the current location hash excluding the '#' symbol. */
172 function setHash(hash
) {
173 // It would be nice if we could use document.location.hash here,
174 // but it's faulty sometimes.
175 if (hash
== '') hash
= '#'
176 document
.location
.hash
= hash
;
179 function createState(baseUrl
, newUrl
, flexAppUrl
) {
180 return { 'baseUrl': baseUrl
, 'newUrl': newUrl
, 'flexAppUrl': flexAppUrl
, 'title': null };
183 /* Add a history entry to the browser.
184 * baseUrl: the portion of the location prior to the '#'
185 * newUrl: the entire new URL, including '#' and following fragment
186 * flexAppUrl: the portion of the location following the '#' only
188 function addHistoryEntry(baseUrl
, newUrl
, flexAppUrl
) {
190 //delete all the history entries
194 //Check to see if we are being asked to do a navigate for the first
195 //history entry, and if so ignore, because it's coming from the creation
196 //of the history iframe
197 if (flexAppUrl
== defaultHash
&& document
.location
.href
== initialHref
&& window
['_ie_firstload']) {
198 currentHref
= initialHref
;
201 if ((!flexAppUrl
|| flexAppUrl
== defaultHash
) && window
['_ie_firstload']) {
202 newUrl
= baseUrl
+ '#' + defaultHash
;
203 flexAppUrl
= defaultHash
;
205 // for IE, tell the history frame to go somewhere without a '#'
206 // in order to get this entry into the browser history.
207 getHistoryFrame().src
= historyFrameSourcePrefix
+ flexAppUrl
;
213 if (backStack
.length
== 0 && initialState
.flexAppUrl
== flexAppUrl
) {
214 initialState
= createState(baseUrl
, newUrl
, flexAppUrl
);
215 } else if(backStack
.length
> 0 && backStack
[backStack
.length
- 1].flexAppUrl
== flexAppUrl
) {
216 backStack
[backStack
.length
- 1] = createState(baseUrl
, newUrl
, flexAppUrl
);
219 if (browser
.safari
) {
220 // for Safari, submit a form whose action points to the desired URL
221 if (browser
.version
<= 419.3) {
222 var file
= window
.location
.pathname
.toString();
223 file
= file
.substring(file
.lastIndexOf("/")+1);
224 getFormElement().innerHTML
= '<form name="historyForm" action="'+file
+'#' + flexAppUrl
+ '" method="GET"></form>';
225 //get the current elements and add them to the form
226 var qs
= window
.location
.search
.substring(1);
227 var qs_arr
= qs
.split("&");
228 for (var i
= 0; i
< qs_arr
.length
; i
++) {
229 var tmp
= qs_arr
[i
].split("=");
230 var elem
= document
.createElement("input");
231 elem
.type
= "hidden";
234 document
.forms
.historyForm
.appendChild(elem
);
236 document
.forms
.historyForm
.submit();
238 top
.location
.hash
= flexAppUrl
;
240 // We also have to maintain the history by hand for Safari
241 historyHash
[history
.length
] = flexAppUrl
;
244 // Otherwise, write an anchor into the page and tell the browser to go there
245 addAnchor(flexAppUrl
);
249 backStack
.push(createState(baseUrl
, newUrl
, flexAppUrl
));
252 function _storeStates() {
253 if (browser
.safari
) {
254 getRememberElement().value
= historyHash
.join(",");
258 function handleBackButton() {
259 //The "current" page is always at the top of the history stack.
260 var current
= backStack
.pop();
261 if (!current
) { return; }
262 var last
= backStack
[backStack
.length
- 1];
263 if (!last
&& backStack
.length
== 0){
266 forwardStack
.push(current
);
269 function handleForwardButton() {
270 //summary: private method. Do not call this directly.
272 var last
= forwardStack
.pop();
273 if (!last
) { return; }
274 backStack
.push(last
);
277 function handleArbitraryUrl() {
278 //delete all the history entries
282 /* Called periodically to poll to see if we need to detect navigation that has occurred */
283 function checkForUrlChange() {
286 if (currentHref
!= document
.location
.href
&& currentHref
+ '#' != document
.location
.href
) {
287 //This occurs when the user has navigated to a specific URL
288 //within the app, and didn't use browser back/forward
289 //IE seems to have a bug where it stops updating the URL it
290 //shows the end-user at this point, but programatically it
291 //appears to be correct. Do a full app reload to get around
293 if (browser
.version
< 7) {
294 currentHref
= document
.location
.href
;
295 document
.location
.reload();
297 if (getHash() != getIframeHash()) {
298 // this.iframe.src = this.blankURL + hash;
299 var sourceToSet
= historyFrameSourcePrefix
+ getHash();
300 getHistoryFrame().src
= sourceToSet
;
306 if (browser
.safari
) {
307 // For Safari, we have to check to see if history.length changed.
308 if (currentHistoryLength
>= 0 && history
.length
!= currentHistoryLength
) {
309 //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
310 // If it did change, then we have to look the old state up
311 // in our hand-maintained array since document.location.hash
312 // won't have changed, then call back into BrowserManager.
313 currentHistoryLength
= history
.length
;
314 var flexAppUrl
= historyHash
[currentHistoryLength
];
315 if (flexAppUrl
== '') {
316 //flexAppUrl = defaultHash;
318 //ADR: to fix multiple
319 if (typeof BrowserHistory_multiple
!= "undefined" && BrowserHistory_multiple
== true) {
320 var pl
= getPlayers();
321 for (var i
= 0; i
< pl
.length
; i
++) {
322 pl
[i
].browserURLChange(flexAppUrl
);
325 getPlayer().browserURLChange(flexAppUrl
);
330 if (browser
.firefox
) {
331 if (currentHref
!= document
.location
.href
) {
332 var bsl
= backStack
.length
;
340 if ((window
.location
.hash
== initialHash
|| window
.location
.href
== initialHref
) && (bsl
== 1)) {
341 urlActions
.back
= true;
342 // FIXME: could this ever be a forward button?
343 // we can't clear it because we still need to check for forwards. Ugg.
344 // clearInterval(this.locationTimer);
348 // first check to see if we could have gone forward. We always halt on
350 if (forwardStack
.length
> 0) {
351 if (forwardStack
[forwardStack
.length
-1].flexAppUrl
== getHash()) {
352 urlActions
.forward
= true;
353 handleForwardButton();
357 // ok, that didn't work, try someplace back in the history stack
358 if ((bsl
>= 2) && (backStack
[bsl
- 2])) {
359 if (backStack
[bsl
- 2].flexAppUrl
== getHash()) {
360 urlActions
.back
= true;
365 if (!urlActions
.back
&& !urlActions
.forward
) {
366 var foundInStacks
= {
371 for (var i
= 0; i
< backStack
.length
; i
++) {
372 if (backStack
[i
].flexAppUrl
== getHash() && i
!= (bsl
- 2)) {
374 foundInStacks
.back
= i
;
377 for (var i
= 0; i
< forwardStack
.length
; i
++) {
378 if (forwardStack
[i
].flexAppUrl
== getHash() && i
!= (bsl
- 2)) {
380 foundInStacks
.forward
= i
;
383 handleArbitraryUrl();
386 // Firefox changed; do a callback into BrowserManager to tell it.
387 currentHref
= document
.location
.href
;
388 var flexAppUrl
= getHash();
389 if (flexAppUrl
== '') {
390 //flexAppUrl = defaultHash;
392 //ADR: to fix multiple
393 if (typeof BrowserHistory_multiple
!= "undefined" && BrowserHistory_multiple
== true) {
394 var pl
= getPlayers();
395 for (var i
= 0; i
< pl
.length
; i
++) {
396 pl
[i
].browserURLChange(flexAppUrl
);
399 getPlayer().browserURLChange(flexAppUrl
);
403 //setTimeout(checkForUrlChange, 50);
406 /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
407 function addAnchor(flexAppUrl
)
409 if (document
.getElementsByName(flexAppUrl
).length
== 0) {
410 getAnchorElement().innerHTML
+= "<a name='" + flexAppUrl
+ "'>" + flexAppUrl
+ "</a>";
414 var _initialize = function () {
417 var scripts
= document
.getElementsByTagName('script');
418 for (var i
= 0, s
; s
= scripts
[i
]; i
++) {
419 if (s
.src
.indexOf("history.js") > -1) {
420 var iframe_location
= (new String(s
.src
)).replace("history.js", "historyFrame.html");
423 historyFrameSourcePrefix
= iframe_location
+ "?";
424 var src
= historyFrameSourcePrefix
;
426 var iframe
= document
.createElement("iframe");
427 iframe
.id
= 'ie_historyFrame';
428 iframe
.name
= 'ie_historyFrame';
429 //iframe.src = historyFrameSourcePrefix;
431 document
.body
.appendChild(iframe
);
433 setTimeout(function() {
434 document
.body
.appendChild(iframe
);
441 var rememberDiv
= document
.createElement("div");
442 rememberDiv
.id
= 'safari_rememberDiv';
443 document
.body
.appendChild(rememberDiv
);
444 rememberDiv
.innerHTML
= '<input type="text" id="safari_remember_field" style="width: 500px;">';
446 var formDiv
= document
.createElement("div");
447 formDiv
.id
= 'safari_formDiv';
448 document
.body
.appendChild(formDiv
);
450 var reloader_content
= document
.createElement('div');
451 reloader_content
.id
= 'safarireloader';
452 var scripts
= document
.getElementsByTagName('script');
453 for (var i
= 0, s
; s
= scripts
[i
]; i
++) {
454 if (s
.src
.indexOf("history.js") > -1) {
455 html
= (new String(s
.src
)).replace(".js", ".html");
458 reloader_content
.innerHTML
= '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
459 document
.body
.appendChild(reloader_content
);
460 reloader_content
.style
.position
= 'absolute';
461 reloader_content
.style
.left
= reloader_content
.style
.top
= '-9999px';
462 iframe
= reloader_content
.getElementsByTagName('iframe')[0];
464 if (document
.getElementById("safari_remember_field").value
!= "" ) {
465 historyHash
= document
.getElementById("safari_remember_field").value
.split(",");
472 var anchorDiv
= document
.createElement("div");
473 anchorDiv
.id
= 'firefox_anchorDiv';
474 document
.body
.appendChild(anchorDiv
);
477 //setTimeout(checkForUrlChange, 50);
481 historyHash
: historyHash
,
482 backStack: function() { return backStack
; },
483 forwardStack: function() { return forwardStack
},
484 getPlayer
: getPlayer
,
485 initialize: function(src
) {
488 setURL: function(url
) {
489 document
.location
.href
= url
;
492 return document
.location
.href
;
494 getTitle: function() {
495 return document
.title
;
497 setTitle: function(title
) {
499 backStack
[backStack
.length
- 1].title
= title
;
501 //if on safari, set the title to be the empty string.
502 if (browser
.safari
) {
505 var tmp
= window
.location
.href
.toString();
506 title
= tmp
.substring((tmp
.lastIndexOf("/")+1), tmp
.lastIndexOf("#"));
512 document
.title
= title
;
514 setDefaultURL: function(def
)
518 //trailing ? is important else an extra frame gets added to the history
519 //when navigating back to the first page. Alternatively could check
520 //in history frame navigation to compare # and ?.
523 window
['_ie_firstload'] = true;
524 var sourceToSet
= historyFrameSourcePrefix
+ def
;
525 var func = function() {
526 getHistoryFrame().src
= sourceToSet
;
527 window
.location
.replace("#" + def
);
528 setInterval(checkForUrlChange
, 50);
533 window
.setTimeout(function() { func(); }, 0);
539 currentHistoryLength
= history
.length
;
540 if (historyHash
.length
== 0) {
541 historyHash
[currentHistoryLength
] = def
;
542 var newloc
= "#" + def
;
543 window
.location
.replace(newloc
);
545 //alert(historyHash[historyHash.length-1]);
548 setInterval(checkForUrlChange
, 50);
552 if (browser
.firefox
|| browser
.opera
)
554 var reg
= new RegExp("#" + def
+ "$");
555 if (window
.location
.toString().match(reg
)) {
557 var newloc
="#" + def
;
558 window
.location
.replace(newloc
);
560 setInterval(checkForUrlChange
, 50);
566 /* Set the current browser URL; called from inside BrowserManager to propagate
567 * the application state out to the container.
569 setBrowserURL: function(flexAppUrl
, objectId
) {
570 if (browser
.ie
&& typeof objectId
!= "undefined") {
571 currentObjectId
= objectId
;
573 //fromIframe = fromIframe || false;
574 //fromFlex = fromFlex || false;
575 //alert("setBrowserURL: " + flexAppUrl);
576 //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
578 var pos
= document
.location
.href
.indexOf('#');
579 var baseUrl
= pos
!= -1 ? document
.location
.href
.substr(0, pos
) : document
.location
.href
;
580 var newUrl
= baseUrl
+ '#' + flexAppUrl
;
582 if (document
.location
.href
!= newUrl
&& document
.location
.href
+ '#' != newUrl
) {
583 currentHref
= newUrl
;
584 addHistoryEntry(baseUrl
, newUrl
, flexAppUrl
);
585 currentHistoryLength
= history
.length
;
589 browserURLChange: function(flexAppUrl
) {
591 if (browser
.ie
&& currentObjectId
!= null) {
592 objectId
= currentObjectId
;
596 if (typeof BrowserHistory_multiple
!= "undefined" && BrowserHistory_multiple
== true) {
597 var pl
= getPlayers();
598 for (var i
= 0; i
< pl
.length
; i
++) {
600 pl
[i
].browserURLChange(flexAppUrl
);
605 getPlayer(objectId
).browserURLChange(flexAppUrl
);
609 currentObjectId
= null;
611 getUserAgent: function() {
612 return navigator
.userAgent
;
614 getPlatform: function() {
615 return navigator
.platform
;
624 // Automated unit testing and other diagnostics
628 document
.location
.href
= url
;
631 function backButton()
636 function forwardButton()
641 function goForwardOrBackInHistory(step
)
646 //BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
648 var u
=navigator
.userAgent
;var e
=/*@cc_on!@*/false;
650 if(/webkit/i.test(u
)){
652 var dr
=document
.readyState
;
653 if(dr
=="loaded"||dr
=="complete"){i()}
654 else{st(arguments
.callee
,10);}},10);
655 } else if((/mozilla/i.test(u
)&&!/(compati)/.test(u
)) || (/opera/i.test(u
))){
656 document
.addEventListener("DOMContentLoaded",i
,false);
659 var t
=document
.createElement('doc:rdy');
660 try{t
.doScroll('left');
662 }catch(e
){st(arguments
.callee
,0);}})();
666 })( function() {BrowserHistory
.initialize();} );