BrowserHistoryUtils = {
2            addEvent: function(elm, evType, fn, useCapture) {
3                useCapture = useCapture || false;
4                if (elm.addEventListener) {
5                    elm.addEventListener(evType, fn, useCapture);
6                    return true;
7                }
8                else if (elm.attachEvent) {
9                    var r = elm.attachEvent('on' + evType, fn);
10                    return r;
11                }
12                else {
13                    elm['on' + evType] = fn;
14                }
15            }
16        }
17        
18        BrowserHistory = (function() {
19            // type of browser
20            var browser = {
21                ie: false,
22                firefox: false,
23                safari: false,
24                opera: false,
25                version: -1
26            };
27        
28            // if setDefaultURL has been called, our first clue
29            // that the SWF is ready and listening
30            //var swfReady = false;
31        
32            // the URL we'll send to the SWF once it is ready
33            //var pendingURL = '';
34        
35            // Default app state URL to use when no fragment ID present
36            var defaultHash = '';
37        
38            // Last-known app state URL
39            var currentHref = document.location.href;
40        
41            // Initial URL (used only by IE)
42            var initialHref = document.location.href;
43        
44            // Initial URL (used only by IE)
45            var initialHash = document.location.hash;
46        
47            // History frame source URL prefix (used only by IE)
48            var historyFrameSourcePrefix = 'history/historyFrame.html?';
49        
50            // History maintenance (used only by Safari)
51            var currentHistoryLength = -1;
52        
53            var historyHash = [];
54        
55            var initialState = createState(initialHref, initialHref + '#' +  
initialHash, initialHash);
56        
57            var backStack = [];
58            var forwardStack = [];
59        
60            var currentObjectId = null;
61        
62            //UserAgent detection
63            var useragent = navigator.userAgent.toLowerCase();
64        
65            if (useragent.indexOf("opera") != -1) {
66                browser.opera = true;
67            } else if (useragent.indexOf("msie") != -1) {
68                browser.ie = true;
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;
75            }
76        
77            if (browser.ie == true && browser.version == 7) {
78                window["_ie_firstload"] = false;
79            }
80        
81            // Accessor functions for obtaining specific elements of the  
page.
82            function getHistoryFrame()
83            {
84                return document.getElementById('ie_historyFrame');
85            }
86        
87            function getAnchorElement()
88            {
89                return document.getElementById('firefox_anchorDiv');
90            }
91        
92            function getFormElement()
93            {
94                return document.getElementById('safari_formDiv');
95            }
96        
97            function getRememberElement()
98            {
99                return document.getElementById("safari_remember_field");
100            }
101        
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") {
108                                        return r;
109                                }
110                                else {
111                                        var o =  
r.getElementsByTagName("object");
112                                        var e =  
r.getElementsByTagName("embed");
113                                        if (o.length > 0 && typeof  
o[0].SetVariable != "undefined") {
114                                                return o[0];
115                                        }
116                                        else if (e.length > 0 && typeof  
e[0].SetVariable != "undefined") {
117                                                return e[0];
118                                        }
119                                }
120                        }
121                        else {
122                                var o =  
document.getElementsByTagName("object");
123                                var e =  
document.getElementsByTagName("embed");
124                                if (e.length > 0 && typeof  
e[0].SetVariable != "undefined") {
125                                        return e[0];
126                                }
127                                else if (o.length > 0 && typeof  
o[0].SetVariable != "undefined") {
128                                        return o[0];
129                                }
130                                else if (o.length > 1 && typeof  
o[1].SetVariable != "undefined") {
131                                        return o[1];
132                                }
133                        }
134                        return undefined;
135                }
136        
137            function getPlayers() {
138                var players = [];
139                if (players.length == 0) {
140                    var tmp = document.getElementsByTagName('object');
141                    players = tmp;
142                }
143        
144                if (players.length == 0 || players[0].object == null) {
145                    var tmp = document.getElementsByTagName('embed');
146                    players = tmp;
147                }
148                return players;
149            }
150        
151                function getIframeHash() {
152                        var doc = getHistoryFrame().contentWindow.document;
153                        var hash = String(doc.location.search);
154                        if (hash.length == 1 && hash.charAt(0) == "?") {
155                                hash = "";
156                        }
157                        else if (hash.length >= 2 && hash.charAt(0) ==  
"?") {
158                                hash = hash.substring(1);
159                        }
160                        return hash;
161                }
162        
163            /* Get the current location hash excluding the '#' symbol. */
164            function getHash() {
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) :  
'';
169            }
170        
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;
177            }
178        
179            function createState(baseUrl, newUrl, flexAppUrl) {
180                return { 'baseUrl': baseUrl, 'newUrl': newUrl,  
'flexAppUrl': flexAppUrl, 'title': null };
181            }
182        
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
187             */
188            function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
189        
190                //delete all the history entries
191                forwardStack = [];
192        
193                if (browser.ie) {
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;
199                        return;
200                    }
201                    if ((!flexAppUrl || flexAppUrl == defaultHash) &&  
window['_ie_firstload']) {
202                        newUrl = baseUrl + '#' + defaultHash;
203                        flexAppUrl = defaultHash;
204                    } else {
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;
208                    }
209                    setHash(flexAppUrl);
210                } else {
211        
212                    //ADR
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);
217                    }
218        
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";
232                                elem.name = tmp[0];
233                                elem.value = tmp[1];
234                                 
document.forms.historyForm.appendChild(elem);
235                            }
236                            document.forms.historyForm.submit();
237                        } else {
238                            top.location.hash = flexAppUrl;
239                        }
240                        // We also have to maintain the history by hand  
for Safari
241                        historyHash[history.length] = flexAppUrl;
242                        _storeStates();
243                    } else {
244                        // Otherwise, write an anchor into the page and  
tell the browser to go there
245                        addAnchor(flexAppUrl);
246                        setHash(flexAppUrl);
247                    }
248                }
249                backStack.push(createState(baseUrl, newUrl, flexAppUrl));
250            }
251        
252            function _storeStates() {
253                if (browser.safari) {
254                    getRememberElement().value = historyHash.join(",");
255                }
256            }
257        
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){
264                    last = initialState;
265                }
266                forwardStack.push(current);
267            }
268        
269            function handleForwardButton() {
270                //summary: private method. Do not call this directly.
271        
272                var last = forwardStack.pop();
273                if (!last) { return; }
274                backStack.push(last);
275            }
276        
277            function handleArbitraryUrl() {
278                //delete all the history entries
279                forwardStack = [];
280            }
281        
282            /* Called periodically to poll to see if we need to detect  
navigation that has occurred */
283            function checkForUrlChange() {
284        
285                if (browser.ie) {
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
292                        //this issue.
293                        if (browser.version < 7) {
294                            currentHref = document.location.href;
295                            document.location.reload();
296                        } else {
297                                                if (getHash() !=  
getIframeHash()) {
298                                                        // this.iframe.src  
= this.blankURL + hash;
299                                                        var sourceToSet =  
historyFrameSourcePrefix + getHash();
300                                                         
getHistoryFrame().src = sourceToSet;
301                                                }
302                        }
303                    }
304                }
305        
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;
317                        }
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);
323                            }
324                        } else {
325                            getPlayer().browserURLChange(flexAppUrl);
326                        }
327                        _storeStates();
328                    }
329                }
330                if (browser.firefox) {
331                    if (currentHref != document.location.href) {
332                        var bsl = backStack.length;
333        
334                        var urlActions = {
335                            back: false,
336                            forward: false,
337                            set: false
338                        }
339        
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);
345                            handleBackButton();
346                        }
347        
348                        // first check to see if we could have gone  
forward. We always halt on
349                        // a no-hash item.
350                        if (forwardStack.length > 0) {
351                            if  
(forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
352                                urlActions.forward = true;
353                                handleForwardButton();
354                            }
355                        }
356        
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;
361                                handleBackButton();
362                            }
363                        }
364        
365                        if (!urlActions.back && !urlActions.forward) {
366                            var foundInStacks = {
367                                back: -1,
368                                forward: -1
369                            }
370        
371                            for (var i = 0; i < backStack.length; i++) {
372                                if (backStack[i].flexAppUrl == getHash()  
&& i != (bsl - 2)) {
373                                    arbitraryUrl = true;
374                                    foundInStacks.back = i;
375                                }
376                            }
377                            for (var i = 0; i < forwardStack.length; i++) {
378                                if (forwardStack[i].flexAppUrl ==  
getHash() && i != (bsl - 2)) {
379                                    arbitraryUrl = true;
380                                    foundInStacks.forward = i;
381                                }
382                            }
383                            handleArbitraryUrl();
384                        }
385        
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;
391                        }
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);
397                            }
398                        } else {
399                            getPlayer().browserURLChange(flexAppUrl);
400                        }
401                    }
402                }
403                //setTimeout(checkForUrlChange, 50);
404            }
405        
406            /* Write an anchor into the page to legitimize it as a URL for  
Firefox et al. */
407            function addAnchor(flexAppUrl)
408            {
409               if (document.getElementsByName(flexAppUrl).length == 0) {
410                   getAnchorElement().innerHTML += "<a name='" +  
flexAppUrl + "'>" + flexAppUrl + "</a>";
411               }
412            }
413        
414            var _initialize = function () {
415                if (browser.ie)
416                {
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");
421                        }
422                    }
423                    historyFrameSourcePrefix = iframe_location + "?";
424                    var src = historyFrameSourcePrefix;
425        
426                    var iframe = document.createElement("iframe");
427                    iframe.id = 'ie_historyFrame';
428                    iframe.name = 'ie_historyFrame';
429                    //iframe.src = historyFrameSourcePrefix;
430                    try {
431                        document.body.appendChild(iframe);
432                    } catch(e) {
433                        setTimeout(function() {
434                            document.body.appendChild(iframe);
435                        }, 0);
436                    }
437                }
438        
439                if (browser.safari)
440                {
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;">';
445        
446                    var formDiv = document.createElement("div");
447                    formDiv.id = 'safari_formDiv';
448                    document.body.appendChild(formDiv);
449        
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");
456                        }
457                    }
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];
463        
464                    if  
(document.getElementById("safari_remember_field").value != "" ) {
465                        historyHash =  
document.getElementById("safari_remember_field").value.split(",");
466                    }
467        
468                }
469        
470                if (browser.firefox)
471                {
472                    var anchorDiv = document.createElement("div");
473                    anchorDiv.id = 'firefox_anchorDiv';
474                    document.body.appendChild(anchorDiv);
475                }
476        
477                //setTimeout(checkForUrlChange, 50);
478            }
479        
480            return {
481                historyHash: historyHash,
482                backStack: function() { return backStack; },
483                forwardStack: function() { return forwardStack },
484                getPlayer: getPlayer,
485                initialize: function(src) {
486                    _initialize(src);
487                },
488                setURL: function(url) {
489                    document.location.href = url;
490                },
491                getURL: function() {
492                    return document.location.href;
493                },
494                getTitle: function() {
495                    return document.title;
496                },
497                setTitle: function(title) {
498                    try {
499                        backStack[backStack.length - 1].title = title;
500                    } catch(e) { }
501                    //if on safari, set the title to be the empty string.
502                    if (browser.safari) {
503                        if (title == "") {
504                            try {
505                            var tmp = window.location.href.toString();
506                            title = tmp.substring((tmp.lastIndexOf("/") 
+1), tmp.lastIndexOf("#"));
507                            } catch(e) {
508                                title = "";
509                            }
510                        }
511                    }
512                    document.title = title;
513                },
514                setDefaultURL: function(def)
515                {
516                    defaultHash = def;
517                    def = getHash();
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 ?.
521                    if (browser.ie)
522                    {
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);
529                        }
530                        try {
531                            func();
532                        } catch(e) {
533                            window.setTimeout(function() { func(); }, 0);
534                        }
535                    }
536        
537                    if (browser.safari)
538                    {
539                        currentHistoryLength = history.length;
540                        if (historyHash.length == 0) {
541                            historyHash[currentHistoryLength] = def;
542                            var newloc = "#" + def;
543                            window.location.replace(newloc);
544                        } else {
545                            //alert(historyHash[historyHash.length-1]);
546                        }
547                        //setHash(def);
548                        setInterval(checkForUrlChange, 50);
549                    }
550        
551        
552                    if (browser.firefox || browser.opera)
553                    {
554                        var reg = new RegExp("#" + def + "$");
555                        if (window.location.toString().match(reg)) {
556                        } else {
557                            var newloc ="#" + def;
558                            window.location.replace(newloc);
559                        }
560                        setInterval(checkForUrlChange, 50);
561                        //setHash(def);
562                    }
563        
564                },
565        
566                /* Set the current browser URL; called from inside  
BrowserManager to propagate
567                 * the application state out to the container.
568                 */
569                setBrowserURL: function(flexAppUrl, objectId) {
570                    if (browser.ie && typeof objectId != "undefined") {
571                        currentObjectId = objectId;
572                    }
573                   //fromIframe = fromIframe || false;
574                   //fromFlex = fromFlex || false;
575                   //alert("setBrowserURL: " + flexAppUrl);
576                   //flexAppUrl = (flexAppUrl == "") ? defaultHash :  
flexAppUrl ;
577        
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;
581        
582                   if (document.location.href != newUrl &&  
document.location.href + '#' != newUrl) {
583                       currentHref = newUrl;
584                       addHistoryEntry(baseUrl, newUrl, flexAppUrl);
585                       currentHistoryLength = history.length;
586                   }
587                },
588        
589                browserURLChange: function(flexAppUrl) {
590                    var objectId = null;
591                    if (browser.ie && currentObjectId != null) {
592                        objectId = currentObjectId;
593                    }
594                    pendingURL = '';
595        
596                    if (typeof BrowserHistory_multiple != "undefined" &&  
BrowserHistory_multiple == true) {
597                        var pl = getPlayers();
598                        for (var i = 0; i < pl.length; i++) {
599                            try {
600                                pl[i].browserURLChange(flexAppUrl);
601                            } catch(e) { }
602                        }
603                    } else {
604                        try {
605                             
getPlayer(objectId).browserURLChange(flexAppUrl);
606                        } catch(e) { }
607                    }
608        
609                    currentObjectId = null;
610                },
611                getUserAgent: function() {
612                    return navigator.userAgent;
613                },
614                getPlatform: function() {
615                    return navigator.platform;
616                }
617        
618            }
619        
620        })();
621        
622        // Initialization
623        
624        // Automated unit testing and other diagnostics
625        
626        function setURL(url)
627        {
628            document.location.href = url;
629        }
630        
631        function backButton()
632        {
633            history.back();
634        }
635        
636        function forwardButton()
637        {
638            history.forward();
639        }
640        
641        function goForwardOrBackInHistory(step)
642        {
643            history.go(step);
644        }
645        
646        //BrowserHistoryUtils.addEvent(window, "load", function()  
{ BrowserHistory.initialize(); });
647        (function(i) {
648            var u =navigator.userAgent;var e=/*@cc_on!@*/false;
649            var st = setTimeout;
650            if(/webkit/i.test(u)){
651                st(function(){
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);
657            } else if(e){
658            (function(){
659                var t=document.createElement('doc:rdy');
660                try{t.doScroll('left');
661                    i();t=null;
662                }catch(e){st(arguments.callee,0);}})();
663            } else{
664                window.onload=i;
665            }
666        })( function() {BrowserHistory.initialize();} );

