3
Copyright 2011 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
7
YUI.add('history-hash-ie', function(Y) {
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.
15
* @submodule history-hash-ie
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) {
24
GlobalEnv = YUI.namespace('Env.HistoryHash'),
25
HistoryHash = Y.HistoryHash,
27
iframe = GlobalEnv._iframe,
29
location = win.location;
32
* Gets the raw (not decoded) current location hash from the IE iframe,
33
* minus the preceding '#' character and the hashPrefix (if one is set).
35
* @method getIframeHash
36
* @return {String} current iframe hash
39
HistoryHash.getIframeHash = function () {
40
if (!iframe || !iframe.contentWindow) {
44
var prefix = HistoryHash.hashPrefix,
45
hash = iframe.contentWindow.location.hash.substr(1);
47
return prefix && hash.indexOf(prefix) === 0 ?
48
hash.replace(prefix, '') : hash;
52
* Updates the history iframe with the specified hash.
54
* @method _updateIframe
55
* @param {String} hash location hash
56
* @param {Boolean} replace (optional) if <code>true</code>, the current
57
* history state will be replaced without adding a new history entry
62
HistoryHash._updateIframe = function (hash, replace) {
63
var iframeDoc = iframe && iframe.contentWindow && iframe.contentWindow.document,
64
iframeLocation = iframeDoc && iframeDoc.location;
66
if (!iframeDoc || !iframeLocation) {
72
iframeLocation.replace(hash.charAt(0) === '#' ? hash : '#' + hash);
74
iframeDoc.open().close();
75
iframeLocation.hash = hash;
79
Do.before(HistoryHash._updateIframe, HistoryHash, 'replaceHash', HistoryHash, true);
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.
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.
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.
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.
103
iframe = GlobalEnv._iframe = Y.Node.getDOMNode(Y.Node.create(
104
'<iframe src="javascript:0" style="display:none" height="0" width="0" tabindex="-1" title="empty"/>'
107
// Append the iframe to the documentElement rather than the body.
108
// Keeping it outside the body prevents scrolling on the initial
109
// page load (hat tip to Ben Alman and jQuery BBQ for this
111
Y.config.doc.documentElement.appendChild(iframe);
113
// Update the iframe with the initial location hash, if any. This
114
// will create an initial history entry that the user can return to
115
// after the state has changed.
116
HistoryHash._updateIframe(lastUrlHash || '#');
118
// Listen for hashchange events and keep the iframe's hash in sync
119
// with the parent frame's hash.
120
Y.on('hashchange', function (e) {
121
lastUrlHash = e.newHash;
123
if (HistoryHash.getIframeHash() !== lastUrlHash) {
124
HistoryHash._updateIframe(lastUrlHash);
128
// Watch the iframe hash in order to detect back/forward navigation.
129
Y.later(50, null, function () {
130
var iframeHash = HistoryHash.getIframeHash();
132
if (iframeHash !== lastUrlHash) {
133
HistoryHash.setHash(iframeHash);
141
}, '3.4.1' ,{requires:['history-hash', 'node-base']});