From 51199dd14bd0c2f7a2f053fd324150fda5566477 Mon Sep 17 00:00:00 2001 From: scottjehl Date: Thu, 28 Jul 2011 19:15:48 -0400 Subject: [PATCH 1/2] first pass at implementing pushstate support from an external file. --- Makefile | 1 + build.xml | 1 + js/index.php | 1 + js/jquery.mobile.navigation.pushstate.js | 50 ++++++++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 js/jquery.mobile.navigation.pushstate.js diff --git a/Makefile b/Makefile index a1705408..21c38f28 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ JSFILES = js/jquery.ui.widget.js \ js/jquery.mobile.page.js \ js/jquery.mobile.core.js \ js/jquery.mobile.navigation.js \ + js/jquery.mobile.navigation.pushstate.js \ js/jquery.mobile.transition.js \ js/jquery.mobile.degradeInputs.js \ js/jquery.mobile.dialog.js \ diff --git a/build.xml b/build.xml index 21baaabf..5a9d779b 100644 --- a/build.xml +++ b/build.xml @@ -29,6 +29,7 @@ js/jquery.mobile.page.js, js/jquery.mobile.core.js, js/jquery.mobile.navigation.js, + js/jquery.mobile.navigation.pushstate.js, js/jquery.mobile.transition.js, js/jquery.mobile.degradeInputs.js, js/jquery.mobile.dialog.js, diff --git a/js/index.php b/js/index.php index ba6bcf1c..6feecfeb 100644 --- a/js/index.php +++ b/js/index.php @@ -11,6 +11,7 @@ $elements = array( 'jquery.mobile.page.js', 'jquery.mobile.core.js', 'jquery.mobile.navigation.js', + 'jquery.mobile.navigation.pushstate.js', 'jquery.mobile.transition.js', 'jquery.mobile.degradeInputs.js', 'jquery.mobile.dialog.js', diff --git a/js/jquery.mobile.navigation.pushstate.js b/js/jquery.mobile.navigation.pushstate.js new file mode 100644 index 00000000..1f4e4741 --- /dev/null +++ b/js/jquery.mobile.navigation.pushstate.js @@ -0,0 +1,50 @@ +/* +* jQuery Mobile Framework : history.pushState support, layered on top of hashchange +* Copyright (c) jQuery Project +* Dual licensed under the MIT or GPL Version 2 licenses. +* http://jquery.org/license +*/ +( function( $ ) { + + // For now, let's Monkeypatch this onto the end of $.mobile._registerInternalEvents + var oldRegisterInternalEvents = $.mobile._registerInternalEvents; + + $.mobile._registerInternalEvents = function(){ + + // Call previous function + oldRegisterInternalEvents(); + + // Initial href without hash becomes base for hash changes + var initUrl = location.href.split( "#" )[0].match( /[^\/]*\/\/[^\/]+(.*)/ ) && RegExp.$1, + // Begin with popstate listening disabled, since it fires at onload in chrome + popListeningEnabled = false; + + $( window ).bind( "hashchange replacehash", function( e ) { + if( $.support.pushState ){ + history.replaceState( { hash: location.hash || "#" + initUrl, title: document.title }, document.title, location.href.split( "#" )[ 1 ] ); + } + }); + + // Handle popstate events the occur through history changes + $( window ).bind( "popstate", function( e ) { + if( popListeningEnabled ){ + if( e.originalEvent.state ){ + history.replaceState( e.originalEvent.state, e.originalEvent.state.title, initUrl + e.originalEvent.state.hash ); + $( window ).trigger( "hashchange" ); + } + } + }); + + // Replace the hash before pushstate listening is enabled + $( window ).trigger( "replacehash" ); + + // Enable pushstate listening after window onload + $( window ).load( function(){ + setTimeout(function(){ + popListeningEnabled = true; + }, 10 ); + }); + + }; + +})( jQuery ); \ No newline at end of file From 5f2462d031b9bff25ab9f8ac4e393dbd1e019015 Mon Sep 17 00:00:00 2001 From: scottjehl Date: Fri, 29 Jul 2011 10:06:33 -0400 Subject: [PATCH 2/2] updated to support deep links to nested lists and dialog parent pages. Still battling a 2x back history issue on those. --- js/jquery.mobile.navigation.pushstate.js | 39 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/js/jquery.mobile.navigation.pushstate.js b/js/jquery.mobile.navigation.pushstate.js index 1f4e4741..9c658194 100644 --- a/js/jquery.mobile.navigation.pushstate.js +++ b/js/jquery.mobile.navigation.pushstate.js @@ -15,34 +15,59 @@ oldRegisterInternalEvents(); // Initial href without hash becomes base for hash changes - var initUrl = location.href.split( "#" )[0].match( /[^\/]*\/\/[^\/]+(.*)/ ) && RegExp.$1, + // TODO - get this value from $.mobile.path ? + var initialFilePath = location.href.split( "#" )[0].match( /[^\/]*\/\/[^\/]+(.*)/ ) && RegExp.$1, + // Begin with popstate listening disabled, since it fires at onload in chrome - popListeningEnabled = false; + popListeningEnabled = false, + + // Support for nested lists and any other clientside-generated subpages + subkey = "&" + $.mobile.subPageUrlKey, + + // Support for dialog hash urls + dialog = "&ui-state"; $( window ).bind( "hashchange replacehash", function( e ) { + if( $.support.pushState ){ - history.replaceState( { hash: location.hash || "#" + initUrl, title: document.title }, document.title, location.href.split( "#" )[ 1 ] ); + var hash = location.hash || "#" + initialFilePath, + href = hash.replace( "#", "" ); + + //support dialog urls + if( href ){ + if( href.indexOf( dialog ) > -1 ){ + href = href.split( dialog ).join( "#" + dialog ); + } + else if( href.indexOf( subkey ) > -1 ){ + href = href.split( subkey ).join( "#" + subkey ); + } + } + + + history.replaceState( { hash: hash, title: document.title }, document.title, href ); } }); // Handle popstate events the occur through history changes $( window ).bind( "popstate", function( e ) { if( popListeningEnabled ){ + if( e.originalEvent.state ){ - history.replaceState( e.originalEvent.state, e.originalEvent.state.title, initUrl + e.originalEvent.state.hash ); + history.replaceState( e.originalEvent.state, e.originalEvent.state.title, initialFilePath + e.originalEvent.state.hash ); $( window ).trigger( "hashchange" ); } } }); - + // Replace the hash before pushstate listening is enabled $( window ).trigger( "replacehash" ); - // Enable pushstate listening after window onload + // Enable pushstate listening *after window onload + // to ignore the initial pop that Chrome calls at onload $( window ).load( function(){ setTimeout(function(){ popListeningEnabled = true; - }, 10 ); + }, 0 ); }); };