⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deeplinking.js

📁 Simple RIA-> Example
💻 JS
字号:
/**
 * ADR
 * remove for debugging
 */
if (!("console" in window) || !("firebug" in console)) {
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i) {
        window.console[names[i]] = function() {}
    }
}

DeepLinking = (function() {

    var browser = '';

    // Default app state URL to use when no fragment ID present
    var defaultHash = '';

    // Last-known app state URL
    var currentHref = document.location.href;

    // Initial URL (used only by IE)
    var initialHref = document.location.href;

    // Initial URL (used only by IE)
    var initialHash = document.location.hash;

    // History frame source URL prefix (used only by IE)
    var historyFrameSourcePrefix = 'deeplinking/historyFrame.html?';

    // History maintenance (used only by Safari)
    var currentHistoryLength = -1;

    var historyHash = [];

    var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);

	var backStack = [];
	var forwardStack = [];

	// Accessor functions for obtaining specific elements of the page.

	function getHistoryFrame()
	{
		return document.getElementById('historyFrame');
	}

	function getAnchorElement()
	{
		return document.getElementById('anchorDiv');
	}

	function getFormElement()
	{
		return document.getElementById('formDiv');
	}


    /* Get the Flash player object for performing ExternalInterface callbacks. */
    function getPlayer() {
        var player = null; /* AJH, needed?  = document.getElementById(getPlayerId()); */
        
        if (player == null) {
            player = document.getElementsByTagName('object')[0];
        }
        
        if (player == null || player.object == null) {
            player = document.getElementsByTagName('embed')[0];
        }

        return player;
    }

    /* Get the current location hash excluding the '#' symbol. */
    function getHash() {
       // It would be nice if we could use document.location.hash here,
       // but it's faulty sometimes.
       var idx = document.location.href.indexOf('#');
       return (idx >= 0) ? document.location.href.substr(idx+1) : '';
    }

    /* Get the current location hash excluding the '#' symbol. */
    function setHash(hash) {
       // It would be nice if we could use document.location.hash here,
       // but it's faulty sometimes.
       if (hash == '') hash = '#'
       document.location.hash = hash;
    }

    function createState(baseUrl, newUrl, flexAppUrl) {
        return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
    }

    /* Add a history entry to the browser.
     *   baseUrl: the portion of the location prior to the '#'
     *   newUrl: the entire new URL, including '#' and following fragment
     *   flexAppUrl: the portion of the location following the '#' only
     */
    function addHistoryEntry(baseUrl, newUrl, flexAppUrl, copyToAddressBar) {

        //delete all the history entries
        forwardStack = [];

        if (browser == 'IE') {
            //Check to see if we are being asked to do a navigate for the first
            //history entry, and if so ignore, because it's coming from the creation
            //of the history iframe
            if (flexAppUrl == defaultHash && document.location.href == initialHref) {
                currentHref = initialHref;
                return;
            }
            if (!flexAppUrl || flexAppUrl == defaultHash) {
                newUrl = baseUrl + '#' + defaultHash;
                flexAppUrl = defaultHash;
            } else {
                // for IE, tell the history frame to go somewhere without a '#'
                // in order to get this entry into the browser history.
                getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
            }
            if (copyToAddressBar) {
                setHash(flexAppUrl);
                //document.location.href = newUrl;
            }
        } else {

            //ADR
			if(backStack.length == 0 && initialState.flexAppUrl == flexAppUrl){
				initialState = createState(baseUrl, newUrl, flexAppUrl);
			}else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl){
				backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
			}

            if (browser == 'Safari') {
                // for Safari, submit a form whose action points to the desired URL
                getFormElement().innerHTML = '<form name="historyForm" action="#' + flexAppUrl + '" method="GET"></form>';
                document.forms.historyForm.submit();
                // We also have to maintain the history by hand for Safari
                historyHash[history.length] = flexAppUrl;
           } else {
                // Otherwise, write an anchor into the page and tell the browser to go there
                addAnchor(flexAppUrl);
                console.info("before setting hash: " + flexAppUrl);
                if (copyToAddressBar) {
                    setHash(flexAppUrl);
                }
           }
        }
		backStack.push(createState(baseUrl, newUrl, flexAppUrl));
    }

	function debugStacks() {
		var str = "backStack: ";
		for (var i = 0; i < backStack.length; i++) {
			str += backStack[i].flexAppUrl + ", ";
		}
		str += "| historyStack: ";
		for (var i = 0; i < forwardStack.length; i++) {
			str += forwardStack[i].flexAppUrl + ", ";
		}
		console.info(str);
	}

	function handleBackButton() {
		//The "current" page is always at the top of the history stack.
		var current = backStack.pop();
		if (!current) { return; }
		var last = backStack[backStack.length - 1];
		if (!last && backStack.length == 0){
			last = initialState;
		}
		forwardStack.push(current);
	}

	function handleForwardButton() {
		//summary: private method. Do not call this directly.

		var last = forwardStack.pop();
		if (!last) { return; }
		backStack.push(last);
	}

	function handleArbitraryUrl() {
        //delete all the history entries
        forwardStack = [];
	}

    /* Called periodically to poll to see if we need to detect navigation that has occurred */
    function checkForUrlChange() {

        if (browser == 'IE') {
            if (currentHref != document.location.href) {

                 //This occurs when the user has navigated to a specific URL
                 //within the app, and didn't use browser back/forward
                 //IE seems to have a bug where it stops updating the URL it
                 //shows the end-user at this point, but programatically it
                 //appears to be correct.  Do a full app reload to get around
                 //this issue.
                 currentHref = document.location.href;
                 document.location.reload();
            }
        } else if (browser == 'Safari') {
            // For Safari, we have to check to see if history.length changed.
            if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
                // If it did change, then we have to look the old state up
                // in our hand-maintained array since document.location.hash
                // won't have changed, then call back into BrowserManager.
                currentHistoryLength = history.length;
                var flexAppUrl = historyHash[currentHistoryLength];
                if (flexAppUrl == '') {
                    //flexAppUrl = defaultHash;
                }
                getPlayer().browserURLChange(flexAppUrl);
            }
        } else {
            if (currentHref != document.location.href) {
				var bsl = backStack.length;
				debugStacks();

				var urlActions = {
					back: false, 
					forward: false, 
					set: false
				}

				if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
					urlActions.back = true;
					// FIXME: could this ever be a forward button?
					// we can't clear it because we still need to check for forwards. Ugg.
					// clearInterval(this.locationTimer);
					handleBackButton();
					console.info("action: back button 1");
				}
				
				// first check to see if we could have gone forward. We always halt on
				// a no-hash item.
				if (forwardStack.length > 0) {
					if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
						urlActions.forward = true;
						handleForwardButton();
						console.info("action: forward button");
					}
				}

				// ok, that didn't work, try someplace back in the history stack
				if ((bsl >= 2) && (backStack[bsl - 2])) {
					console.info("before comparing " + backStack[bsl - 2].flexAppUrl + " with " + getHash());
					if (backStack[bsl - 2].flexAppUrl == getHash()) {
						urlActions.back = true;
						handleBackButton();
						console.info("action: back button 2");
					}
				}

				
				if (!urlActions.back && !urlActions.forward) {
					var foundInStacks = {
						back: -1, 
						forward: -1
					}

					for (var i = 0; i < backStack.length; i++) {
						if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
							arbitraryUrl = true;
							foundInStacks.back = i;
						}
					}
					for (var i = 0; i < forwardStack.length; i++) {
						if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
							arbitraryUrl = true;
							foundInStacks.forward = i;
						}
					}
					console.info("arbitrary url: " + foundInStacks.back + ", " + foundInStacks.forward);
					handleArbitraryUrl();
				}

                // Firefox changed; do a callback into BrowserManager to tell it.
                currentHref = document.location.href;
                var flexAppUrl = getHash();
                if (flexAppUrl == '') {
                    //flexAppUrl = defaultHash;
                }
                getPlayer().browserURLChange(flexAppUrl);
            }
        }
        setTimeout(checkForUrlChange, 50);
    }

    /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
    function addAnchor(flexAppUrl)
    {
       if (document.getElementsByName(flexAppUrl).length == 0) {
           getAnchorElement().innerHTML += "<a name='" + flexAppUrl + "'>" + flexAppUrl + "</a>";
       }
    }

    function addEvent(elm, evType, fn, useCapture) {
        useCapture = useCapture || false;
        if (elm.addEventListener) {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        }
        else if (elm.attachEvent) {
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        }
        else {
            elm['on' + evType] = fn;
        }
    }

    function _initialize(src) {
		src = src || historyFrameSourcePrefix;

		var formDiv = document.createElement("div");
		formDiv.id = 'formDiv';
		document.body.appendChild(formDiv);

		var anchorDiv = document.createElement("div");
		anchorDiv.id = 'anchorDiv';
		document.body.appendChild(anchorDiv);
		
		if (browser == "IE") {
			var iframe = document.createElement("iframe");
			iframe.id = 'historyFrame';
			iframe.name = 'historyFrame';
			//iframe.src = historyFrameSourcePrefix;
			document.body.appendChild(iframe);
		}
		
		setTimeout(checkForUrlChange, 50);
    }

    var useragent = navigator.userAgent.toLowerCase();
    if (useragent.indexOf("opera") != -1) {
        browser = "Opera";
    } else if (useragent.indexOf("msie") != -1) {
        browser = 'IE';
    } else if (useragent.indexOf("safari") != -1) {
        browser = "Safari";
    } else if (useragent.indexOf("gecko") != -1) {
        browser = "Firefox";
    }

    return {
		backStack: function() { return backStack; }, 
		forwardStack: function() { return forwardStack }, 
        getPlayer: getPlayer, 
        initialize: function(src) {
            addEvent(window, 'load', function() { _initialize(src) });
        }, 
        setURL: function(url) {
            document.location.href = url;
        }, 
        getURL: function() {
            return document.location.href;
        }, 
        getTitle: function() {
            return document.title;
        }, 
        setTitle: function(title) {
			console.info("DeepLinking.setTitle: " + title);
            try {
			backStack[backStack.length - 1].title = title;
            } catch(e) { }
            document.title = title;
        }, 
        setDefaultURL: function(def)
        {
            console.info("setDefaultURL: " + def);
            defaultHash = def;
            //trailing ? is important else an extra frame gets added to the history
            //when navigating back to the first page.  Alternatively could check
            //in history frame navigation to compare # and ?.
            if (browser == 'IE') {
               getHistoryFrame().src = historyFrameSourcePrefix + defaultHash;
            } else if (browser == 'Safari') {
                currentHistoryLength = history.length;
                historyHash[currentHistoryLength] = defaultHash;
            }
        }, 

        /* Set the current browser URL; called from inside BrowserManager to propagate
         * the application state out to the container.
         */
        setBrowserURL: function(flexAppUrl, copyToAddressBar) {

           //fromIframe = fromIframe || false;
           //fromFlex = fromFlex || false;
           //alert("setBrowserURL: " + flexAppUrl + ", " + fromIframe + ", " + fromFlex);
           flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
           console.info(">>set url" + flexAppUrl);

           var pos = document.location.href.indexOf('#');
           var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
           var newUrl = baseUrl + '#' + flexAppUrl;

           if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
               currentHref = newUrl;
               addHistoryEntry(baseUrl, newUrl, flexAppUrl, copyToAddressBar);
               currentHistoryLength = history.length;
           }

           return false;
        }
    }

})();

// Initialization

// Automated unit testing and other diagnostics

function setURL(url)
{
	document.location.href = url;
}

function backButton()
{
	history.back();
}

function forwardButton()
{
	history.forward();
}

function goForwardOrBackInHistory(step)
{
	history.go(step);
}

DeepLinking.initialize();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -