Merge remote-tracking branch 'upstream/master' into issue-1470

Conflicts:
	tests/unit/listview/listview_core.js
This commit is contained in:
Ghislain Seguin 2011-06-17 10:46:52 -07:00
commit f32fe66bf7
56 changed files with 2176 additions and 1339 deletions

35
Makefile Executable file → Normal file
View file

@ -13,6 +13,7 @@ JQUERY = $(shell grep Library js/jquery.js | sed s'/ \* jQuery JavaScript Librar
# The directory to create the zipped files in and also serves as the filenames
DIR = jquery.mobile-${VER}
nightly: DIR = jquery.mobile
# The output folder for the finished files
OUTPUT = compiled
@ -24,7 +25,6 @@ RMLATEST = echo ""
NIGHTLY_OUTPUT = nightlies/${DATE}
ifeq (${NIGHTLY_OUTPUT}, latest)
RMLATEST = ssh jqadmin@code.origin.jquery.com 'rm -rf /var/www/html/code.jquery.com/mobile/latest'
DIR = jquery.mobile
endif
NIGHTLY_WEBPATH = http://code.jquery.com/mobile/${NIGHTLY_OUTPUT}
@ -87,21 +87,30 @@ all: init js min css cssmin notify
# Build the normal CSS file.
css: init
# Build the CSS file
@@head -8 js/jquery.mobile.core.js | ${SED_VER} > ${OUTPUT}/${CSS}
@@cat ${CSSFILES} >> ${OUTPUT}/${CSS}
# Build the minified CSS file
cssmin: init css
@@head -8 js/jquery.mobile.core.js | ${SED_VER} > ${OUTPUT}/${CSSMIN}
# Build the minified CSS file
@@java -jar build/yuicompressor-2.4.4.jar --type css ${OUTPUT}/${CSS} >> ${OUTPUT}/${CSSMIN}
# Build the normal JS file
js: init
# Build the JavaScript file
@@head -8 js/jquery.mobile.core.js | ${SED_VER} > ${OUTPUT}/${JS}
@@cat ${JSFILES} >> ${OUTPUT}/${JS}
# Create the output directory. This is in a separate step so its not dependant on other targets
init:
# Building jQuery Mobile in the "${OUTPUT}" folder
@@rm -rf ${OUTPUT}
@@mkdir ${OUTPUT}
# Build the minified JS file
min: init js
# Build the minified JavaScript file
@@head -8 js/jquery.mobile.core.js | ${SED_VER} > ${OUTPUT}/${MIN}
@@java -jar build/google-compiler-20110405.jar --js ${OUTPUT}/${JS} --warning_level QUIET --js_output_file ${MIN}.tmp
@@cat ${MIN}.tmp >> ${OUTPUT}/${MIN}
@ -111,18 +120,12 @@ min: init js
notify:
@@echo "The files have been built and are in " $$(pwd)/${OUTPUT}
# Create the output directory. This is in a separate step so its not dependant on other targets
init:
@@rm -rf ${OUTPUT}
@@mkdir ${OUTPUT}
# Pull the latest commits. This is used for the nightly build but can be used to save some keystrokes
pull:
@@git pull --quiet
# Zip the 4 files and the theme images into one convenient package
zip: init js min css cssmin
@@rm -rf ${DIR}
@@mkdir -p ${DIR}
@@cp ${OUTPUT}/${DIR}*.js ${DIR}/
@@cp ${OUTPUT}/${DIR}*.css ${DIR}/
@ -133,12 +136,6 @@ zip: init js min css cssmin
# Used by the jQuery team to make the nightly builds
nightly: pull zip
# Create a log that lists the current version according to the code and the git information for the last commit
@@echo $$"\nGit Release Version: " >> ${OUTPUT}/log.txt
@@cat version.txt >> ${OUTPUT}/log.txt
@@echo $$"\nGit Information for this build:" >> ${OUTPUT}/log.txt
@@git log -1 --format=format:"SHA1: %H \nDate: %cd \nTitle: %s" >> ${OUTPUT}/log.txt
# Create the folder to hold the files for the demos
@@mkdir -p ${VER}
@ -174,12 +171,11 @@ nightly: pull zip
# Used by the jQuery team to deploy a build to the CDN
deploy: zip
# Deploy to CDN
@@mv ${DIR} ${VER}
@@cp ${DIR}.zip ${VER}/
@@mv ${OUTPUT} ${VER}
@@scp -r ${VER} jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/mobile/
@@mv ${VER} ${DIR}
@@mv ${VER} ${OUTPUT}
# Deploy Demos
# Deploy Demos to the jQueryMobile.com site
@@mkdir -p ${VER}
@@cp -r index.html themes experiments docs ${VER}/
@ -198,3 +194,6 @@ deploy: zip
@@scp -r ${VER} jqadmin@jquerymobile.com:/srv/jquerymobile.com/htdocs/demos/
# Clean up the local files
@@rm -rf ${VER}
@@echo "All Done"

View file

@ -1,18 +1,17 @@
<?php
if (!isset($type) || !isset($elements))
if ( ! isset($type) || ! isset($elements) )
{
echo "\$type and \$elements must be specified!";
echo '$type and $elements must be specified!';
exit;
}
$contents = '';
reset($elements);
while (list(,$element) = each($elements)) {
$contents .= "\n\n" . file_get_contents($element);
foreach ( $elements as $file ) {
$contents .= file_get_contents($file). "\n\n";
}
header("Content-Type: " . $type);
header("Content-Length: " . strlen($contents));
echo $contents;
?>
header('Content-Type: ' . $type);
header('Content-Length: ' . strlen($contents));
echo $contents;

View file

@ -95,17 +95,14 @@ $(document).bind("mobileinit", function(){
<dt>ajaxEnabled (<em>boolean</em>, default: true):</dt>
<dd>jQuery Mobile will automatically handle link clicks and form submissions through Ajax, when possible. If false, url hash listening will be disabled as well, and urls will load as regular http requests.</dd>
<dt>ajaxLinksEnabled (<strong>deprecated</strong> <em>boolean</em>, default: true):</dt>
<dd>jQuery Mobile will automatically handle link clicks through Ajax, when possible.</dd>
<dt>ajaxFormsEnabled (<strong>deprecated</strong> <em>boolean</em>, default: true):</dt>
<dd>jQuery Mobile will automatically handle form submissions through Ajax, when possible.</dd>
<dt>hashListeningEnabled (<em>boolean</em>, default: true):</dt>
<dd>jQuery Mobile will automatically listen and handle changes to the location.hash. Disabling this will prevent jQuery Mobile from handling hash changes, which allows you to handle them yourself, or simply to use simple deep-links within a document that scroll to a particular ID.</dd>
<dt>defaultTransition (<em>string</em>, default: 'slide'):</dt>
<dd>Set the default transition for page changes that use Ajax. The default transition for dialog presentation is 'pop'. Set to 'none' for no transitions by default.</dd>
<dt>defaultPageTransition (<em>string</em>, default: 'slide'):</dt>
<dd>Set the default transition for page changes that use Ajax. Set to 'none' for no transitions by default.</dd>
<dt>defaultDialogTransition (<em>string</em>, default: 'pop'):</dt>
<dd>Set the default transition for dialog changes that use Ajax. Set to 'none' for no transitions by default.</dd>
<dt>loadingMessage (<em>string</em>, default: "loading"):</dt>
<dd>Set the text that appears when a page is loading. If set to false, the message will not appear at all.</dd>

View file

@ -26,24 +26,48 @@
<dl>
<dt><code>$.mobile.changePage</code> (<em>method</em>)</dt>
<dd>Programmatically change from one page to another. This method is used internally for transitions that occur as a result of clicking a link or submitting a form, when those features are enabled.</dd>
<dd>Programmatically change from one page to another. This method is used internally for the page loading and transitioning that occurs as a result of clicking a link or submitting a form, when those features are enabled.</dd>
<dd>
<dl>
<dt>Arguments</dt>
<dd><code>to</code>
<ul>
<li>String, url to transition to (<code>"about/us.html"</code>)</li>
<li>jQuery object (<code>$("#about")</code>)</li>
<li>Array specifying two page references [from,to] for transitioning from a known page. From is otherwise assumed to be the current page in view (or $.mobile.activePage ).</li>
<li>Object for sending form data. (<code>{url: url, data: serialized form data, type: "get" or "post"}</code></li>
</ul>
</dd>
<dd><code>to</code> (<em>string or object</em>, required)
<ul>
<li>String: Absolute or relative URL. (&quot;about/us.html&quot;)</li>
<li>Object: jQuery collection object. (<code>$("#about")</code>)</li>
</ul>
</dd>
<dd><code>transition</code> (<em>string</em>, examples: "pop", "slide"," "none")</dd>
<dd><code>reverse</code> (<em>boolean</em>, default: false). True will cause a reverse-direction transition.</dd>
<dd><code>changeHash</code> (<em>boolean</em>, default: true). Update the hash to the to page's URL when page change is complete.</dd>
<dd><code>options</code> (<em>object</em>, optional)
<ul>
<li>Properties:
<ul>
<li><code>transition</code> (<em>string</em>, default: $.mobile.defaultPageTransition) The transition to use when showing the page. </li>
<li><code>reverse</code> (<em>boolean</em>, default: false) Decides what direction the transition will run when showing the page. </li>
<li><code>changeHash</code> (<em>boolean</em>, default: true) Decides if the hash in the location bar should be updated. </li>
<li><code>role</code> (<em>string</em>, default: undefined) The data-role value to be used when displaying the page. By default this is undefined which means rely on the value of the @data-role attribute defined on the element.</li>
<li><code>pageContainer</code> (jQuery collection, default: $.mobile.pageContainer) Specifies the element that should contain the page. </li>
<li><code>type</code> (<em>string</em>, default: &quot;get&quot;) Specifies the method ("get" or "post") to use when making a page request.
<ul>
<li>Used only when the 'to' argument of changePage() is a URL.</li>
</ul>
</li>
<li><code>data</code> (<em>object</em> or string, default: undefined) The data to send with an Ajax page request.
<ul>
<li>Used only when the 'to' argument of changePage() is a URL.</li>
</ul>
</li>
<li><code>reloadPage</code> (<em>boolean</em>, default: false) Forces a reload of a page, even if it is already in the DOM of the page container.
<ul>
<li>Used only when the 'to' argument of changePage() is a URL.</li>
</ul>
</li>
</ul>
</li>
</ul>
</dd>
</dl>
</dd>
@ -51,17 +75,20 @@
<pre>
<code>
<strong>//transition to the "about us" page with a slideup transition</strong>
$.mobile.changePage("about/us.html", "slideup");
$.mobile.changePage( "about/us.html", { transition: "slideup"} );
<strong>//transition to the "search results" page, using data from a form with an ID of "search"" </strong>
$.mobile.changePage({
url: "searchresults.php",
type: "get",
$.mobile.changePage( "searchresults.php", {
type: "post",
data: $("form#search").serialize()
});
<strong>//transition to the "confirm" page with a "pop" transition without tracking it in history </strong>
$.mobile.changePage("../alerts/confirm.html", "pop", false, false);
$.mobile.changePage( "../alerts/confirm.html", {
transition: "pop",
reverse: false,
changeHash: false
});
</code>
</pre>
@ -69,6 +96,50 @@ $.mobile.changePage("../alerts/confirm.html", "pop", false, false);
</dd>
<dt><code>$.mobile.loadPage</code> (<em>method</em>)</dt>
<dd>Load an external page, enhance its content, and insert it into the DOM. This method is called internally by the changePage() function when its first argument is a URL. This function does not affect the current active page so it can be used to load pages in the background. The function returns a deferred promise object that gets resolved after the page has been enhanced and inserted into the document.</dd>
<dd>
<dl>
<dt>Arguments</dt>
<dd><code>url</code> (<em>string or object</em>, required) A relative or absolute URL.</dd>
<dd><code>options</code> (<em>object</em>, optional)
<ul>
<li>Properties:
<ul>
<li><code>role</code> (<em>string</em>, default: undefined) The data-role value to be used when displaying the page. By default this is undefined which means rely on the value of the @data-role attribute defined on the element.</li>
<li><code>pageContainer</code> (jQuery collection, default: $.mobile.pageContainer) Specifies the element that should contain the page after it is loaded. </li>
<li><code>type</code> (<em>string</em>, default: &quot;get&quot;) Specifies the method ("get" or "post") to use when making a page request.
</li>
<li><code>data</code> (<em>object</em> or string, default: undefined) The data to send with an Ajax page request. </li>
<li><code>reloadPage</code> (<em>boolean</em>, default: false) Forces a reload of a page, even if it is already in the DOM of the page container. </li>
</ul>
</li>
</ul>
</dd>
</dl>
</dd>
<dd>Examples:
<pre>
<code>
<strong>//load the "about us" page into the DOM</strong>
$.mobile.loadPage( "about/us.html" );
<strong>//load a "search results" page, using data from a form with an ID of "search"" </strong>
$.mobile.loadPage( "searchresults.php", {
type: "post",
data: $("form#search").serialize()
});
</code>
</pre>
</dd>
<dt><code>jqmData(), jqmRemoveData(), and jqmHasData()</code> (<em>method</em>)</dt>
<dd>When working with jQuery Mobile, <code>jqmData</code> and <code>jqmRemoveData</code> should be used in place of jQuery core's <code>data</code> and <code>removeData</code> methods (note that this includes $.fn.data, $.fn.removeData, and the $.data, $.removeData, and $.hasData utilities), as they automatically incorporate getting and setting of namespaced data attributes (even if no namespace is currently in use).</dd>
<dd>
@ -83,23 +154,30 @@ $.mobile.changePage("../alerts/confirm.html", "pop", false, false);
<dt><code>$.mobile.pageLoading</code> (<em>method</em>)</dt>
<dd>Show or hide the page loading message, which is configurable via $.mobile.loadingMessage.</dd>
<dd>
<dl>
<dt>Arguments:</dt>
<dd><code>Done</code> (<em>boolean</em>, defaults to false, meaning loading has started). True will hide the loading message.</dd>
</dl>
</dd>
<dt><code>$.mobile.showPageLoadingMsg</code> (<em></em>)</dt>
<dd>Show the page loading message, which is configurable via $.mobile.loadingMessage.</dd>
<dd>Examples:
<dd>Example:
<pre>
<code>
<strong>//cue the page loader</strong>
$.mobile.pageLoading();
$.mobile.showPageLoadingMsg();
</code>
</pre>
</dd>
<strong>//hide the page loader</strong>
$.mobile.pageLoading( true );
<dt><code>$.mobile.hidePageLoadingMsg</code> (<em></em>)</dt>
<dd>Hide the page loading message, which is configurable via $.mobile.loadingMessage.</dd>
<dd>Example:
<pre>
<code>
<strong>//cue the page loader</strong>
$.mobile.hidePageLoadingMsg();
</code>
</pre>

2
docs/buttons/buttons-themes.html Executable file → Normal file
View file

@ -84,7 +84,7 @@
<a href="index.html" data-role="button" data-theme="e" data-icon="arrow-l" data-inline="true">Theme e</a>
</div>
<p><strong>"d" theme</strong> on container with themed buttons inside</p>
<p><strong>"e" theme</strong> on container with themed buttons inside</p>
<div data-role="content" data-theme="e">
<a href="index.html" data-role="button" data-theme="a" data-icon="arrow-l" data-inline="true">Theme a</a>
<a href="index.html" data-role="button" data-theme="b" data-icon="arrow-l" data-inline="true">Theme b</a>

View file

@ -27,7 +27,7 @@
<h2>Non-Ajax handling</h2>
<p>To prevent form submissions from being automatically handled with Ajax, add the <code>data-ajax="false"</code> attribute to the form element. You can also turn of Ajax form handling completely via the <code>ajaxFormsEnabled</code> <a href="../api/globalconfig.html">global config option</a>.</p>
<p>To prevent form submissions from being automatically handled with Ajax, add the <code>data-ajax="false"</code> attribute to the form element. You can also turn of Ajax form handling completely via the <code>ajaxEnabled</code> <a href="../api/globalconfig.html">global config option</a>.</p>
<h2>Simple Ajax form example</h2>
<p>This page demonstrates automated ajax handling of form submissions. The form below is configured to send regular a <code>get</code> request to <code>forms-sample-response.php</code>. On submit, jQuery Mobile will make sure that the Url specified is able to be retrieved via Ajax, and handle it appropriately. Keep in mind that just like ordinary HTTP form submissions, jQuery Mobile allows <code>get</code> result pages to be bookmarked by updating the Url hash when the response returns successfully. Also like ordinary form submissions, <code>post</code> requests do not contain query parameters in the hash, so they are not bookmarkable.</p>

View file

@ -38,11 +38,6 @@
<li><a href="plugin-eventsmethods.html">Plugin methods</a></li>
</ul>
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Experimental Form Plugins</li>
<li><a href="../../experiments/ui-datepicker/" rel="external">Datepicker</a></li>
</ul>
</div><!-- /ui-body wrapper -->
</div><!-- /page -->

1
docs/toolbars/bars-themes.html Executable file → Normal file
View file

@ -120,6 +120,7 @@
<a href="index.html" data-role="button" data-icon="arrow-l" data-iconpos="right">left</a>
<a href="index.html" data-role="button" data-icon="arrow-r" data-iconpos="right">right</a>
<a href="index.html" data-role="button" data-icon="arrow-u" data-iconpos="right">up</a>
<a href="index.html" data-role="button" data-icon="arrow-d" data-iconpos="right">down</a>
</div>
<div data-role="footer" data-theme="d">

View file

@ -55,6 +55,6 @@ $(":jqmData(role='page')").live("pageshow", function(event) {
ResizePageContentHeight(event.target);
});
$(document).live("orientationchange", function(event) {
$(window).bind("orientationchange", function(event) {
ResizePageContentHeight($(".ui-page"));
});

View file

@ -1,82 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile Framework - Datepicker</title>
<link rel="stylesheet" href="../../themes/default/" />
<link rel="stylesheet" href="../../docs/_assets/css/jqm-docs.css" />
<link rel="stylesheet" href="jquery.ui.datepicker.mobile.css" />
<script src="../../js/jquery.js"></script>
<script>
//reset type=date inputs to text
$( document ).bind( "mobileinit", function(){
$.mobile.page.prototype.options.degradeInputs.date = true;
});
</script>
<script src="../../js/"></script>
<script src="jQuery.ui.datepicker.js"></script>
<script src="jquery.ui.datepicker.mobile.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>jQuery UI's Datepicker Styled for mobile</h1>
</div>
<div data-role="content">
<p>The included files extend the jQuery UI datepicker to make it suitable for touch devices. This plugin is not included in jQuery Mobile by default, so you'll need to include the files yourself if you'd like to use them. Scroll down for usage instructions.</p>
<form action="#" method="get">
<div data-role="fieldcontain">
<label for="date">Date Input:</label>
<input type="date" name="date" id="date" value="" />
</div>
</form>
<h2>Usage Instructions</h2>
<p>The datepicker auto-generates from a regular <code>input</code> element with a <code>type="date"</code> attribute.</p>
<pre><code>
&lt;label for=&quot;date&quot;&gt;Date Input:&lt;/label&gt;
&lt;input type=&quot;date&quot; name=&quot;date&quot; id=&quot;date&quot; value=&quot;&quot; /&gt;
</code></pre>
<p>We'd recommend wrapping the label and input in a fieldcontain div for presentation purposes, and these elements should be placed within a <code>form</code> element for C-Grade browser accessibility.</p>
<p><strong>Note:</strong> This plugin is not included in jQuery Mobile by default, so you'll need to include the following files in order to use it:</p>
<pre><code>
&lt;link rel=&quot;stylesheet&quot; href=&quot;jquery.ui.datepicker.mobile.css&quot; /&gt;
&lt;script src=&quot;jQuery.ui.datepicker.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;jquery.ui.datepicker.mobile.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>You'll also want to configure the page plugin to convert "date" input elements to "text" inputs after they're enhanced with our datepicker, so that no native datepicker will conflict with the custom one we're adding. To do this, bind to the "mobileinit" event and set input types of "date" back to text using the page plugin's options:</p>
<pre><code>
&lt;script&gt;
//reset type=date inputs to text
$( document ).bind( &quot;mobileinit&quot;, function(){
$.mobile.page.prototype.options.degradeInputs.date = true;
});
&lt;/script&gt;
</code></pre>
<p>Be sure to place this event binding in a script that loads after jQuery, but before jQuery Mobile. Check this page's source for an example.</p>
</div>
</div>
</body>
</html>

View file

@ -1,98 +0,0 @@
/*!
* jQuery UI 1.8.5
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI
*/
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.5",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}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind("mousedown.ui-disableSelection selectstart.ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,
h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
c(function(){var a=document.createElement("div"),b=document.body;c.extend(a.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.appendChild(a).offsetHeight===100;b.removeChild(a).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,
d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
;/*
* jQuery UI Datepicker 1.8.5
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Datepicker
*
* Depends:
* jquery.ui.core.js
*/
(function(d,G){function L(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}function E(a,b){d.extend(a,
b);for(var c in b)if(b[c]==null||b[c]==G)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.5"}});var y=(new Date).getTime();d.extend(L.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){E(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=
f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}},
_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&
b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==
""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,
c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),
true);this._updateDatepicker(b);this._updateAlternate(b)}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}E(a.settings,e||{});b=b&&b.constructor==
Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);
d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},
_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=
d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;
for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&
this._hideDatepicker();var h=this._getDateDatepicker(a,true);E(e.settings,f);this._attachments(d(a),e);this._autoSize(e);this._setDateDatepicker(a,h);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&
!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass,b.dpDiv).add(d("td."+d.datepicker._currentClass,b.dpDiv));c[0]?d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();
return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||
a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,
a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));
var c=String.fromCharCode(a.charCode==G?a.keyCode:a.charCode);return a.ctrlKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||
a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");E(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);
d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&
d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=d.datepicker._getBorders(b.dpDiv);b.dpDiv.find("iframe.ui-datepicker-cover").css({left:-i[0],top:-i[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,
h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a)).find("iframe.ui-datepicker-cover").css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){d(this).removeClass("ui-state-hover");
this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).addClass("ui-datepicker-prev-hover");
this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);var e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");
a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input.focus()},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),
k=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>k&&k>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1);)a=a[b?"previousSibling":"nextSibling"];
a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val():
"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&
!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;
b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=
this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=
d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,
"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b==
"object"?b.toString():b+"";if(b=="")return null;for(var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff,f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,k=c=-1,l=-1,u=-1,j=false,o=function(p){(p=z+1<a.length&&a.charAt(z+1)==p)&&z++;return p},m=function(p){o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"?4:p=="o"?
3:2)+"}");p=b.substring(s).match(p);if(!p)throw"Missing number at position "+s;s+=p[0].length;return parseInt(p[0],10)},n=function(p,w,H){p=o(p)?H:w;for(w=0;w<p.length;w++)if(b.substr(s,p[w].length).toLowerCase()==p[w].toLowerCase()){s+=p[w].length;return w+1}throw"Unknown name at position "+s;},r=function(){if(b.charAt(s)!=a.charAt(z))throw"Unexpected literal at position "+s;s++},s=0,z=0;z<a.length;z++)if(j)if(a.charAt(z)=="'"&&!o("'"))j=false;else r();else switch(a.charAt(z)){case "d":l=m("d");
break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":k=m("m");break;case "M":k=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();k=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();k=v.getMonth()+1;l=v.getDate();break;case "'":if(o("'"))r();else j=true;break;default:r()}if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>
-1){k=1;l=u;do{e=this._getDaysInMonth(c,k-1);if(l<=e)break;k++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,k-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=k||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*
60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=j+1<a.length&&a.charAt(j+1)==o)&&j++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},k=function(o,m,n,r){return i(o)?r[m]:n[m]},l="",u=false;if(b)for(var j=0;j<a.length;j++)if(u)if(a.charAt(j)==
"'"&&!i("'"))u=false;else l+=a.charAt(j);else switch(a.charAt(j)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=k("D",b.getDay(),e,f);break;case "o":l+=g("o",(b.getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5,3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=k("M",b.getMonth(),h,c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+=
"'";else u=true;break;default:l+=a.charAt(j)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+="0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==G?a.settings[b]:this._defaults[b]},
_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,
this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,k=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,j=u.exec(h);j;){switch(j[2]||"d"){case "d":case "D":g+=
parseInt(j[1],10);break;case "w":case "W":g+=parseInt(j[1],10)*7;break;case "m":case "M":l+=parseInt(j[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(k,l));break;case "y":case "Y":k+=parseInt(j[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(k,l));break}j=u.exec(h)}return new Date(k,l,g)};if(b=(b=b==null?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):b)&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},
_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?
"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),k=
this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),j=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=j&&n<j?j:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,
"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-k,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', -"+k+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+
n+"</span></a>";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m,g+k,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', +"+k+", 'M');\" title=\""+r+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+r+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+r+'"><span class="ui-icon ui-icon-circle-triangle-'+
(c?"w":"e")+'">'+r+"</span></a>";k=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&&a.currentDay?u:b;k=!h?k:this.formatDate(k,r,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+y+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,r)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
y+".datepicker._gotoToday('#"+a.id+"');\">"+k+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;k=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),w=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var M=this._getDefaultDate(a),I="",C=0;C<i[0];C++){for(var N=
"",D=0;D<i[1];D++){var J=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",x="";if(l){x+='<div class="ui-datepicker-group';if(i[1]>1)switch(D){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?
f:n:"")+(/all|right/.test(t)&&C==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,j,o,C>0||D>0,z,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var A=k?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var q=(t+h)%7;A+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+r[q]+'">'+s[q]+"</span></th>"}x+=A+"</tr></thead><tbody>";A=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,
A);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;A=l?6:Math.ceil((t+A)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var O=0;O<A;O++){x+="<tr>";var P=!k?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(q)+"</td>";for(t=0;t<7;t++){var F=p?p.apply(a.input?a.input[0]:null,[q]):[true,""],B=q.getMonth()!=g,K=B&&!H||!F[0]||j&&q<j||o&&q>o;P+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(B?" ui-datepicker-other-month":"")+(q.getTime()==J.getTime()&&g==a.selectedMonth&&
a._keyEvent||M.getTime()==q.getTime()&&M.getTime()==J.getTime()?" "+this._dayOverClass:"")+(K?" "+this._unselectableClass+" ui-state-disabled":"")+(B&&!w?"":" "+F[1]+(q.getTime()==u.getTime()?" "+this._currentClass:"")+(q.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!B||w)&&F[2]?' title="'+F[2]+'"':"")+(K?"":' onclick="DP_jQuery_'+y+".datepicker._selectDay('#"+a.id+"',"+q.getMonth()+","+q.getFullYear()+', this);return false;"')+">"+(B&&!w?"&#xa0;":K?'<span class="ui-state-default">'+q.getDate()+
"</span>":'<a class="ui-state-default'+(q.getTime()==b.getTime()?" ui-state-highlight":"")+(q.getTime()==J.getTime()?" ui-state-active":"")+(B?" ui-priority-secondary":"")+'" href="#">'+q.getDate()+"</a>")+"</td>";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+=P+"</tr>"}g++;if(g>11){g=0;m++}x+="</tbody></table>"+(l?"</div>"+(i[0]>0&&D==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");N+=x}I+=N}I+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':
"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var k=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),j='<div class="ui-datepicker-title">',o="";if(h||!k)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+
a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(j+=o+(h||!(k&&l)?"&#xa0;":""));if(h||!l)j+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,
i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(j+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)j+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";j+="</select>"}j+=this._get(a,"yearSuffix");if(u)j+=(h||!(k&&l)?"&#xa0;":"")+o;j+="</div>";return j},_adjustInstDate:function(a,b,c){var e=
a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,
"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);
c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,
"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));
return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new L;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.5";window["DP_jQuery_"+y]=d})(jQuery);
;

View file

@ -1,32 +0,0 @@
/*
* jQuery UI Datepicker @VERSION
*
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Datepicker#theming
*/
div.hasDatepicker{ display: block; padding: 0; overflow: visible; margin: 8px 0; }
.ui-datepicker { overflow: visible; margin: 0; max-width: 500px; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.4em 0; border-bottom: 0; font-weight: bold; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { padding: 1px 0 1px 2px; position:absolute; top: .5em; margin-top: 0; text-indent: -9999px; }
.ui-datepicker .ui-datepicker-prev { left:6px; }
.ui-datepicker .ui-datepicker-next { right:6px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker table {width: 100%; border-collapse: collapse; margin:0; }
.ui-datepicker td { border-width: 1px; padding: 0; text-align: center; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em 0; font-weight: bold; margin: 0; border-width: 0; text-align: center; text-decoration: none; }
.ui-datepicker-calendar th { padding-top: .3em; padding-bottom: .3em; }
.ui-datepicker-calendar th span, .ui-datepicker-calendar span.ui-state-default { opacity: .3; }
.ui-datepicker-calendar td a { padding-top: .5em; padding-bottom: .5em; }
@media all and (min-width: 450px){
div.hasDatepicker { width: 63%; display: inline-block; margin: 0; }
}

View file

@ -1,55 +0,0 @@
/*
* jQuery Mobile Framework : temporary extension to port jQuery UI's datepicker for mobile
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {
//cache previous datepicker ui method
var prevDp = $.fn.datepicker;
//rewrite datepicker
$.fn.datepicker = function( options ){
var dp = this;
//call cached datepicker plugin
prevDp.call( this, options );
//extend with some dom manipulation to update the markup for jQM
//call immediately
function updateDatepicker(){
$( ".ui-datepicker-header", dp ).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
$( ".ui-datepicker-prev, .ui-datepicker-next", dp ).attr("href", "#");
$( ".ui-datepicker-prev", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-l", shadow: true, corners: true});
$( ".ui-datepicker-next", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-r", shadow: true, corners: true});
$( ".ui-datepicker-calendar th", dp ).addClass("ui-bar-c");
$( ".ui-datepicker-calendar td", dp ).addClass("ui-body-c");
$( ".ui-datepicker-calendar a", dp ).buttonMarkup({corners: false, shadow: false});
$( ".ui-datepicker-calendar a.ui-state-active", dp ).addClass("ui-btn-active"); // selected date
$( ".ui-datepicker-calendar a.ui-state-highlight", dp ).addClass("ui-btn-up-e"); // today"s date
$( ".ui-datepicker-calendar .ui-btn", dp ).each(function(){
var el = $(this);
// remove extra button markup - necessary for date value to be interpreted correctly
el.html( el.find( ".ui-btn-text" ).text() );
});
};
//update now
updateDatepicker();
// and on click
$( dp ).click( updateDatepicker );
//return jqm obj
return this;
};
//bind to pagecreate to automatically enhance date inputs
$( ".ui-page" ).live( "pagecreate", function(){
$( "input[type='date'], input:jqmData(type='date')", this ).each(function(){
$(this).after( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
});
});
})( jQuery );

View file

@ -1,4 +1,4 @@
<?
<?php
$location = isset($_GET['location']) ? $_GET['location'] : '02135';
//get xml from google api
@ -21,7 +21,7 @@ $forecast_list = $xml->xpath("/xml_api_reply/weather/forecast_conditions");
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile Framework - Weather for <?= $information[0]->city['data']; ?></title>
<title>jQuery Mobile Framework - Weather for <?php echo $information[0]->city['data']; ?></title>
<link rel="stylesheet" href="../../themes/default/" />
<script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script>
@ -47,7 +47,7 @@ $forecast_list = $xml->xpath("/xml_api_reply/weather/forecast_conditions");
<form action="" method="get" class="ui-body ui-body-a ">
<label for="location">Change zip code:</label>
<input type="search" name="location" id="location" value="<?=$location; ?>" placeholder="zip code..." data-theme="a" />
<input type="search" name="location" id="location" value="<?php echo$location; ?>" placeholder="zip code..." data-theme="a" />
<input type="submit" data-role="nojs" value="submit" />
</form>
@ -56,10 +56,10 @@ $forecast_list = $xml->xpath("/xml_api_reply/weather/forecast_conditions");
<h1>Currently in <?=$information[0]->city['data']; ?>:</h1>
<div class="current ui-body ui-bar-a ui-corner-all">
<img src="<?= 'http://www.google.com' . $current[0]->icon['data']?>" alt="weather">
<img src="<?php echo 'http://www.google.com' . $current[0]->icon['data']?>" alt="weather">
<p class="condition">
<?= $current[0]->temp_f['data'] ?>&deg; F,
<?= $current[0]->condition['data'] ?>
<?php echo $current[0]->temp_f['data']; ?>&deg; F,
<?php echo $current[0]->condition['data']; ?>
</p>
</div>
@ -67,24 +67,23 @@ $forecast_list = $xml->xpath("/xml_api_reply/weather/forecast_conditions");
<ul data-role="listview" data-inset="true" data-theme="a">
<li data-role="list-divider">This week's forecast</li>
<? foreach ($forecast_list as $forecast) : ?>
<?php foreach ($forecast_list as $forecast) : ?>
<li>
<img src="<?= 'http://www.google.com' . $forecast->icon['data']?>">
<h3><?= $forecast->day_of_week['data']; ?></h3>
<img src="<?php echo 'http://www.google.com' . $forecast->icon['data']; ?>">
<h3><?php echo $forecast->day_of_week['data']; ?></h3>
<p>
<?= $forecast->low['data'] ?>&deg; F - <?= $forecast->high['data'] ?>&deg; F,
<?= $forecast->condition['data'] ?>
<?php echo $forecast->low['data']; ?>&deg; F - <?php echo $forecast->high['data']; ?>&deg; F,
<?php echo $forecast->condition['data']; ?>
</p>
</li>
<? endforeach ?>
<?php endforeach; ?>
</ul>
</div>
</div>
</body>
</html>

View file

@ -30,5 +30,4 @@ $elements = array(
'jquery.mobile.init.js'
);
include('../combine.php');
?>
include('../combine.php');

View file

@ -4,12 +4,12 @@
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {
( function( $, undefined ) {
$.fn.buttonMarkup = function( options ){
$.fn.buttonMarkup = function( options ) {
return this.each( function() {
var el = $( this ),
o = $.extend( {}, $.fn.buttonMarkup.defaults, el.jqmData(), options),
o = $.extend( {}, $.fn.buttonMarkup.defaults, el.jqmData(), options ),
// Classes Defined
buttonClass,
@ -22,9 +22,9 @@ $.fn.buttonMarkup = function( options ){
// if not, try to find closest theme container
if ( !o.theme ) {
var themedParent = el.closest("[class*='ui-bar-'],[class*='ui-body-']");
var themedParent = el.closest( "[class*='ui-bar-'],[class*='ui-body-']" );
o.theme = themedParent.length ?
/ui-(bar|body)-([a-z])/.exec( themedParent.attr("class") )[2] :
/ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) )[2] :
"c";
}
@ -48,7 +48,7 @@ $.fn.buttonMarkup = function( options ){
if ( o.iconpos ) {
buttonClass += " ui-btn-icon-" + o.iconpos;
if ( o.iconpos == "notext" && !el.attr("title") ) {
if ( o.iconpos == "notext" && !el.attr( "title" ) ) {
el.attr( "title", el.text() );
}
}
@ -66,9 +66,9 @@ $.fn.buttonMarkup = function( options ){
.attr( "data-" + $.mobile.ns + "theme", o.theme )
.addClass( buttonClass );
var wrap = ("<D class='" + innerClass + "'><D class='ui-btn-text'></D>" +
var wrap = ( "<D class='" + innerClass + "'><D class='ui-btn-text'></D>" +
( o.icon ? "<span class='" + iconClass + "'></span>" : "" ) +
"</D>").replace(/D/g, o.wrapperEls);
"</D>" ).replace( /D/g, o.wrapperEls );
el.wrapInner( wrap );
});
@ -81,11 +81,11 @@ $.fn.buttonMarkup.defaults = {
wrapperEls: "span"
};
function closestEnabledButton(element)
function closestEnabledButton( element )
{
while (element){
var $ele = $(element);
if ($ele.hasClass("ui-btn") && !$ele.hasClass("ui-disabled")){
while ( element ) {
var $ele = $( element );
if ( $ele.hasClass( "ui-btn" ) && !$ele.hasClass( "ui-disabled" ) ) {
break;
}
element = element.parentNode;
@ -94,35 +94,35 @@ function closestEnabledButton(element)
}
var attachEvents = function() {
$(document).bind({
"vmousedown": function(event) {
var btn = closestEnabledButton(event.target);
if (btn){
var $btn = $(btn),
$( document ).bind( {
"vmousedown": function( event ) {
var btn = closestEnabledButton( event.target );
if ( btn ) {
var $btn = $( btn ),
theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
$btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme );
}
},
"vmousecancel vmouseup": function(event) {
var btn = closestEnabledButton(event.target);
if (btn){
var $btn = $(btn),
"vmousecancel vmouseup": function( event ) {
var btn = closestEnabledButton( event.target );
if ( btn ) {
var $btn = $( btn ),
theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
$btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme );
}
},
"vmouseover focus": function(event) {
var btn = closestEnabledButton(event.target);
if (btn){
var $btn = $(btn),
"vmouseover focus": function( event ) {
var btn = closestEnabledButton( event.target );
if ( btn ) {
var $btn = $( btn ),
theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
$btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme );
}
},
"vmouseout blur": function(event) {
var btn = closestEnabledButton(event.target);
if (btn){
var $btn = $(btn),
"vmouseout blur": function( event ) {
var btn = closestEnabledButton( event.target );
if ( btn ) {
var $btn = $( btn ),
theme = $btn.attr( "data-" + $.mobile.ns + "theme" );
$btn.removeClass( "ui-btn-hover-" + theme ).addClass( "ui-btn-up-" + theme );
}
@ -132,4 +132,4 @@ var attachEvents = function() {
attachEvents = null;
};
})(jQuery);
})( jQuery );

View file

@ -3,146 +3,147 @@
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {
*/
( function( $, undefined ) {
$.widget( "mobile.collapsible", $.mobile.widget, {
options: {
expandCueText: ' click to expand contents',
collapseCueText: ' click to collapse contents',
expandCueText: " click to expand contents",
collapseCueText: " click to collapse contents",
collapsed: false,
heading: '>:header,>legend',
heading: ">:header,>legend",
theme: null,
iconTheme: 'd'
iconTheme: "d"
},
_create: function(){
var $el = this.element,
o = this.options,
collapsibleContain = $el.addClass('ui-collapsible-contain'),
collapsibleHeading = $el.find(o.heading).eq(0),
collapsibleContent = collapsibleContain.wrapInner('<div class="ui-collapsible-content"></div>').find('.ui-collapsible-content'),
collapsibleParent = $el.closest( ":jqmData(role='collapsible-set')" ).addClass('ui-collapsible-set');
//replace collapsibleHeading if it's a legend
if(collapsibleHeading.is('legend')){
collapsibleHeading = $('<div role="heading">'+ collapsibleHeading.html() +'</div>').insertBefore(collapsibleHeading);
collapsibleContain = $el.addClass( "ui-collapsible-contain" ),
collapsibleHeading = $el.find( o.heading ).eq( 0 ),
collapsibleContent = collapsibleContain.wrapInner( '<div class="ui-collapsible-content"></div>' ).find( ".ui-collapsible-content" ),
collapsibleParent = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" );
//replace collapsibleHeading if it's a legend
if( collapsibleHeading.is( "legend" )){
collapsibleHeading = $( '<div role="heading">'+ collapsibleHeading.html() +"</div>" ).insertBefore( collapsibleHeading );
collapsibleHeading.next().remove();
}
}
//drop heading in before content
collapsibleHeading.insertBefore(collapsibleContent);
collapsibleHeading.insertBefore( collapsibleContent );
//modify markup & attributes
collapsibleHeading.addClass('ui-collapsible-heading')
.append('<span class="ui-collapsible-heading-status"></span>')
.wrapInner('<a href="#" class="ui-collapsible-heading-toggle"></a>')
.find('a:eq(0)')
.buttonMarkup({
collapsibleHeading.addClass( "ui-collapsible-heading" )
.append( '<span class="ui-collapsible-heading-status"></span>' )
.wrapInner( '<a href="#" class="ui-collapsible-heading-toggle"></a>' )
.find( "a:eq(0)" )
.buttonMarkup( {
shadow: !!!collapsibleParent.length,
corners:false,
iconPos: 'left',
icon: 'plus',
iconPos: "left",
icon: "plus",
theme: o.theme
})
.find('.ui-icon')
.removeAttr('class')
.buttonMarkup({
} )
.find( ".ui-icon" )
.removeAttr( "class" )
.buttonMarkup( {
shadow: true,
corners:true,
iconPos: 'notext',
icon: 'plus',
iconPos: "notext",
icon: "plus",
theme: o.iconTheme
});
} );
if( !collapsibleParent.length ){
collapsibleHeading
.find('a:eq(0)')
.addClass('ui-corner-all')
.find('.ui-btn-inner')
.addClass('ui-corner-all');
.find( "a:eq(0)" )
.addClass( "ui-corner-all" )
.find( ".ui-btn-inner" )
.addClass( "ui-corner-all" );
}
else {
if( collapsibleContain.jqmData('collapsible-last') ){
if( collapsibleContain.jqmData( "collapsible-last" ) ){
collapsibleHeading
.find('a:eq(0), .ui-btn-inner')
.addClass('ui-corner-bottom');
}
.find( "a:eq(0), .ui-btn-inner" )
.addClass( "ui-corner-bottom" );
}
}
//events
collapsibleContain
.bind('collapse', function(event){
if( !event.isDefaultPrevented() ){
collapsibleContain
.bind( "collapse", function( event ){
if( !event.isDefaultPrevented() && $( event.target ).closest( ".ui-collapsible-contain" ).is( collapsibleContain ) ){
event.preventDefault();
collapsibleHeading
.addClass('ui-collapsible-heading-collapsed')
.find('.ui-collapsible-heading-status').text(o.expandCueText);
collapsibleHeading.find('.ui-icon').removeClass('ui-icon-minus').addClass('ui-icon-plus');
collapsibleContent.addClass('ui-collapsible-content-collapsed').attr('aria-hidden',true);
if( collapsibleContain.jqmData('collapsible-last') ){
.addClass( "ui-collapsible-heading-collapsed" )
.find( ".ui-collapsible-heading-status" ).text( o.expandCueText );
collapsibleHeading.find( ".ui-icon" ).removeClass( "ui-icon-minus" ).addClass( "ui-icon-plus" );
collapsibleContent.addClass( "ui-collapsible-content-collapsed" ).attr( "aria-hidden", true );
if( collapsibleContain.jqmData( "collapsible-last" ) ){
collapsibleHeading
.find('a:eq(0), .ui-btn-inner')
.addClass('ui-corner-bottom');
}
}
})
.bind('expand', function(event){
if( !event.isDefaultPrevented() ){
event.preventDefault();
collapsibleHeading
.removeClass('ui-collapsible-heading-collapsed')
.find('.ui-collapsible-heading-status').text(o.collapseCueText);
collapsibleHeading.find('.ui-icon').removeClass('ui-icon-plus').addClass('ui-icon-minus');
collapsibleContent.removeClass('ui-collapsible-content-collapsed').attr('aria-hidden',false);
if( collapsibleContain.jqmData('collapsible-last') ){
collapsibleHeading
.find('a:eq(0), .ui-btn-inner')
.removeClass('ui-corner-bottom');
.find( "a:eq(0), .ui-btn-inner" )
.addClass( "ui-corner-bottom" );
}
}
})
.trigger(o.collapsed ? 'collapse' : 'expand');
} )
.bind( "expand", function( event ){
if( !event.isDefaultPrevented() ){
event.preventDefault();
collapsibleHeading
.removeClass( "ui-collapsible-heading-collapsed" )
.find( ".ui-collapsible-heading-status" ).text( o.collapseCueText );
collapsibleHeading.find( ".ui-icon" ).removeClass( "ui-icon-plus" ).addClass( "ui-icon-minus" );
collapsibleContent.removeClass( "ui-collapsible-content-collapsed" ).attr( "aria-hidden", false );
if( collapsibleContain.jqmData( "collapsible-last" ) ){
collapsibleHeading
.find( "a:eq(0), .ui-btn-inner" )
.removeClass( "ui-corner-bottom" );
}
}
} )
.trigger( o.collapsed ? "collapse" : "expand" );
//close others in a set
if( collapsibleParent.length && !collapsibleParent.jqmData("collapsiblebound") ){
if( collapsibleParent.length && !collapsibleParent.jqmData( "collapsiblebound" ) ){
collapsibleParent
.jqmData("collapsiblebound", true)
.bind("expand", function( event ){
$(this).find( ".ui-collapsible-contain" )
.not( $(event.target).closest( ".ui-collapsible-contain" ) )
.not( "> .ui-collapsible-contain .ui-collapsible-contain" )
.jqmData( "collapsiblebound", true )
.bind( "expand", function( event ){
$( event.target )
.closest( ".ui-collapsible-contain" )
.siblings( ".ui-collapsible-contain" )
.trigger( "collapse" );
});
var set = collapsibleParent.find( ":jqmData(role=collapsible)" )
} );
var set = collapsibleParent.find( ":jqmData(role=collapsible ):first" );
set.first()
.find('a:eq(0)')
.addClass('ui-corner-top')
.find('.ui-btn-inner')
.addClass('ui-corner-top');
set.last().jqmData('collapsible-last', true)
.find( "a:eq(0)" )
.addClass( "ui-corner-top" )
.find( ".ui-btn-inner" )
.addClass( "ui-corner-top" );
set.last().jqmData( "collapsible-last", true );
}
collapsibleHeading
.bind("vclick", function(e){
if( collapsibleHeading.is('.ui-collapsible-heading-collapsed') ){
collapsibleContain.trigger('expand');
}
.bind( "vclick", function( e ){
if( collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ){
collapsibleContain.trigger( "expand" );
}
else {
collapsibleContain.trigger('collapse');
collapsibleContain.trigger( "collapse" );
}
e.preventDefault();
});
} );
}
});
})( jQuery );
} );
} )( jQuery );

View file

@ -20,7 +20,7 @@
//hash segment before &ui-page= is used to make Ajax request
subPageUrlKey: "ui-page",
//anchor links with a data-rel, or pages with a data-role, that match these selectors will be untrackable in history
//anchor links with a data-rel, or pages with a data-role, that match these selectors will be untrackable in history
//(no change in URL, not bookmarkable)
nonHistorySelectors: "dialog",
@ -36,16 +36,11 @@
//automatically load and show pages based on location.hash
hashListeningEnabled: true,
// TODO: deprecated - remove at 1.0
//automatically handle link clicks through Ajax, when possible
ajaxLinksEnabled: true,
//set default page transition - 'none' for no transitions
defaultPageTransition: "slide",
// TODO: deprecated - remove at 1.0
//automatically handle form submissions through Ajax, when possible
ajaxFormsEnabled: true,
//set default transition - 'none' for no transitions
defaultTransition: "slide",
//set default dialog transition - 'none' for no transitions
defaultDialogTransition: "pop",
//show loading message during Ajax requests
//if false, message will not appear, but loading classes will still be toggled on html el
@ -110,31 +105,41 @@
setTimeout(function() {
$.event.special.scrollstart.enabled = true;
}, 150 );
},
// compile the namespace normalization regex once
normalizeRegex: /-([a-z])/g,
// take a data attribute property, prepend the namespace
// and then camel case the attribute string
nsNormalize: function(prop){
if(!prop) return;
return $.camelCase( $.mobile.ns + prop );
}
});
//mobile version of data and removeData and hasData methods
//ensures all data is set and retrieved using jQuery Mobile's data namespace
$.fn.jqmData = function( prop, value ){
return this.data( prop ? $.mobile.ns + prop : prop, value );
};
$.fn.jqmData = function( prop, value ){
return this.data( prop ? $.mobile.nsNormalize(prop) : prop, value );
};
$.jqmData = function( elem, prop, value ){
return $.data( elem, prop && $.mobile.ns + prop, value );
};
$.jqmData = function( elem, prop, value ){
return $.data( elem, $.mobile.nsNormalize(prop), value );
};
$.fn.jqmRemoveData = function( prop ){
return this.removeData( $.mobile.ns + prop );
};
$.fn.jqmRemoveData = function( prop ){
return this.removeData( $.mobile.nsNormalize(prop) );
};
$.jqmRemoveData = function( elem, prop ){
return $.removeData( elem, prop && $.mobile.ns + prop );
};
$.jqmHasData = function( elem, prop ){
return $.hasData( elem, prop && $.mobile.ns + prop );
};
$.jqmRemoveData = function( elem, prop ){
return $.removeData( elem, $.mobile.nsNormalize(prop) );
};
$.jqmHasData = function( elem, prop ){
return $.hasData( elem, $.mobile.nsNormalize(prop) );
};
// Monkey-patching Sizzle to filter the :jqmData selector
var oldFind = $.find;

View file

@ -4,58 +4,51 @@
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
* Note: Code is in draft form and is subject to change
*/
(function($, undefined ) {
( function( $, undefined ) {
$.widget( "mobile.dialog", $.mobile.widget, {
options: {
closeBtnText: "Close"
},
_create: function(){
var self = this,
$el = self.element;
_create: function() {
var $el = this.element;
/* class the markup for dialog styling */
this.element
$el
//add ARIA role
.attr("role","dialog")
.addClass('ui-page ui-dialog ui-body-a')
.attr( "role", "dialog" )
.addClass( "ui-page ui-dialog ui-body-a" )
.find( ":jqmData(role=header)" )
.addClass('ui-corner-top ui-overlay-shadow')
.addClass( "ui-corner-top ui-overlay-shadow" )
.prepend( "<a href='#' data-" + $.mobile.ns + "icon='delete' data-" + $.mobile.ns + "rel='back' data-" + $.mobile.ns + "iconpos='notext'>"+ this.options.closeBtnText +"</a>" )
.end()
.find('.ui-content:not([class*="ui-body-"])')
.addClass('ui-body-c')
.find( '.ui-content:not([class*="ui-body-"])' )
.addClass( 'ui-body-c' )
.end()
.find( ".ui-content,:jqmData(role='footer')" )
.last()
.addClass('ui-corner-bottom ui-overlay-shadow');
.addClass( "ui-corner-bottom ui-overlay-shadow" );
/* bind events
- clicks and submits should use the closing transition that the dialog opened with
unless a data-transition is specified on the link/form
- if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally
*/
this.element
.bind( "vclick submit", function(e){
var $targetel;
if( e.type == "vclick" ){
$targetel = $(e.target).closest("a");
}
else{
$targetel = $(e.target).closest("form");
}
$el
.bind( "vclick submit", function( e ) {
var $target = $( e.target ).closest( e.type === "vclick" ? "a" : "form" );
if( $targetel.length && !$targetel.jqmData("transition") ){
$targetel
.attr("data-" + $.mobile.ns + "transition", $.mobile.urlHistory.getActive().transition )
.attr("data-" + $.mobile.ns + "direction", "reverse");
if( $target.length && ! $target.jqmData( "transition" ) ) {
var active = $.mobile.urlHistory.getActive() || {};
$target
.attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) )
.attr( "data-" + $.mobile.ns + "direction", "reverse" );
}
});
},
//close method goes back in history
close: function(){
close: function() {
window.history.back();
}
});
})( jQuery );
})( jQuery );

View file

@ -68,6 +68,19 @@ $.fixedToolbars = (function(){
}
}
})
.bind('silentscroll', showEventCallback);
/*
The below checks first for a $(document).scrollTop() value, and if zero, binds scroll events to $(window) instead. If the scrollTop value is actually zero, both will return zero anyway.
Works with $(document), not $(window) : Opera Mobile (WinMO phone; kinda broken anyway)
Works with $(window), not $(document) : IE 7/8
Works with either $(window) or $(document) : Chrome, FF 3.6/4, Android 1.6/2.1, iOS
Needs work either way : BB5, Opera Mobile (iOS)
*/
(( $(document).scrollTop() == 0 ) ? $(window) : $(document))
.bind('scrollstart',function(event){
scrollTriggered = true;
if(stateBefore == null){ stateBefore = currentstate; }
@ -93,8 +106,7 @@ $.fixedToolbars = (function(){
$.fixedToolbars.startShowTimer();
}
stateBefore = null;
})
.bind('silentscroll', showEventCallback);
});
$(window).bind('resize', showEventCallback);
});

View file

@ -58,13 +58,13 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
}
self._cacheVals();
input.attr( "checked", inputtype === "radio" && true || !input.is( ":checked" ) );
input.prop( "checked", inputtype === "radio" && true || !(input.prop("checked")) );
// input set for common radio buttons will contain all the radio
// buttons, but will not for checkboxes. clearing the checked status
// of other radios ensures the active button state is applied properly
self._getInputSet().not(input).removeAttr('checked');
self._getInputSet().not(input).prop('checked', false);
self._updateAll();
return false;
@ -79,6 +79,13 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
},
vclick: function(){
// adds checked attribute to checked input when keyboard is used
if ($(this).is(":checked")) {
$(this).prop( "checked", true);
self._getInputSet().not($(this)).prop('checked', false);
} else {
$(this).prop("checked", false);
}
self._updateAll();
},
@ -125,7 +132,7 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
// input[0].checked expando doesn't always report the proper value
// for checked='checked'
if ( $(input[0]).attr('checked') ) {
if ( $(input[0]).prop('checked') ) {
label.addClass( $.mobile.activeBtnClass );
icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );
@ -143,11 +150,11 @@ $.widget( "mobile.checkboxradio", $.mobile.widget, {
},
disable: function(){
this.element.attr("disabled",true).parent().addClass("ui-disabled");
this.element.prop("disabled",true).parent().addClass("ui-disabled");
},
enable: function(){
this.element.attr("disabled",false).parent().removeClass("ui-disabled");
this.element.prop("disabled",false).parent().removeClass("ui-disabled");
}
});
})( jQuery );

View file

@ -486,7 +486,7 @@ $.widget( "mobile.selectmenu", $.mobile.widget, {
self.menuType = "page";
self.menuPageContent.append( self.list );
$.mobile.changePage(self.menuPage, 'pop', false, true);
$.mobile.changePage( self.menuPage, { transition: 'pop' } );
}
else {
self.menuType = "overlay";

View file

@ -21,6 +21,12 @@
if ( !$.mobile.gradeA() ) {
return;
}
// override ajaxEnabled on platforms that have known conflicts with hash history updates
// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini)
if( window.blackberry && !window.WebKitPoint || window.operamini && Object.prototype.toString.call( window.operamini ) === "[object OperaMini]" ){
$.mobile.ajaxEnabled = false;
}
//add mobile, initial load "rendering" classes to docEl
$html.addClass( "ui-mobile ui-mobile-rendering" );
@ -31,23 +37,32 @@
$.extend($.mobile, {
// turn on/off page loading message.
showPageLoadingMsg: function() {
if( $.mobile.loadingMessage ){
var activeBtn = $( "." + $.mobile.activeBtnClass ).first();
$loader
.appendTo( $.mobile.pageContainer )
//position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top
.css( {
top: $.support.scrollTop && $(window).scrollTop() + $(window).height() / 2 ||
activeBtn.length && activeBtn.offset().top || 100
} );
}
$html.addClass( "ui-loading" );
},
hidePageLoadingMsg: function() {
$html.removeClass( "ui-loading" );
},
// XXX: deprecate for 1.0
pageLoading: function ( done ) {
if ( done ) {
$html.removeClass( "ui-loading" );
$.mobile.hidePageLoadingMsg();
} else {
if( $.mobile.loadingMessage ){
var activeBtn = $( "." + $.mobile.activeBtnClass ).first();
$loader
.appendTo( $.mobile.pageContainer )
//position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top
.css( {
top: $.support.scrollTop && $(window).scrollTop() + $(window).height() / 2 ||
activeBtn.length && activeBtn.offset().top || 100
} );
}
$html.addClass( "ui-loading" );
$.mobile.showPageLoadingMsg();
}
},
@ -73,11 +88,11 @@
$.mobile.pageContainer = $pages.first().parent().addClass( "ui-mobile-viewport" );
//cue page loading message
$.mobile.pageLoading();
$.mobile.showPageLoadingMsg();
// if hashchange listening is disabled or there's no hash deeplink, change to the first page in the DOM
if( !$.mobile.hashListeningEnabled || !$.mobile.path.stripHash( location.hash ) ){
$.mobile.changePage( $.mobile.firstPage, false, true, false, true );
$.mobile.changePage( $.mobile.firstPage, { transition: "none", reverse: true, changeHash: false, fromHashChange: true } );
}
// otherwise, trigger a hashchange to load a deeplink
else {

View file

@ -53,7 +53,7 @@ $( ":jqmData(role='listview')" ).live( "listviewcreate", function() {
childItems = false,
itemtext="";
for (var i = listItems.length; i >= 0; i--) {
for ( var i = listItems.length - 1; i >= 0; i-- ) {
item = $( listItems[i] );
itemtext = item.jqmData( 'filtertext' ) || item.text();

View file

@ -5,6 +5,10 @@
* http://jquery.org/license
*/
(function($, undefined ) {
//Keeps track of the number of lists per page UID
//This allows support for multiple nested list in the same page
//https://github.com/jquery/jquery-mobile/issues/1617
var listCountPerPage = {};
$.widget( "mobile.listview", $.mobile.widget, {
options: {
@ -196,23 +200,31 @@ $.widget( "mobile.listview", $.mobile.widget, {
_idStringEscape: function( str ){
return str.replace(/[^a-zA-Z0-9]/g, '-');
},
_createSubPages: function() {
var parentList = this.element,
parentPage = parentList.closest( ".ui-page" ),
parentId = parentPage.jqmData( "url" ),
parentUrl = parentPage.jqmData( "url" ),
parentId = parentUrl || parentPage[ 0 ][ $.expando ],
parentListId = parentList.attr( "id" ),
o = this.options,
dns = "data-" + $.mobile.ns,
self = this,
persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" );
if ( typeof( listCountPerPage[ parentId ] ) === 'undefined' ) {
listCountPerPage[ parentId ] = -1;
}
parentListId = parentListId || ++listCountPerPage[ parentId ];
$( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) {
var list = $( this ),
listId = list.attr( "id" ) || parentListId + "-" + i,
parent = list.parent(),
nodeEls = $( list.prevAll().toArray().reverse() ),
nodeEls = nodeEls.length ? nodeEls : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" ),
title = nodeEls.first().text(),//url limits to first 30 chars of text
id = parentId + "&" + $.mobile.subPageUrlKey + "=" + self._idStringEscape(title + " " + i),
id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId;
theme = list.jqmData( "theme" ) || o.theme,
countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme,
newPage = list.detach()

File diff suppressed because it is too large Load diff

View file

@ -56,6 +56,7 @@ $.mobile.browser.ie = ( function() {
return v > 4 ? v : !v;
}() );
$.extend( $.support, {
orientation: "orientation" in window,
touch: "ontouchend" in document,

View file

@ -73,6 +73,33 @@
$.each(fns, function(i, fn){
setTimeout(fn, i * interval);
});
},
pageSequence: function(fns, event){
var fn = fns.shift(),
self = this;
if(fn === undefined) return;
event = event || "changepage";
// if a changepage or defined event is never triggered
// continue in the sequence to alert possible failures
var warnTimer = setTimeout(function(){
self.pageSequence(fns, event);
}, 2000);
// bind the recursive call to the event
$.mobile.pageContainer.one(event, function(){
clearTimeout(warnTimer);
// Let the current stack unwind before we fire off the next item in the sequence.
setTimeout(function(){ self.pageSequence(fns, event); }, 0);
});
// invoke the function which should, in some fashion,
// trigger the defined event
fn();
}
};
})(jQuery);

View file

@ -34,57 +34,75 @@
ok($.mobile.gradeA());
});
});
test( "$.mobile.nsNormalize works properly with namespace defined (test default)", function(){
equal($.mobile.nsNormalize("foo"), "nstestFoo", "appends ns and initcaps");
equal($.mobile.nsNormalize("fooBar"), "nstestFooBar", "leaves capped strings intact");
equal($.mobile.nsNormalize("foo-bar"), "nstestFooBar", "changes dashed strings");
equal($.mobile.nsNormalize("foo-bar-bak"), "nstestFooBarBak", "changes multiple dashed strings");
});
test( "$.mobile.nsNormalize works properly with an empty namespace", function(){
var realNs = $.mobile.ns;
$.mobile.ns = "";
equal($.mobile.nsNormalize("foo"), "foo", "leaves uncapped and undashed");
equal($.mobile.nsNormalize("fooBar"), "fooBar", "leaves capped strings intact");
equal($.mobile.nsNormalize("foo-bar"), "fooBar", "changes dashed strings");
equal($.mobile.nsNormalize("foo-bar-bak"), "fooBarBak", "changes multiple dashed strings");
$.mobile.ns = realNs;
});
//data tests
test( "$.fn.jqmData and $.fn.jqmRemoveData methods are working properly", function(){
same( $("body").jqmData("foo", true), $("body"), "setting data returns the element" );
same( $("body").jqmData("foo"), true, "getting data returns the right value" );
same( $("body").data($.mobile.ns + "foo"), true, "data was set using namespace" );
same( $("body").data($.mobile.nsNormalize("foo")), true, "data was set using namespace" );
same( $("body").jqmData("foo", undefined), true, "getting data still returns the value if there's an undefined second arg" );
same( $("body").jqmData(), { "nstest-foo": true}, "passing no arguments returns a hash with all set properties" );
same( $("body").jqmData(undefined), { "nstest-foo": true}, "passing a single undefined argument returns a hash with all set properties" );
same( $("body").jqmData(undefined, undefined), {"nstest-foo": true}, "passing 2 undefined arguments returns a hash with all set properties" );
same( $("body").jqmData(), { "nstestFoo": true}, "passing no arguments returns a hash with all set properties" );
same( $("body").jqmData(undefined), { "nstestFoo": true}, "passing a single undefined argument returns a hash with all set properties" );
same( $("body").jqmData(undefined, undefined), {"nstestFoo": true}, "passing 2 undefined arguments returns a hash with all set properties" );
same( $("body").jqmRemoveData("foo"), $("body"), "jqmRemoveData returns the element" );
same( $("body").jqmData("foo"), undefined, "jqmRemoveData properly removes namespaced data" );
});
test( "$.jqmData and $.jqmRemoveData methods are working properly", function(){
same( $.jqmData(document.body, "foo", true), true, "setting data returns the value" );
same( $.jqmData(document.body, "foo"), true, "getting data returns the right value" );
same( $.data(document.body, $.mobile.ns + "foo"), true, "data was set using namespace" );
same( $.data(document.body, $.mobile.nsNormalize("foo")), true, "data was set using namespace" );
same( $.jqmData(document.body, "foo", undefined), true, "getting data still returns the value if there's an undefined second arg" );
same( $.jqmData(document.body), { "nstest-foo": true}, "passing no arguments returns a hash with all set properties" );
same( $.jqmData(document.body, undefined), { "nstest-foo": true}, "passing a single undefined argument returns a hash with all set properties" );
same( $.jqmData(document.body, undefined, undefined), {"nstest-foo": true}, "passing 2 undefined arguments returns a hash with all set properties" );
same( $.jqmData(document.body), { "nstestFoo": true}, "passing no arguments returns a hash with all set properties" );
same( $.jqmData(document.body, undefined), { "nstestFoo": true}, "passing a single undefined argument returns a hash with all set properties" );
same( $.jqmData(document.body, undefined, undefined), {"nstestFoo": true}, "passing 2 undefined arguments returns a hash with all set properties" );
same( $.jqmRemoveData(document.body, "foo"), undefined, "jqmRemoveData returns the undefined value" );
same( $("body").jqmData("foo"), undefined, "jqmRemoveData properly removes namespaced data" );
});
test( "jqmHasData method is working properly", function(){
same( $.jqmHasData(document.body, "foo"), false, "body has no data defined under 'foo'" );
$.jqmData(document.body, "foo", true);
same( $.jqmHasData(document.body, "foo"), true, "after setting, body has data defined under 'foo' equal to true" );
$.jqmRemoveData(document.body, "foo");
});
})(jQuery);

View file

@ -3,7 +3,7 @@
*/
(function($){
var mobilePage = undefined,
libName = 'jquery.mobile.init.js',
libName = 'jquery.mobile.init.js',
coreLib = 'jquery.mobile.core.js',
extendFn = $.extend,
setGradeA = function(value) { $.mobile.gradeA = function(){ return value; }; },
@ -27,9 +27,6 @@
// NOTE reset for pageLoading tests
$('.ui-loader').remove();
// reset meta view port content
$.mobile.metaViewportContent = metaViewportContentDefault;
}
});
@ -76,7 +73,7 @@
ok($("html").hasClass("ui-mobile"));
});
var findFirstPage = function() {
return $(":jqmData(role='page')").first();

View file

@ -80,22 +80,40 @@
<ul data-nstest-role="listview" data-nstest-inset="true">
<li>Item 1</li>
<li>Item 2</li>
<li>Parent Item
<li>Item 3
<ul data-nstest-role="listview">
<li>Sub Item 10</li>
<li>Sub Item 11</li>
<li>Sub Item 12</li>
<li>Item A-3-0</li>
<li>Item A-3-1</li>
<li>Item A-3-2</li>
</ul>
</li>
</ul>
<ul data-nstest-role="listview" data-nstest-inset="true">
<li>Item 3</li>
<li>Item 4</li>
<li>Parent Item
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ul data-nstest-role="listview">
<li>Sub Item 20</li>
<li>Sub Item 21</li>
<li>Sub Item 22</li>
<li>Item B-3-0
<ul data-nstest-role="listview">
<li>Item B-3-0-0</li>
<li>Item B-3-0-1
<ul data-nstest-role="listview">
<li>Item B-3-0-1-0</li>
<li>Item B-3-0-1-1</li>
<li>Item B-3-0-1-2</li>
</ul>
</li>
<li>Item B-3-0-2</li>
</ul>
</li>
<li>Item B-3-1
<ul data-nstest-role="listview">
<li>Item B-3-1-0</li>
<li>Item B-3-1-1</li>
<li>Item B-3-1-2</li>
</ul>
</li>
<li>Item B-3-2</li>
</ul>
</li>
</ul>

View file

@ -4,6 +4,7 @@
// TODO split out into seperate test files
(function($){
$.mobile.defaultTransition = "none";
module('Basic Linked list', {
setup: function(){
@ -19,152 +20,226 @@
});
asyncTest( "Slides to the listview page when the li a is clicked", function() {
$.testHelper.openPage("#basic-linked-test");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#basic-linked-test");
},
setTimeout(function(){
$('#basic-linked-test li a').first().click();
}, 500);
function(){
$('#basic-linked-test li a').first().click();
},
setTimeout(function() {
ok($('#basic-link-results').hasClass('ui-page-active'));
start();
}, 1000);
function(){
ok($('#basic-link-results').hasClass('ui-page-active'));
start();
}
]);
});
asyncTest( "Slides back to main page when back button is clicked", function() {
$.testHelper.openPage("#basic-link-results");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#basic-link-results");
},
window.history.back();
function(){
window.history.back();
},
setTimeout(function() {
ok($('#basic-linked-test').hasClass('ui-page-active'));
start();
}, 1000);
function(){
ok($('#basic-linked-test').hasClass('ui-page-active'));
start();
}
]);
});
module('Nested List Test');
asyncTest( "Changes page to nested list test and enhances", function() {
$.testHelper.openPage("#nested-list-test");
setTimeout(function() {
ok($('#nested-list-test').hasClass('ui-page-active'), "makes nested list test page active");
ok($(':jqmData(url="nested-list-test&ui-page=More-animals-0")').length == 1, "Adds first UL to the page");
ok($(':jqmData(url="nested-list-test&ui-page=Groups-of-animals-1")').length == 1, "Adds second nested UL to the page");
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#nested-list-test");
},
function(){
ok($('#nested-list-test').hasClass('ui-page-active'), "makes nested list test page active");
ok($(':jqmData(url="nested-list-test&ui-page=0-0")').length == 1, "Adds first UL to the page");
ok($(':jqmData(url="nested-list-test&ui-page=0-1")').length == 1, "Adds second nested UL to the page");
start();
}
]);
});
asyncTest( "change to nested page when the li a is clicked", function() {
$.testHelper.openPage("#nested-list-test");
$('.ui-page-active li:eq(1) a:eq(0)').click();
setTimeout(function() {
var $new_page = $(':jqmData(url="nested-list-test&ui-page=More-animals-0")');
ok($new_page.hasClass('ui-page-active'), 'Makes the nested page the active page.');
ok($('.ui-listview', $new_page).find(":contains('Rhumba of rattlesnakes')").length == 1, "The current page should have the proper text in the list.");
ok($('.ui-listview', $new_page).find(":contains('Shoal of Bass')").length == 1, "The current page should have the proper text in the list.");
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#nested-list-test");
},
function(){
$('.ui-page-active li:eq(1) a:eq(0)').click();
},
function(){
var $new_page = $(':jqmData(url="nested-list-test&ui-page=0-0")');
ok($new_page.hasClass('ui-page-active'), 'Makes the nested page the active page.');
ok($('.ui-listview', $new_page).find(":contains('Rhumba of rattlesnakes')").length == 1, "The current page should have the proper text in the list.");
ok($('.ui-listview', $new_page).find(":contains('Shoal of Bass')").length == 1, "The current page should have the proper text in the list.");
start();
}
]);
});
asyncTest( "should go back to top level when the back button is clicked", function() {
$.testHelper.openPage("#nested-list-test&ui-page=More-animals-0");
window.history.back();
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#nested-list-test&ui-page=0-0");
},
setTimeout(function() {
ok($('#nested-list-test').hasClass('ui-page-active'), 'Transitions back to the parent nested page');
start();
}, 1000);
function(){
window.history.back();
},
function(){
ok($('#nested-list-test').hasClass('ui-page-active'), 'Transitions back to the parent nested page');
start();
}
]);
});
test( "nested list title should use first text node, regardless of line breaks", function(){
ok($('#nested-list-test .linebreaknode').text() === "More animals", 'Text should be "More animals"');
});
asyncTest( "Multiple nested lists on a page", function() {
// https://github.com/jquery/jquery-mobile/issues/1617
$.testHelper.openPage("#nested-lists-test");
asyncTest( "Multiple nested lists on a page with same labels", function() {
$.testHelper.pageSequence([
function(){
// https://github.com/jquery/jquery-mobile/issues/1617
$.testHelper.openPage("#nested-lists-test");
},
setTimeout(function() {
$('.ui-page-active li:eq(2) a:eq(0)').click();
function(){
// Click on the link of the third li element
$('.ui-page-active li:eq(2) a:eq(0)').click();
},
equal($('.ui-page-active .ui-content .ui-listview li').text(), "Sub Item 10Sub Item 11Sub Item 12", 'Text should be "Sub Item 10Sub Item 11Sub Item 12"');
start();
}, 500);
function(){
equal($('.ui-page-active .ui-content .ui-listview li').text(), "Item A-3-0Item A-3-1Item A-3-2", 'Text should be "Item A-3-0Item A-3-1Item A-3-2"');
start();
}
]);
});
module('Ordered Lists');
asyncTest( "changes to the numbered list page and enhances it", function() {
location.href = location.href.split('#')[0] + "#numbered-list-test";
setTimeout(function() {
var $new_page = $('#numbered-list-test');
ok($new_page.hasClass('ui-page-active'), "Makes the new page active when the hash is changed.");
ok($('.ui-link-inherit', $new_page).first().text() == "Number 1", "The text of the first LI should be Number 1");
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#numbered-list-test");
},
function(){
var $new_page = $('#numbered-list-test');
ok($new_page.hasClass('ui-page-active'), "Makes the new page active when the hash is changed.");
ok($('.ui-link-inherit', $new_page).first().text() == "Number 1", "The text of the first LI should be Number 1");
start();
}
]);
});
asyncTest( "changes to number 1 page when the li a is clicked", function() {
$('#numbered-list-test li a').first().click();
setTimeout(function() {
ok($('#numbered-list-results').hasClass('ui-page-active'), "The new numbered page was transitioned correctly.");
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$('#numbered-list-test li a').first().click();
},
function(){
ok($('#numbered-list-results').hasClass('ui-page-active'), "The new numbered page was transitioned correctly.");
start();
}
]);
});
asyncTest( "takes us back to the numbered list when the back button is clicked", function() {
$.testHelper.openPage('#numbered-list-test')
$.testHelper.openPage('#numbered-list-results')
window.history.back();
setTimeout(function() {
ok($('#numbered-list-test').hasClass('ui-page-active'));
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$.testHelper.openPage('#numbered-list-test')
},
function(){
$.testHelper.openPage('#numbered-list-results')
},
function(){
window.history.back();
},
function(){
ok($('#numbered-list-test').hasClass('ui-page-active'));
start();
}
]);
});
module('Read only list');
asyncTest( "changes to the read only page when hash is changed", function() {
location.href = location.href.split('#')[0] + "#read-only-list-test";
setTimeout(function() {
var $new_page = $('#read-only-list-test');
ok($new_page.hasClass('ui-page-active'), "makes the read only page the active page");
ok($('li', $new_page).first().text() === "Read", "The first LI has the proper text.");
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#read-only-list-test")
},
function(){
var $new_page = $('#read-only-list-test');
ok($new_page.hasClass('ui-page-active'), "makes the read only page the active page");
ok($('li', $new_page).first().text() === "Read", "The first LI has the proper text.");
start();
}
]);
});
module('Split view list');
asyncTest( "changes the page to the split view list and enhances it correctly.", function() {
$.testHelper.openPage("#split-list-test");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#split-list-test");
},
setTimeout(function() {
var $new_page = $('#split-list-test');
ok($('.ui-li-link-alt', $new_page).length == 3);
ok($('.ui-link-inherit', $new_page).length == 3);
start();
}, 1000);
function(){
var $new_page = $('#split-list-test');
ok($('.ui-li-link-alt', $new_page).length == 3);
ok($('.ui-link-inherit', $new_page).length == 3);
start();
}
]);
});
asyncTest( "change the page to the split view page 1 when the first link is clicked", function() {
$.testHelper.openPage("#split-list-test");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#split-list-test");
},
setTimeout(function(){
$('.ui-page-active .ui-li a:eq(0)').click();
}, 500);
function(){
$('.ui-page-active .ui-li a:eq(0)').click();
},
setTimeout(function() {
ok($('#split-list-link1').hasClass('ui-page-active'));
start();
}, 1000);
function(){
ok($('#split-list-link1').hasClass('ui-page-active'));
start();
}
]);
});
asyncTest( "Slide back to the parent list view when the back button is clicked", function() {
$.testHelper.openPage("#split-list-test");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#split-list-test");
},
$.testHelper.sequence([
function(){
$('.ui-page-active .ui-listview a:eq(0)').click();
},
@ -173,36 +248,45 @@
history.back();
},
function() {
function(){
ok($('#split-list-test').hasClass('ui-page-active'));
start();
}
], 1000);
]);
});
asyncTest( "Clicking on the icon (the second link) should take the user to other a href of this LI", function() {
$.testHelper.openPage("#split-list-test");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#split-list-test");
},
setTimeout(function(){
$('.ui-page-active .ui-li-link-alt:eq(0)').click();
}, 500);
function(){
$('.ui-page-active .ui-li-link-alt:eq(0)').click();
},
setTimeout(function() {
ok($('#split-list-link2').hasClass('ui-page-active'));
start();
}, 1000);
function(){
ok($('#split-list-link2').hasClass('ui-page-active'));
start();
}
]);
});
module( "List Dividers" );
asyncTest( "Makes the list divider page the active page and enhances it correctly.", function() {
location.href = location.href.split('#')[0] + "#list-divider-test";
setTimeout(function() {
var $new_page = $('#list-divider-test');
ok($new_page.find('.ui-li-divider').length == 2);
ok($new_page.hasClass('ui-page-active'));
start();
}, 1000);
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#list-divider-test");
},
function(){
var $new_page = $('#list-divider-test');
ok($new_page.find('.ui-li-divider').length == 2);
ok($new_page.hasClass('ui-page-active'));
start();
}
]);
});
module( "Search Filter");
@ -339,4 +423,4 @@
ok(!$('#programmatically-generated-list-items li:first-child').hasClass("ui-corner-bottom"), "First list item should not have class ui-corner-bottom");
});
})(jQuery);
})(jQuery);

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Mobile Navigation Test Suite</title>
<script>
// This unit test requires a base tag to be set within the file.
// Most browsers require a base tag with an @href URL that is absolute.
// We need to dynamically inject the base tag so we can prefix it with
// the location of this test on the server without any server-side language
// requirements.
var baseUrl = location.href.replace(/[^\?\#\/]*(\?[^#]*)?(#.*)?$/, "");
document.write("<base href=\"" + baseUrl + "base-tests/app-base/\"/>\n");
</script>
<script src="../../../../../js/jquery.js"></script>
<script src="../../../jquery.setNameSpace.js"></script>
<script src="../../../../../js/"></script>
<script src="../../../../../tests/jquery.testHelper.js"></script>
<link rel="stylesheet" href="../../../../../themes/default/"/>
<link rel="stylesheet" href="../../../../../external/qunit.css"/>
<script src="../../../../../external/qunit.js"></script>
<script src="../../navigation_base.js"></script>
</head>
<body>
<h1 id="qunit-header">jQuery Mobile Navigation Base Tag Test Suite</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests">
</ol>
<div id="internal-page-1" data-nstest-role="page">
<a href="base-page-1.html" class="bp1"></a>
<a href="base-page-2.html" class="bp2"></a>
<a href="../content/content-page-1.html" class="cp1"></a>
<a href="../content/content-page-2.html" class="cp2"></a>
<a href="#internal-page-2" class="ip2"></a>
<img src="images/internal-page-1.png">
</div>
<div id="internal-page-2" data-nstest-role="page">
<a href="base-page-1.html" class="bp1"></a>
<a href="base-page-2.html" class="bp2"></a>
<a href="../content/content-page-1.html" class="cp1"></a>
<a href="../content/content-page-2.html" class="cp2"></a>
<a href="#internal-page-1" class="ip1"></a>
<img src="images/internal-page-2.png">
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="base-page-1" data-nstest-role="page">
<a href="base-page-2.html" class="bp2">Base Page 2</a>
<a href="../content/content-page-1.html" class="cp1">Content Page 1</a>
<a href="../../#internal-page-1" class="ip1">Internal Page 1</a>
<a href="../../#internal-page-2" class="ip2">Internal Page 2</a>
<img src="images/base-page-1.png">
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="base-page-2" data-nstest-role="page">
<a href="base-page-1.html" class="bp1">Base Page 1</a>
<a href="../content/content-page-1.html" class="cp1">Content Page 1</a>
<a href="../../#internal-page-1" class="ip1">Internal Page 1</a>
<a href="../../#internal-page-2" class="ip2">Internal Page 2</a>
<img src="images/base-page-2.png">
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="content-page-1" data-nstest-role="page">
<a href="content-page-2.html" class="cp2">Content Page 2</a>
<a href="../app-base/base-page-1.html" class="bp1">Base Page 1</a>
<a href="../../#internal-page-1" class="ip1">Internal Page 1</a>
<a href="../../#internal-page-2" class="ip2">Internal Page 2</a>
<img src="images/content-page-1.png">
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="content-page-2" data-nstest-role="page">
<a href="content-page-1.html" class="cp1">Content Page 1</a>
<a href="../app-base/base-page-1.html" class="bp1">Base Page 1</a>
<a href="../../#internal-page-1" class="ip1">Internal Page 1</a>
<a href="../../#internal-page-2" class="ip2">Internal Page 2</a>
<img src="images/content-page-2.png">
</div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-nstest-role="page">
<div class="test-value">doc rel test one</div>
</div>
</body>
</html>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="changepage-data" data-nstest-role="page"> </div>
</body>
</html>

View file

@ -16,8 +16,9 @@
<script src="../../../external/qunit.js"></script>
<script src="navigation_transitions.js"></script>
<script src="navigation_helpers.js"></script>
<script src="navigation_core.js"></script>
<script src="navigation_helpers.js"></script>
<script src="navigation_core.js"></script>
<script src="navigation_paths.js"></script>
</head>
<body>
@ -181,5 +182,49 @@
<div data-nstest-role="page" id="dialog-param-link">
<a href="dialog-param-test/dialog-param.html">go</a>
</div>
<div data-nstest-role="page" id="pathing-tests">
<!-- doc rel links -->
<a href="file.html" id="doc-rel-test-one">go</a>
<a href="path-tests/file.html" id="doc-rel-test-two">go</a>
<a href="path-tests/sub-dir/file.html" id="doc-rel-test-three">go</a>
<a href="path-tests/sub-dir/" id="doc-rel-test-four">go</a>
<a href="../../unit/navigation/path-tests/parent-ref.html" id="doc-rel-test-five">go</a>
<a href="../../unit/navigation/path-tests/parent/" id="doc-rel-test-six">go</a>
<!-- site rel links -->
<!-- these will be altered before the test suite runs to use the current path -->
<a href="file.html" id="site-rel-test-one" class="site-rel">go</a>
<a href="path-tests/file.html" id="site-rel-test-two" class="site-rel">go</a>
<a href="path-tests/sub-dir/file.html" id="site-rel-test-three" class="site-rel">go</a>
<a href="path-tests/sub-dir/" id="site-rel-test-four" class="site-rel">go</a>
<a href="../../unit/navigation/path-tests/parent-ref.html" id="site-rel-test-five" class="site-rel">go</a>
<a href="../../unit/navigation/path-tests/parent/" id="site-rel-test-six" class="site-rel">go</a>
<!-- protocol rel links -->
<!-- these will be altered before the test suite runs to use the
current domain and path -->
<a href="file.html" id="protocol-rel-test-one" class="protocol-rel">go</a>
<a href="path-tests/file.html" id="protocol-rel-test-two" class="protocol-rel">go</a>
<a href="path-tests/sub-dir/file.html" id="protocol-rel-test-three" class="protocol-rel">go</a>
<a href="path-tests/sub-dir/" id="protocol-rel-test-four" class="protocol-rel">go</a>
<a href="../../unit/navigation/path-tests/parent-ref.html" id="protocol-rel-test-five" class="protocol-rel">go</a>
<a href="../../unit/navigation/path-tests/parent/" id="protocol-rel-test-six" class="protocol-rel">go</a>
<!-- absolute links -->
<!-- these will be altered before the test suite runs to use the
current protocol, domain and path -->
<a href="file.html" id="absolute-test-one" class="absolute">go</a>
<a href="path-tests/file.html" id="absolute-test-two" class="absolute">go</a>
<a href="path-tests/sub-dir/file.html" id="absolute-test-three" class="absolute">go</a>
<a href="path-tests/sub-dir/" id="absolute-test-four" class="absolute">go</a>
<a href="../../unit/navigation/path-tests/parent-ref.html" id="absolute-test-five" class="absolute">go</a>
<a href="../../unit/navigation/path-tests/parent/" id="absolute-test-six" class="absolute">go</a>
</div>
<div data-nstest-role="page" id="pathing-tests-reset">
<div class="reset-value">page didn't change!</div>
</div>
</body>
</html>

View file

@ -0,0 +1,114 @@
/*
* mobile navigation base tag unit tests
*/
(function($){
var baseDir = $.mobile.path.parseUrl($("base").attr("href")).directory,
contentDir = $.mobile.path.makePathAbsolute("../content/", baseDir);
module('jquery.mobile.navigation.js - base tag', {
setup: function(){
if ( location.hash ) {
stop();
$(document).one("changepage", function() {
start();
} );
location.hash = "";
}
}
});
asyncTest( "can navigate between internal and external pages", function(){
$.testHelper.pageSequence([
function(){
// Navigate from default internal page to another internal page.
$.testHelper.openPage("#internal-page-2");
},
function(){
// Verify that we are on the 2nd internal page.
same(location.hash, "#internal-page-2", "navigate to internal page");
// Navigate to a page that is in the base directory. Note that the application
// document and this new page are *NOT* in the same directory.
$("#internal-page-2 .bp1").click();
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + baseDir + "base-page-1.html", "navigate from internal page to page in base directory");
// Navigate to another page in the same directory as the current page.
$("#base-page-1 .bp2").click();
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + baseDir + "base-page-2.html", "navigate from base directory page to another base directory page");
// Navigate to another page in a directory that is the sibling of the base.
$("#base-page-2 .cp1").click();
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + contentDir + "content-page-1.html", "navigate from base directory page to a page in a different directory hierarchy");
// Navigate to another page in a directory that is the sibling of the base.
$("#content-page-1 .cp2").click();
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + contentDir + "content-page-2.html", "navigate to another page within the same non-base directory hierarchy");
// Navigate to an internal page.
$("#content-page-2 .ip1").click();
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#internal-page-1", "navigate from a page in a non-base directory to an internal page");
// Try calling changePage() directly with a relative path.
$.mobile.changePage("base-page-1.html");
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + baseDir + "base-page-1.html", "call changePage() with a filename (no path)");
// Try calling changePage() directly with a relative path.
$.mobile.changePage("../content/content-page-1.html");
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + contentDir + "content-page-1.html", "call changePage() with a relative path containing up-level references");
// Try calling changePage() with an id
$.mobile.changePage("content-page-2.html");
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#" + contentDir + "content-page-2.html", "call changePage() with a relative path should resolve relative to current page");
// Try calling changePage() with an id
$.mobile.changePage("#internal-page-2");
},
function(){
// Verify that we are on the expected page.
same(location.hash, "#internal-page-2", "call changePage() with a page id");
// Try calling changePage() with an id
$.mobile.changePage("internal-page-1");
},
function(){
// Previous load should have failed and left us on internal-page-2.
same(location.hash, "#internal-page-2", "calling changePage() with a page id that is not prefixed with '#' should not change page");
start();
}]);
});
})(jQuery);

View file

@ -3,42 +3,30 @@
*/
(function($){
var changePageFn = $.mobile.changePage,
originalTitle = document.title;
originalTitle = document.title,
siteDirectory = location.pathname.replace(/[^/]+$/, "");
module('jquery.mobile.navigation.js', {
setup: function(){
$.mobile.urlHistory.stack = [];
$.mobile.urlHistory.activeIndex = 0;
$.mobile.changePage = changePageFn;
document.title = originalTitle;
location.hash = "";
if ( location.hash ) {
stop();
$(document).one("changepage", function() {
start();
} );
location.hash = "";
}
}
});
asyncTest( "changepage will only run once when a new page is visited", function(){
var called = 0,
newChangePage = function(a,b,c,d,e){
changePageFn( a,b,c,d,e );
called ++;
};
$.testHelper.sequence([
// avoid initial page load triggering changePage early
function(){
$.mobile.changePage = newChangePage;
$('#foo a').click();
},
function(){
ok(called == 1, "change page should be called once");
start();
}], 500);
});
asyncTest( "forms with data attribute ajax set to false will not call changePage", function(){
var called = false,
newChangePage = function(){
called = true;
};
var called = false;
var newChangePage = function(){
called = true;
};
$.testHelper.sequence([
// avoid initial page load triggering changePage early
@ -54,7 +42,7 @@
function(){
ok(!called, "change page should not be called");
start();
}], 500);
}], 1000);
});
asyncTest( "forms with data attribute ajax not set or set to anything but false will call changepage", function(){
@ -132,7 +120,6 @@
//url listening
function testListening( prop ){
prop = false;
var stillListening = false;
$(document).bind("pagebeforehide", function(){
stillListening = true;
@ -147,7 +134,7 @@
}
asyncTest( "ability to disable our hash change event listening internally", function(){
testListening( $.mobile.urlHistory.ignoreNextHashChange );
testListening( ! $.mobile.urlHistory.ignoreNextHashChange );
});
asyncTest( "ability to disable our hash change event listening globally", function(){
@ -166,7 +153,7 @@
};
test( "when loading a page where data-url is not defined on a sub element hash defaults to the url", function(){
testDataUrlHash("#non-data-url a", new RegExp("^#/tests/unit/navigation/data-url-tests/non-data-url.html$"));
testDataUrlHash("#non-data-url a", new RegExp("^#" + siteDirectory + "data-url-tests/non-data-url.html$"));
});
test( "data url works for nested paths", function(){
@ -182,9 +169,8 @@
});
asyncTest( "last entry choosen amongst multiple identical url history stack entries on hash change", function(){
$.testHelper.openPage("#dup-history-first");
$.testHelper.sequence([
$.testHelper.pageSequence([
function(){ $.testHelper.openPage("#dup-history-first"); },
function(){ $("#dup-history-first a").click(); },
function(){ $("#dup-history-second a:first").click(); },
function(){ $("#dup-history-first a").click(); },
@ -195,15 +181,15 @@
// fourth page (third index) in the stack to account for first page being hash manipulation,
// the third page is dup-history-second which has two entries in history
// the test is to make sure the index isn't 1 in this case, or the first entry for dup-history-second
same($.mobile.urlHistory.activeIndex, 3, "should be the third page in the stack");
same($.mobile.urlHistory.activeIndex, 4, "should be the fourth page in the stack");
start();
}], 1000);
}]);
});
asyncTest( "going back from a page entered from a dialog skips the dialog and goes to the previous page", function(){
$.testHelper.openPage("#skip-dialog-first");
$.testHelper.pageSequence([
// setup
function(){ $.testHelper.openPage("#skip-dialog-first"); },
$.testHelper.sequence([
// transition to the dialog
function(){ $("#skip-dialog-first a").click(); },
@ -217,13 +203,14 @@
function(){
same(location.hash, "#skip-dialog-first", "should be the first page in the sequence");
start();
}], 1000);
}]);
});
asyncTest( "going forward from a page entered from a dialog skips the dialog and goes to the next page", function(){
$.testHelper.openPage("#skip-dialog-first");
$.testHelper.pageSequence([
// setup
function(){ $.testHelper.openPage("#skip-dialog-first"); },
$.testHelper.sequence([
// transition to the dialog
function(){ $("#skip-dialog-first a").click(); },
@ -240,14 +227,15 @@
function(){
same(location.hash, "#skip-dialog-second", "should be the second page after the dialog");
start();
}], 1000);
}]);
});
asyncTest( "going back from a dialog triggered from a dialog should result in the first dialog ", function(){
$.testHelper.openPage("#nested-dialog-page");
$.testHelper.pageSequence([
// setup
function(){ $.testHelper.openPage("#nested-dialog-page"); },
$.testHelper.sequence([
// transition to the dialog
function(){ $("#nested-dialog-page a").click(); },
@ -261,13 +249,14 @@
function(){
same($(".ui-page-active")[0], $("#nested-dialog-first")[0], "should be the first dialog");
start();
}], 1000);
}]);
});
asyncTest( "loading a relative file path after an embeded page works", function(){
$.testHelper.openPage("#relative-after-embeded-page-first");
$.testHelper.pageSequence([
// transition second page
function(){ $.testHelper.openPage("#relative-after-embeded-page-first"); },
$.testHelper.sequence([
// transition second page
function(){ $("#relative-after-embeded-page-first a").click(); },
@ -279,13 +268,15 @@
// data attribute intentionally left without namespace
same($(".ui-page-active").data("other"), "for testing", "should be relative ajax loaded page");
start();
}], 1000);
}]);
});
asyncTest( "Page title updates properly when clicking back to previous page", function(){
$.testHelper.openPage("#relative-after-embeded-page-first");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#relative-after-embeded-page-first");
},
$.testHelper.sequence([
function(){
window.history.back();
},
@ -294,13 +285,15 @@
same(document.title, "jQuery Mobile Navigation Test Suite");
start();
}
], 500);
]);
});
asyncTest( "Page title updates properly from title tag when loading an external page", function(){
$.testHelper.openPage("#ajax-title-page");
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#ajax-title-page");
},
$.testHelper.sequence([
function(){
$("#titletest1").click();
},
@ -309,12 +302,15 @@
same(document.title, "Title Tag");
start();
}
], 500);
]);
});
asyncTest( "Page title updates properly from data-title attr when loading an external page", function(){
$.testHelper.openPage("#ajax-title-page");
$.testHelper.sequence([
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#ajax-title-page");
},
function(){
$("#titletest2").click();
},
@ -323,12 +319,15 @@
same(document.title, "Title Attr");
start();
}
], 500);
]);
});
asyncTest( "Page title updates properly from heading text in header when loading an external page", function(){
$.testHelper.openPage("#ajax-title-page");
$.testHelper.sequence([
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#ajax-title-page");
},
function(){
$("#titletest3").click();
},
@ -337,12 +336,15 @@
same(document.title, "Title Heading");
start();
}
], 500);
]);
});
asyncTest( "Page links to the current active page result in the same active page", function(){
$.testHelper.openPage("#self-link");
$.testHelper.sequence([
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#self-link");
},
function(){
$("a[href='#self-link']").click();
},
@ -351,11 +353,11 @@
same($.mobile.activePage[0], $("#self-link")[0], "self-link page is still the active page" );
start();
}
], 500);
]);
});
asyncTest( "links on subdirectory pages with query params use an absolute path", function(){
$.testHelper.sequence([
asyncTest( "links on subdirectory pages with query params append the params and load the page", function(){
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#data-url-tests/non-data-url.html");
},
@ -365,15 +367,15 @@
},
function(){
same(location.hash, "#data-url-tests/non-data-url.html?foo=bar");
ok($(".ui-page-active").jqmData("url").indexOf("?foo=bar") > -1, "the query params are in the hash");
same(location.hash, "#" + siteDirectory + "data-url-tests/non-data-url.html?foo=bar");
ok($(".ui-page-active").jqmData("url").indexOf("?foo=bar") > -1, "the query params are in the data url");
start();
}
], 1000);
]);
});
asyncTest( "identical query param link doesn't add additional set of query params", function(){
$.testHelper.sequence([
$.testHelper.pageSequence([
function(){
$.testHelper.openPage("#data-url-tests/non-data-url.html");
},
@ -383,15 +385,15 @@
},
function(){
same(location.hash, "#data-url-tests/non-data-url.html?foo=bar");
same(location.hash, "#" + siteDirectory + "data-url-tests/non-data-url.html?foo=bar");
$("#query-param-anchor").click();
},
function(){
same(location.hash, "#data-url-tests/non-data-url.html?foo=bar");
same(location.hash, "#" + siteDirectory + "data-url-tests/non-data-url.html?foo=bar");
start();
}
], 1000);
]);
});
// Special handling inside navigation because query params must be applied to the hash
@ -399,7 +401,7 @@
asyncTest( "query param link from a dialog to itself should be a not add another dialog", function(){
var firstDialogHash;
$.testHelper.sequence([
$.testHelper.pageSequence([
// open our test page
function(){
$.testHelper.openPage("#dialog-param-link");
@ -426,6 +428,43 @@
same(location.hash, firstDialogHash, "additional dialog hash key not added");
start();
}
], 1000);
]);
});
asyncTest( "query data passed as string to changePage is appended to URL", function(){
$.testHelper.pageSequence([
// open our test page
function(){
$.mobile.changePage( "form-tests/changepage-data.html", {
data: "foo=1&bar=2"
} );
},
function(){
same(location.hash, "#" + siteDirectory + "form-tests/changepage-data.html?foo=1&bar=2");
start();
}
]);
});
asyncTest( "query data passed as object to changePage is appended to URL", function(){
$.testHelper.pageSequence([
// open our test page
function(){
$.mobile.changePage( "form-tests/changepage-data.html", {
data: {
foo: 3,
bar: 4
}
} );
},
function(){
same(location.hash, "#" + siteDirectory + "form-tests/changepage-data.html?foo=3&bar=4");
start();
}
]);
});
})(jQuery);

View file

@ -2,9 +2,17 @@
* mobile navigation unit tests
*/
(function($){
var siteDirectory = location.pathname.replace(/[^/]+$/, "");
module('jquery.mobile.navigation.js', {
setup: function(){
location.hash = "";
if ( location.hash ) {
stop();
$(document).one("changepage", function() {
start();
} );
location.hash = "";
}
}
});
@ -33,26 +41,91 @@
same("foo", window.location.hash.replace(/^#/,""), "sets location.hash properly");
});
test( "path.makeAbsolute is working properly", function(){
$.mobile.urlHistory.ignoreNextHashChange = false;
test( "path.makeUrlAbsolute is working properly", function(){
var mua = $.mobile.path.makeUrlAbsolute,
p1 = "http://jqm.com/",
p2 = "http://jqm.com/?foo=1&bar=2",
p3 = "http://jqm.com/#spaz",
p4 = "http://jqm.com/?foo=1&bar=2#spaz",
$.mobile.path.set("bar/");
same( $.mobile.path.makeAbsolute("test.html"), "bar/test.html", "prefixes path with absolute base path from hash");
p5 = "http://jqm.com/test.php",
p6 = "http://jqm.com/test.php?foo=1&bar=2",
p7 = "http://jqm.com/test.php#spaz",
p8 = "http://jqm.com/test.php?foo=1&bar=2#spaz",
$.mobile.path.set("bar");
same( $.mobile.path.makeAbsolute("test.html"), "/tests/unit/navigation/test.html", "returns the absolute path unaltered ignoring non path hash");
p9 = "http://jqm.com/dir1/dir2/",
p10 = "http://jqm.com/dir1/dir2/?foo=1&bar=2",
p11 = "http://jqm.com/dir1/dir2/#spaz",
p12 = "http://jqm.com/dir1/dir2/?foo=1&bar=2#spaz",
$.mobile.path.set("bar/bing/bang");
same( $.mobile.path.makeAbsolute("?foo=bar&bak=baz"), "bar/bing/bang?foo=bar&bak=baz", "appends query string paths to current path");
p13 = "http://jqm.com/dir1/dir2/test.php",
p14 = "http://jqm.com/dir1/dir2/test.php?foo=1&bar=2",
p15 = "http://jqm.com/dir1/dir2/test.php#spaz",
p16 = "http://jqm.com/dir1/dir2/test.php?foo=1&bar=2#spaz";
$.mobile.path.set("");
same( $.mobile.path.makeAbsolute("?foo=bar&bak=baz"), "/tests/unit/navigation/?foo=bar&bak=baz", "uses pathname for empty hash");
// Test URL conversion against an absolute URL to the site root.
$.mobile.path.set("bar");
same( $.mobile.path.makeAbsolute("?foo=bar&bak=baz"), "/tests/unit/navigation/?foo=bar&bak=baz", "uses pathname for embedded pages");
// directory tests
same( mua( "http://jqm.com/", p1 ), "http://jqm.com/", "absolute root - absolute root" );
same( mua( "//jqm.com/", p1 ), "http://jqm.com/", "protocol relative root - absolute root" );
same( mua( "/", p1 ), "http://jqm.com/", "site relative root - absolute root" );
$.mobile.path.set("bar/bing?foo=bar");
same( $.mobile.path.makeAbsolute("?foo=bar&bak=baz"), "bar/bing?foo=bar&bak=baz", "prevents addition of many sets of query params");
same( mua( "http://jqm.com/?foo=1&bar=2", p1 ), "http://jqm.com/?foo=1&bar=2", "absolute root with query - absolute root" );
same( mua( "//jqm.com/?foo=1&bar=2", p1 ), "http://jqm.com/?foo=1&bar=2", "protocol relative root with query - absolute root" );
same( mua( "/?foo=1&bar=2", p1 ), "http://jqm.com/?foo=1&bar=2", "site relative root with query - absolute root" );
same( mua( "?foo=1&bar=2", p1 ), "http://jqm.com/?foo=1&bar=2", "query relative - absolute root" );
same( mua( "http://jqm.com/#spaz", p1 ), "http://jqm.com/#spaz", "absolute root with fragment - absolute root" );
same( mua( "//jqm.com/#spaz", p1 ), "http://jqm.com/#spaz", "protocol relative root with fragment - absolute root" );
same( mua( "/#spaz", p1 ), "http://jqm.com/#spaz", "site relative root with fragment - absolute root" );
same( mua( "#spaz", p1 ), "http://jqm.com/#spaz", "fragment relative - absolute root" );
same( mua( "http://jqm.com/?foo=1&bar=2#spaz", p1 ), "http://jqm.com/?foo=1&bar=2#spaz", "absolute root with query and fragment - absolute root" );
same( mua( "//jqm.com/?foo=1&bar=2#spaz", p1 ), "http://jqm.com/?foo=1&bar=2#spaz", "protocol relative root with query and fragment - absolute root" );
same( mua( "/?foo=1&bar=2#spaz", p1 ), "http://jqm.com/?foo=1&bar=2#spaz", "site relative root with query and fragment - absolute root" );
same( mua( "?foo=1&bar=2#spaz", p1 ), "http://jqm.com/?foo=1&bar=2#spaz", "query relative and fragment - absolute root" );
// file tests
same( mua( "http://jqm.com/test.php", p1 ), "http://jqm.com/test.php", "absolute file at root - absolute root" );
same( mua( "//jqm.com/test.php", p1 ), "http://jqm.com/test.php", "protocol relative file at root - absolute root" );
same( mua( "/test.php", p1 ), "http://jqm.com/test.php", "site relative file at root - absolute root" );
same( mua( "test.php", p1 ), "http://jqm.com/test.php", "document relative file at root - absolute root" );
same( mua( "http://jqm.com/test.php?foo=1&bar=2", p1 ), "http://jqm.com/test.php?foo=1&bar=2", "absolute file at root with query - absolute root" );
same( mua( "//jqm.com/test.php?foo=1&bar=2", p1 ), "http://jqm.com/test.php?foo=1&bar=2", "protocol relative file at root with query - absolute root" );
same( mua( "/test.php?foo=1&bar=2", p1 ), "http://jqm.com/test.php?foo=1&bar=2", "site relative file at root with query - absolute root" );
same( mua( "test.php?foo=1&bar=2", p1 ), "http://jqm.com/test.php?foo=1&bar=2", "document relative file at root with query - absolute root" );
same( mua( "http://jqm.com/test.php#spaz", p1 ), "http://jqm.com/test.php#spaz", "absolute file at root with fragment - absolute root" );
same( mua( "//jqm.com/test.php#spaz", p1 ), "http://jqm.com/test.php#spaz", "protocol relative file at root with fragment - absolute root" );
same( mua( "/test.php#spaz", p1 ), "http://jqm.com/test.php#spaz", "site relative file at root with fragment - absolute root" );
same( mua( "test.php#spaz", p1 ), "http://jqm.com/test.php#spaz", "file at root with fragment - absolute root" );
same( mua( "http://jqm.com/test.php?foo=1&bar=2#spaz", p1 ), "http://jqm.com/test.php?foo=1&bar=2#spaz", "absolute file at root with query and fragment - absolute root" );
same( mua( "//jqm.com/test.php?foo=1&bar=2#spaz", p1 ), "http://jqm.com/test.php?foo=1&bar=2#spaz", "protocol relative file at root with query and fragment - absolute root" );
same( mua( "/test.php?foo=1&bar=2#spaz", p1 ), "http://jqm.com/test.php?foo=1&bar=2#spaz", "site relative file at root with query and fragment - absolute root" );
same( mua( "test.php?foo=1&bar=2#spaz", p1 ), "http://jqm.com/test.php?foo=1&bar=2#spaz", "query relative file at root fragment - absolute root" );
// Test URL conversion against an absolute URL to a file at the site root.
same( mua( "http://jqm.com/", p5 ), "http://jqm.com/", "absolute root - absolute root" );
same( mua( "//jqm.com/", p5 ), "http://jqm.com/", "protocol relative root - absolute root" );
same( mua( "/", p5 ), "http://jqm.com/", "site relative root - absolute root" );
same( mua( "http://jqm.com/?foo=1&bar=2", p5 ), "http://jqm.com/?foo=1&bar=2", "absolute root with query - absolute root" );
same( mua( "//jqm.com/?foo=1&bar=2", p5 ), "http://jqm.com/?foo=1&bar=2", "protocol relative root with query - absolute root" );
same( mua( "/?foo=1&bar=2", p5 ), "http://jqm.com/?foo=1&bar=2", "site relative root with query - absolute root" );
same( mua( "?foo=1&bar=2", p5 ), "http://jqm.com/test.php?foo=1&bar=2", "query relative - absolute root" );
same( mua( "http://jqm.com/#spaz", p5 ), "http://jqm.com/#spaz", "absolute root with fragment - absolute root" );
same( mua( "//jqm.com/#spaz", p5 ), "http://jqm.com/#spaz", "protocol relative root with fragment - absolute root" );
same( mua( "/#spaz", p5 ), "http://jqm.com/#spaz", "site relative root with fragment - absolute root" );
same( mua( "#spaz", p5 ), "http://jqm.com/test.php#spaz", "fragment relative - absolute root" );
same( mua( "http://jqm.com/?foo=1&bar=2#spaz", p5 ), "http://jqm.com/?foo=1&bar=2#spaz", "absolute root with query and fragment - absolute root" );
same( mua( "//jqm.com/?foo=1&bar=2#spaz", p5 ), "http://jqm.com/?foo=1&bar=2#spaz", "protocol relative root with query and fragment - absolute root" );
same( mua( "/?foo=1&bar=2#spaz", p5 ), "http://jqm.com/?foo=1&bar=2#spaz", "site relative root with query and fragment - absolute root" );
same( mua( "?foo=1&bar=2#spaz", p5 ), "http://jqm.com/test.php?foo=1&bar=2#spaz", "query relative and fragment - absolute root" );
});
test( "path.clean is working properly", function(){
@ -79,11 +152,23 @@
same( $.mobile.path.hasProtocol( "file://foo/bar/baz.html" ), true, "simple directory path with file:// has protocol" );
});
test( "path.isRelative is working properly", function(){
same( $.mobile.path.isRelative("#foo/bar"), false, "path starting with a # is not relative" );
same( $.mobile.path.isRelative("/foo/bar"), false, "path starting with a / is not relative" );
same( $.mobile.path.isRelative("http://example.com/foo"), false, "full url path is not relative" );
same( $.mobile.path.isRelative("foo/bar.html"), true, "simple path is relative" );
test( "path.isRelativeUrl is working properly", function(){
same( $.mobile.path.isRelativeUrl("http://company.com/"), false, "absolute url is not relative" );
same( $.mobile.path.isRelativeUrl("//company.com/"), true, "protocol relative url is relative" );
same( $.mobile.path.isRelativeUrl("/"), true, "site relative url is relative" );
same( $.mobile.path.isRelativeUrl("http://company.com/test.php"), false, "absolute url is not relative" );
same( $.mobile.path.isRelativeUrl("//company.com/test.php"), true, "protocol relative url is relative" );
same( $.mobile.path.isRelativeUrl("/test.php"), true, "site relative url is relative" );
same( $.mobile.path.isRelativeUrl("test.php"), true, "document relative url is relative" );
same( $.mobile.path.isRelativeUrl("http://company.com/dir1/dir2/test.php?foo=1&bar=2#frag"), false, "absolute url is not relative" );
same( $.mobile.path.isRelativeUrl("//company.com/dir1/dir2/test.php?foo=1&bar=2#frag"), true, "protocol relative url is relative" );
same( $.mobile.path.isRelativeUrl("/dir1/dir2/test.php?foo=1&bar=2#frag"), true, "site relative url is relative" );
same( $.mobile.path.isRelativeUrl("dir1/dir2/test.php?foo=1&bar=2#frag"), true, "document relative path url is relative" );
same( $.mobile.path.isRelativeUrl("test.php?foo=1&bar=2#frag"), true, "document relative file url is relative" );
same( $.mobile.path.isRelativeUrl("?foo=1&bar=2#frag"), true, "query relative url is relative" );
same( $.mobile.path.isRelativeUrl("#frag"), true, "fragments are relative" );
});
test( "path.isExternal is working properly", function(){
@ -101,11 +186,6 @@
same($.mobile.path.isExternal("#foo"), false, "local id reference");
});
test( "path.isQuery is working properly", function(){
ok( $.mobile.path.isQuery( "?foo=bar" ), "string prefixed with ?");
ok( !$.mobile.path.isQuery( "anything else" ), "string not prefixed with ?");
});
test( "path.cleanHash", function(){
same( $.mobile.path.cleanHash( "#anything/atall?akjfdjjf" ), "anything/atall", "removes query param");
same( $.mobile.path.cleanHash( "#nothing/atall" ), "nothing/atall", "removes query param");

View file

@ -0,0 +1,173 @@
/*
* mobile navigation path unit tests
*/
(function($){
var testPageLoad = function(testPageAnchorSelector, expectedTextValue){
expect( 2 );
$.testHelper.pageSequence([
// open our test page
function(){
$.testHelper.openPage("#pathing-tests");
},
// navigate to the linked page
function(){
var page = $.mobile.activePage;
// check that the reset page isn't still open
equal("", page.find(".reset-value").text());
//click he test page link to execute the path
page.find("a" + testPageAnchorSelector).click();
},
// verify that the page has changed and the expected text value is present
function(){
same($.mobile.activePage.find(".test-value").text(), expectedTextValue);
$.testHelper.openPage("#pathing-tests-reset");
},
function(){
start();
}
]);
};
// all of these alterations assume location.pathname will be a directory
// this is required to prevent the tests breaking in a subdirectory
// TODO could potentially be fragile since the tests could be running while
// the urls are being updated
$(function(){
$("a.site-rel").each(function(i, elem){
var $elem = $(elem);
$elem.attr("href", location.pathname + $(elem).attr("href"));
});
$('a.protocol-rel').each(function(i, elem){
var $elem = $(elem);
$elem.attr("href", "//" + location.host + location.pathname + $(elem).attr("href"));
});
$('a.absolute').each(function(i, elem){
var $elem = $(elem);
$elem.attr("href",
location.protocol + "//" + location.host +
location.pathname + $(elem).attr("href"));
});
});
//Doc relative tests
module("document relative paths");
asyncTest( "file reference no nesting", function(){
testPageLoad("#doc-rel-test-one", "doc rel test one");
});
asyncTest( "file reference with nesting", function(){
testPageLoad("#doc-rel-test-two", "doc rel test two");
});
asyncTest( "file reference with double nesting", function(){
testPageLoad("#doc-rel-test-three", "doc rel test three");
});
asyncTest( "dir refrence with nesting", function(){
testPageLoad("#doc-rel-test-four", "doc rel test four");
});
asyncTest( "file refrence with parent dir", function(){
testPageLoad("#doc-rel-test-five", "doc rel test five");
});
asyncTest( "dir refrence with parent dir", function(){
testPageLoad("#doc-rel-test-six", "doc rel test six");
});
// Site relative tests
// NOTE does not test root path or non nested references
module("site relative paths");
asyncTest( "file reference no nesting", function(){
testPageLoad("#site-rel-test-one", "doc rel test one");
});
asyncTest( "file reference with nesting", function(){
testPageLoad("#site-rel-test-two", "doc rel test two");
});
asyncTest( "file reference with double nesting", function(){
testPageLoad("#site-rel-test-three", "doc rel test three");
});
asyncTest( "dir refrence with nesting", function(){
testPageLoad("#site-rel-test-four", "doc rel test four");
});
asyncTest( "file refrence with parent dir", function(){
testPageLoad("#site-rel-test-five", "doc rel test five");
});
asyncTest( "dir refrence with parent dir", function(){
testPageLoad("#site-rel-test-six", "doc rel test six");
});
// Protocol relative tests
// NOTE does not test root path or non nested references
module("protocol relative paths");
asyncTest( "file reference no nesting", function(){
testPageLoad("#protocol-rel-test-one", "doc rel test one");
});
asyncTest( "file reference with nesting", function(){
testPageLoad("#protocol-rel-test-two", "doc rel test two");
});
asyncTest( "file reference with double nesting", function(){
testPageLoad("#protocol-rel-test-three", "doc rel test three");
});
asyncTest( "dir refrence with nesting", function(){
testPageLoad("#protocol-rel-test-four", "doc rel test four");
});
asyncTest( "file refrence with parent dir", function(){
testPageLoad("#protocol-rel-test-five", "doc rel test five");
});
asyncTest( "dir refrence with parent dir", function(){
testPageLoad("#protocol-rel-test-six", "doc rel test six");
});
// absolute tests
// NOTE does not test root path or non nested references
module("abolute paths");
asyncTest( "file reference no nesting", function(){
testPageLoad("#absolute-test-one", "doc rel test one");
});
asyncTest( "file reference with nesting", function(){
testPageLoad("#absolute-test-two", "doc rel test two");
});
asyncTest( "file reference with double nesting", function(){
testPageLoad("#absolute-test-three", "doc rel test three");
});
asyncTest( "dir refrence with nesting", function(){
testPageLoad("#absolute-test-four", "doc rel test four");
});
asyncTest( "file refrence with parent dir", function(){
testPageLoad("#absolute-test-five", "doc rel test five");
});
asyncTest( "dir refrence with parent dir", function(){
testPageLoad("#absolute-test-six", "doc rel test six");
});
})(jQuery);

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-nstest-role="page">
<div class="test-value">doc rel test two</div>
</div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-nstest-role="page">
<div class="test-value">doc rel test five</div>
</div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-nstest-role="page">
<div class="test-value">doc rel test six</div>
</div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-nstest-role="page">
<div class="test-value">doc rel test three</div>
</div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div data-nstest-role="page">
<div class="test-value">doc rel test four</div>
</div>
</body>
</html>

View file

@ -19,5 +19,4 @@ $elements = array(
'jquery.mobile.forms.slider.css'
);
include('../../combine.php');
?>
include('../../combine.php');

View file

@ -7,7 +7,7 @@
.ui-btn:focus, .ui-btn:active { outline: none; }
.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; }
.ui-btn-inline { display: inline-block; }
.ui-btn-inner { padding: .6em 25px; display: block; height: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; }
.ui-btn-inner { padding: .6em 25px; display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; }
.ui-header .ui-btn-inner, .ui-footer .ui-btn-inner, .ui-bar .ui-btn-inner { padding: .4em 8px .5em; }
.ui-btn-icon-notext { display: inline-block; width: 20px; height: 20px; padding: 2px 1px 2px 3px; text-indent: -9999px; }
.ui-btn-icon-notext .ui-btn-inner { padding: 0; }

View file

@ -8,7 +8,7 @@
.ui-collapsible-heading a { text-align: left; margin: 0; }
.ui-collapsible-heading a .ui-btn-inner { padding-left: 40px; }
.ui-collapsible-heading a span.ui-btn { position: absolute; left: 6px; top: 50%; margin: -12px 0 0 0; width: 20px; height: 20px; padding: 1px 0px 1px 2px; text-indent: -9999px; }
.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 0; }
.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 10px 0; }
.ui-collapsible-heading a span.ui-btn .ui-icon { left: 0; margin-top: -10px; }
.ui-collapsible-heading-status { position:absolute; left:-9999px; }
.ui-collapsible-content { display: block; padding: 10px 0 10px 8px; }

View file

@ -19,7 +19,7 @@
/*orientations from js are available */
.portrait,
.portrait .ui-page { min-height: 100%; }
.portrait .ui-page,
.landscape,
.landscape .ui-page { min-height: 100%; }

View file

@ -7,7 +7,8 @@
.ui-select select { position: absolute; left: -9999px; top: -9999px; }
.ui-select .ui-btn { overflow: hidden; }
.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); }
.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; }
@-moz-document url-prefix() {.ui-select .ui-btn select { opacity: 0.0001; }}
.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; text-indent: 0; }
.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; }
.ui-select .ui-btn-icon-right .ui-icon { right: 15px; }

View file

@ -693,7 +693,7 @@ a.ui-link-inherit {
}
.ui-disabled,
.ui-disabled a {
cursor: default !important;
cursor: default;
}
/* Icons

View file

@ -20,4 +20,3 @@ $elements = array(
);
include('../../combine.php');
?>