diff --git a/backbone.js b/backbone.js index d5e0a287..61d2aace 100644 --- a/backbone.js +++ b/backbone.js @@ -1471,38 +1471,9 @@ this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); this.fragment = this.getFragment(); - // Add a cross-platform `addEventListener` shim for older browsers. - var addEventListener = window.addEventListener || function (eventName, listener) { - return attachEvent('on' + eventName, listener); - }; - // Normalize root to always include a leading and trailing slash. this.root = ('/' + this.root + '/').replace(rootStripper, '/'); - // Proxy an iframe to handle location events if the browser doesn't - // support the `hashchange` event, HTML5 history, or the user wants - // `hashChange` but not `pushState`. - if (!this._hasHashChange && this._wantsHashChange && (!this._wantsPushState || !this._hasPushState)) { - var iframe = document.createElement('iframe'); - iframe.src = 'javascript:0'; - iframe.style.display = 'none'; - iframe.tabIndex = -1; - var body = document.body; - // Using `appendChild` will throw on IE < 9 if the document is not ready. - this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow; - this.navigate(this.fragment); - } - - // Depending on whether we're using pushState or hashes, and whether - // 'onhashchange' is supported, determine how we check the URL state. - if (this._hasPushState) { - addEventListener('popstate', this.checkUrl, false); - } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { - addEventListener('hashchange', this.checkUrl, false); - } else if (this._wantsHashChange) { - this._checkUrlInterval = setInterval(this.checkUrl, this.interval); - } - // Transition from hashChange to pushState or vice versa if both are // requested. if (this._wantsHashChange && this._wantsPushState) { @@ -1522,6 +1493,36 @@ } + // Proxy an iframe to handle location events if the browser doesn't + // support the `hashchange` event, HTML5 history, or the user wants + // `hashChange` but not `pushState`. + if (!this._hasHashChange && this._wantsHashChange && (!this._wantsPushState || !this._hasPushState)) { + var iframe = document.createElement('iframe'); + iframe.src = 'javascript:0'; + iframe.style.display = 'none'; + iframe.tabIndex = -1; + var body = document.body; + // Using `appendChild` will throw on IE < 9 if the document is not ready. + this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow; + this.iframe.document.open().close(); + this.iframe.location.hash = '#' + this.fragment; + } + + // Add a cross-platform `addEventListener` shim for older browsers. + var addEventListener = window.addEventListener || function (eventName, listener) { + return attachEvent('on' + eventName, listener); + }; + + // Depending on whether we're using pushState or hashes, and whether + // 'onhashchange' is supported, determine how we check the URL state. + if (this._hasPushState) { + addEventListener('popstate', this.checkUrl, false); + } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { + addEventListener('hashchange', this.checkUrl, false); + } else if (this._wantsHashChange) { + this._checkUrlInterval = setInterval(this.checkUrl, this.interval); + } + if (!this.options.silent) return this.loadUrl(); }, @@ -1561,6 +1562,9 @@ // calls `loadUrl`, normalizing across the hidden iframe. checkUrl: function(e) { var current = this.getFragment(); + if (current === this.fragment && this.iframe) { + current = this.getHash(this.iframe); + } if (current === this.fragment) return false; if (this.iframe) this.navigate(current); this.loadUrl(); diff --git a/test/router.js b/test/router.js index 9cd23f94..407c332d 100644 --- a/test/router.js +++ b/test/router.js @@ -375,14 +375,6 @@ strictEqual(Backbone.history.getFragment(), 'foo'); }); - test("#1003 - History is started before navigate is called", 1, function() { - Backbone.history.stop(); - Backbone.history.navigate = function(){ ok(Backbone.History.started); }; - Backbone.history.start(); - // If this is not an old IE navigate will not be called. - if (!Backbone.history.iframe) ok(true); - }); - test("#967 - Route callback gets passed encoded values.", 3, function() { var route = 'has%2Fslash/complex-has%23hash/has%20space'; Backbone.history.navigate(route, {trigger: true});