From fd5a3c06543e92f39c7e1e065613e58966577c05 Mon Sep 17 00:00:00 2001 From: Jihoon Song Date: Tue, 9 Apr 2013 15:06:54 +0900 Subject: [PATCH] [Title] common-eplugin: updated tizen web ui framework to 0.2.22 [Desc.] [Issue] Change-Id: I6a59563a97707375e5a91e788e1cd56295b13795 --- .../tizen-web-ui-fw/VERSION | 2 +- .../tizen-web-ui-fw/latest/js/depData.json | 11 + .../latest/js/src/jquery.mobile.navigation.js | 12 +- .../latest/js/src/jquery.mobile.navigation.js.orig | 1549 ++ .../latest/js/src/jquery.mobile.tizen.pinch.js | 173 + .../widgets/jquery.mobile.tizen.datetimepicker.js | 7 + .../js/src/widgets/jquery.mobile.tizen.gallery.js | 25 +- .../widgets/jquery.mobile.tizen.multimediaview.js | 117 +- .../src/widgets/jquery.mobile.tizen.pagelayout.js | 29 +- .../src/widgets/jquery.mobile.tizen.searchbar.js | 1 + .../latest/js/tizen-web-ui-fw-libs.js | 14 +- .../latest/js/tizen-web-ui-fw-libs.min.js | 8 +- .../tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js | 17909 ++++++++++--------- .../latest/js/tizen-web-ui-fw.min.js | 14 +- .../themes/tizen-white/tizen-web-ui-fw-theme.css | 8 +- .../tizen-white/tizen-web-ui-fw-theme.min.css | 2 +- .../templates/jar/common-resources.jar | Bin 18584 -> 18584 bytes .../templates/jar/jqm-common-resources.jar | Bin 197288 -> 197288 bytes .../templates/jar/jqm-masterdetail.jar | Bin 3015 -> 3015 bytes .../templates/jar/jqm-multipage.jar | Bin 2280 -> 2280 bytes .../templates/jar/jqm-navigation.jar | Bin 2893 -> 2893 bytes .../templates/jar/jqm-singlepage.jar | Bin 1587 -> 1587 bytes .../templates/jar/tizen-basic.jar | Bin 20614 -> 20614 bytes .../jar/tizenwebuifw-common-resources.jar | Bin 1835410 -> 1855143 bytes .../templates/jar/tizenwebuifw-masterdetail.jar | Bin 2864 -> 2864 bytes .../templates/jar/tizenwebuifw-multipage.jar | Bin 2249 -> 2249 bytes .../templates/jar/tizenwebuifw-navigation.jar | Bin 2854 -> 2854 bytes .../templates/jar/tizenwebuifw-singlepage.jar | Bin 1703 -> 1703 bytes 28 files changed, 10895 insertions(+), 8986 deletions(-) create mode 100644 org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js.orig create mode 100644 org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.tizen.pinch.js diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/VERSION b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/VERSION index 599028f..109a20f 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/VERSION +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/VERSION @@ -1 +1 @@ -0.2.21 +0.2.22 diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/depData.json b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/depData.json index 9da6c2b..1d07da2 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/depData.json +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/depData.json @@ -45,6 +45,17 @@ "group": "Events", "description": "Orientation change event" }, + "jquery.mobile.tizen.pinch": { + "basedir": "/home/blueisle/playground/web/tizen/web-ui-fw.rsa/build/tizen-web-ui-fw/0.2/js/src", + "path": "jquery.mobile.tizen.pinch.js", + "name": "jquery.mobile.tizen.pinch", + "depends": [ + "jquery.mobile.core" + ], + "label": "Tizen core", + "group": "Tizen:Core", + "description": "Tizen core library" + }, "jquery.mobile.define": { "basedir": "/home/blueisle/playground/web/tizen/web-ui-fw.rsa/build/tizen-web-ui-fw/0.2/js/src", "path": "jquery.mobile.define.js", diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js index 64ea296..530d847 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js @@ -738,6 +738,10 @@ if ( !settings.reloadPage ) { enhancePage( page, settings.role ); deferred.resolve( absUrl, options, page ); + //if we are reloading the page make sure we update the base if its not a prefetch + if( base && !options.prefetch ){ + base.set(url); + } return deferred.promise(); } dupCachedPage = page; @@ -774,7 +778,8 @@ } // Reset base to the default document base. - if ( base ) { + // only reset if we are not prefetching + if ( base && typeof options.prefetch === "undefined" ) { base.reset(); } @@ -809,7 +814,8 @@ url = fileUrl = path.getFilePath( $( "
" + RegExp.$1 + "
" ).text() ); } - if ( base ) { + //dont update the base tag if we are prefetching + if ( base && typeof options.prefetch === "undefined") { base.set( fileUrl ); } @@ -1417,7 +1423,7 @@ if ( url && $.inArray( url, urls ) === -1 ) { urls.push( url ); - $.mobile.loadPage( url, { role: $link.attr( "data-" + $.mobile.ns + "rel" ) } ); + $.mobile.loadPage( url, { role: $link.attr( "data-" + $.mobile.ns + "rel" ),prefetch: true } ); } }); }); diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js.orig b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js.orig new file mode 100644 index 0000000..0be7861 --- /dev/null +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.navigation.js.orig @@ -0,0 +1,1549 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Applies the AJAX navigation system to links and forms to enable page transitions +//>>label: AJAX Navigation System +//>>group: Navigation + +define( [ + "jquery", + "./jquery.mobile.core", + "./jquery.mobile.events", + "./jquery.mobile.support", + "depend!./jquery.hashchange[jquery]", + "./widgets/page", + "./jquery.mobile.transition" ], function( $ ) { +//>>excludeEnd("jqmBuildExclude"); +(function( $, undefined ) { + + //define vars for interal use + var $window = $.mobile.$window, + $html = $( 'html' ), + $head = $( 'head' ), + + //url path helpers for use in relative url management + path = { + + // This scary looking regular expression parses an absolute URL or its relative + // variants (protocol, site, document, query, and hash), into the various + // components (protocol, host, path, query, fragment, etc that make up the + // URL as well as some other commonly used sub-parts. When used with RegExp.exec() + // or String.match, it parses the URL into a results array that looks like this: + // + // [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content + // [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread + // [2]: http://jblas:password@mycompany.com:8080/mail/inbox + // [3]: http://jblas:password@mycompany.com:8080 + // [4]: http: + // [5]: // + // [6]: jblas:password@mycompany.com:8080 + // [7]: jblas:password + // [8]: jblas + // [9]: password + // [10]: mycompany.com:8080 + // [11]: mycompany.com + // [12]: 8080 + // [13]: /mail/inbox + // [14]: /mail/ + // [15]: inbox + // [16]: ?msg=1234&type=unread + // [17]: #msg-content + // + urlParseRE: /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/, + + // Abstraction to address xss (Issue #4787) by removing the authority in + // browsers that auto decode it. All references to location.href should be + // replaced with a call to this method so that it can be dealt with properly here + getLocation: function( url ) { + var uri = url ? this.parseUrl( url ) : location, + hash = this.parseUrl( url || location.href ).hash; + + // mimic the browser with an empty string when the hash is empty + hash = hash === "#" ? "" : hash; + + // Make sure to parse the url or the location object for the hash because using location.hash + // is autodecoded in firefox, the rest of the url should be from the object (location unless + // we're testing) to avoid the inclusion of the authority + return uri.protocol + "//" + uri.host + uri.pathname + uri.search + hash; + }, + + parseLocation: function() { + return this.parseUrl( this.getLocation() ); + }, + + //Parse a URL into a structure that allows easy access to + //all of the URL components by name. + parseUrl: function( url ) { + // If we're passed an object, we'll assume that it is + // a parsed url object and just return it back to the caller. + if ( $.type( url ) === "object" ) { + return url; + } + + var matches = path.urlParseRE.exec( url || "" ) || []; + + // Create an object that allows the caller to access the sub-matches + // by name. Note that IE returns an empty string instead of undefined, + // like all other browsers do, so we normalize everything so its consistent + // no matter what browser we're running on. + return { + href: matches[ 0 ] || "", + hrefNoHash: matches[ 1 ] || "", + hrefNoSearch: matches[ 2 ] || "", + domain: matches[ 3 ] || "", + protocol: matches[ 4 ] || "", + doubleSlash: matches[ 5 ] || "", + authority: matches[ 6 ] || "", + username: matches[ 8 ] || "", + password: matches[ 9 ] || "", + host: matches[ 10 ] || "", + hostname: matches[ 11 ] || "", + port: matches[ 12 ] || "", + pathname: matches[ 13 ] || "", + directory: matches[ 14 ] || "", + filename: matches[ 15 ] || "", + search: matches[ 16 ] || "", + hash: matches[ 17 ] || "" + }; + }, + + //Turn relPath into an asbolute path. absPath is + //an optional absolute path which describes what + //relPath is relative to. + makePathAbsolute: function( relPath, absPath ) { + if ( relPath && relPath.charAt( 0 ) === "/" ) { + return relPath; + } + + relPath = relPath || ""; + absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : ""; + + var absStack = absPath ? absPath.split( "/" ) : [], + relStack = relPath.split( "/" ); + for ( var i = 0; i < relStack.length; i++ ) { + var d = relStack[ i ]; + switch ( d ) { + case ".": + break; + case "..": + if ( absStack.length ) { + absStack.pop(); + } + break; + default: + absStack.push( d ); + break; + } + } + return "/" + absStack.join( "/" ); + }, + + //Returns true if both urls have the same domain. + isSameDomain: function( absUrl1, absUrl2 ) { + return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain; + }, + + //Returns true for any relative variant. + isRelativeUrl: function( url ) { + // All relative Url variants have one thing in common, no protocol. + return path.parseUrl( url ).protocol === ""; + }, + + //Returns true for an absolute url. + isAbsoluteUrl: function( url ) { + return path.parseUrl( url ).protocol !== ""; + }, + + //Turn the specified realtive URL into an absolute one. This function + //can handle all relative variants (protocol, site, document, query, fragment). + makeUrlAbsolute: function( relUrl, absUrl ) { + if ( !path.isRelativeUrl( relUrl ) ) { + return relUrl; + } + + if ( absUrl === undefined ) { + absUrl = documentBase; + } + + var relObj = path.parseUrl( relUrl ), + absObj = path.parseUrl( absUrl ), + protocol = relObj.protocol || absObj.protocol, + doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash ), + authority = relObj.authority || absObj.authority, + hasPath = relObj.pathname !== "", + pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ), + search = relObj.search || ( !hasPath && absObj.search ) || "", + hash = relObj.hash; + + return protocol + doubleSlash + authority + pathname + search + hash; + }, + + //Add search (aka query) params to the specified url. + addSearchParams: function( url, params ) { + var u = path.parseUrl( url ), + p = ( typeof params === "object" ) ? $.param( params ) : params, + s = u.search || "?"; + return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" ); + }, + + convertUrlToDataUrl: function( absUrl ) { + var u = path.parseUrl( absUrl ); + if ( path.isEmbeddedPage( u ) ) { + // For embedded pages, remove the dialog hash key as in getFilePath(), + // otherwise the Data Url won't match the id of the embedded Page. + return u.hash.split( dialogHashKey )[0].replace( /^#/, "" ); + } else if ( path.isSameDomain( u, documentBase ) ) { + return u.hrefNoHash.replace( documentBase.domain, "" ).split( dialogHashKey )[0]; + } + + return window.decodeURIComponent(absUrl); + }, + + //get path from current hash, or from a file path + get: function( newPath ) { + if ( newPath === undefined ) { + newPath = path.parseLocation().hash; + } + return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' ); + }, + + //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 && path.split( splitkey )[0].split( dialogHashKey )[0]; + }, + + //set location hash to path + set: function( path ) { + location.hash = path; + }, + + //test if a given url (string) is a path + //NOTE might be exceptionally naive + isPath: function( url ) { + return ( /\// ).test( url ); + }, + + //return a url path with the window's location protocol/hostname/pathname removed + clean: function( url ) { + return url.replace( documentBase.domain, "" ); + }, + + //just return the url without an initial # + stripHash: function( url ) { + return url.replace( /^#/, "" ); + }, + + //remove the preceding hash, any query params, and dialog notations + cleanHash: function( hash ) { + return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) ); + }, + + isHashValid: function( hash ) { + return ( /^#[^#]+$/ ).test( hash ); + }, + + //check whether a url is referencing the same domain, or an external domain or different protocol + //could be mailto, etc + isExternal: function( url ) { + var u = path.parseUrl( url ); + return u.protocol && u.domain !== documentUrl.domain ? true : false; + }, + + hasProtocol: function( url ) { + return ( /^(:?\w+:)/ ).test( url ); + }, + + //check if the specified url refers to the first page in the main application document. + isFirstPageUrl: function( url ) { + // We only deal with absolute paths. + var u = path.parseUrl( path.makeUrlAbsolute( url, documentBase ) ), + + // Does the url have the same path as the document? + samePath = u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ), + + // Get the first page element. + fp = $.mobile.firstPage, + + // Get the id of the first page element if it has one. + fpId = fp && fp[0] ? fp[0].id : undefined; + + // The url refers to the first page if the path matches the document and + // it either has no hash value, or the hash is exactly equal to the id of the + // first page element. + return samePath && ( !u.hash || u.hash === "#" || ( fpId && u.hash.replace( /^#/, "" ) === fpId ) ); + }, + + isEmbeddedPage: function( url ) { + var u = path.parseUrl( url ); + + //if the path is absolute, then we need to compare the url against + //both the documentUrl and the documentBase. The main reason for this + //is that links embedded within external documents will refer to the + //application document, whereas links embedded within the application + //document will be resolved against the document base. + if ( u.protocol !== "" ) { + return ( u.hash && ( u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ) ) ); + } + return ( /^#/ ).test( u.href ); + }, + + + // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR + // requests if the document doing the request was loaded via the file:// protocol. + // This is usually to allow the application to "phone home" and fetch app specific + // data. We normally let the browser handle external/cross-domain urls, but if the + // allowCrossDomainPages option is true, we will allow cross-domain http/https + // requests to go through our page loading logic. + isPermittedCrossDomainRequest: function( docUrl, reqUrl ) { + return $.mobile.allowCrossDomainPages && + docUrl.protocol === "file:" && + reqUrl.search( /^https?:/ ) !== -1; + } + }, + + //will be defined when a link is clicked and given an active class + $activeClickedLink = null, + + //urlHistory is purely here to make guesses at whether the back or forward button was clicked + //and provide an appropriate transition + urlHistory = { + // Array of pages that are visited during a single page load. + // Each has a url and optional transition, title, and pageUrl (which represents the file path, in cases where URL is obscured, such as dialogs) + stack: [], + + //maintain an index number for the active page in the stack + activeIndex: 0, + + //get active + getActive: function() { + return urlHistory.stack[ urlHistory.activeIndex ]; + }, + + getPrev: function() { + return urlHistory.stack[ urlHistory.activeIndex - 1 ]; + }, + + getNext: function() { + return urlHistory.stack[ urlHistory.activeIndex + 1 ]; + }, + + // addNew is used whenever a new page is added + addNew: function( url, transition, title, pageUrl, role ) { + //if there's forward history, wipe it + if ( urlHistory.getNext() ) { + urlHistory.clearForward(); + } + + urlHistory.stack.push( {url : url, transition: transition, title: title, pageUrl: pageUrl, role: role } ); + + urlHistory.activeIndex = urlHistory.stack.length - 1; + }, + + //wipe urls ahead of active index + clearForward: function() { + urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 ); + }, + + directHashChange: function( opts ) { + var back , forward, newActiveIndex, prev = this.getActive(); + + // check if url is in history and if it's ahead or behind current page + $.each( urlHistory.stack, function( i, historyEntry ) { + + //if the url is in the stack, it's a forward or a back + if ( decodeURIComponent( opts.currentUrl ) === decodeURIComponent( historyEntry.url ) ) { + //define back and forward by whether url is older or newer than current page + back = i < urlHistory.activeIndex; + forward = !back; + newActiveIndex = i; + } + }); + + // save new page index, null check to prevent falsey 0 result + this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex; + + if ( back ) { + ( opts.either || opts.isBack )( true ); + } else if ( forward ) { + ( opts.either || opts.isForward )( false ); + } + }, + + //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: false + }, + + //define first selector to receive focus when a page is shown + focusable = "[tabindex],a,button:visible,select:visible,input", + + //queue to hold simultanious page transitions + pageTransitionQueue = [], + + //indicates whether or not page is in process of transitioning + isPageTransitioning = false, + + //nonsense hash change key for dialogs, so they create a history entry + dialogHashKey = "&ui-state=dialog", + + //existing base tag? + $base = $head.children( "base" ), + + //tuck away the original document URL minus any fragment. + documentUrl = path.parseLocation(), + + //if the document has an embedded base tag, documentBase is set to its + //initial value. If a base tag does not exist, then we default to the documentUrl. + documentBase = $base.length ? path.parseUrl( path.makeUrlAbsolute( $base.attr( "href" ), documentUrl.href ) ) : documentUrl, + + //cache the comparison once. + documentBaseDiffers = ( documentUrl.hrefNoHash !== documentBase.hrefNoHash ), + + getScreenHeight = $.mobile.getScreenHeight; + + //base element management, defined depending on dynamic base tag support + var base = $.support.dynamicBaseTag ? { + + //define base element, for use in routing asset urls that are referenced in Ajax-requested markup + element: ( $base.length ? $base : $( "", { href: documentBase.hrefNoHash } ).prependTo( $head ) ), + + //set the generated BASE element's href attribute to a new page's base path + set: function( href ) { + base.element.attr( "href", path.makeUrlAbsolute( href, documentBase ) ); + }, + + //set the generated BASE element's href attribute to a new page's base path + reset: function() { + base.element.attr( "href", documentBase.hrefNoHash ); + } + + } : undefined; + + /* internal utility functions */ + + // NOTE Issue #4950 Android phonegap doesn't navigate back properly + // when a full page refresh has taken place. It appears that hashchange + // and replacestate history alterations work fine but we need to support + // both forms of history traversal in our code that uses backward history + // movement + $.mobile.back = function() { + var nav = window.navigator; + + // if the setting is on and the navigator object is + // available use the phonegap navigation capability + if( this.phonegapNavigationEnabled && + nav && + nav.app && + nav.app.backHistory ){ + nav.app.backHistory(); + } else { + window.history.back(); + } + }; + + //direct focus to the page title, or otherwise first focusable element + $.mobile.focusPage = function ( page ) { + var autofocus = page.find( "[autofocus]" ), + pageTitle = page.find( ".ui-title:eq(0)" ); + + if ( autofocus.length ) { + autofocus.focus(); + return; + } + + if ( pageTitle.length ) { + pageTitle.focus(); + } else{ + page.focus(); + } + }; + + //remove active classes after page transition or error + function removeActiveLinkClass( forceRemoval ) { + if ( !!$activeClickedLink && ( !$activeClickedLink.closest( "." + $.mobile.activePageClass ).length || forceRemoval ) ) { + $activeClickedLink.removeClass( $.mobile.activeBtnClass ); + } + $activeClickedLink = null; + } + + function releasePageTransitionLock() { + isPageTransitioning = false; + if ( pageTransitionQueue.length > 0 ) { + $.mobile.changePage.apply( null, pageTransitionQueue.pop() ); + } + } + + // Save the last scroll distance per page, before it is hidden + var setLastScrollEnabled = true, + setLastScroll, delayedSetLastScroll; + + setLastScroll = function() { + // this barrier prevents setting the scroll value based on the browser + // scrolling the window based on a hashchange + if ( !setLastScrollEnabled ) { + return; + } + + var active = $.mobile.urlHistory.getActive(); + + if ( active ) { + var lastScroll = $window.scrollTop(); + + // Set active page's lastScroll prop. + // If the location we're scrolling to is less than minScrollBack, let it go. + active.lastScroll = lastScroll < $.mobile.minScrollBack ? $.mobile.defaultHomeScroll : lastScroll; + } + }; + + // bind to scrollstop to gather scroll position. The delay allows for the hashchange + // event to fire and disable scroll recording in the case where the browser scrolls + // to the hash targets location (sometimes the top of the page). once pagechange fires + // getLastScroll is again permitted to operate + delayedSetLastScroll = function() { + setTimeout( setLastScroll, 100 ); + }; + + // disable an scroll setting when a hashchange has been fired, this only works + // because the recording of the scroll position is delayed for 100ms after + // the browser might have changed the position because of the hashchange + $window.bind( $.support.pushState ? "popstate" : "hashchange", function() { + setLastScrollEnabled = false; + }); + + // handle initial hashchange from chrome :( + $window.one( $.support.pushState ? "popstate" : "hashchange", function() { + setLastScrollEnabled = true; + }); + + // wait until the mobile page container has been determined to bind to pagechange + $window.one( "pagecontainercreate", function() { + // once the page has changed, re-enable the scroll recording + $.mobile.pageContainer.bind( "pagechange", function() { + + setLastScrollEnabled = true; + + // remove any binding that previously existed on the get scroll + // which may or may not be different than the scroll element determined for + // this page previously + $window.unbind( "scrollstop", delayedSetLastScroll ); + + // determine and bind to the current scoll element which may be the window + // or in the case of touch overflow the element with touch overflow + $window.bind( "scrollstop", delayedSetLastScroll ); + }); + }); + + // bind to scrollstop for the first page as "pagechange" won't be fired in that case + $window.bind( "scrollstop", delayedSetLastScroll ); + + // No-op implementation of transition degradation + $.mobile._maybeDegradeTransition = $.mobile._maybeDegradeTransition || function( transition ) { + return transition; + }; + + //function for transitioning between two existing pages + function transitionPages( toPage, fromPage, transition, reverse ) { + + if ( fromPage ) { + //trigger before show/hide events + fromPage.data( "page" )._trigger( "beforehide", null, { nextPage: toPage } ); + } + + toPage.data( "page" )._trigger( "beforeshow", null, { prevPage: fromPage || $( "" ) } ); + + //clear page loader + $.mobile.hidePageLoadingMsg(); + + transition = $.mobile._maybeDegradeTransition( transition ); + + //find the transition handler for the specified transition. If there + //isn't one in our transitionHandlers dictionary, use the default one. + //call the handler immediately to kick-off the transition. + var th = $.mobile.transitionHandlers[ transition || "default" ] || $.mobile.defaultTransitionHandler, + promise = th( transition, reverse, toPage, fromPage ); + + promise.done(function() { + + //trigger show/hide events + if ( fromPage ) { + fromPage.data( "page" )._trigger( "hide", null, { nextPage: toPage } ); + } + + //trigger pageshow, define prevPage as either fromPage or empty jQuery obj + toPage.data( "page" )._trigger( "show", null, { prevPage: fromPage || $( "" ) } ); + + setTimeout( function () { + $.mobile.removeEventBlocker(); + }, 0 ); + }); + + return promise; + } + + //shared page enhancements + function enhancePage( $page, role ) { + // If a role was specified, make sure the data-role attribute + // on the page element is in sync. + if ( role ) { + $page.attr( "data-" + $.mobile.ns + "role", role ); + } + + //run page plugin + $page.page(); + } + + /* exposed $.mobile methods */ + + //animation complete callback + $.fn.animationComplete = function( callback ) { + if ( $.support.cssTransitions ) { + return $( this ).one( 'webkitAnimationEnd animationend', callback ); + } + else{ + // defer execution for consistency between webkit/non webkit + setTimeout( callback, 0 ); + return $( this ); + } + }; + + //expose path object on $.mobile + $.mobile.path = path; + + //expose base object on $.mobile + $.mobile.base = base; + + //history stack + $.mobile.urlHistory = urlHistory; + + $.mobile.dialogHashKey = dialogHashKey; + + + + //enable cross-domain page support + $.mobile.allowCrossDomainPages = false; + + //return the original document url + $.mobile.getDocumentUrl = function( asParsedObject ) { + return asParsedObject ? $.extend( {}, documentUrl ) : documentUrl.href; + }; + + //return the original document base url + $.mobile.getDocumentBase = function( asParsedObject ) { + return asParsedObject ? $.extend( {}, documentBase ) : documentBase.href; + }; + + $.mobile._bindPageRemove = function() { + var page = $( this ); + + // when dom caching is not enabled or the page is embedded bind to remove the page on hide + if ( !page.data( "page" ).options.domCache && + page.is( ":jqmData(external-page='true')" ) ) { + + page.bind( 'pagehide.remove', function() { + var $this = $( this ), + prEvent = new $.Event( "pageremove" ); + + $this.trigger( prEvent ); + + if ( !prEvent.isDefaultPrevented() ) { + $this.removeWithDependents(); + } + }); + } + }; + + // Load a page into the DOM. + $.mobile.loadPage = function( url, options ) { + // This function uses deferred notifications to let callers + // know when the page is done loading, or if an error has occurred. + var deferred = $.Deferred(), + + // The default loadPage options with overrides specified by + // the caller. + settings = $.extend( {}, $.mobile.loadPage.defaults, options ), + + // The DOM element for the page after it has been loaded. + page = null, + + // If the reloadPage option is true, and the page is already + // in the DOM, dupCachedPage will be set to the page element + // so that it can be removed after the new version of the + // page is loaded off the network. + dupCachedPage = null, + + // determine the current base url + findBaseWithDefault = function() { + var closestBase = ( $.mobile.activePage && getClosestBaseUrl( $.mobile.activePage ) ); + return closestBase || documentBase.hrefNoHash; + }, + + // The absolute version of the URL passed into the function. This + // version of the URL may contain dialog/subpage params in it. + absUrl = path.makeUrlAbsolute( url, findBaseWithDefault() ); + + + // If the caller provided data, and we're using "get" request, + // append the data to the URL. + if ( settings.data && settings.type === "get" ) { + absUrl = path.addSearchParams( absUrl, settings.data ); + settings.data = undefined; + } + + // If the caller is using a "post" request, reloadPage must be true + if ( settings.data && settings.type === "post" ) { + settings.reloadPage = true; + } + + // The absolute version of the URL minus any dialog/subpage params. + // In otherwords the real URL of the page to be loaded. + var fileUrl = path.getFilePath( absUrl ), + + // The version of the Url actually stored in the data-url attribute of + // the page. For embedded pages, it is just the id of the page. For pages + // within the same domain as the document base, it is the site relative + // path. For cross-domain pages (Phone Gap only) the entire absolute Url + // used to load the page. + dataUrl = path.convertUrlToDataUrl( absUrl ); + + // Make sure we have a pageContainer to work with. + settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; + + // Check to see if the page already exists in the DOM. + // NOTE do _not_ use the :jqmData psuedo selector because parenthesis + // are a valid url char and it breaks on the first occurence + page = settings.pageContainer.children( "[data-" + $.mobile.ns +"url='" + dataUrl + "']" ); + + // If we failed to find the page, check to see if the url is a + // reference to an embedded page. If so, it may have been dynamically + // injected by a developer, in which case it would be lacking a data-url + // attribute and in need of enhancement. + if ( page.length === 0 && dataUrl && !path.isPath( dataUrl ) ) { + page = settings.pageContainer.children( "#" + dataUrl ) + .attr( "data-" + $.mobile.ns + "url", dataUrl ) + .jqmData( "url", dataUrl ); + } + + // If we failed to find a page in the DOM, check the URL to see if it + // refers to the first page in the application. If it isn't a reference + // to the first page and refers to non-existent embedded page, error out. + if ( page.length === 0 ) { + if ( $.mobile.firstPage && path.isFirstPageUrl( fileUrl ) ) { + // Check to make sure our cached-first-page is actually + // in the DOM. Some user deployed apps are pruning the first + // page from the DOM for various reasons, we check for this + // case here because we don't want a first-page with an id + // falling through to the non-existent embedded page error + // case. If the first-page is not in the DOM, then we let + // things fall through to the ajax loading code below so + // that it gets reloaded. + if ( $.mobile.firstPage.parent().length ) { + page = $( $.mobile.firstPage ); + } + } else if ( path.isEmbeddedPage( fileUrl ) ) { + deferred.reject( absUrl, options ); + return deferred.promise(); + } + } + + // If the page we are interested in is already in the DOM, + // and the caller did not indicate that we should force a + // reload of the file, we are done. Otherwise, track the + // existing page as a duplicated. + if ( page.length ) { + if ( !settings.reloadPage ) { + enhancePage( page, settings.role ); + deferred.resolve( absUrl, options, page ); + return deferred.promise(); + } + dupCachedPage = page; + } + + var mpc = settings.pageContainer, + pblEvent = new $.Event( "pagebeforeload" ), + triggerData = { url: url, absUrl: absUrl, dataUrl: dataUrl, deferred: deferred, options: settings }; + + // Let listeners know we're about to load a page. + mpc.trigger( pblEvent, triggerData ); + + // If the default behavior is prevented, stop here! + if ( pblEvent.isDefaultPrevented() ) { + return deferred.promise(); + } + + if ( settings.showLoadMsg ) { + + // This configurable timeout allows cached pages a brief delay to load without showing a message + var loadMsgDelay = setTimeout(function() { + $.mobile.showPageLoadingMsg(); + }, settings.loadMsgDelay ), + + // Shared logic for clearing timeout and removing message. + hideMsg = function() { + + // Stop message show timer + clearTimeout( loadMsgDelay ); + + // Hide loading message + $.mobile.hidePageLoadingMsg(); + }; + } + + // Reset base to the default document base. + if ( base ) { + base.reset(); + } + + if ( !( $.mobile.allowCrossDomainPages || path.isSameDomain( documentUrl, absUrl ) ) ) { + deferred.reject( absUrl, options ); + } else { + // Load the new page. + $.ajax({ + url: fileUrl, + type: settings.type, + data: settings.data, + dataType: "html", + success: function( html, textStatus, xhr ) { + //pre-parse html to check for a data-url, + //use it as the new fileUrl, base path, etc + var all = $( "
" ), + + //page title regexp + newPageTitle = html.match( /]*>([^<]*)/ ) && RegExp.$1, + + // TODO handle dialogs again + pageElemRegex = new RegExp( "(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>)" ), + dataUrlRegex = new RegExp( "\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?" ); + + + // data-url must be provided for the base tag so resource requests can be directed to the + // correct url. loading into a temprorary element makes these requests immediately + if ( pageElemRegex.test( html ) && + RegExp.$1 && + dataUrlRegex.test( RegExp.$1 ) && + RegExp.$1 ) { + url = fileUrl = path.getFilePath( $( "
" + RegExp.$1 + "
" ).text() ); + } + + if ( base ) { + base.set( fileUrl ); + } + + //workaround to allow scripts to execute when included in page divs + all.get( 0 ).innerHTML = html; + page = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first(); + + //if page elem couldn't be found, create one and insert the body element's contents + if ( !page.length ) { + page = $( "
" + html.split( /<\/?body[^>]*>/gmi )[1] + "
" ); + } + + if ( newPageTitle && !page.jqmData( "title" ) ) { + if ( ~newPageTitle.indexOf( "&" ) ) { + newPageTitle = $( "
" + newPageTitle + "
" ).text(); + } + page.jqmData( "title", newPageTitle ); + } + + //rewrite src and href attrs to use a base url + if ( !$.support.dynamicBaseTag ) { + var newPath = path.get( fileUrl ); + page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() { + var thisAttr = $( this ).is( '[href]' ) ? 'href' : + $( this ).is( '[src]' ) ? 'src' : 'action', + thisUrl = $( this ).attr( thisAttr ); + + // XXX_jblas: We need to fix this so that it removes the document + // base URL, and then prepends with the new page URL. + //if full path exists and is same, chop it - helps IE out + thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' ); + + if ( !/^(\w+:|#|\/)/.test( thisUrl ) ) { + $( this ).attr( thisAttr, newPath + thisUrl ); + } + }); + } + + //append to page and enhance + // TODO taging a page with external to make sure that embedded pages aren't removed + // by the various page handling code is bad. Having page handling code in many + // places is bad. Solutions post 1.0 + page + .attr( "data-" + $.mobile.ns + "url", path.convertUrlToDataUrl( fileUrl ) ) + .attr( "data-" + $.mobile.ns + "external-page", true ) + .appendTo( settings.pageContainer ); + + // wait for page creation to leverage options defined on widget + page.one( 'pagecreate', $.mobile._bindPageRemove ); + + enhancePage( page, settings.role ); + + // Enhancing the page may result in new dialogs/sub pages being inserted + // into the DOM. If the original absUrl refers to a sub-page, that is the + // real page we are interested in. + if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) { + page = settings.pageContainer.children( "[data-" + $.mobile.ns +"url='" + dataUrl + "']" ); + } + + //bind pageHide to removePage after it's hidden, if the page options specify to do so + + // Remove loading message. + if ( settings.showLoadMsg ) { + hideMsg(); + } + + // Add the page reference and xhr to our triggerData. + triggerData.xhr = xhr; + triggerData.textStatus = textStatus; + triggerData.page = page; + + // Let listeners know the page loaded successfully. + settings.pageContainer.trigger( "pageload", triggerData ); + + deferred.resolve( absUrl, options, page, dupCachedPage ); + }, + error: function( xhr, textStatus, errorThrown ) { + //set base back to current path + if ( base ) { + base.set( path.get() ); + } + + // Add error info to our triggerData. + triggerData.xhr = xhr; + triggerData.textStatus = textStatus; + triggerData.errorThrown = errorThrown; + + var plfEvent = new $.Event( "pageloadfailed" ); + + // Let listeners know the page load failed. + settings.pageContainer.trigger( plfEvent, triggerData ); + + // If the default behavior is prevented, stop here! + // Note that it is the responsibility of the listener/handler + // that called preventDefault(), to resolve/reject the + // deferred object within the triggerData. + if ( plfEvent.isDefaultPrevented() ) { + return; + } + + // Remove loading message. + if ( settings.showLoadMsg ) { + + // Remove loading message. + hideMsg(); + + // show error message + $.mobile.showPageLoadingMsg( $.mobile.pageLoadErrorMessageTheme, $.mobile.pageLoadErrorMessage, true ); + + // hide after delay + setTimeout( $.mobile.hidePageLoadingMsg, 1500 ); + } + + deferred.reject( absUrl, options ); + } + }); + } + + return deferred.promise(); + }; + + $.mobile.loadPage.defaults = { + type: "get", + data: undefined, + reloadPage: false, + role: undefined, // By default we rely on the role defined by the @data-role attribute. + showLoadMsg: false, + pageContainer: undefined, + loadMsgDelay: 50 // This delay allows loads that pull from browser cache to occur without showing the loading message. + }; + + // Show a specific page in the page container. + $.mobile.changePage = function( toPage, options ) { + // If we are in the midst of a transition, queue the current request. + // We'll call changePage() once we're done with the current transition to + // service the request. + if ( isPageTransitioning ) { + pageTransitionQueue.unshift( arguments ); + return; + } + + var settings = $.extend( {}, $.mobile.changePage.defaults, options ); + + // Make sure we have a pageContainer to work with. + settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; + + // Make sure we have a fromPage. + settings.fromPage = settings.fromPage || $.mobile.activePage; + + var mpc = settings.pageContainer, + pbcEvent = new $.Event( "pagebeforechange" ), + triggerData = { toPage: toPage, options: settings }; + + // Let listeners know we're about to change the current page. + mpc.trigger( pbcEvent, triggerData ); + + // If the default behavior is prevented, stop here! + if ( pbcEvent.isDefaultPrevented() ) { + return; + } + + // We allow "pagebeforechange" observers to modify the toPage in the trigger + // data to allow for redirects. Make sure our toPage is updated. + + toPage = triggerData.toPage; + + // Set the isPageTransitioning flag to prevent any requests from + // entering this method while we are in the midst of loading a page + // or transitioning. + + isPageTransitioning = true; + + // If the caller passed us a url, call loadPage() + // to make sure it is loaded into the DOM. We'll listen + // to the promise object it returns so we know when + // it is done loading or if an error ocurred. + if ( typeof toPage === "string" ) { + $.mobile.loadPage( toPage, settings ) + .done(function( url, options, newPage, dupCachedPage ) { + isPageTransitioning = false; + options.duplicateCachedPage = dupCachedPage; + $.mobile.changePage( newPage, options ); + }) + .fail(function( url, options ) { + isPageTransitioning = false; + + //clear out the active button state + removeActiveLinkClass( true ); + + //release transition lock so navigation is free again + releasePageTransitionLock(); + settings.pageContainer.trigger( "pagechangefailed", triggerData ); + }); + return; + } + + // If we are going to the first-page of the application, we need to make + // sure settings.dataUrl is set to the application document url. This allows + // us to avoid generating a document url with an id hash in the case where the + // first-page of the document has an id attribute specified. + if ( toPage[ 0 ] === $.mobile.firstPage[ 0 ] && !settings.dataUrl ) { + settings.dataUrl = documentUrl.hrefNoHash; + } + + // The caller passed us a real page DOM element. Update our + // internal state and then trigger a transition to the page. + var fromPage = settings.fromPage, + url = ( settings.dataUrl && path.convertUrlToDataUrl( settings.dataUrl ) ) || toPage.jqmData( "url" ), + // The pageUrl var is usually the same as url, except when url is obscured as a dialog url. pageUrl always contains the file path + pageUrl = url, + fileUrl = path.getFilePath( url ), + active = urlHistory.getActive(), + activeIsInitialPage = urlHistory.activeIndex === 0, + historyDir = 0, + pageTitle = document.title, + isDialog = settings.role === "dialog" || $.mobile.getAttrFixed( toPage [0], "data-" + $.mobile.ns + "role" ) === "dialog"; + + // By default, we prevent changePage requests when the fromPage and toPage + // are the same element, but folks that generate content manually/dynamically + // and reuse pages want to be able to transition to the same page. To allow + // this, they will need to change the default value of allowSamePageTransition + // to true, *OR*, pass it in as an option when they manually call changePage(). + // It should be noted that our default transition animations assume that the + // formPage and toPage are different elements, so they may behave unexpectedly. + // It is up to the developer that turns on the allowSamePageTransitiona option + // to either turn off transition animations, or make sure that an appropriate + // animation transition is used. + if ( fromPage && fromPage[0] === toPage[0] && !settings.allowSamePageTransition ) { + isPageTransitioning = false; + mpc.trigger( "pagechange", triggerData ); + + // Even if there is no page change to be done, we should keep the urlHistory in sync with the hash changes + if ( settings.fromHashChange ) { + urlHistory.directHashChange({ + currentUrl: url, + isBack: function() {}, + isForward: function() {} + }); + } + + return; + } + + // We need to make sure the page we are given has already been enhanced. + enhancePage( toPage, settings.role ); + + // If the changePage request was sent from a hashChange event, check to see if the + // page is already within the urlHistory stack. If so, we'll assume the user hit + // the forward/back button and will try to match the transition accordingly. + if ( settings.fromHashChange ) { + urlHistory.directHashChange({ + currentUrl: url, + isBack: function() { historyDir = -1; }, + isForward: function() { historyDir = 1; } + }); + } + + // Kill the keyboard. + // XXX_jblas: We need to stop crawling the entire document to kill focus. Instead, + // we should be tracking focus with a delegate() handler so we already have + // the element in hand at this point. + // Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement + // is undefined when we are in an IFrame. + try { + if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== 'body' ) { + $( document.activeElement ).blur(); + } else { + $( "input:focus, textarea:focus, select:focus" ).blur(); + } + } catch( e ) {} + + // Record whether we are at a place in history where a dialog used to be - if so, do not add a new history entry and do not change the hash either + var alreadyThere = false; + + // If we're displaying the page as a dialog, we don't want the url + // for the dialog content to be used in the hash. Instead, we want + // to append the dialogHashKey to the url of the current page. + if ( isDialog && active ) { + // on the initial page load active.url is undefined and in that case should + // be an empty string. Moving the undefined -> empty string back into + // urlHistory.addNew seemed imprudent given undefined better represents + // the url state + + // If we are at a place in history that once belonged to a dialog, reuse + // this state without adding to urlHistory and without modifying the hash. + // However, if a dialog is already displayed at this point, and we're + // about to display another dialog, then we must add another hash and + // history entry on top so that one may navigate back to the original dialog + if ( active.url.indexOf( dialogHashKey ) > -1 && !$.mobile.activePage.is( ".ui-dialog" ) ) { + settings.changeHash = false; + alreadyThere = true; + } + + // Normally, we tack on a dialog hash key, but if this is the location of a stale dialog, + // we reuse the URL from the entry + url = ( active.url || "" ) + ( alreadyThere ? "" : dialogHashKey ); + + // tack on another dialogHashKey if this is the same as the initial hash + // this makes sure that a history entry is created for this dialog + if ( urlHistory.activeIndex === 0 && url === urlHistory.initialDst ) { + url += dialogHashKey; + } + } + + // Set the location hash. + if ( settings.changeHash !== false && url ) { + //disable hash listening temporarily + urlHistory.ignoreNextHashChange = true; + //update hash and history + path.set( url ); + } + + // if title element wasn't found, try the page div data attr too + // If this is a deep-link or a reload ( active === undefined ) then just use pageTitle + var newPageTitle = ( !active )? pageTitle : toPage.jqmData( "title" ) || toPage.children( ":jqmData(role='header')" ).find( ".ui-title" ).getEncodedText(); + if ( !!newPageTitle && pageTitle === document.title ) { + pageTitle = newPageTitle; + } + if ( !toPage.jqmData( "title" ) ) { + toPage.jqmData( "title", pageTitle ); + } + + // Make sure we have a transition defined. + settings.transition = settings.transition || + ( ( historyDir && !activeIsInitialPage ) ? active.transition : undefined ) || + ( isDialog ? $.mobile.defaultDialogTransition : $.mobile.defaultPageTransition ); + + //add page to history stack if it's not back or forward + if ( !historyDir ) { + // Overwrite the current entry if it's a leftover from a dialog + if ( alreadyThere ) { + urlHistory.activeIndex = Math.max( 0, urlHistory.activeIndex - 1 ); + } + urlHistory.addNew( url, settings.transition, pageTitle, pageUrl, settings.role ); + } + + //set page title + document.title = urlHistory.getActive().title; + + //set "toPage" as activePage + $.mobile.activePage = toPage; + + // If we're navigating back in the URL history, set reverse accordingly. + settings.reverse = settings.reverse || historyDir < 0; + + transitionPages( toPage, fromPage, settings.transition, settings.reverse ) + .done(function( name, reverse, $to, $from, alreadyFocused ) { + removeActiveLinkClass(); + + //if there's a duplicateCachedPage, remove it from the DOM now that it's hidden + if ( settings.duplicateCachedPage ) { + settings.duplicateCachedPage.remove(); + } + + // Send focus to the newly shown page. Moved from promise .done binding in transitionPages + // itself to avoid ie bug that reports offsetWidth as > 0 (core check for visibility) + // despite visibility: hidden addresses issue #2965 + // https://github.com/jquery/jquery-mobile/issues/2965 + if ( !alreadyFocused ) { + $.mobile.focusPage( toPage ); + } + + releasePageTransitionLock(); + + // Let listeners know we're all done changing the current page. + mpc.trigger( "pagechange", triggerData ); + }); + }; + + $.mobile.changePage.defaults = { + transition: undefined, + reverse: false, + changeHash: true, + fromHashChange: false, + role: undefined, // By default we rely on the role defined by the @data-role attribute. + duplicateCachedPage: undefined, + pageContainer: undefined, + showLoadMsg: true, //loading message shows by default when pages are being fetched during changePage + dataUrl: undefined, + fromPage: undefined, + allowSamePageTransition: false + }; + +/* Event Bindings - hashchange, submit, and click */ + function findClosestLink( ele ) + { + while ( ele ) { + // Look for the closest element with a nodeName of "a". + // Note that we are checking if we have a valid nodeName + // before attempting to access it. This is because the + // node we get called with could have originated from within + // an embedded SVG document where some symbol instance elements + // don't have nodeName defined on them, or strings are of type + // SVGAnimatedString. + if ( ( typeof ele.nodeName === "string" ) && ele.nodeName.toLowerCase() === "a" ) { + break; + } + ele = ele.parentNode; + } + return ele; + } + + // The base URL for any given element depends on the page it resides in. + function getClosestBaseUrl( ele ) + { + // Find the closest page and extract out its url. + var url = $( ele ).closest( ".ui-page" ).jqmData( "url" ), + base = documentBase.hrefNoHash; + + if ( !url || !path.isPath( url ) ) { + url = base; + } + + return path.makeUrlAbsolute( url, base); + } + + //The following event bindings should be bound after mobileinit has been triggered + //the following deferred is resolved in the init file + $.mobile.navreadyDeferred = $.Deferred(); + $.mobile.navreadyDeferred.done(function() { + //bind to form submit events, handle with Ajax + $.mobile.$document.delegate( "form", "submit", function( event ) { + var $this = $( this ); + + if ( !$.mobile.ajaxEnabled || + // test that the form is, itself, ajax false + $this.is( ":jqmData(ajax='false')" ) || + // test that $.mobile.ignoreContentEnabled is set and + // the form or one of it's parents is ajax=false + !$this.jqmHijackable().length ) { + return; + } + + var type = $this.attr( "method" ), + target = $this.attr( "target" ), + url = $this.attr( "action" ); + + // If no action is specified, browsers default to using the + // URL of the document containing the form. Since we dynamically + // pull in pages from external documents, the form should submit + // to the URL for the source document of the page containing + // the form. + if ( !url ) { + // Get the @data-url for the page containing the form. + url = getClosestBaseUrl( $this ); + if ( url === documentBase.hrefNoHash ) { + // The url we got back matches the document base, + // which means the page must be an internal/embedded page, + // so default to using the actual document url as a browser + // would. + url = documentUrl.hrefNoSearch; + } + } + + url = path.makeUrlAbsolute( url, getClosestBaseUrl( $this ) ); + + if ( ( path.isExternal( url ) && !path.isPermittedCrossDomainRequest( documentUrl, url ) ) || target ) { + return; + } + + $.mobile.changePage( + url, + { + type: type && type.length && type.toLowerCase() || "get", + data: $this.serialize(), + transition: $.mobile.getAttrFixed( $this [0], "data-" + $.mobile.ns + "transition" ), + reverse: $.mobile.getAttrFixed( $this [0], "data-" + $.mobile.ns + "direction" ) === "reverse", + reloadPage: true + } + ); + event.preventDefault(); + }); + + //add active state on vclick + $.mobile.$document.bind( "vclick", function( event ) { + // if this isn't a left click we don't care. Its important to note + // that when the virtual event is generated it will create the which attr + if ( event.which > 1 || !$.mobile.linkBindingEnabled ) { + return; + } + + var link = findClosestLink( event.target ); + + // split from the previous return logic to avoid find closest where possible + // TODO teach $.mobile.hijackable to operate on raw dom elements so the link wrapping + // can be avoided + if ( !$( link ).jqmHijackable().length ) { + return; + } + + if ( link ) { + if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) { + removeActiveLinkClass( true ); + $activeClickedLink = $( link ).closest( ".ui-btn" ).not( ".ui-disabled" ); + $activeClickedLink.addClass( $.mobile.activeBtnClass ); + } + } + }); + + // click routing - direct to HTTP or Ajax, accordingly + $.mobile.$document.bind( "click", function( event ) { + if ( !$.mobile.linkBindingEnabled ) { + return; + } + + var link = findClosestLink( event.target ), $link = $( link ), httpCleanup; + + // If there is no link associated with the click or its not a left + // click we want to ignore the click + // TODO teach $.mobile.hijackable to operate on raw dom elements so the link wrapping + // can be avoided + if ( !link || event.which > 1 || !$link.jqmHijackable().length ) { + return; + } + + //remove active link class if external (then it won't be there if you come back) + httpCleanup = function() { + window.setTimeout(function() { removeActiveLinkClass( true ); }, 200 ); + }; + + //if there's a data-rel=back attr, go back in history + if ( $link.is( ":jqmData(rel='back')" ) ) { + $.mobile.back(); + return false; + } + + var baseUrl = getClosestBaseUrl( $link ), + + //get href, if defined, otherwise default to empty hash + href = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl ); + + //if ajax is disabled, exit early + if ( !$.mobile.ajaxEnabled && !path.isEmbeddedPage( href ) ) { + httpCleanup(); + //use default click handling + return; + } + + // XXX_jblas: Ideally links to application pages should be specified as + // an url to the application document with a hash that is either + // the site relative path or id to the page. But some of the + // internal code that dynamically generates sub-pages for nested + // lists and select dialogs, just write a hash in the link they + // create. This means the actual URL path is based on whatever + // the current value of the base tag is at the time this code + // is called. For now we are just assuming that any url with a + // hash in it is an application page reference. + if ( href.search( "#" ) !== -1 ) { + href = href.replace( /[^#]*#/, "" ); + if ( !href ) { + //link was an empty hash meant purely + //for interaction, so we ignore it. + event.preventDefault(); + return; + } else if ( path.isPath( href ) ) { + //we have apath so make it the href we want to load. + href = path.makeUrlAbsolute( href, baseUrl ); + } else { + //we have a simple id so use the documentUrl as its base. + href = path.makeUrlAbsolute( "#" + href, documentUrl.hrefNoHash ); + } + } + + // Should we handle this link, or let the browser deal with it? + var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ), + + // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR + // requests if the document doing the request was loaded via the file:// protocol. + // This is usually to allow the application to "phone home" and fetch app specific + // data. We normally let the browser handle external/cross-domain urls, but if the + // allowCrossDomainPages option is true, we will allow cross-domain http/https + // requests to go through our page loading logic. + + //check for protocol or rel and its not an embedded page + //TODO overlap in logic from isExternal, rel=external check should be + // moved into more comprehensive isExternalLink + isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !path.isPermittedCrossDomainRequest( documentUrl, href ) ); + + if ( isExternal ) { + httpCleanup(); + //use default click handling + return; + } + + //use ajax + var transition = $.mobile.getAttrFixed( $link [0], "data-" + $.mobile.ns + "transition" ), + reverse = $.mobile.getAttrFixed( $link [0], "data-" + $.mobile.ns + "direction" ) === "reverse" || + // deprecated - remove by 1.0 + $.mobile.getAttrFixed( $link [0], "data-" + $.mobile.ns + "back" ), + + //this may need to be more specific as we use data-rel more + role = $link.attr( "data-" + $.mobile.ns + "rel" ) || undefined; + + $.mobile.changePage( href, { transition: transition, reverse: reverse, role: role, link: $link } ); + event.preventDefault(); + }); + + //prefetch pages when anchors with data-prefetch are encountered + $.mobile.$document.delegate( ".ui-page", "pageshow.prefetch", function() { + var urls = []; + $( this ).find( "a:jqmData(prefetch)" ).each(function() { + var $link = $( this ), + url = $link.attr( "href" ); + + if ( url && $.inArray( url, urls ) === -1 ) { + urls.push( url ); + + $.mobile.loadPage( url, { role: $link.attr( "data-" + $.mobile.ns + "rel" ) } ); + } + }); + }); + + $.mobile._handleHashChange = function( hash ) { + //find first page via hash + var to = path.stripHash( hash ), + //transition is false if it's the first page, undefined otherwise (and may be overridden by default) + transition = $.mobile.urlHistory.stack.length === 0 ? "none" : undefined, + + // "navigate" event fired to allow others to take advantage of the more robust hashchange handling + navEvent = new $.Event( "navigate" ), + + // default options for the changPage calls made after examining the current state + // of the page and the hash + changePageOptions = { + transition: transition, + changeHash: false, + fromHashChange: true + }; + + if ( 0 === urlHistory.stack.length ) { + urlHistory.initialDst = to; + } + + // We should probably fire the "navigate" event from those places that make calls to _handleHashChange, + // and have _handleHashChange hook into the "navigate" event instead of triggering it here + $.mobile.pageContainer.trigger( navEvent ); + if ( navEvent.isDefaultPrevented() ) { + return; + } + + //if listening is disabled (either globally or temporarily), or it's a dialog hash + if ( !$.mobile.hashListeningEnabled || urlHistory.ignoreNextHashChange ) { + urlHistory.ignoreNextHashChange = false; + return; + } + + // special case for dialogs + if ( urlHistory.stack.length > 1 && to.indexOf( dialogHashKey ) > -1 && urlHistory.initialDst !== to ) { + + // If current active page is not a dialog skip the dialog and continue + // in the same direction + if ( !$.mobile.activePage.is( ".ui-dialog" ) ) { + //determine if we're heading forward or backward and continue accordingly past + //the current dialog + urlHistory.directHashChange({ + currentUrl: to, + isBack: function() { $.mobile.back(); }, + isForward: function() { window.history.forward(); } + }); + + // prevent changePage() + return; + } else { + // if the current active page is a dialog and we're navigating + // to a dialog use the dialog objected saved in the stack + urlHistory.directHashChange({ + currentUrl: to, + + // regardless of the direction of the history change + // do the following + either: function( isBack ) { + var active = $.mobile.urlHistory.getActive(); + + to = active.pageUrl; + + // make sure to set the role, transition and reversal + // as most of this is lost by the domCache cleaning + $.extend( changePageOptions, { + role: active.role, + transition: active.transition, + reverse: isBack + }); + } + }); + } + } + + //if to is defined, load it + if ( to ) { + // At this point, 'to' can be one of 3 things, a cached page element from + // a history stack entry, an id, or site-relative/absolute URL. If 'to' is + // an id, we need to resolve it against the documentBase, not the location.href, + // since the hashchange could've been the result of a forward/backward navigation + // that crosses from an external page/dialog to an internal page/dialog. + to = ( typeof to === "string" && !path.isPath( to ) ) ? ( path.makeUrlAbsolute( '#' + to, documentBase ) ) : to; + + // If we're about to go to an initial URL that contains a reference to a non-existent + // internal page, go to the first page instead. We know that the initial hash refers to a + // non-existent page, because the initial hash did not end up in the initial urlHistory entry + if ( to === path.makeUrlAbsolute( '#' + urlHistory.initialDst, documentBase ) && + urlHistory.stack.length && urlHistory.stack[0].url !== urlHistory.initialDst.replace( dialogHashKey, "" ) ) { + to = $.mobile.firstPage; + } + $.mobile.changePage( to, changePageOptions ); + } else { + //there's no hash, go to the first page in the dom + $.mobile.changePage( $.mobile.firstPage, changePageOptions ); + } + }; + + //hashchange event handler + $window.bind( "hashchange", function( e, triggered ) { + // Firefox auto-escapes the location.hash as for v13 but + // leaves the href untouched + $.mobile._handleHashChange( path.parseLocation().hash ); + }); + + });//navreadyDeferred done callback + +})( jQuery ); +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +}); +//>>excludeEnd("jqmBuildExclude"); diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.tizen.pinch.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.tizen.pinch.js new file mode 100644 index 0000000..0213c7b --- /dev/null +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/jquery.mobile.tizen.pinch.js @@ -0,0 +1,173 @@ + +/* *************************************************************************** + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * *************************************************************************** + * + * Author: Minkyu Kang + */ + +/* + * Pinch Event + * + * Events + * pinchstart: triggered when start the touched two points + * pinch: triggered when move the touch point after pinchstart event occured + * pinchend: triggered when touchend event after pinchstart event occured + * + * Parameters + * point: touched points + * ratio: origin point-to-current point ratio for moving distance + * + * $("#pinch").bind("pinch", function (e, p) { + * console.log("point[0].x: " + p.point[0].x); + * console.log("point[0].y: " + p.point[0].y); + * console.log("point[1].x: " + p.point[1].x); + * console.log("point[1].y: " + p.point[1].y); + * console.log("ratio: " + p.ratio); + * }); + * + * Options + * $.mobile.pinch.enabled: true or false + * $.mobile.pinch.min: minimum value of ratio + * $.mobile.pinch.max: maximum value of ratio + * $.mobile.pinch.factor: scale factor of ratio + * $.mobile.pinch.threshold: move threshold of ratio + * $.mobile.pinch.interval: interval for pinch event + */ + +( function( $, window, undefined ) { + +pinch_event = { + setup: function () { + var thisObject = this, + $this = $( thisObject ); + + if ( !$.mobile.support.touch ) { + return; + } + + function getDistance( point ) { + var x = point[0].x - point[1].x, + y = point[0].y - point[0].y; + + return Math.sqrt( ( x * x ) + ( y * y ) ); + } + + function getParameter( point, ratio ) { + return { point: point, ratio: ratio }; + } + + $this.bind( "touchstart", function ( event ) { + var data = event.originalEvent.touches, + origin, + last_ratio = 1, + processing = false; + + if ( !$.mobile.pinch.enabled ) { + return; + } + + if ( data.length != 2 ) { + return; + } + + origin = [ + { x: data[0].pageX, y: data[0].pageY }, + { x: data[1].pageX, y: data[1].pageY } + ]; + + $( event.target ).trigger( "pinchstart", getParameter( origin, undefined ) ); + + function pinchHandler( event ) { + var data = event.originalEvent.touches, + current, + ratio, + delta, + factor = $( window ).width() / $.mobile.pinch.factor; + + if ( processing ) { + return; + } + + if ( !origin ) { + return; + } + + current = [ + { x: data[0].pageX, y: data[0].pageY }, + { x: data[1].pageX, y: data[1].pageY } + ]; + + delta = getDistance( current ) - getDistance( origin ); + + ratio = 1 + delta / factor; + + if ( ratio < $.mobile.pinch.min ) { + ratio = $.mobile.pinch.min; + } else if ( ratio > $.mobile.pinch.max ) { + ratio = $.mobile.pinch.max; + } + + if ( Math.abs( ratio - last_ratio ) < $.mobile.pinch.threshold ) { + return; + } + + $( event.target ).trigger( "pinch", getParameter( current, ratio ) ); + + last_ratio = ratio; + + if ( $.mobile.pinch.interval ) { + processing = true; + + setTimeout( function () { + processing = false; + }, $.mobile.pinch.interval ); + } + } + + $this.bind( "touchmove", pinchHandler ) + .one( "touchend", function ( event ) { + $this.unbind( "touchmove", pinchHandler ); + $( event.target ).trigger( "pinchend", + getParameter( undefined, last_ratio ) ); + + origin = undefined; + current = undefined; + last_ratio = 1; + processing = false; + }); + }); + } +}; + +$.event.special["pinch"] = pinch_event; + +$.mobile.pinch = { + enabled: true, + min: 0.1, + max: 3, + factor: 4, + threshold: 0.01, + interval: 50 +}; + +})( jQuery, this ); + diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.datetimepicker.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.datetimepicker.js index 1101fc1..58860ac 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.datetimepicker.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.datetimepicker.js @@ -709,6 +709,13 @@ $( $li[current] ).addClass("current"); $div.jqmData( "list", $li ); $div.circularview(); + if( !obj._reflow ) { + obj._reflow = function() { + $div.circularview( "reflow" ); + $div.circularview( 'centerTo', '.current', 0 ); + } + $(window).bind( "resize" , obj._reflow ); + } // cause ctxpopup forced to subtract 10 if ( $( window ).width() / 2 < target.offset().left ) { newLeft = -10; diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.gallery.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.gallery.js index 68c3800..b0cac08 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.gallery.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.gallery.js @@ -240,7 +240,6 @@ obj.css( "display", "block" ); obj.append( this.images[index] ); - loading(); }, @@ -446,6 +445,24 @@ this.container.unbind( 'vmouseup' ); this.container.unbind( 'vmouseout' ); }, + _setTranslateposition : function ( $ele, value ) { + var translate, + cssArray = null; + + if ( $.support.cssTransform3d ) { + translate = "translate3d(" + value + ", 0px, 0px)"; + } else { + translate = "translate(" + value + ", 0px)"; + } + cssArray = {"-moz-transform": translate, + "-webkit-transform": translate, + "-ms-transform": translate, + "-o-transform": translate, + "transform": translate}; + + $ele.css(cssArray); + return $ele; + }, _moveLeft : function ( $ele , value , duration) { var translate, transition = "", @@ -456,7 +473,7 @@ } else { translate = "translate(" + value + ", 0px)"; } - if( !duration || duration !== undefined ) { + if( duration !== undefined ) { transition = "-webkit-transform " + (duration / 1000)+ "s ease"; } cssArray = {"-moz-transform": translate, @@ -487,12 +504,12 @@ this._attach( this.index + 1, this.next_img ); if ( this.prev_img.length ) { - this._moveLeft( this.prev_img, -this.window_width + 'px'); + this._setTranslateposition( this.prev_img, -this.window_width + 'px'); } this._moveLeft( this.cur_img, '0px'); if ( this.next_img.length ) { - this._moveLeft( this.next_img, this.window_width + 'px' ); + this._setTranslateposition( this.next_img, this.window_width + 'px' ); } }, diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.multimediaview.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.multimediaview.js index 67c430c..094660e 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.multimediaview.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.multimediaview.js @@ -284,7 +284,7 @@ }; } docWidth = body.clientWidth; - docHeight = body.clientHeight; + docHeight = body.clientHeight - 1; header.hide(); footer.hide(); @@ -294,15 +294,10 @@ .siblings() .addClass( "ui-multimediaview-siblings-off" ); }); - this._fitContentArea( currentPage ); fullscreenButton.removeClass( "ui-fullscreen-on" ).addClass( "ui-fullscreen-off" ); - view.width( docWidth ).height( docHeight - 1 ); - wrap.height( docHeight - 1 ); - view.offset( { - top: 0, - left: 0 - }).addClass( "ui-multimediaview-fullscreen" ); + wrap.height( docHeight ); + view.width( docWidth ).height( docHeight ); } else { if ( !self.backupView ) { return; @@ -316,7 +311,7 @@ .siblings() .removeClass( "ui-multimediaview-siblings-off" ); }); - this._fitContentArea( currentPage ); + fullscreenButton.removeClass( "ui-fullscreen-off" ).addClass( "ui-fullscreen-on" ); wrap.css( "height", self.backupView.wrapHeight ); @@ -325,8 +320,10 @@ "height": self.backupView.height, "position": self.backupView.position, "z-index": self.backupView.zindex - }).removeClass( "ui-multimediaview-fullscreen" ); + }); self.backupView = null; + + $( window ).trigger( "throttledresize" ); } }, @@ -351,51 +348,6 @@ currenttimeBar = seekBar.find( ".ui-currenttime" ), $document = $( document ); - $document.unbind( ".multimediaview" ).bind( "pagechange.multimediaview", function ( e ) { - var $page = $( e.target ); - if ( $page.find( view ).length > 0 && viewElement.autoplay ) { - viewElement.play(); - } - - if ( option.controls ) { - self._resize(); - } - }).bind( "pagebeforechange.multimediaview", function ( e ) { - if ( option.fullScreen ) { - self.fullScreen( !option.fullScreen ); - } - - if ( viewElement.played.length !== 0 ) { - viewElement.pause(); - } - }); - - $( window ).unbind( ".multimediaview" ).bind( "resize.multimediaview orientationchange.multimediaview", function ( e ) { - if ( !option.controls ) { - return; - } - var $page = $( e.target ), - $scrollview = view.parents( ".ui-scrollview-clip" ); - - $scrollview.each( function ( i ) { - if ( $.data( this, "scrollview" ) ) { - $( this ).scrollview( "scrollTo", 0, 0 ); - } - }); - - // for maintaining page layout - if ( !option.fullScreen ) { - $( ".ui-footer:visible" ).show(); - } else { - $( ".ui-footer" ).hide(); - self._fitContentArea( $page ); - } - - if ( control.css( "display" ) !== "none" ) { - self._resize(); - } - }); - view.bind( "loadedmetadata.multimediaview", function ( e ) { if ( !isNaN( viewElement.duration ) ) { durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) ); @@ -465,9 +417,7 @@ fullscreenButton.bind( "click.multimediaview", function ( e ) { e.preventDefault(); self.fullScreen( !self.options.fullScreen ); - control.fadeIn( "fast", function () { - self._resize(); - }); + self._resize(); self._endTimer(); e.stopPropagation(); }); @@ -575,7 +525,7 @@ var view = this.element, viewElement = view[0], control = $( "" ).addClass( "ui-multimediaview-control" ), - playpauseButton = $( "" ).addClass( "ui-playpausebutton ui-button" ), + playpauseButton = $( "" ).addClass( "ui-playpausebutton ui-button ui-play-icon" ), seekBar = $( "" ).addClass( "ui-seekbar ui-multimediaview-bar" ), timestampLabel = $( "

00:00:00

" ).addClass( "ui-timestamplabel" ), durationLabel = $( "

00:00:00

" ).addClass( "ui-durationlabel" ), @@ -591,7 +541,6 @@ seekBar.append( durationBar ).append( currenttimeBar ).append( durationLabel ).append( timestampLabel ); - playpauseButton.addClass( "ui-play-icon" ); volumeButton.addClass( viewElement.muted ? "ui-mute-icon" : "ui-volume-icon" ); volumeBar.append( volumeGuide ).append( volumeValue ).append( volumeHandle ); volumeControl.append( volumeBar ); @@ -711,25 +660,6 @@ viewElement.volume = value; }, - _fitContentArea: function ( page, parent ) { - if ( typeof parent === "undefined" ) { - parent = window; - } - - var $page = $( page ), - $content = $( ".ui-content:visible:first" ), - hh = $( ".ui-header:visible" ).outerHeight() || 0, - fh = $( ".ui-footer:visible" ).outerHeight() || 0, - pt = parseFloat( $content.css( "padding-top" ) ), - pb = parseFloat( $content.css( "padding-bottom" ) ), - wh = ( ( parent === window ) ? window.innerHeight : $( parent ).height() ), - height = wh - ( hh + fh ) - ( pt + pb ); - - $content.offset( { - top: ( hh + pt ) - }).height( height ); - }, - width: function ( value ) { if ( this.options.fullScreen ) { return; @@ -791,6 +721,35 @@ $( document ).bind( "pagecreate create", function ( e ) { $.tizen.multimediaview.prototype.enhanceWithin( e.target ); + }).bind( "pagechange", function ( e ) { + $( e.target ).find( ".ui-multimediaview" ).each( function () { + var view = $( this ), + viewElement = view[0]; + + if ( viewElement.autoplay ) { + viewElement.play(); + } + view.multimediaview( "refresh" ); + }); + }).bind( "pagebeforechange", function ( e ) { + $( e.target ).find( ".ui-multimediaview" ).each( function () { + var view = $( this ), + viewElement = view[0], + isFullscreen = view.multimediaview( "fullScreen" ); + + if ( isFullscreen ) { + view.multimediaview( "fullScreen", !isFullscreen ); + } + + if ( viewElement.played.length !== 0 ) { + viewElement.pause(); + } + }); }); + + $( window ).bind( "resize orientationchange", function ( e ) { + $( ".ui-page-active" ).find( ".ui-multimediaview" ).multimediaview( "refresh" ); + }); + } ( jQuery, document, window ) ); diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.pagelayout.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.pagelayout.js index c1f427b..3283b24 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.pagelayout.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.pagelayout.js @@ -245,13 +245,10 @@ if ( e.state == "on" ) { if ( !$elPage.find( ".ui-" + backBtnPosition + " .ui-btn-footer-down" ).length ) { $elDownBtn.buttonMarkup( { icon: "down" } ).appendTo( $elPage.find( ".ui-" + backBtnPosition ) ); - $( ".ui-btn-footer-down" ).bind( "vclick", function ( ) { - $elPage.find( "input" ).blur(); - }); } - $( ".ui-page-active .ui-btn-back" ).remove(); + $( ".ui-page-active .ui-btn-back" ).hide(); } else if ( e.state == "off" ) { - $elPage.page( "addBackBtn", backBtnPosition ); + $( ".ui-page-active .ui-btn-back" ).show(); $( ".ui-btn-footer-down" ).remove(); } } @@ -275,9 +272,16 @@ $elHeader = $elPage.find( ":jqmData(role='header')" ), $elFooter = $elPage.find( ":jqmData(role='footer')" ), $elContent = $elPage.find( ":jqmData(role='content')" ), - resultMinHeight; + resultMinHeight, + dpr = 1, + layoutInnerHeight = window.innerHeight; - resultMinHeight = window.innerHeight - $elHeader.height() - $elFooter.height(); + if ( !$.support.scrollview ) { + dpr = window.outerWidth / window.innerWidth; + layoutInnerHeight = Math.floor( window.outerHeight / dpr ); + } + + resultMinHeight = layoutInnerHeight - $elHeader.height() - $elFooter.height(); $elContent.css( "min-height", resultMinHeight - parseFloat( $elContent.css("padding-top") ) - parseFloat( $elContent.css("padding-bottom") ) + "px" ); }, @@ -323,7 +327,9 @@ $elContent = $elPage.find( ":jqmData(role='content')" ), resultContentHeight = 0, resultFooterHeight = 0, - resultHeaderHeight = 0; + resultHeaderHeight = 0, + layoutInnerHeight = window.innerHeight, + dpr = 1; if ( $elPage.length ) { $elFooter = $elPage.find( ":jqmData(role='footer')" ); @@ -339,7 +345,12 @@ $elFooter.css( "bottom", 0 ); } - resultContentHeight = window.innerHeight - resultFooterHeight - resultHeaderHeight; + if ( !$.support.scrollview ) { + dpr = window.outerWidth / window.innerWidth; + layoutInnerHeight = Math.floor( window.outerHeight / dpr ); + } + + resultContentHeight = layoutInnerHeight - resultFooterHeight - resultHeaderHeight; if ( $.support.scrollview ) { $elContent.height( resultContentHeight - diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.searchbar.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.searchbar.js index 63b0e5e..7f5f131 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.searchbar.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/src/widgets/jquery.mobile.tizen.searchbar.js @@ -174,6 +174,7 @@ .appendTo( focusedEl.parent() ) .buttonMarkup( { icon: IconStyle, + iconpos: "notext", corners: true, shadow: true } ); diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js index 65be3fb..1bbbeba 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js @@ -687,7 +687,7 @@ jQuery.extend( jQuery.easing, } })( jQuery ); /* -* jQuery Mobile Framework Git Build: SHA1: c0250ad99ccee0a2f9d32bf15956115bb9fe45b8 <> Date: Wed Apr 3 22:50:40 2013 +0900 +* jQuery Mobile Framework Git Build: SHA1: 47569f70c0fea5edd17ea08af7efdfbbf8a4ad7c <> Date: Fri Apr 5 16:34:44 2013 +0900 * http://jquerymobile.com * * Copyright 2012 jQuery Foundation and other contributors @@ -4336,6 +4336,10 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau if ( !settings.reloadPage ) { enhancePage( page, settings.role ); deferred.resolve( absUrl, options, page ); + //if we are reloading the page make sure we update the base if its not a prefetch + if( base && !options.prefetch ){ + base.set(url); + } return deferred.promise(); } dupCachedPage = page; @@ -4372,7 +4376,8 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau } // Reset base to the default document base. - if ( base ) { + // only reset if we are not prefetching + if ( base && typeof options.prefetch === "undefined" ) { base.reset(); } @@ -4407,7 +4412,8 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau url = fileUrl = path.getFilePath( $( "
" + RegExp.$1 + "
" ).text() ); } - if ( base ) { + //dont update the base tag if we are prefetching + if ( base && typeof options.prefetch === "undefined") { base.set( fileUrl ); } @@ -5015,7 +5021,7 @@ $.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defau if ( url && $.inArray( url, urls ) === -1 ) { urls.push( url ); - $.mobile.loadPage( url, { role: $link.attr( "data-" + $.mobile.ns + "rel" ) } ); + $.mobile.loadPage( url, { role: $link.attr( "data-" + $.mobile.ns + "rel" ),prefetch: true } ); } }); }); diff --git a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js index 6838923..689eca2 100644 --- a/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js +++ b/org.tizen.common.verrari/templates/cli/tizenwebuifw-common-resources/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js @@ -45,7 +45,7 @@ jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeO * http://jquery.org/license */(function(a,b){function m(b,c,d,e){var h={data:e||e===0||e===!1?e:c?c.data:{},_wrap:c?c._wrap:null,tmpl:null,parent:c||null,nodes:[],calls:u,nest:v,wrap:w,html:x,update:y};return b&&a.extend(h,b,{nodes:[],parent:c}),d&&(h.tmpl=d,h._ctnt=h._ctnt||h.tmpl(a,h),h.key=++j,(l.length?g:f)[j]=h),h}function n(b,c,e){var f,g=e?a.map(e,function(a){return typeof a=="string"?b.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+b.key+'" $2'):a:n(a,b,a._ctnt)}):b;return c?g:(g=g.join(""),g.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(b,c,d,e){f=a(d).get(),t(f),c&&(f=o(c).concat(f)),e&&(f=f.concat(o(e)))}),f?f:o(g))}function o(b){var c=document.createElement("div");return c.innerHTML=b,a.makeArray(c.childNodes)}function p(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(b,c,d,e,f,g,h){var i=a.tmpl.tag[d],j,k,l;if(!i)throw"Unknown template tag: "+d;return j=i._default||[],g&&!/\w$/.test(f)&&(f+=g,g=""),f?(f=r(f),h=h?","+r(h)+")":g?")":"",k=g?f.indexOf(".")>-1?f+r(g):"("+f+").call($item"+h:f,l=g?k:"(typeof("+f+")==='function'?("+f+").call($item):("+f+"))"):l=k=j.$1||"null",e=r(e),"');"+i[c?"close":"open"].split("$notnull_1").join(f?"typeof("+f+")!=='undefined' && ("+f+")!=null":"true").split("$1a").join(l).split("$1").join(k).split("$2").join(e||j.$2||"")+"__.push('"})+"');}return __;")}function q(b,c){b._wrap=n(b,!0,a.isArray(c)?c:[e.test(c)?c:a(c).html()]).join("")}function r(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(a){var b=document.createElement("div");return b.appendChild(a.cloneNode(!0)),b.innerHTML}function t(b){function p(b){function p(a){a+=c,n=i[a]=i[a]||m(n,f[n.parent.key+c]||n.parent)}var e,h=b,l,n,o;if(o=b.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(e=h.getAttribute(d)));e!==o&&(h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0,(n=f[o])||(n=g[o],n=m(n,f[h]||g[h]),n.key=++j,f[j]=n),k&&p(o)),b.removeAttribute(d)}else k&&(n=a.data(b,"tmplItem"))&&(p(n.key),f[n.key]=n,h=a.data(b.parentNode,"tmplItem"),h=h?h.key:0);if(n){l=n;while(l&&l.key!=h)l.nodes.push(b),l=l.parent;delete n._ctnt,delete n._wrap,a.data(b,"tmplItem",n)}}var c="_"+k,e,h,i={},l,n,o;for(l=0,n=b.length;l=0;o--)p(h[o]);p(e)}}function u(a,b,c,d){if(!a)return l.pop();l.push({_:a,tmpl:b,item:this,data:c,options:d})}function v(b,c,d){return a.tmpl(a.template(b),c,d,this)}function w(b,c){var d=b.options||{};return d.wrapped=c,a.tmpl(a.template(b.tmpl),b.data,d,b.item)}function x(b,c){var d=this._wrap;return a.map(a(a.isArray(d)?d.join(""):d).filter(b||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function y(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]),a(b).remove()}var c=a.fn.domManip,d="_tmplitem",e=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,f={},g={},h,i={key:0,data:{}},j=0,k=0,l=[];a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(b,c){a.fn[b]=function(d){var e=[],g=a(d),i,j,l,m,n=this.length===1&&this[0].parentNode;h=f||{};if(n&&n.nodeType===11&&n.childNodes.length===1&&g.length===1)g[c](this[0]),e=this;else{for(j=0,l=g.length;j0?this.clone(!0):this).get(),a(g[j])[c](i),e=e.concat(i);k=0,e=this.pushStack(e,b,g.selector)}return m=h,h=null,a.tmpl.complete(m),e}}),a.fn.extend({tmpl:function(b,c,d){return a.tmpl(this[0],b,c,d)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(b,d,e,g){if(b[0]&&a.isArray(b[0])){var i=a.makeArray(arguments),j=b[0],l=j.length,m=0,n;while(m").join(">").split('"').join(""").split("'").join("'")}}),a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(a){f={}},afterManip:function(c,d,e){var f=d.nodeType===11?a.makeArray(d.childNodes):d.nodeType===1?[d]:[];e.call(c,d),t(f),k++}})})(jQuery); /* -* jQuery Mobile Framework Git Build: SHA1: c0250ad99ccee0a2f9d32bf15956115bb9fe45b8 <> Date: Wed Apr 3 22:50:40 2013 +0900 +* jQuery Mobile Framework Git Build: SHA1: 47569f70c0fea5edd17ea08af7efdfbbf8a4ad7c <> Date: Fri Apr 5 16:34:44 2013 +0900 * http://jquerymobile.com * * Copyright 2012 jQuery Foundation and other contributors @@ -53,9 +53,9 @@ jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeO * http://jquery.org/license * */(function(a,b,c){typeof define=="function"&&define.amd?define(["jquery"],function(d){return c(d,a,b),d.mobile}):c(a.jQuery,a,b)})(this,document,function(a,b,c,d){(function(a,b,d){var e={};a.mobile=a.extend({},{version:"1.2.0",ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",focusClass:"ui-focus",ajaxEnabled:!0,hashListeningEnabled:!0,linkBindingEnabled:!0,defaultPageTransition:"fade",maxTransitionWidth:!1,minScrollBack:250,touchOverflowEnabled:!1,defaultDialogTransition:"pop",pageLoadErrorMessage:"Error Loading Page",pageLoadErrorMessageTheme:"e",phonegapNavigationEnabled:!1,autoInitializePage:!0,pushStateEnabled:!0,ignoreContentEnabled:!1,orientationChangeEnabled:!0,buttonMarkup:{hoverDelay:200},$window:a(b),$document:a(c),getAttrFixed:function(a,b){var c=a.getAttribute(b);return c==="true"?!0:c==="false"?!1:c===null?d:c},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},silentScroll:function(c){a.type(c)!=="number"&&(c=a.mobile.defaultHomeScroll),a.event.special.scrollstart.enabled=!1,setTimeout(function(){b.scrollTo(0,c),a.mobile.$document.trigger("silentscroll",{x:0,y:c})},20),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},nsNormalizeDict:e,nsNormalize:function(b){if(!b)return;return e[b]||(e[b]=a.camelCase(a.mobile.ns+b))},getInheritedTheme:function(a,b){var c=a[0],d="",e=/ui-(bar|body|overlay)-([a-z])\b/,f,g;while(c){f=c.className||"";if(f&&(g=e.exec(f))&&(d=g[2]))break;c=c.parentNode}return d||b||"a"},closestPageData:function(a){return a.closest(':jqmData(role="page"), :jqmData(role="dialog")').data("page")},enhanceable:function(a){return this.haveParents(a,"enhance")},hijackable:function(a){return this.haveParents(a,"ajax")},haveParents:function(b,c){if(!a.mobile.ignoreContentEnabled)return b;var d=b.length,e=a(),f,g,h;for(var i=0;i").text(a(this).text()).html()},a.fn.jqmEnhanceable=function(){return a.mobile.enhanceable(this)},a.fn.jqmHijackable=function(){return a.mobile.hijackable(this)};var f=a.find,g=/:jqmData\(([^)]*)\)/g;a.find=function(b,c,d,e){return b=b.replace(g,"[data-"+(a.mobile.ns||"")+"$1]"),f.call(this,b,c,d,e)},a.extend(a.find,f),a.find.matches=function(b,c){return a.find(b,null,null,c)},a.find.matchesSelector=function(b,c){return a.find(c,null,null,[b]).length>0},a.extend({creatorDict:{},delegateSelfInitWithSingleSelector:function(b,c){if(typeof b!="function")return!1;var d=b.prototype.options.initSelector,e=/:jqmData\(role='[A-z\-]+'\)$/;if(e.test(d)){var f=d.indexOf("'")+1,g=d.lastIndexOf("'"),h=d.substring(f,g);if(!a.creatorDict.hasOwnProperty(h))return a.creatorDict[h]={},a.creatorDict[h].target=b,c===!0&&(a.creatorDict[h].useKeepNative=c),!0}return!1}}),a(c).bind("pagecreate create",function(b){var c="*[data-"+a.mobile.ns+"role]";a(c,b.target).each(function(){dataRoleValue=this.getAttribute("data-role"),matchedObj=a.creatorDict[dataRoleValue],matchedObj&&matchedObj.target.prototype.enhance(this,matchedObj.useKeepNative)})})})(a,this),function(a,b){var c=0,d=Array.prototype.slice,e=a.cleanData;a.cleanData=function(b){for(var c=0,d;(d=b[c])!=null;c++)try{a(d).triggerHandler("remove")}catch(f){}e(b)},a.widget=function(b,c,d){var e,f,g,h,i=b.split(".")[0];b=b.split(".")[1],e=i+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][e]=function(b){return!!a.data(b,e)},a[i]=a[i]||{},f=a[i][b],g=a[i][b]=function(a,b){if(!this._createWidget)return new g(a,b);arguments.length&&this._createWidget(a,b)},a.extend(g,f,{version:d.version,_proto:a.extend({},d),_childConstructors:[]}),h=new c,h.options=a.widget.extend({},h.options),a.each(d,function(b,e){a.isFunction(e)&&(d[b]=function(){var a=function(){return c.prototype[b].apply(this,arguments)},d=function(a){return c.prototype[b].apply(this,a)};return function(){var b=this._super,c=this._superApply,f;return this._super=a,this._superApply=d,f=e.apply(this,arguments),this._super=b,this._superApply=c,f}}())}),g.prototype=a.widget.extend(h,{widgetEventPrefix:b},d,{constructor:g,namespace:i,widgetName:b,widgetBaseClass:e,widgetFullName:e}),f?(a.each(f._childConstructors,function(b,c){var d=c.prototype;a.widget(d.namespace+"."+d.widgetName,g,c._proto)}),delete f._childConstructors):c._childConstructors.push(g),a.widget.bridge(b,g)},a.widget.extend=function(c){var e=d.call(arguments,1),f=0,g=e.length,h,i;for(;f",options:{disabled:!1,create:null},_createWidget:function(b,d){d=a(d||this.defaultElement||this)[0],this.element=a(d),this.uuid=c++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=a.widget.extend({},this.options,this._getCreateOptions(),b),this.bindings=a(),this.hoverable=a(),this.focusable=a(),d!==this&&(a.data(d,this.widgetName,this),a.data(d,this.widgetFullName,this),this._on({remove:"destroy"}),this.document=a(d.style?d.ownerDocument:d.document||d),this.window=a(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:a.noop,_getCreateEventData:a.noop,_create:a.noop,_init:a.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(a.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:a.noop,widget:function(){return this.element},option:function(c,d){var e=c,f,g,h;if(arguments.length===0)return a.widget.extend({},this.options);if(typeof c=="string"){e={},f=c.split("."),c=f.shift();if(f.length){g=e[c]=a.widget.extend({},this.options[c]);for(h=0;h"+""+"

"+"",fakeFixLoader:function(){var b=a("."+a.mobile.activeBtnClass).first();this.element.css({top:a.support.scrollTop&&f.scrollTop()+f.height()/2||b.length&&b.offset().top||100})},checkLoaderPosition:function(){var b=this.element.offset(),c=f.scrollTop(),d=a.mobile.getScreenHeight();if(b.topd)this.element.addClass("ui-loader-fakefix"),this.fakeFixLoader(),f.unbind("scroll",this.checkLoaderPosition).bind("scroll",this.fakeFixLoader)},resetHtml:function(){this.element.html(a(this.defaultHtml).html())},show:function(b,g,h){var i,j,k,l;this.resetHtml(),a.type(b)==="object"?(l=a.extend({},this.options,b),b=l.theme||a.mobile.loadingMessageTheme):(l=this.options,b=b||a.mobile.loadingMessageTheme||l.theme),j=g||a.mobile.loadingMessage||l.text,e.addClass("ui-loading");if(a.mobile.loadingMessage!==!1||l.html)a.mobile.loadingMessageTextVisible!==d?i=a.mobile.loadingMessageTextVisible:i=l.textVisible,this.element.attr("class",c+" ui-corner-all ui-body-"+b+" ui-loader-"+(i||g||b.text?"verbose":"default")+(l.textonly||h?" ui-loader-textonly":"")),l.html?this.element.html(l.html):this.element.find("h1").text(j),this.element.appendTo(a.mobile.pageContainer),this.checkLoaderPosition(),f.bind("scroll",a.proxy(this.checkLoaderPosition,this))},hide:function(){e.removeClass("ui-loading"),a.mobile.loadingMessage&&this.element.removeClass("ui-loader-fakefix"),a.mobile.$window.unbind("scroll",a.proxy(this.fakeFixLoader,this)),a.mobile.$window.unbind("scroll",a.proxy(this.checkLoaderPosition,this))}}),f.bind("pagecontainercreate",function(){a.mobile.loaderWidget=a.mobile.loaderWidget||a(a.mobile.loader.prototype.defaultHtml).loader()})}(a,this),function(a,b,c,d){function x(a){while(a&&typeof a.originalEvent!="undefined")a=a.originalEvent;return a}function y(b,c){var e=b.type,f,g,i,k,l,m,n,o,p;b=a.Event(b),b.type=c,f=b.originalEvent,g=a.event.props,e.search(/^(mouse|click)/)>-1&&(g=j);if(f)for(n=g.length,k;n;)k=g[--n],b[k]=f[k];e.search(/mouse(down|up)|click/)>-1&&!b.which&&(b.which=1);if(e.search(/^touch/)!==-1){i=x(f),e=i.touches,l=i.changedTouches,m=e&&e.length?e[0]:l&&l.length?l[0]:d;if(m)for(o=0,p=h.length;oe||Math.abs(c.pageY-n)>e,o&&!d&&H("vmousecancel",b,f),H("vmousemove",b,f),F()}function M(a){if(r)return;C();var b=z(a.target),c;H("vmouseup",a,b);if(!o){var d=H("vclick",a,b);d&&d.isDefaultPrevented()&&(c=x(a).changedTouches[0],p.push({touchID:v,target:a.target,x:c.clientX,y:c.clientY}),q=!0)}H("vmouseout",a,b),o=!1,F()}function N(b){var c=a.data(b,e),d;if(c)for(d in c)if(c[d])return!0;return!1}function O(){}function P(b){var c=b.substr(1);return{setup:function(d,f){N(this)||a.data(this,e,{});var g=a.data(this,e);g[b]=!0,k[b]=(k[b]||0)+1,k[b]===1&&t.bind(c,I),a(this).bind(c,O),s&&(k.touchstart=(k.touchstart||0)+1,k.touchstart===1&&t.bind("touchstart",J).bind("touchend",M).bind("touchmove",L).bind("scroll",K))},teardown:function(d,f){--k[b],k[b]||t.unbind(c,I),s&&(--k.touchstart,k.touchstart||t.unbind("touchstart",J).unbind("touchmove",L).unbind("touchend",M).unbind("scroll",K));var g=a(this),h=a.data(this,e);h&&(h[b]=!1),g.unbind(c,O),N(this)||g.removeData(e)}}}var e="virtualMouseBindings",f="virtualTouchID",g="vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "),h="clientX clientY pageX pageY screenX screenY".split(" "),i=a.event.mouseHooks?a.event.mouseHooks.props:[],j=a.event.props.concat(i),k={},l=0,m=0,n=0,o=!1,p=[],q=!1,r=!1,s="addEventListener"in c,t=a.mobile.$document,u=1,v=0,w;a.vmouse={moveDistanceThreshold:10,clickDistanceThreshold:10,resetTimerDuration:1500};for(var Q=0;Qa.event.special.swipe.scrollSupressionThreshold&&b.preventDefault()}var e=b.originalEvent.touches?b.originalEvent.touches[0]:b,f={time:(new Date).getTime(),coords:[e.pageX,e.pageY],origin:a(b.target)},i;d.bind(h,j).one(g,function(b){d.unbind(h,j),f&&i&&i.time-f.timea.event.special.swipe.horizontalDistanceThreshold&&Math.abs(f.coords[1]-i.coords[1])i.coords[0]?"swipeleft":"swiperight"),f=i=c})})}},a.each({scrollstop:"scrollstart",taphold:"tap",swipeleft:"swipe",swiperight:"swipe"},function(b,c){a.event.special[b]={setup:function(){a(this).bind(c,a.noop)}}})}(a,this),function(a,c){a.extend(a.support,{orientation:"orientation"in b&&"onorientationchange"in b})}(a),function(a){a.event.special.throttledresize={setup:function(){a(this).bind("resize",c)},teardown:function(){a(this).unbind("resize",c)}};var b=250,c=function(){f=(new Date).getTime(),g=f-d,g>=b?(d=f,a(this).trigger("throttledresize")):(e&&clearTimeout(e),e=setTimeout(c,b-g))},d=0,e,f,g}(a),function(a,b){function o(){var a=g();a!==h&&(h=a,d.trigger(e))}var d=a.mobile.$window,e="orientationchange",f,g,h,i,j,k={0:!0,180:!0};if(a.support.orientation){var l=b.innerWidth||a.mobile.$window.width(),m=b.innerHeight||a.mobile.$window.height(),n=50;i=l>m&&l-m>n,j=k[b.orientation];if(i&&j||!i&&!j)k={"-90":!0,90:!0}}a.event.special.orientationchange=a.extend({},a.event.special.orientationchange,{setup:function(){if(a.support.orientation&&!a.event.special.orientationchange.disabled)return!1;h=g(),d.bind("throttledresize",o)},teardown:function(){if(a.support.orientation&&!a.event.special.orientationchange.disabled)return!1;d.unbind("throttledresize",o)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}}),a.event.special.orientationchange.orientation=g=function(){var d=!0,e=c.documentElement;return a.support.orientation?d=k[b.orientation]:d=e&&e.clientWidth/e.clientHeight<1.1,d?"portrait":"landscape"},a.fn[e]=function(a){return a?this.bind(e,a):this.trigger(e)},a.attrFn&&(a.attrFn[e]=!0)}(a,this),function(a,b){var d=a.mobile.$window,e=a("html");a.mobile.media=function(){var b={},d=a("
"),f=a("").append(d);return function(a){if(!(a in b)){var g=c.createElement("style"),h="@media "+a+" { #jquery-mediatest { position:absolute; } }";g.type="text/css",g.styleSheet?g.styleSheet.cssText=h:g.appendChild(c.createTextNode(h)),e.prepend(f).prepend(g),b[a]=d.css("position")==="absolute",f.add(g).remove()}return b[a]}}()}(a),function(a,d){function e(a){var b=a.charAt(0).toUpperCase()+a.substr(1),c=(a+" "+h.join(b+" ")+b).split(" ");for(var e in c)if(g[c[e]]!==d)return!0}function m(a,b,d){var e=c.createElement("div"),f=function(a){return a.charAt(0).toUpperCase()+a.substr(1)},g=function(a){return"-"+a.charAt(0).toLowerCase()+a.substr(1)+"-"},i=function(c){var d=g(c)+a+": "+b+";",h=f(c),i=h+f(a);e.setAttribute("style",d),!e.style[i]||(k=!0)},j=d?[d]:h,k;for(var l=0;l",{href:b}).appendTo("head"),g=a("").prependTo(f),h=g[0].href,c[0].href=e||location.pathname,d&&d.remove(),h.indexOf(b)===0}function p(){var a=c.createElement("x"),d=c.documentElement,e=b.getComputedStyle,f;return"pointerEvents"in a.style?(a.style.pointerEvents="auto",a.style.pointerEvents="x",d.appendChild(a),f=e&&e(a,"").pointerEvents==="auto",d.removeChild(a),!!f):!1}function q(){var a=c.createElement("div");return typeof a.getBoundingClientRect!="undefined"}var f=a("").prependTo("html"),g=f[0].style,h=["Webkit","Moz","O"],i="palmGetResource"in b,j=b.opera,k=b.operamini&&{}.toString.call(b.operamini)==="[object OperaMini]",l=b.blackberry&&!e("-webkit-transform");a.extend(a.mobile,{browser:{}}),a.mobile.browser.ie=function(){var a=3,b=c.createElement("div"),d=b.all||[];do b.innerHTML="";while(d[0]);return a>4?a:!a}(),a.extend(a.support,{cssTransitions:"WebKitTransitionEvent"in b||m("transition","height 100ms linear")&&!j,pushState:"pushState"in history&&"replaceState"in history,mediaquery:a.mobile.media("only all"),cssPseudoElement:!!e("content"),touchOverflow:!!e("overflowScrolling"),cssTransform3d:n(),boxShadow:!!e("boxShadow")&&!l,scrollTop:("pageXOffset"in b||"scrollTop"in c.documentElement||"scrollTop"in f[0])&&!i&&!k,dynamicBaseTag:o(),cssPointerEvents:p(),boundingRect:q()}),f.remove();var r=function(){var a=b.navigator.userAgent;return a.indexOf("Nokia")>-1&&(a.indexOf("Symbian/3")>-1||a.indexOf("Series60/5")>-1)&&a.indexOf("AppleWebKit")>-1&&a.match(/(BrowserNG|NokiaBrowser)\/7\.[0-3]/)}();a.mobile.gradeA=function(){return(a.support.mediaquery||a.mobile.browser.ie&&a.mobile.browser.ie>=7)&&(a.support.boundingRect||a.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/)!==null)},a.mobile.ajaxBlacklist=b.blackberry&&!b.WebKitPoint||k||r,r&&a(function(){a("head link[rel='stylesheet']").attr("rel","alternate stylesheet").attr("rel","stylesheet")}),a.support.boxShadow||a("html").addClass("ui-mobile-nosupport-boxshadow")}(a),function(a,b){a.widget("mobile.page",a.mobile.widget,{options:{theme:"c",domCache:!1,keepNativeDefault:":jqmData(role='none'), :jqmData(role='nojs')"},_create:function(){var a=this;if(a._trigger("beforecreate")===!1)return!1;a.element.addClass("ui-page ui-body-"+a.options.theme).bind("pagebeforehide",function(){a.removeContainerBackground()}).bind("pagebeforeshow",function(){a.setContainerBackground()})},refresh:function(){a(this.element).children(".ui-content").trigger("updatelayout",["external"])},setToolbar:function(){a(this.element).trigger("pagebeforeshow")},removeContainerBackground:function(){a.mobile.pageContainer.removeClass("ui-overlay-"+a.mobile.getInheritedTheme(this.element.parent()))},setContainerBackground:function(b){this.options.theme&&a.mobile.pageContainer.addClass("ui-overlay-"+(b||this.options.theme))},addBackBtn:function(b){var c=a(".ui-page-active .ui-footer");b=="header"&&(c=a(".ui-page-active .ui-header")),backBtn=a("").buttonMarkup({icon:"header-back-btn",theme:"s"}),c.find(".ui-btn-back").length||backBtn.prependTo(c)},keepNativeSelector:function(){var b=this.options,c=b.keepNative&&a.trim(b.keepNative);return c&&b.keepNative!==b.keepNativeDefault?[b.keepNative,b.keepNativeDefault].join(", "):b.keepNativeDefault}})}(a),function(a,b,d){function k(a){return a=a||location.href,"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var e="hashchange",f=c,g,h=a.event.special,i=f.documentMode,j="on"+e in b&&(i===d||i>7);a.fn[e]=function(a){return a?this.bind(e,a):this.trigger(e)},a.fn[e].delay=50,h[e]=a.extend(h[e],{setup:function(){if(j)return!1;a(g.start)},teardown:function(){if(j)return!1;a(g.stop)}}),g=function(){function n(){var c=k(),d=m(h);c!==h?(l(h=c,d),a(b).trigger(e)):d!==h&&(location.href=location.href.replace(/#.*/,"")+d),g=setTimeout(n,a.fn[e].delay)}var c={},g,h=k(),i=function(a){return a},l=i,m=i;return c.start=function(){g||n()},c.stop=function(){g&&clearTimeout(g),g=d},a.browser.msie&&!j&&function(){var b,d;c.start=function(){b||(d=a.fn[e].src,d=d&&d+k(),b=a('