diff --git a/docs/_assets/js/jqm-docs.js b/docs/_assets/js/jqm-docs.js index 7dc84c78..72279730 100644 --- a/docs/_assets/js/jqm-docs.js +++ b/docs/_assets/js/jqm-docs.js @@ -1,7 +1,7 @@ //set up the theme switcher on the homepage $('div').live('pagecreate',function(event){ if( !$(this).is('.ui-dialog')){ - $('Switch theme') + $('Switch theme') .buttonMarkup({ 'icon':'gear', 'inline': true, @@ -12,7 +12,6 @@ $('div').live('pagecreate',function(event){ .wrap('
') .click(function(){ $.themeswitcher(); - return false; }); } event.stopPropagation(); diff --git a/docs/api/events.html b/docs/api/events.html index a8802a33..219115d9 100755 --- a/docs/api/events.html +++ b/docs/api/events.html @@ -95,10 +95,33 @@ $('div').live('pagehide',function(event, ui){
Triggered on the page being initialized, after initialization occurs.
+ +
+		
+$('#aboutPage').live('pagebeforecreate',function(event){
+  alert('This page was just inserted into the dom!');
+});
+
+$('#aboutPage').live('pagecreate',function(event){
+  alert('This page was just enhanced by jQuery Mobile!');
+});
+		
+		
+

Note that by binding to pagebeforecreate and returning false, you can prevent the page plugin from making its manipulations.

+
+		
+$('#aboutPage').live('pagebeforecreate',function(event){
+  //run your own enhancement scripting here...
+  return false;
+});
+
+		
+		
+
-

Note on Page IDs: Page elements in jQuery Mobile utilize the ID attribute for storing the location from which they came. When you place an ID attribute on a page that is brought into jQuery Mobile's single-page environment through Ajax, jQuery Mobile wraps that page with a new "page" div element, preserving any CSS references to your ID. However, this means that your ID attribute is no longer on the "page" element, so you must keep this in mind when binding to page events (pagebeforecreate, pagecreate, etc). To avoid issues, try using a class if possible.

+

Note on Page IDs in Alpha 2 release (no longer an issue): In jQuery Mobile Alpha 2 and older, page elements utilized the ID attribute for storing the location from which they came. When you place an ID attribute on a page that is brought into jQuery Mobile's single-page environment through Ajax, jQuery Mobile wraps that page with a new "page" div element, preserving any CSS references to your ID. However, this means that your ID attribute is no longer on the "page" element, so you must keep this in mind when binding to page events (pagebeforecreate, pagecreate, etc). To avoid issues, try using a class if possible.

diff --git a/docs/pages/docs-pages.html b/docs/pages/docs-pages.html index dfa1f46c..8a2fc415 100755 --- a/docs/pages/docs-pages.html +++ b/docs/pages/docs-pages.html @@ -160,7 +160,7 @@ </body> - View multi-page template + View multi-page template

diff --git a/docs/pages/multipage-template.html b/docs/pages/multipage-template.html index 6ae5dc62..9674a425 100755 --- a/docs/pages/multipage-template.html +++ b/docs/pages/multipage-template.html @@ -3,9 +3,8 @@ Page Title - - - + + diff --git a/experiments/themeswitcher/jquery.mobile.themeswitcher.js b/experiments/themeswitcher/jquery.mobile.themeswitcher.js index 248f8a3c..726448d4 100644 --- a/experiments/themeswitcher/jquery.mobile.themeswitcher.js +++ b/experiments/themeswitcher/jquery.mobile.themeswitcher.js @@ -1,10 +1,11 @@ //quick & dirty theme switcher, written to potentially work as a bookmarklet (function($){ $.themeswitcher = function(){ + if( $('[data-url=themeswitcher]').length ){ return; } var themesDir = 'http://jquerymobile.com/test/themes/', themes = ['default','valencia'], currentPage = $.mobile.activePage, - menuPage = $( '
' + + menuPage = $( '
' + '
' + '
Switch Theme:
'+ '
'+ @@ -32,8 +33,6 @@ //create page, listview menuPage.page(); - - //change page now - $.mobile.changePage([currentPage, menuPage], 'pop', false); + }; })(jQuery); diff --git a/js/jquery.mobile.core.js b/js/jquery.mobile.core.js index 11709e9f..8de48421 100644 --- a/js/jquery.mobile.core.js +++ b/js/jquery.mobile.core.js @@ -120,6 +120,10 @@ //find present pages var $pages = $("[data-role='page']"); + $pages.each(function(){ + $(this).attr('data-url', $(this).attr('id')); + }); + //set up active page $.mobile.startPage = $.mobile.activePage = $pages.first(); diff --git a/js/jquery.mobile.dialog.js b/js/jquery.mobile.dialog.js index 28e8a6ab..c61bd76a 100644 --- a/js/jquery.mobile.dialog.js +++ b/js/jquery.mobile.dialog.js @@ -44,7 +44,7 @@ $.widget( "mobile.dialog", $.mobile.widget, { if( $el.is('.ui-page-active') ){ self.close(); $el.bind('pagehide',function(){ - $.mobile.updateHash( $prevPage.attr('id'), true); + $.mobile.updateHash( $prevPage.attr('data-url'), true); }); } }); diff --git a/js/jquery.mobile.forms.button.js b/js/jquery.mobile.forms.button.js index 2afeb732..31db9786 100644 --- a/js/jquery.mobile.forms.button.js +++ b/js/jquery.mobile.forms.button.js @@ -17,36 +17,11 @@ $.widget( "mobile.button", $.mobile.widget, { }, _create: function(){ var $el = this.element, - o = this.options, - type = $el.attr('type'); - $el - .addClass('ui-btn-hidden') - .attr('tabindex','-1'); + o = this.options; //add ARIA role - this.button = $( "", { - "href": "#", - "role": "button", - "aria-label": $el.attr( "type" ) - } ) + this.button = $( "
" ) .text( $el.text() || $el.val() ) - .insertBefore( $el ) - .click(function(e){ - if(!o.disabled){ - if ( $el.attr("type") !== "reset" ){ - var $buttonPlaceholder = $("", - {type: "hidden", name: $el.attr("name"), value: $el.attr("value")}) - .insertBefore($el); - - } - $el.submit(); - $buttonPlaceholder.remove(); - } - else{ - $el.trigger("click") - } - e.preventDefault(); - }) .buttonMarkup({ theme: o.theme, icon: o.icon, @@ -55,7 +30,24 @@ $.widget( "mobile.button", $.mobile.widget, { corners: o.corners, shadow: o.shadow, iconshadow: o.iconshadow + }) + .insertBefore( $el ) + .append( $el.addClass('ui-btn-hidden') ); + + //add hidden input during submit + if( $el.attr('type') !== 'reset' ){ + $el.click(function(){ + var $buttonPlaceholder = $("", + {type: "hidden", name: $el.attr("name"), value: $el.attr("value")}) + .insertBefore($el); + + //bind to doc to remove after submit handling + $(document).submit(function(){ + $buttonPlaceholder.remove(); + }); }); + } + }, enable: function(){ diff --git a/js/jquery.mobile.listview.js b/js/jquery.mobile.listview.js index 80b0f643..cc564109 100644 --- a/js/jquery.mobile.listview.js +++ b/js/jquery.mobile.listview.js @@ -290,7 +290,7 @@ $.widget( "mobile.listview", $.mobile.widget, { _createSubPages: function() { var parentList = this.element, parentPage = parentList.closest( ".ui-page" ), - parentId = parentPage.attr( "id" ), + parentId = parentPage.data( "url" ), o = this.options, self = this, persistentFooterID = parentPage.find( "[data-role='footer']" ).data( "id" ); @@ -308,7 +308,7 @@ $.widget( "mobile.listview", $.mobile.widget, { .after( persistentFooterID ? $( "
", { "data-role": "footer", "data-id": persistentFooterID, "class": "ui-footer-duplicate" } ) : "" ) .parent() .attr({ - id: id, + "data-url": id, "data-theme": theme, "data-count-theme": countTheme }) diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js index 4f758fd5..75cd50e3 100644 --- a/js/jquery.mobile.navigation.js +++ b/js/jquery.mobile.navigation.js @@ -20,14 +20,19 @@ newPath = location.hash; } newPath = newPath.replace(/#/,'').split('/'); - newPath.pop(); + if(newPath.length){ + var lastSegment = newPath[newPath.length-1]; + if( lastSegment.indexOf('.') > -1 || lastSegment == ''){ + newPath.pop(); + } + } return newPath.join('/') + (newPath.length ? '/' : ''); }, //return the substring of a filepath before the sub-page key, for making a server request getFilePath: function( path ){ var splitkey = '&' + $.mobile.subPageUrlKey; - return path.indexOf( splitkey ) > -1 ? path.split( splitkey )[0] : path; + return path && path.indexOf( splitkey ) > -1 ? path.split( splitkey )[0] : path; }, set: function( path, disableListening){ @@ -36,7 +41,7 @@ }, //location pathname from intial directory request - origin: null, + origin: '', setOrigin: function(){ path.origin = path.get( location.protocol + '//' + location.host + location.pathname ); @@ -85,7 +90,6 @@ //set location pathname from intial directory request path.setOrigin(); - /* internal utility functions @@ -134,7 +138,7 @@ // changepage function $.mobile.changePage = function( to, transition, back, changeHash){ - + //from is always the currently viewed page var toIsArray = $.type(to) === "array", from = toIsArray ? to[0] : $.mobile.activePage, @@ -147,11 +151,13 @@ back = (back !== undefined) ? back : ( urlStack.length > 1 && urlStack[ urlStack.length - 2 ].url === url ), transition = (transition !== undefined) ? transition : $.mobile.defaultTransition; + //If we are trying to transition to the same page that we are currently on ignore the request. - if(urlStack.length > 1 && url === urlStack[urlStack.length -1].url) { + if(urlStack.length > 1 && url === urlStack[urlStack.length -1].url && !toIsArray ) { return; } + if( $.type(to) === "object" && to.url ){ url = to.url, data = to.data, @@ -163,6 +169,9 @@ data = undefined; } } + + + //reset base to pathname for new request if(base){ base.reset(); } @@ -243,9 +252,12 @@ function enhancePage(){ //set next page role, if defined - if ( nextPageRole ) { - to.attr( "data-role", nextPageRole ); - nextPageRole = undefined; + if ( nextPageRole || to.data('role') == 'dialog' ) { + changeHash = false; + if(nextPageRole){ + to.attr( "data-role", nextPageRole ); + nextPageRole = null; + } } //run page plugin @@ -254,11 +266,11 @@ //if url is a string if( url ){ - to = $( "[id='" + url + "']" ), + to = $( "[data-url='" + url + "']" ); fileUrl = path.getFilePath(url); } else{ //find base url of element, if avail - var toID = to.attr('id'), + var toID = to.attr('data-url'), toIDfileurl = path.getFilePath(toID); if(toID != toIDfileurl){ @@ -287,13 +299,12 @@ type: type, data: data, success: function( html ) { - if(base){ base.set(fileUrl); } var all = $("
"); //workaround to allow scripts to execute when included in page divs all.get(0).innerHTML = html; - to = all.find('[data-role="page"]'); + to = all.find('[data-role="page"], [data-role="dialog"]').first(); //rewrite src and href attrs to use a base url if( !$.support.dynamicBaseTag ){ @@ -310,24 +321,9 @@ } }); } - - //preserve ID on a retrieved page - if ( to.attr('id') ) { - //wrap page and transfer data-attrs if it has an ID - var copyAttrs = ['data-role', 'data-theme', 'data-fullscreen'], //TODO: more page-level attrs? - wrapper = to.wrap( "
" ).parent(); - - $.each(copyAttrs,function(i){ - if( to.attr( copyAttrs[ i ] ) ){ - wrapper.attr( copyAttrs[ i ], to.attr( copyAttrs[ i ] ) ); - to.removeAttr( copyAttrs[ i ] ); - } - }); - to = wrapper; - } to - .attr( "id", fileUrl ) + .attr( "data-url", fileUrl ) .appendTo( $.mobile.pageContainer ); enhancePage(); @@ -336,6 +332,7 @@ error: function() { $.mobile.pageLoading( true ); removeActiveLinkClass(true); + base.set(path.get()); $("

Error Loading Page

") .css({ "display": "block", "opacity": 0.96, "top": $(window).scrollTop() + 100 }) .appendTo( $.mobile.pageContainer ) @@ -349,8 +346,6 @@ }; - - /* Event Bindings - hashchange, submit, and click */ @@ -386,6 +381,7 @@ //click routing - direct to HTTP or Ajax, accordingly $( "a" ).live( "click", function(event) { + if( !$.mobile.ajaxLinksEnabled ){ return; } var $this = $(this), //get href, remove same-domain protocol and host @@ -418,8 +414,7 @@ else { //use ajax var transition = $this.data( "transition" ), - back = $this.data( "back" ), - changeHashOnSuccess = !$this.is( "[data-rel="+ $.mobile.nonHistorySelectors +"]" ); + back = $this.data( "back" ); nextPageRole = $this.attr( "data-rel" ); @@ -430,7 +425,7 @@ href.replace(/^#/,''); - $.mobile.changePage(href, transition, back, changeHashOnSuccess); + $.mobile.changePage(href, transition, back); } event.preventDefault(); }); diff --git a/themes/default/jquery.mobile.button.css b/themes/default/jquery.mobile.button.css index 2ae040d7..0b10abba 100644 --- a/themes/default/jquery.mobile.button.css +++ b/themes/default/jquery.mobile.button.css @@ -50,4 +50,4 @@ .ui-btn-icon-top .ui-icon { top: 5px; } .ui-btn-icon-bottom .ui-icon { bottom: 5px; } /*hiding native button,inputs */ -.ui-btn-hidden { position: absolute; left: -9999px; } +.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: 0; cursor: pointer; }