From 2d8383b797f51d2b64a359ce333e36ff450f4eb8 Mon Sep 17 00:00:00 2001 From: Staffan Eketorp Date: Tue, 1 Apr 2014 11:35:05 -0700 Subject: [PATCH 1/4] Better handling of cases where there's a race condition on start, setRoute called before onpopstate is set. When fire is triggered (e.g. through setRoute) an error occurs if we haven't set onpopstate. Thus, make sure to record any fire calls, set onpopstate as soon as DOM is ready (+1 event loop), and then resume, possibly triggering a recorded fire --- lib/director/browser.js | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/director/browser.js b/lib/director/browser.js index 34519f7..d2634cd 100644 --- a/lib/director/browser.js +++ b/lib/director/browser.js @@ -77,10 +77,29 @@ var listener = { // upon initial page load. Since the handler is run manually in init(), // this would cause Chrome to run it twise. Currently the only // workaround seems to be to set the handler after the initial page load + // We then need to keep track of outstanding fire requests // http://code.google.com/p/chromium/issues/detail?id=63040 - setTimeout(function() { - window.onpopstate = onchange; - }, 500); + var fireOnReady = false; + var fire = this.fire; + this.fire = function() { + fireOnReady = true; + }; + var onDOMReady = function() { + setTimeout(function() { + self.fire = fire; + window.onpopstate = onchange; + if (fireOnReady) { + self.fire(); + } + }, 1) + }; + + if(document.readyState === 'complete') { + onDOMReady(); + } + else { + window.addEventListener('onload', onDOMReady); + } } else { window.onhashchange = onchange; From 85e8877bec74003400cc95382338689e40c01654 Mon Sep 17 00:00:00 2001 From: Staffan Eketorp Date: Tue, 1 Apr 2014 11:43:41 -0700 Subject: [PATCH 2/4] And latest build files --- build/director.js | 29 ++++++++++++++++++++++++----- build/director.min.js | 6 +++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/build/director.js b/build/director.js index 76717ed..504896f 100644 --- a/build/director.js +++ b/build/director.js @@ -1,8 +1,8 @@ // -// Generated on Fri Dec 27 2013 12:02:11 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon). -// Version 1.2.2 +// Generated on Tue Apr 01 2014 11:43:26 GMT-0700 (PDT) by Nodejitsu, Inc (Using Codesurgeon). +// Version 1.2.3 // (function (exports) { @@ -86,10 +86,29 @@ var listener = { // upon initial page load. Since the handler is run manually in init(), // this would cause Chrome to run it twise. Currently the only // workaround seems to be to set the handler after the initial page load + // We then need to keep track of outstanding fire requests // http://code.google.com/p/chromium/issues/detail?id=63040 - setTimeout(function() { - window.onpopstate = onchange; - }, 500); + var fireOnReady = false; + var fire = this.fire; + this.fire = function() { + fireOnReady = true; + }; + var onDOMReady = function() { + setTimeout(function() { + self.fire = fire; + window.onpopstate = onchange; + if (fireOnReady) { + self.fire(); + } + }, 1) + }; + + if(document.readyState === 'complete') { + onDOMReady(); + } + else { + window.addEventListener('onload', onDOMReady); + } } else { window.onhashchange = onchange; diff --git a/build/director.min.js b/build/director.min.js index 55a8e64..4a5e674 100644 --- a/build/director.min.js +++ b/build/director.min.js @@ -1,7 +1,7 @@ // -// Generated on Fri Dec 27 2013 12:02:11 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon). -// Version 1.2.2 +// Generated on Tue Apr 01 2014 11:43:27 GMT-0700 (PDT) by Nodejitsu, Inc (Using Codesurgeon). +// Version 1.2.3 // -(function(a){function k(a,b,c,d){var e=0,f=0,g=0,c=(c||"(").toString(),d=(d||")").toString(),h;for(h=0;hi.indexOf(d,e)||~i.indexOf(c,e)&&!~i.indexOf(d,e)||!~i.indexOf(c,e)&&~i.indexOf(d,e)){f=i.indexOf(c,e),g=i.indexOf(d,e);if(~f&&!~g||!~f&&~g){var j=a.slice(0,(h||1)+1).join(b);a=[j].concat(a.slice((h||1)+1))}e=(g>f?g:f)+1,h=0}else e=0}return a}function j(a,b){var c,d=0,e="";while(c=a.substr(d).match(/[^\w\d\- %@&]*\*[^\w\d\- %@&]*/))d=c.index+c[0].length,c[0]=c[0].replace(/^\*/,"([_.()!\\ %@&a-zA-Z0-9-]+)"),e+=a.substr(0,c.index)+c[0];a=e+=a.substr(d);var f=a.match(/:([^\/]+)/ig),g,h;if(f){h=f.length;for(var j=0;j7))this.history===!0?setTimeout(function(){window.onpopstate=d},500):window.onhashchange=d,this.mode="modern";else{var f=document.createElement("iframe");f.id="state-frame",f.style.display="none",document.body.appendChild(f),this.writeFrame(""),"onpropertychange"in document&&"attachEvent"in document&&document.attachEvent("onpropertychange",function(){event.propertyName==="location"&&c.check()}),window.setInterval(function(){c.check()},50),this.onHashChanged=d,this.mode="legacy"}e.listeners.push(a);return this.mode},destroy:function(a){if(!!e&&!!e.listeners){var b=e.listeners;for(var c=b.length-1;c>=0;c--)b[c]===a&&b.splice(c,1)}},setHash:function(a){this.mode==="legacy"&&this.writeFrame(a),this.history===!0?(window.history.pushState({},document.title,a),this.fire()):b.hash=a[0]==="/"?a:"/"+a;return this},writeFrame:function(a){var b=document.getElementById("state-frame"),c=b.contentDocument||b.contentWindow.document;c.open(),c.write("