diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js
index 2037d6e9..95f55cdf 100644
--- a/js/jquery.mobile.navigation.js
+++ b/js/jquery.mobile.navigation.js
@@ -116,7 +116,7 @@
clearForward: function(){
urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 );
},
-
+
//disable hashchange event listener internally to ignore one change
//toggled internally when location.hash is updated to match the url of a successful page load
ignoreNextHashChange: true
@@ -258,7 +258,7 @@
from = toIsArray ? to[0] : $.mobile.activePage;
to = toIsArray ? to[1] : to;
-
+
var url = $.type(to) === "string" ? path.stripHash( to ) : "",
fileUrl = url,
data,
@@ -280,7 +280,7 @@
pageTransitionQueue.unshift(arguments);
return;
}
-
+
isPageTransitioning = true;
// if the changePage was sent from a hashChange event
@@ -346,7 +346,7 @@
$.mobile.changePage.apply($.mobile, pageTransitionQueue.pop());
}
}
-
+
//function for transitioning between two existing pages
function transitionPages() {
$.mobile.silentScroll();
@@ -360,13 +360,13 @@
if( url.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ){
to = $( "[data-url='" + url + "']" );
}
-
+
if( from ){
//set as data for returning to that spot
from.data( "lastScroll", currScroll);
//trigger before show/hide events
from.data( "page" )._trigger( "beforehide", { nextPage: to } );
- }
+ }
to.data( "page" )._trigger( "beforeshow", { prevPage: from || $("") } );
function loadComplete(){
@@ -386,7 +386,7 @@
removeActiveLinkClass();
//jump to top or prev scroll, sometimes on iOS the page has not rendered yet. I could only get by this with a setTimeout, but would like to avoid that.
- $.mobile.silentScroll( to.data( "lastScroll" ) );
+ $.mobile.silentScroll( to.data( "lastScroll" ) );
reFocus( to );
@@ -396,7 +396,7 @@
}
//trigger pageshow, define prevPage as either from or empty jQuery obj
to.data( "page" )._trigger( "show", null, { prevPage: from || $("") } );
-
+
//set "to" as activePage
$.mobile.activePage = to;
@@ -404,7 +404,7 @@
if (duplicateCachedPage !== null) {
duplicateCachedPage.remove();
}
-
+
//remove initial build class (only present on first pageshow)
$html.removeClass( "ui-mobile-rendering" );
@@ -445,7 +445,7 @@
to.add(from).removeClass("out in reverse " + transition );
if( from ){
from.removeClass( $.mobile.activePageClass );
- }
+ }
loadComplete();
removeContainerClasses();
});
@@ -454,7 +454,7 @@
$.mobile.pageLoading( true );
if( from ){
from.removeClass( $.mobile.activePageClass );
- }
+ }
to.addClass( $.mobile.activePageClass );
loadComplete();
}
@@ -497,7 +497,7 @@
if ( to.length && !isFormRequest ) {
if( fileUrl && base ){
base.set( fileUrl );
- }
+ }
enhancePage();
transitionPages();
} else {
@@ -514,10 +514,15 @@
type: type,
data: data,
success: function( html ) {
-
//pre-parse html to check for a data-url,
//use it as the new fileUrl, base path, etc
- var redirectLoc = / data-url="(.*)"/.test( html ) && RegExp.$1;
+ var all = $("
"),
+ redirectLoc;
+
+ //workaround to allow scripts to execute when included in page divs
+ all.get(0).innerHTML = html;
+ to = all.find('[data-role="page"], [data-role="dialog"]').first();
+ redirectLoc = all.find('[data-url]').data('url');
if( redirectLoc ){
if(base){
@@ -531,11 +536,6 @@
}
}
- var all = $("");
- //workaround to allow scripts to execute when included in page divs
- all.get(0).innerHTML = html;
- to = all.find('[data-role="page"], [data-role="dialog"]').first();
-
//rewrite src and href attrs to use a base url
if( !$.support.dynamicBaseTag ){
var newPath = path.get( fileUrl );
@@ -619,10 +619,10 @@
$( "a" ).live( "click", function(event) {
var $this = $(this),
-
+
//get href, if defined, otherwise fall to null #
href = $this.attr( "href" ) || "#",
-
+
//get href, remove same-domain protocol and host
url = path.clean( href ),
@@ -703,7 +703,7 @@
var to = path.stripHash( location.hash ),
//transition is false if it's the first page, undefined otherwise (and may be overridden by default)
transition = $.mobile.urlHistory.stack.length === 0 ? false : undefined;
-
+
//if listening is disabled (either globally or temporarily), or it's a dialog hash
if( !$.mobile.hashListeningEnabled || !urlHistory.ignoreNextHashChange ||
(urlHistory.stack.length > 1 && to.indexOf( dialogHashKey ) > -1 && !$.mobile.activePage.is( ".ui-dialog" ))
diff --git a/tests/unit/dialog/dialog_events.js b/tests/unit/dialog/dialog_events.js
index 54a55c27..57e1e80b 100644
--- a/tests/unit/dialog/dialog_events.js
+++ b/tests/unit/dialog/dialog_events.js
@@ -2,38 +2,23 @@
* mobile dialog unit tests
*/
(function($){
- var wait = function(length){
- setTimeout(start, length);
- stop();
- };
+ module('jquery.mobile.dialog.js');
- module('jquery.mobile.dialog.js', {
- setup: function(){
- //bring up the dialog
- $("a[href='#foo-dialog']").click();
+ asyncTest( "dialog hash is added when the dialog is opened and removed when closed", function(){
+ expect( 2 );
- //wait for the dialog to appear
- wait(500);
- },
- teardown: function(){
+ //bring up the dialog
+ $("a[href='#foo-dialog']").click();
+
+ setTimeout(function(){
+ ok(/&ui-state=dialog/.test(location.hash), "ui-state=dialog =~ location.hash");
// close the dialog
$(".ui-dialog .ui-icon-delete").parents("a").click();
-
- // wait for the dialog to disappear
- wait(500);
- }
- });
-
- test( "dialog hash is added when the dialog is opened", function(){
- ok(/&ui-state=dialog/.test(location.hash), "ui-state=dialog =~ location.hash");
- });
-
- asyncTest( "dialog hash param is removed on close", function(){
- $(".ui-dialog .ui-icon-delete").parents("a").click();
+ }, 500);
setTimeout(function(){
ok(!/&ui-state=dialog/.test(location.hash), "ui-state=dialog !~ location.hash");
start();
- }, 600);
+ }, 1000);
});
})(jQuery);
diff --git a/tests/unit/listview/listview_core.js b/tests/unit/listview/listview_core.js
index 0ac969f8..86d21feb 100644
--- a/tests/unit/listview/listview_core.js
+++ b/tests/unit/listview/listview_core.js
@@ -194,7 +194,7 @@
$('.ui-page-active input').trigger('change');
setTimeout(function() {
- same($('.ui-page-active li[style="display: none;"]').length, 2);
+ same($('.ui-page-active li[style^="display: none;"]').length, 2);
start();
}, 1000);
});
@@ -203,7 +203,7 @@
$('.ui-page-active input').val('a');
$('.ui-page-active input').trigger('change');
setTimeout(function() {
- same($('.ui-page-active li[style="display: none;"]').length, 0);
+ same($('.ui-page-active li[style^="display: none;"]').length, 0);
start();
}, 1000);
});
diff --git a/tests/unit/navigation/data-url.html b/tests/unit/navigation/data-url.html
new file mode 100644
index 00000000..6f8bf224
--- /dev/null
+++ b/tests/unit/navigation/data-url.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/unit/navigation/index.html b/tests/unit/navigation/index.html
index daeaf3c2..85625249 100644
--- a/tests/unit/navigation/index.html
+++ b/tests/unit/navigation/index.html
@@ -79,6 +79,14 @@
+
+
+
+
diff --git a/tests/unit/navigation/navigation_core.js b/tests/unit/navigation/navigation_core.js
index 2300c07b..224ff068 100644
--- a/tests/unit/navigation/navigation_core.js
+++ b/tests/unit/navigation/navigation_core.js
@@ -37,82 +37,82 @@
same(called, 2, "change page should be called twice");
});
-
-
+
+
asyncTest( "anchors with no href attribute will do nothing when clicked", function(){
var fired = false;
-
+
$(window).bind("hashchange.temp", function(){
fired = true;
});
-
+
$( "
test" ).appendTo( $.mobile.pageContainer ).click();
-
+
setTimeout(function(){
start();
same(fired, false, "hash shouldn't change after click");
$(window).unbind("hashchange.temp");
}, 500);
});
-
-
-
-
+
+
+
+
test( "path.get method is working properly", function(){
window.location.hash = "foo"
same($.mobile.path.get(), "foo", "get method returns location.hash minus hash character");
same($.mobile.path.get( "#foo/bar/baz.html" ), "foo/bar/", "get method with hash arg returns path with no filename or hash prefix");
same($.mobile.path.get( "#foo/bar/baz.html/" ), "foo/bar/baz.html/", "last segment of hash is retained if followed by a trailing slash");
});
-
+
test( "path.getFilePath method is working properly", function(){
same($.mobile.path.getFilePath("foo.html" + "&" + $.mobile.subPageUrlKey ), "foo.html", "returns path without sub page key");
});
-
-
+
+
test( "path.set method is working properly", function(){
$.mobile.urlHistory.ignoreNextHashChange = false;
$.mobile.path.set("foo");
same("foo", window.location.hash.replace(/^#/,""), "sets location.hash properly");
location.hash = "";
});
-
+
test( "path.makeAbsolute is working properly", function(){
$.mobile.urlHistory.ignoreNextHashChange = false;
$.mobile.path.set("bar/");
same( $.mobile.path.makeAbsolute("test.html"), "bar/test.html", "prefixes path with absolute base path from hash");
location.hash = "";
});
-
+
test( "path.clean is working properly", function(){
var localroot = location.href.split("/").slice(0, 3).join("/"),
remoteroot = "http://google.com/",
fakepath = "foo/bar/baz.html",
localpath = localroot + fakepath,
remotepath = remoteroot + fakepath;
-
+
same( $.mobile.path.clean( localpath ), fakepath, "removes location protocol, host, port from same-domain path");
same( $.mobile.path.clean( remotepath ), remotepath, "does nothing to an external domain path");
});
-
+
test( "path.stripHash is working properly", function(){
same( $.mobile.path.stripHash( "#bar" ), "bar", "returns a hash without the # prefix");
});
-
+
test( "path.hasProtocol is working properly", function(){
same( $.mobile.path.hasProtocol( "tel:5559999" ), true, "value in tel protocol format has protocol" );
same( $.mobile.path.hasProtocol( location.href ), true, "location href has protocol" );
same( $.mobile.path.hasProtocol( "foo/bar/baz.html" ), false, "simple directory path has no protocol" );
same( $.mobile.path.hasProtocol( "file://foo/bar/baz.html" ), true, "simple directory path with file:// has protocol" );
});
-
+
test( "path.isRelative is working properly", function(){
same( $.mobile.path.isRelative("#foo/bar"), false, "path starting with a # is not relative" );
same( $.mobile.path.isRelative("/foo/bar"), false, "path starting with a / is not relative" );
same( $.mobile.path.isRelative("http://example.com/foo"), false, "full url path is not relative" );
same( $.mobile.path.isRelative("foo/bar.html"), true, "simple path is relative" );
});
-
+
test( "path.isExternal is working properly", function(){
same( $.mobile.path.isExternal( location.href ), false, "same domain is not external" );
same( $.mobile.path.isExternal( "http://example.com" ), true, "example.com is external" );
@@ -127,45 +127,45 @@
same($.mobile.path.isExternal("foo"), false, "simple string");
same($.mobile.path.isExternal("#foo"), false, "local id reference");
});
-
-
+
+
test( "urlHistory is working properly", function(){
-
+
//urlHistory
same( $.type( $.mobile.urlHistory.stack ), "array", "urlHistory.stack is an array" );
-
+
//preload the stack
$.mobile.urlHistory.stack[0] = { url: "foo", transition: "bar" };
$.mobile.urlHistory.stack[1] = { url: "baz", transition: "shizam" };
$.mobile.urlHistory.stack[2] = { url: "shizoo", transition: "shizaah" };
-
+
//active index
same( $.mobile.urlHistory.activeIndex , 0, "urlHistory.activeIndex is 0" );
-
+
//getActive
same( $.type( $.mobile.urlHistory.getActive() ) , "object", "active item is an object" );
same( $.mobile.urlHistory.getActive().url , "foo", "active item has url foo" );
same( $.mobile.urlHistory.getActive().transition , "bar", "active item has transition bar" );
-
+
//get prev / next
same( $.mobile.urlHistory.getPrev(), undefined, "urlHistory.getPrev() is undefined when active index is 0" );
$.mobile.urlHistory.activeIndex = 1;
same( $.mobile.urlHistory.getPrev().url, "foo", "urlHistory.getPrev() has url foo when active index is 1" );
$.mobile.urlHistory.activeIndex = 0;
same( $.mobile.urlHistory.getNext().url, "baz", "urlHistory.getNext() has url baz when active index is 0" );
-
+
//add new
$.mobile.urlHistory.activeIndex = 2;
$.mobile.urlHistory.addNew("test");
same( $.mobile.urlHistory.stack.length, 4, "urlHistory.addNew() adds an item after the active index" );
same( $.mobile.urlHistory.activeIndex, 3, "urlHistory.addNew() moves the activeIndex to the newly added item" );
-
+
//clearForward
$.mobile.urlHistory.activeIndex = 0;
$.mobile.urlHistory.clearForward();
same( $.mobile.urlHistory.stack.length, 1, "urlHistory.clearForward() clears the url stack after the active index" );
});
-
+
//url listening
function testListening( prop ){
prop = false;
@@ -181,15 +181,15 @@
prop = true;
}, 1000);
}
-
+
asyncTest( "ability to disable our hash change event listening internally", function(){
testListening( $.mobile.urlHistory.ignoreNextHashChange );
});
-
+
asyncTest( "ability to disable our hash change event listening globally", function(){
testListening( $.mobile.hashListeningEnabled );
});
-
+
asyncTest( "changepage will only run once when a new page is visited", function(){
var called = 0;
$.mobile.changePage = function(a,b,c,d,e){
@@ -198,11 +198,32 @@
};
$('#foo a').click();
-
+
setTimeout(function(){
start();
ok(called == 1, "change page should be called once");
}, 500);
});
-
+
+ asyncTest( "when loading a page where data-url is defined on a sub element set the hash with that url", function(){
+ location.hash = "";
+ $("#data-url a").click();
+
+ setTimeout(function(){
+ ok(location.hash.indexOf("#foo/") >= 0);
+ start();
+ }, 1000);
+ stop();
+ });
+
+ asyncTest( "when loading a page where data-url is not defined on a sub element hash defaults to the url", function(){
+ location.hash = "";
+ $("#non-data-url a").click();
+
+ setTimeout(function(){
+ ok(location.hash.indexOf("#non-data-url.html") >= 0);
+ start();
+ }, 1000);
+ stop();
+ });
})(jQuery);
diff --git a/tests/unit/navigation/non-data-url.html b/tests/unit/navigation/non-data-url.html
new file mode 100644
index 00000000..c1a4d6a8
--- /dev/null
+++ b/tests/unit/navigation/non-data-url.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+