Merge branch 'MDL-32509' of git://github.com/danpoltawski/moodle
[moodle.git] / lib / yui / 3.5.0 / build / history-hash-ie / history-hash-ie-debug.js
blobbf89519efe6bd2c54ce66f1046ae99dce65e8ab4
1 /*
2 YUI 3.5.0 (build 5089)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('history-hash-ie', function(Y) {
9 /**
10  * Improves IE6/7 support in history-hash by using a hidden iframe to create
11  * entries in IE's browser history. This module is only needed if IE6/7 support
12  * is necessary; it's not needed for any other browser.
13  *
14  * @module history
15  * @submodule history-hash-ie
16  * @since 3.2.0
17  */
19 // Combination of a UA sniff to ensure this is IE (or a browser that wants us to
20 // treat it like IE) and feature detection for native hashchange support (false
21 // for IE < 8 or IE8/9 in IE7 mode).
22 if (Y.UA.ie && !Y.HistoryBase.nativeHashChange) {
23     var Do          = Y.Do,
24         GlobalEnv   = YUI.namespace('Env.HistoryHash'),
25         HistoryHash = Y.HistoryHash,
27         iframe = GlobalEnv._iframe,
28         win    = Y.config.win;
30     /**
31      * Gets the raw (not decoded) current location hash from the IE iframe,
32      * minus the preceding '#' character and the hashPrefix (if one is set).
33      *
34      * @method getIframeHash
35      * @return {String} current iframe hash
36      * @static
37      */
38     HistoryHash.getIframeHash = function () {
39         if (!iframe || !iframe.contentWindow) {
40             return '';
41         }
43         var prefix = HistoryHash.hashPrefix,
44             hash   = iframe.contentWindow.location.hash.substr(1);
46         return prefix && hash.indexOf(prefix) === 0 ?
47                     hash.replace(prefix, '') : hash;
48     };
50     /**
51      * Updates the history iframe with the specified hash.
52      *
53      * @method _updateIframe
54      * @param {String} hash location hash
55      * @param {Boolean} replace (optional) if <code>true</code>, the current
56      *   history state will be replaced without adding a new history entry
57      * @protected
58      * @static
59      * @for HistoryHash
60      */
61     HistoryHash._updateIframe = function (hash, replace) {
62         var iframeDoc      = iframe && iframe.contentWindow && iframe.contentWindow.document,
63             iframeLocation = iframeDoc && iframeDoc.location;
65         if (!iframeDoc || !iframeLocation) {
66             return;
67         }
69         Y.log('updating history iframe: ' + hash + ', replace: ' + !!replace, 'info', 'history');
71         if (replace) {
72             iframeLocation.replace(hash.charAt(0) === '#' ? hash : '#' + hash);
73         } else {
74             iframeDoc.open().close();
75             iframeLocation.hash = hash;
76         }
77     };
79     Do.before(HistoryHash._updateIframe, HistoryHash, 'replaceHash', HistoryHash, true);
81     if (!iframe) {
82         Y.on('domready', function () {
83             var lastUrlHash = HistoryHash.getHash();
85             // Create a hidden iframe to store history state, following the
86             // iframe-hiding recommendations from
87             // http://www.paciellogroup.com/blog/?p=604.
88             //
89             // This iframe will allow history navigation within the current page
90             // context. After navigating to another page, all but the most
91             // recent history state will be lost.
92             //
93             // Earlier versions of the YUI History Utility attempted to work
94             // around this limitation by having the iframe load a static
95             // resource. This workaround was extremely fragile and tended to
96             // break frequently (and silently) since it was entirely dependent
97             // on IE's inconsistent handling of iframe history.
98             //
99             // Since this workaround didn't work much of the time anyway and
100             // added significant complexity, it has been removed, and IE6 and 7
101             // now get slightly degraded history support.
102             Y.log('creating dynamic history iframe', 'info', 'history');
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             ));
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);
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(lastUrlHash || '#');
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;
124                 if (HistoryHash.getIframeHash() !== lastUrlHash) {
125                     Y.log('updating iframe hash to match URL hash', 'info', 'history');
126                     HistoryHash._updateIframe(lastUrlHash);
127                 }
128             }, win);
130             // Watch the iframe hash in order to detect back/forward navigation.
131             Y.later(50, null, function () {
132                 var iframeHash = HistoryHash.getIframeHash();
134                 if (iframeHash !== lastUrlHash) {
135                     Y.log('updating URL hash to match iframe hash', 'info', 'history');
136                     HistoryHash.setHash(iframeHash);
137                 }
138             }, null, true);
139         });
140     }
144 }, '3.5.0' ,{requires:['history-hash', 'node-base']});