]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/history/history-hash-ie.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / history / history-hash-ie.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('history-hash-ie', function(Y) {
9
10 /**
11  * Improves IE6/7 support in history-hash by using a hidden iframe to create
12  * entries in IE's browser history. This module is only needed if IE6/7 support
13  * is necessary; it's not needed for any other browser.
14  *
15  * @module history
16  * @submodule history-hash-ie
17  * @since 3.2.0
18  */
19
20 // Combination of a UA sniff to ensure this is IE (or a browser that wants us to
21 // treat it like IE) and feature detection for native hashchange support (false
22 // for IE < 8 or IE8/9 in IE7 mode).
23 if (Y.UA.ie && !Y.HistoryBase.nativeHashChange) {
24     var Do          = Y.Do,
25         GlobalEnv   = YUI.namespace('Env.HistoryHash'),
26         HistoryHash = Y.HistoryHash,
27
28         iframe      = GlobalEnv._iframe,
29         win         = Y.config.win,
30         location    = win.location,
31         lastUrlHash = '';
32
33     /**
34      * Gets the raw (not decoded) current location hash from the IE iframe,
35      * minus the preceding '#' character and the hashPrefix (if one is set).
36      *
37      * @method getIframeHash
38      * @return {String} current iframe hash
39      * @static
40      */
41     HistoryHash.getIframeHash = function () {
42         if (!iframe || !iframe.contentWindow) {
43             return '';
44         }
45
46         var prefix = HistoryHash.hashPrefix,
47             hash   = iframe.contentWindow.location.hash.substr(1);
48
49         return prefix && hash.indexOf(prefix) === 0 ?
50                     hash.replace(prefix, '') : hash;
51     };
52
53     /**
54      * Updates the history iframe with the specified hash.
55      *
56      * @method _updateIframe
57      * @param {String} hash location hash
58      * @param {Boolean} replace (optional) if <code>true</code>, the current
59      *   history state will be replaced without adding a new history entry
60      * @protected
61      * @static
62      * @for HistoryHash
63      */
64     HistoryHash._updateIframe = function (hash, replace) {
65         var iframeDoc      = iframe && iframe.contentWindow && iframe.contentWindow.document,
66             iframeLocation = iframeDoc && iframeDoc.location;
67
68         if (!iframeDoc || !iframeLocation) {
69             return;
70         }
71
72
73         iframeDoc.open().close();
74
75         if (replace) {
76             iframeLocation.replace(hash.charAt(0) === '#' ? hash : '#' + hash);
77         } else {
78             iframeLocation.hash = hash;
79         }
80     };
81
82     Do.after(HistoryHash._updateIframe, HistoryHash, 'replaceHash', HistoryHash, true);
83
84     if (!iframe) {
85         Y.on('domready', function () {
86             // Create a hidden iframe to store history state, following the
87             // iframe-hiding recommendations from
88             // http://www.paciellogroup.com/blog/?p=604.
89             //
90             // This iframe will allow history navigation within the current page
91             // context. After navigating to another page, all but the most
92             // recent history state will be lost.
93             //
94             // Earlier versions of the YUI History Utility attempted to work
95             // around this limitation by having the iframe load a static
96             // resource. This workaround was extremely fragile and tended to
97             // break frequently (and silently) since it was entirely dependent
98             // on IE's inconsistent handling of iframe history.
99             //
100             // Since this workaround didn't work much of the time anyway and
101             // added significant complexity, it has been removed, and IE6 and 7
102             // now get slightly degraded history support.
103
104             iframe = GlobalEnv._iframe = Y.Node.getDOMNode(Y.Node.create(
105                 '<iframe src="javascript:0" style="display:none" height="0" width="0" tabindex="-1" title="empty"/>'
106             ));
107
108             // Append the iframe to the documentElement rather than the body.
109             // Keeping it outside the body prevents scrolling on the initial
110             // page load (hat tip to Ben Alman and jQuery BBQ for this
111             // technique).
112             Y.config.doc.documentElement.appendChild(iframe);
113
114             // Update the iframe with the initial location hash, if any. This
115             // will create an initial history entry that the user can return to
116             // after the state has changed.
117             HistoryHash._updateIframe(HistoryHash.getHash() || '#');
118
119             // Listen for hashchange events and keep the iframe's hash in sync
120             // with the parent frame's hash.
121             Y.on('hashchange', function (e) {
122                 lastUrlHash = e.newHash;
123
124                 if (HistoryHash.getIframeHash() !== lastUrlHash) {
125                     HistoryHash._updateIframe(lastUrlHash);
126                 }
127             }, win);
128
129             // Watch the iframe hash in order to detect back/forward navigation.
130             Y.later(50, null, function () {
131                 var iframeHash = HistoryHash.getIframeHash();
132
133                 if (iframeHash !== lastUrlHash) {
134                     HistoryHash.setHash(iframeHash);
135                 }
136             }, null, true);
137         });
138     }
139 }
140
141
142 }, '3.3.0' ,{requires:['history-hash', 'node-base']});