58
js/libraries/balupton-history/demo/bcherry-orig.html
Executable file
58
js/libraries/balupton-history/demo/bcherry-orig.html
Executable file
@@ -0,0 +1,58 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<title>WebKit is Dropping HTML5 "popstate" Events</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/lib/css/blueprint/blueprint.min.css" media="screen, projection" />
|
||||
<link rel="stylesheet" href="/static/lib/css/blueprint/print.min.css" media="print" />
|
||||
<!--[if lt IE 8]>
|
||||
<link rel="stylesheet" href="/static/lib/css/blueprint/ie.min.css" media="screen, projection">
|
||||
<![endif]-->
|
||||
<link href="/static/lib/css/bcherry.css" rel="stylesheet" media="screen" />
|
||||
<style>
|
||||
#n {
|
||||
font-size: 48px;
|
||||
}
|
||||
p {
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="../vendor/jquery.js"></script>
|
||||
<script type="text/javascript" src="../scripts/uncompressed/history.adapter.jquery.js"></script>
|
||||
<script type="text/javascript" src="../scripts/uncompressed/history.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="n"></div>
|
||||
<p>There's a bug in the HTML5 "popstate" event, as implemented in WebKit (Safari and Chrome). View this page in one of those browsers. Your browser has had history entries added from #0 to #19 (you should start at #19). Hitting back/forward will navigate through these. On each URL, the large number above should reflect the hash value. If you hit back/forward quickly, you'll notice that your number gets out of sync with the URL. This is because WebKit is dropping popstate events (they are not firing). It seems to happen when outbound network requests are in progress when the user navigates in their browser happens. In this case, your browser is downloading an image that takes 1s to serve on every popstate, so you'll have to wait 1s between backs/forwards to have the feature work correctly. You could also cause constant network traffic by putting an image download in a setInterval, in which case your popstate events will never fire. This implementation simulates an AJAX application that makes a network request when you navigate between URLs using pushState/popstate. View the source for more info.</p>
|
||||
<p>This was filed as <a href="https://bugs.webkit.org/show_bug.cgi?id=42940">Bug 42940</a> with WebKit on July 24, 2010. The Firefox 4 beta does not have this bug, which is good news.</p>
|
||||
<p>This is put together by <a href="http://www.adequatelygood.com">Ben Cherry</a>. Ben is a front-end engineer at <a href="http://twitter.com/">Twitter</a>, and you can follow him at <a href="http://twitter.com/bcherry">@bcherry</a>.</p>
|
||||
<script>
|
||||
// Bind to popstate
|
||||
$(window).bind("popstate", function(e) {
|
||||
var State = e.state;
|
||||
|
||||
// log that this event was fired, and the current URL
|
||||
if (window.console && window.console.log) {
|
||||
console.log("popstate", State, window.location.href);
|
||||
}
|
||||
// update the page
|
||||
$("#n").text(typeof State.n !== 'undefined' ? State.n : document.location.href);
|
||||
|
||||
// Make an outbound image request that will take 1s. This request seems to be the cause of dropped popstates.
|
||||
// Removing this, or replacing it with something else, avoids the issue. Even if it's replaced with slow, blocking code (i.e. 1s of execution) events are not dropped.
|
||||
(new Image()).src = "http://www.bcherry.net/playground/pushstate.jpg";
|
||||
});
|
||||
|
||||
// Seed the browser history
|
||||
for (var i = 0; i < 20; i++) {
|
||||
window.history.pushState({n:i}, i, "?" + i);
|
||||
$("#n").text(i);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
62
js/libraries/balupton-history/demo/bcherry.html
Executable file
62
js/libraries/balupton-history/demo/bcherry.html
Executable file
@@ -0,0 +1,62 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<title>WebKit is Dropping HTML5 "popstate" Events</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/lib/css/blueprint/blueprint.min.css" media="screen, projection" />
|
||||
<link rel="stylesheet" href="/static/lib/css/blueprint/print.min.css" media="print" />
|
||||
<!--[if lt IE 8]>
|
||||
<link rel="stylesheet" href="/static/lib/css/blueprint/ie.min.css" media="screen, projection">
|
||||
<![endif]-->
|
||||
<link href="/static/lib/css/bcherry.css" rel="stylesheet" media="screen" />
|
||||
<style>
|
||||
#n {
|
||||
font-size: 48px;
|
||||
}
|
||||
p {
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="../vendor/jquery.js"></script>
|
||||
<script type="text/javascript" src="../scripts/uncompressed/history.adapter.jquery.js"></script>
|
||||
<script type="text/javascript" src="../scripts/uncompressed/history.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="n"></div>
|
||||
<p>There's a bug in the HTML5 "popstate" event, as implemented in WebKit (Safari and Chrome). View this page in one of those browsers. Your browser has had history entries added from #0 to #19 (you should start at #19). Hitting back/forward will navigate through these. On each URL, the large number above should reflect the hash value. If you hit back/forward quickly, you'll notice that your number gets out of sync with the URL. This is because WebKit is dropping popstate events (they are not firing). It seems to happen when outbound network requests are in progress when the user navigates in their browser happens. In this case, your browser is downloading an image that takes 1s to serve on every popstate, so you'll have to wait 1s between backs/forwards to have the feature work correctly. You could also cause constant network traffic by putting an image download in a setInterval, in which case your popstate events will never fire. This implementation simulates an AJAX application that makes a network request when you navigate between URLs using pushState/popstate. View the source for more info.</p>
|
||||
<p>This was filed as <a href="https://bugs.webkit.org/show_bug.cgi?id=42940">Bug 42940</a> with WebKit on July 24, 2010. The Firefox 4 beta does not have this bug, which is good news.</p>
|
||||
<p>This is put together by <a href="http://www.adequatelygood.com">Ben Cherry</a>. Ben is a front-end engineer at <a href="http://twitter.com/">Twitter</a>, and you can follow him at <a href="http://twitter.com/bcherry">@bcherry</a>.</p>
|
||||
<p>This bug was fixed in <a href="http://github.com/balupton/history.js">History.js</a> by <a href="http://balupton.com">Benjamin Lupton</a>. Benjamin is a freelance web 2.0 consultant, and you can follow him at <a href="http://twitter.com/balupton">@balupton</a>.</p>
|
||||
<script>
|
||||
// Prepare
|
||||
window.History.debug.enable = true;
|
||||
|
||||
// Bind to popstate
|
||||
$(window).bind("statechange", function(e) {
|
||||
var State = window.History.getState();
|
||||
|
||||
// log that this event was fired, and the current URL
|
||||
if (window.console && window.console.log) {
|
||||
console.log("popstate", State, window.location.href);
|
||||
}
|
||||
// update the page
|
||||
$("#n").text(typeof State.data.n !== 'undefined' ? State.data.n : State.url);
|
||||
|
||||
// Make an outbound image request that will take 1s. This request seems to be the cause of dropped popstates.
|
||||
// Removing this, or replacing it with something else, avoids the issue. Even if it's replaced with slow, blocking code (i.e. 1s of execution) events are not dropped.
|
||||
(new Image()).src = "http://www.bcherry.net/playground/pushstate.jpg";
|
||||
});
|
||||
|
||||
// Seed the browser history
|
||||
for (var i = 0; i < 20; i++) {
|
||||
window.History.pushState({n:i}, i, "?" + i);
|
||||
$("#n").text(i);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
37
js/libraries/balupton-history/demo/chrome.html
Executable file
37
js/libraries/balupton-history/demo/chrome.html
Executable file
@@ -0,0 +1,37 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Chrome History API Data Artifact</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This demo demonstrates an issue with Google Chrome versions 8-10 (possibly 11) where if you push a state with data, then do history.back to the initial state, the event.state will contain the pushed states data instead of being null.</p>
|
||||
<p>Note: The issue requires a clean history list, as such this should always be opened in a new tab/window where there are no prior history items.</p>
|
||||
<p>Reported by <a href="http://balupton.com">Benjamin Lupton</a> author of <a href="http://github.com/balupton/history.js">History.js</a></p>
|
||||
<button id="bug">bug</button>
|
||||
<button id="reset">reset</button>
|
||||
<textarea id="log" style="width:100%;height:200px;margin-top:1em;"></textarea>
|
||||
<script type="text/javascript">
|
||||
(function(){
|
||||
|
||||
window.onpopstate = function(event) {
|
||||
var message = ("onpopstate: location: " + document.location.href + ", data: " + JSON.stringify(event.state));
|
||||
document.getElementById('log').innerHTML += message+"\n\n";
|
||||
};
|
||||
|
||||
document.getElementById('bug').onclick = function(){
|
||||
setTimeout(function(){
|
||||
history.pushState({state:'new'},'New State','?new');
|
||||
},1e3);
|
||||
|
||||
setTimeout(function(){
|
||||
history.back();
|
||||
},2e3);
|
||||
};
|
||||
|
||||
document.getElementById('reset').onclick = function(){
|
||||
document.location.href = document.location.href.replace(/[\#\?].*/,"");
|
||||
};
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
86
js/libraries/balupton-history/demo/index.html
Executable file
86
js/libraries/balupton-history/demo/index.html
Executable file
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>
|
||||
History.js
|
||||
</title>
|
||||
</head>
|
||||
<body style="padding-bottom:40px">
|
||||
<!-- Scripts -->
|
||||
<script>if ( typeof window.JSON === 'undefined' ) { document.write('<script src="../scripts/uncompressed/json2.js"><\/script>'); }</script>
|
||||
<script src="../vendor/jquery.js"></script>
|
||||
<script src="../scripts/bundled/html4+html5/jquery.history.js"></script>
|
||||
|
||||
<!-- HTML -->
|
||||
<div id="wrap">
|
||||
<!-- Intro -->
|
||||
<h1><a href="https://github.com/balupton/History.js">History.js</a> by <a href="http://balupton.com">Benjamin Lupton</a></h1>
|
||||
<p>History.js gracefully supports the <a href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history">HTML5 History/State APIs</a> (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports <a href="http://jquery.com/">jQuery</a>, <a href="http://mootools.net">MooTools</a> and <a href="http://prototypejs.org">Prototype</a>. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.</p>
|
||||
|
||||
<!-- Textarea for Logging -->
|
||||
<textarea id="log" style="width:100%;height:400px"></textarea>
|
||||
|
||||
<!-- Note -->
|
||||
<p>Click through the buttons in order and you'll get the results demonstrated in the <a href="../README.md">README.md</a> file.</p>
|
||||
|
||||
<!-- Buttons -->
|
||||
<ul id="buttons">
|
||||
</ul>
|
||||
|
||||
<!-- Our Script -->
|
||||
<script>
|
||||
(function(window,undefined){
|
||||
|
||||
// Check Location
|
||||
if ( document.location.protocol === 'file:' ) {
|
||||
alert('The HTML5 History API (and thus History.js) do not work on files, please upload it to a server.');
|
||||
}
|
||||
|
||||
// Establish Variables
|
||||
var
|
||||
History = window.History, // Note: We are using a capital H instead of a lower h
|
||||
State = History.getState(),
|
||||
$log = $('#log');
|
||||
|
||||
// Log Initial State
|
||||
History.log('initial:', State.data, State.title, State.url);
|
||||
|
||||
// Bind to State Change
|
||||
History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
|
||||
// Log the State
|
||||
var State = History.getState(); // Note: We are using History.getState() instead of event.state
|
||||
History.log('statechange:', State.data, State.title, State.url);
|
||||
});
|
||||
|
||||
// Prepare Buttons
|
||||
var
|
||||
buttons = document.getElementById('buttons'),
|
||||
scripts = [
|
||||
'History.pushState({state:1,rand:Math.random()}, "State 1", "?state=1"); // logs {state:1,rand:"some random value"}, "State 1", "?state=1"',
|
||||
'History.pushState({state:2,rand:Math.random()}, "State 2", "?state=2"); // logs {state:2,rand:"some random value"}, "State 2", "?state=2"',
|
||||
'History.replaceState({state:3,rand:Math.random()}, "State 3", "?state=3"); // logs {state:3,rand:"some random value"}, "State 3", "?state=3"',
|
||||
'History.pushState(null, null, "?state=4"); // logs {}, "", "?state=4"',
|
||||
'History.back(); // logs {state:3}, "State 3", "?state=3"',
|
||||
'History.back(); // logs {state:1}, "State 1", "?state=1"',
|
||||
'History.back(); // logs {}, "The page you started at", "?"',
|
||||
'History.go(2); // logs {state:3}, "State 3", "?state=3"'
|
||||
],
|
||||
buttonsHTML = ''
|
||||
;
|
||||
|
||||
// Add Buttons
|
||||
for ( var i=0,n=scripts.length; i<n; ++i ) {
|
||||
var _script = scripts[i];
|
||||
buttonsHTML +=
|
||||
'<li><button onclick=\'javascript:'+_script+'\'>'+_script+'</button></li>';
|
||||
}
|
||||
buttons.innerHTML = buttonsHTML;
|
||||
|
||||
})(window);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
43
js/libraries/balupton-history/demo/native-auto.html
Executable file
43
js/libraries/balupton-history/demo/native-auto.html
Executable file
@@ -0,0 +1,43 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
(function(){
|
||||
|
||||
window.onpopstate = function(event) {
|
||||
console.log("onpopstate: location: " + document.location.href + ", data: " + JSON.stringify(event.state));
|
||||
};
|
||||
window.onhashchange = function(event) {
|
||||
console.log("onhashchange: location: " + document.location.href);
|
||||
};
|
||||
|
||||
setTimeout(function(){
|
||||
history.pushState({page: 1}, "title 1", "?page=1");
|
||||
},1e3);
|
||||
setTimeout(function(){
|
||||
history.pushState({page: 2}, "title 2", "?page=2");
|
||||
},2e3);
|
||||
setTimeout(function(){
|
||||
history.replaceState({page: 3}, "title 3", "?page=3");
|
||||
},3e3);
|
||||
setTimeout(function(){
|
||||
document.location.hash = 'asd';
|
||||
},4e3);
|
||||
setTimeout(function(){
|
||||
history.back(); // alerts "location: http://example.com/example.html?page=3#asd, state: {"page":3}"
|
||||
},5e3);
|
||||
setTimeout(function(){
|
||||
history.back(); // alerts "location: http://example.com/example.html?page=1, state: {"page":1}"
|
||||
},6e3);
|
||||
setTimeout(function(){
|
||||
history.back(); // alerts "location: http://example.com/example.html, state: null
|
||||
},7e3);
|
||||
setTimeout(function(){
|
||||
history.go(2); // alerts "location: http://example.com/example.html?page=3, state: {"page":3}
|
||||
},8e3);
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
62
js/libraries/balupton-history/demo/native.html
Executable file
62
js/libraries/balupton-history/demo/native.html
Executable file
@@ -0,0 +1,62 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML5 History API Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<textarea id="log" style="width:100%;height:400px;margin:1em;"></textarea>
|
||||
<div id="url" style="border:1px black dotted;height:1em;margin:1em;"></div>
|
||||
<div id="buttons" style="margin:1em;"></div>
|
||||
<script type="text/javascript">
|
||||
var $url = document.getElementById('url'), $log = document.getElementById('log');
|
||||
|
||||
window.onpopstate = function(event) {
|
||||
var message =
|
||||
"onpopstate: "+
|
||||
"location: " + location.href + ", " +
|
||||
"data: " + JSON.stringify(event.state) +
|
||||
"\n\n"
|
||||
;
|
||||
|
||||
$url.innerHTML = location.href;
|
||||
$log.innerHTML += message;
|
||||
console.log(message);
|
||||
};
|
||||
|
||||
window.onhashchange = function(event) {
|
||||
var message =
|
||||
"onhashchange: "+
|
||||
"location: " + location.href + ", "+
|
||||
"hash: " + location.hash +
|
||||
"\n\n"
|
||||
;
|
||||
|
||||
$url.innerHTML = location.href;
|
||||
$log.innerHTML += message;
|
||||
console.log(message);
|
||||
};
|
||||
|
||||
// Prepare Buttons
|
||||
var
|
||||
buttons = document.getElementById('buttons'),
|
||||
scripts = [
|
||||
'history.pushState({state:1}, "State 1", "?state=1");',
|
||||
'history.pushState({state:2}, "State 2", "?state=2");',
|
||||
'history.replaceState({state:3}, "State 3", "?state=3");',
|
||||
'location.hash = Math.random();',
|
||||
'history.back();',
|
||||
'history.forward();',
|
||||
'document.location.href = document.location.href.replace(/[\#\?].*/,"");'
|
||||
],
|
||||
buttonsHTML = ''
|
||||
;
|
||||
|
||||
// Add Buttons
|
||||
for ( var i=0,n=scripts.length; i<n; ++i ) {
|
||||
var _script = scripts[i];
|
||||
buttonsHTML +=
|
||||
'<li><button onclick=\'javascript:'+_script+'\'>'+_script+'</button></li>';
|
||||
}
|
||||
buttons.innerHTML = buttonsHTML;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
23
js/libraries/balupton-history/demo/navigator.html
Executable file
23
js/libraries/balupton-history/demo/navigator.html
Executable file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>
|
||||
Navigator Output
|
||||
</title>
|
||||
<style>
|
||||
label { font-weight:bold; }
|
||||
label:after { content: ":"; margin-right:5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="nav"></div>
|
||||
<script>
|
||||
var nav = document.getElementById('nav'), i,v;
|
||||
for ( i in navigator ) {
|
||||
var v = navigator[i];
|
||||
nav.innerHTML += '<div><label>'+i+'</label>'+v+'</div>';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
61
js/libraries/balupton-history/demo/safari.html
Executable file
61
js/libraries/balupton-history/demo/safari.html
Executable file
@@ -0,0 +1,61 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Safari Hash ReplaceState History Traversal Bug</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This demo demonstrates an issue with Safari 5.0.4 (6533.20.27) handing of hashes and replace state. When a hash is set, and then replaced using replaceState the history list are then broken, when traversing back the hash does not change.</p>
|
||||
<p>Note: The issue requires a clean history list, as such this should always be opened in a new tab/window where there are no prior history items.</p>
|
||||
<p>Reported by <a href="http://balupton.com">Benjamin Lupton</a> author of <a href="http://github.com/balupton/history.js">History.js</a></p>
|
||||
<button id="bug">bug</button>
|
||||
<button id="workaround">workaround</button>
|
||||
<button id="reset">reset</button>
|
||||
<textarea id="log" style="width:100%;height:200px;margin-top:1em;"></textarea>
|
||||
<script type="text/javascript">
|
||||
(function(){
|
||||
|
||||
window.onpopstate = function(event) {
|
||||
var message = ("onpopstate: location: " + document.location.href);
|
||||
document.getElementById('log').innerHTML += message+"\n\n";
|
||||
};
|
||||
|
||||
window.onhashchange = function(event) {
|
||||
var message = ("onhashchange: location: " + document.location.href);
|
||||
document.getElementById('log').innerHTML += message+"\n\n";
|
||||
};
|
||||
|
||||
document.getElementById('bug').onclick = function(){
|
||||
setTimeout(function(){
|
||||
document.location.hash = Math.random();
|
||||
},1e3);
|
||||
|
||||
setTimeout(function(){
|
||||
history.replaceState(null,'','?blah');
|
||||
},2e3);
|
||||
|
||||
setTimeout(function(){
|
||||
history.back(); // should take us to the initial page, it doesn't
|
||||
},3e3);
|
||||
};
|
||||
|
||||
document.getElementById('workaround').onclick = function(){
|
||||
setTimeout(function(){
|
||||
history.pushState(null,'','#'+Math.random());
|
||||
},1e3);
|
||||
|
||||
setTimeout(function(){
|
||||
history.replaceState(null,'','?blah');
|
||||
},2e3);
|
||||
|
||||
setTimeout(function(){
|
||||
history.back(); // will take us to the initial page
|
||||
},3e3);
|
||||
};
|
||||
|
||||
document.getElementById('reset').onclick = function(){
|
||||
document.location.href = document.location.href.replace(/[\#\?].*/,"");
|
||||
};
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user