Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'upstream/master' into defaultTheme

  • Loading branch information...
commit d4d42245774a293040b975a7514c0313094669da 2 parents d7e2289 + baded0d
@hpbuniat authored
Showing with 373 additions and 228 deletions.
  1. +2 −0  .gitignore
  2. +34 −34 build.xml
  3. +1 −1  docs/_assets/css/jqm-docs.css
  4. +1 −1  docs/pages/index.html
  5. +2 −2 docs/pages/page-anatomy.html
  6. +40 −25 docs/pages/page-cache.html
  7. +2 −2 docs/pages/page-dialogs.html
  8. +2 −2 docs/pages/page-links.html
  9. +1 −1  docs/pages/page-navmodel.html
  10. +3 −3 docs/pages/page-scripting.html
  11. +2 −2 docs/pages/page-titles.html
  12. +2 −2 docs/pages/page-transitions.html
  13. +2 −2 docs/pages/pages-themes.html
  14. +1 −1  index.html
  15. +9 −7 js/jquery.mobile.event.js
  16. +11 −6 js/jquery.mobile.forms.select.custom.js
  17. +7 −11 js/jquery.mobile.forms.slider.js
  18. +2 −2 js/jquery.mobile.init.js
  19. +1 −1  js/jquery.mobile.media.classes.js
  20. +4 −3 js/jquery.mobile.navigation.js
  21. +16 −7 js/jquery.mobile.vmouse.js
  22. +128 −41 tests/unit/event/event_core.js
  23. +1 −1  tests/unit/navigation/index.html
  24. +90 −65 tests/unit/navigation/navigation_helpers.js
  25. +7 −5 tests/unit/support/support_core.js
  26. +1 −1  themes/default/jquery.mobile.forms.slider.css
  27. +1 −0  themes/default/jquery.mobile.theme.css
View
2  .gitignore
@@ -9,3 +9,5 @@ combine/
compiled/
gitstatus.log
refreshCDN
+*.swp
+.gitignore
View
68 build.xml
@@ -19,40 +19,40 @@
jquery.mobile.forms.textinput.css,
jquery.mobile.listview.css,
jquery.mobile.forms.slider.css"/>
- <property name="js-sources" value="js/jquery.ui.widget.js,
- js/jquery.mobile.widget.js,
- js/jquery.mobile.media.js,
- js/jquery.mobile.support.js,
- js/jquery.mobile.vmouse.js,
- js/jquery.mobile.event.js,
- js/jquery.mobile.hashchange.js,
- js/jquery.mobile.page.js,
- js/jquery.mobile.core.js,
- js/jquery.mobile.navigation.js,
- js/jquery.mobile.navigation.pushstate.js,
- js/jquery.mobile.transition.js,
- js/jquery.mobile.degradeInputs.js,
- js/jquery.mobile.dialog.js,
- js/jquery.mobile.page.sections.js,
- js/jquery.mobile.collapsible.js,
- js/jquery.mobile.fieldContain.js,
- js/jquery.mobile.grid.js,
- js/jquery.mobile.navbar.js,
- js/jquery.mobile.listview.js,
- js/jquery.mobile.listview.filter.js,
- js/jquery.mobile.nojs.js,
- js/jquery.mobile.forms.checkboxradio.js,
- js/jquery.mobile.forms.button.js,
- js/jquery.mobile.forms.slider.js,
- js/jquery.mobile.forms.textinput.js,
- js/jquery.mobile.forms.select.custom.js,
- js/jquery.mobile.forms.select.js,
- js/jquery.mobile.buttonMarkup.js,
- js/jquery.mobile.controlGroup.js,
- js/jquery.mobile.links.js,
- js/jquery.mobile.fixHeaderFooter.js,
- js/jquery.mobile.media.classes.js,
- js/jquery.mobile.init.js"/>
+ <property name="js-sources" value="jquery.ui.widget.js,
+ jquery.mobile.widget.js,
+ jquery.mobile.media.js,
+ jquery.mobile.support.js,
+ jquery.mobile.vmouse.js,
+ jquery.mobile.event.js,
+ jquery.mobile.hashchange.js,
+ jquery.mobile.page.js,
+ jquery.mobile.core.js,
+ jquery.mobile.navigation.js,
+ jquery.mobile.navigation.pushstate.js,
+ jquery.mobile.transition.js,
+ jquery.mobile.degradeInputs.js,
+ jquery.mobile.dialog.js,
+ jquery.mobile.page.sections.js,
+ jquery.mobile.collapsible.js,
+ jquery.mobile.fieldContain.js,
+ jquery.mobile.grid.js,
+ jquery.mobile.navbar.js,
+ jquery.mobile.listview.js,
+ jquery.mobile.listview.filter.js,
+ jquery.mobile.nojs.js,
+ jquery.mobile.forms.checkboxradio.js,
+ jquery.mobile.forms.button.js,
+ jquery.mobile.forms.slider.js,
+ jquery.mobile.forms.textinput.js,
+ jquery.mobile.forms.select.custom.js,
+ jquery.mobile.forms.select.js,
+ jquery.mobile.buttonMarkup.js,
+ jquery.mobile.controlGroup.js,
+ jquery.mobile.links.js,
+ jquery.mobile.fixHeaderFooter.js,
+ jquery.mobile.media.classes.js,
+ jquery.mobile.init.js"/>
<target name="merge">
<antcall target="merge_css" />
View
2  docs/_assets/css/jqm-docs.css
@@ -6,7 +6,7 @@ cobblers, shoes,
body { background: #dddddd; }
-.ui-mobile #jqm-home { background: #e5e5e5 url(../images/jqm-sitebg.png) top center repeat-x; }
+.ui-mobile .type-home { background: #e5e5e5 url(../images/jqm-sitebg.png) top center repeat-x; }
.ui-mobile #jqm-homeheader { padding: 40px 10px 0; text-align: center; margin: 0 auto; }
.ui-mobile #jqm-homeheader h1 { margin: 0 0 ; }
.ui-mobile #jqm-homeheader p { margin: .3em 0 0; line-height: 1.3; font-size: .9em; font-weight: bold; color: #666; }
View
2  docs/pages/index.html
@@ -33,7 +33,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
View
4 docs/pages/page-anatomy.html
@@ -198,7 +198,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -216,4 +216,4 @@
</div><!-- /page -->
</body>
- </html>
+ </html>
View
65 docs/pages/page-cache.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery Mobile Docs - Preload & cache pages</title>
+ <title>jQuery Mobile Docs - Prefetching &amp; caching pages</title>
<link rel="stylesheet" media="only all" href="../../themes/default/" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>
<script src="../../js/jquery.js"></script>
@@ -16,7 +16,7 @@
<div data-role="page" class="type-interior">
<div data-role="header" data-theme="f">
- <h1>Preload & cache pages</h1>
+ <h1>Prefetching &amp; caching pages</h1>
<a href="../../" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">Home</a>
</div><!-- /header -->
@@ -24,46 +24,61 @@
<div class="content-primary">
- <h2>Pre-fetching pages</h2>
-
- <p>If you're using a single page template, but would prefer to lazy load in a few key pages in the background to avoid seeing the Ajax loader, we recommend using the pre-fetch feature instead of moving to a multi-page template. To pre-fetch a page, simply add the <code>data-prefetch</code> attribute to any link and jQuery Mobile will lazy load this page in the background after the primary page has loaded. Here's an example:</p>
+ <h2>Prefetching pages</h2>
+
+ <p>Usually, it's a good idea to store your app's pages in several single-page templates instead of one large multi-page template. This minimizes the size of the page's DOM.</p>
+
+ <p>When using single-page templates, you can prefetch pages into the DOM so that they're available instantly when the user visits them. To prefetch a page, add the <code>data-prefetch</code> attribute to a link that points to the page. jQuery Mobile then loads the target page in the background after the primary page has loaded and the pagecreate event has triggered. For example:</p>
<pre><code>
- &lt;a href="foo/bar/baz" data-prefetch&gt;link text&lt;/a&gt;
+&lt;a href="prefetchThisPage.html" data-prefetch&gt; ... &lt;/a&gt;
</code></pre>
+ <p>You can prefetch as many linked pages as you like. Just add <code>data-prefetch</code> to all the links you want to prefetch.</p>
- <p>Technically here's how it works: after pagecreate, jQuery Mobile will automatically find all links in a page that have an attribute of <code>data-prefetch</code> and automatically load the pages so they're available as soon as the user clicks on the link. The Ajax loader won't appear unless the framework hasn't loaded the page by the time the link was clicked.</p>
+ <p>Alternatively, you can prefetch a page programmatically using <code>$.mobile.loadPage()</code>:</p>
+
+<pre><code>
+$.mobile.loadPage( <var>pageUrl</var> );
+</code></pre>
- <p>Pre-fetching links will naturally cause additional HTTP requests and increased bandwidth that may never be used, so it's important to use this feature only in situations where it's highly likely that a page will be visited.</p>
-
-
-<pre><code> &lt;a href="foo/bar/baz" data-prefetch&gt;link text&lt;/a&gt;</code></pre>
+ <p>Another advantage of prefetching a page is that the user doesn't see the Ajax loading message when visiting the prefetched page. The Ajax loading message only appears if the framework hasn't finished prefetching the page by the time the link is followed.</p>
- <p>Pages can also be pre-fetched programmatically by calling <code>$.mobile.loadpage( url )</code></p>
+ <p>Prefetching pages naturally creates additional HTTP requests and uses bandwidth, so it's wise to use this feature only in situations where it's highly likely that the prefetched page will be visited. A common scenario is a photo gallery, where you can prefetch the "previous" and "next" photo pages so that the user can move quickly between photos.</p>
<h2>DOM size management</h2>
- <p>Since animated page transitions require that the page you're on and the one you're transitioning to are both in the DOM, we add pages to the DOM as you navigate around. Before Beta 2, those pages would continue to stay in the DOM until a full page refresh occured so there was always a concern that we could hit a memory ceiling on some devices and cause the browser to slow down or even crash.</p>
+ <p>For animated page transitions to work, the pages you're transitioning from and to both need to be in the DOM. However, keeping old pages in the DOM quickly fills the browser's memory, and can cause some mobile browsers to slow down or even crash.</p>
+
+ <p>jQuery Mobile therefore has a simple mechanism to keep the DOM tidy. Whenever it loads a page via Ajax, jQuery Mobile flags the page to be removed from the DOM when you navigate away from it later (technically, on the pagehide event). If you revisit a removed page, the browser may be able to retrieve the page's HTML file from its cache. If not, it refetches the file from the server. (In the case of nested list views, jQuery Mobile removes all the pages that make up the nested list once you navigate to a page that's not part of the list.)</p>
+
+ <p>Pages inside a multi-page template aren't affected by this feature at all - jQuery Mobile only removes pages loaded via Ajax.</p>
+
- <p>The jQuery Mobile framework has a simple mechanism to keep the DOM tidy: whenever a page is loaded in via Ajax, it is flagged for removal from the DOM once you navigate away to another page (technically, on pagehide). If you return to a deleted page, the browser may be able to retrieve the file from it's cache, or it will re-request it fro the sever if needed. In the case of nested lists, we remove all the pages that make up the nested list once you navigate to a page that's not part of the list. Pages that are included in a multi-page setup won't be affected by this feature at all - only pages brought in by Ajax are managed this way by jQuery Mobile.</p>
+ <h2>Caching pages in the DOM</h2>
- <p>A page option called <code>domCache</code> controls whether to leave pages in the DOM as a way to cache them (the way things used to work) or keep the DOM clean and remove hidden pages (the new way). By default, <code>domCache</code> is set to <code>false</code> to keep the DOM size actively managed. If you set this to <code>true</code>, you need to take care to manage the DOM yourself and test thoroughly on a range of devices.</p>
+ <p>If you prefer, you can tell jQuery Mobile to keep previously-visited pages in the DOM instead of removing them. This lets you cache pages so that they're available instantly if the user returns to them.</p>
- <p>Set the domCache option globally like this:
-<pre><code>$.mobile.page.prototype.options.domCache = true;</code></pre>
+ <p>To keep all previously-visited pages in the DOM, set the <code>domCache</code> option on the page plugin to <code>true</code>, like this:</p>
- <p>To set the domCache option on an individual pages, you can add the <code>data-dom-cache="true"</code> attribute to the page container to tell teh framework to not remove the page when it's hidden:</p>
-<pre><code>&lt;a href="foo/bar/baz" data-dom-cache="true"&gt;link text&lt;/a&gt;
+<pre><code>
+$.mobile.page.prototype.options.domCache = true;
</code></pre>
-
-
- <p>Alternatively, pages can be cached in the DOM programmatically like this:</p>
-<pre><code>elem.page({ domCache: true });</code></pre>
+ <p>Alternatively, to cache just a particular page, you can add the <code>data-dom-cache="true"</code> attribute to the page's container:</p>
+
+<pre><code>
+&lt;div data-role="page" id="cacheMe" data-dom-cache="true"&gt;
+</code></pre>
+ <p>You can also cache a page programmatically like this:</p>
+
+<pre><code>
+<var>pageContainerElement</var>.page({ domCache: true });
+</code></pre>
+ <p>The drawback of DOM caching is that the DOM can get very large, resulting in slowdowns and memory issues on some devices. If you enable DOM caching, take care to manage the DOM yourself and test thoroughly on a range of devices.</p>
</div><!--/content-primary -->
@@ -84,7 +99,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li data-theme="a"><a href="page-cache.html">Preload & cache pages</a></li>
+ <li data-theme="a"><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -102,4 +117,4 @@
</div><!-- /page -->
</body>
- </html>
+ </html>
View
4 docs/pages/page-dialogs.html
@@ -86,7 +86,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li data-theme="a"><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -104,4 +104,4 @@
</div><!-- /page -->
</body>
-</html>
+</html>
View
4 docs/pages/page-links.html
@@ -114,7 +114,7 @@
<li data-theme="a"><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -132,4 +132,4 @@
</div><!-- /page -->
</body>
- </html>
+ </html>
View
2  docs/pages/page-navmodel.html
@@ -122,7 +122,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li data-theme="a"><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
View
6 docs/pages/page-scripting.html
@@ -27,7 +27,7 @@
<h2>Scripts & styles in the head</h2>
<p>When you click a link in jQuery Mobile, the Ajax navigation system uses the link's href to formulate an Ajax request. Although the full page is loaded with Ajax, the framework only pulls in the <em>contents of the page</em>, and ignores anything in the <code>head</code> except for title tag contents.</p>
- <p> This means that any scripts or styles in the <code>head</code> of the page won't have any affect <em>when the page is loaded via Ajax</em>. The same page will work as expected if you were to load a page directly but both scenarios need to be considered. The reason that the <code>head</code> is ignored for Ajax page content: it's just too complex. The framework would need to compare and reconcile the contents of multiple page <code>head</code> elements as they are loaded into the DOM so we leave this task to the developer.</p>
+ <p> This means that any scripts or styles in the <code>head</code> of the page won't have any effect <em>when the page is loaded via Ajax</em>. The same page will work as expected if you were to load a page directly but both scenarios need to be considered. The reason that the <code>head</code> is ignored for Ajax page content: it's just too complex. The framework would need to compare and reconcile the contents of multiple page <code>head</code> elements as they are loaded into the DOM so we leave this task to the developer.</p>
<p>The simplest approach is to add the same set of stylesheets and scripts into all your pages. If you need to load in specific scripts or styles for a particular page, bind to the <code>pagecreate</code> event (details below) to run the necessary code when a specific page ID is created. Following this approach will ensure that the code executes if the page is loaded directly or is pulled in and shown via Ajax.</p>
@@ -105,7 +105,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li>
<li data-theme="a"><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -123,4 +123,4 @@
</div><!-- /page -->
</body>
- </html>
+ </html>
View
4 docs/pages/page-titles.html
@@ -57,7 +57,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -75,4 +75,4 @@
</div><!-- /page -->
</body>
- </html>
+ </html>
View
4 docs/pages/page-transitions.html
@@ -67,7 +67,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li data-theme="a"><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li><a href="pages-themes.html">Theming pages</a></li>
@@ -103,4 +103,4 @@
</div>
</body>
- </html>
+ </html>
View
4 docs/pages/pages-themes.html
@@ -203,7 +203,7 @@
<li><a href="page-links.html">Linking pages</a></li>
<li><a href="page-transitions.html" data-ajax="false">Page transitions</a></li>
<li><a href="page-dialogs.html">Dialogs</a></li>
- <li><a href="page-cache.html">Preload & cache pages</a></li>
+ <li><a href="page-cache.html">Prefetching &amp; caching pages</a></li>
<li><a href="page-navmodel.html">Ajax, hashes &amp; history</a></li>
<li><a href="page-scripting.html">Scripting pages</a></li>
<li data-theme="a"><a href="pages-themes.html">Theming pages</a></li>
@@ -221,4 +221,4 @@
</div><!-- /page -->
</body>
- </html>
+ </html>
View
2  index.html
@@ -13,7 +13,7 @@
</head>
<body>
-<div data-role="page" id="jqm-home" class="type-home">
+<div data-role="page" class="type-home">
<div data-role="content">
View
16 js/jquery.mobile.event.js
@@ -78,16 +78,19 @@ $.event.special.tap = {
return false;
}
- var touching = true,
- origTarget = event.target,
+ var origTarget = event.target,
origEvent = event.originalEvent,
timer;
+ function clearTapTimer() {
+ clearTimeout( timer );
+ }
+
function clearTapHandlers() {
- touching = false;
- clearTimeout(timer);
+ clearTapTimer();
$this.unbind( "vclick", clickHandler )
+ .unbind( "vmouseup", clearTapTimer )
.unbind( "vmousecancel", clearTapHandlers );
}
@@ -102,12 +105,11 @@ $.event.special.tap = {
}
$this.bind( "vmousecancel", clearTapHandlers )
+ .bind( "vmouseup", clearTapTimer )
.bind( "vclick", clickHandler );
timer = setTimeout(function() {
- if ( touching ) {
- triggerCustomEvent( thisObject, "taphold", event );
- }
+ triggerCustomEvent( thisObject, "taphold", $.Event( "taphold" ) );
}, 750 );
});
}
View
17 js/jquery.mobile.forms.select.custom.js
@@ -103,12 +103,12 @@
.delegate( ".ui-li>a", "focusout", function() {
$( this ).attr( "tabindex", "-1" );
})
- .delegate( "li:not(.ui-disabled, .ui-li-divider)", "vclick", function( event ) {
+ .delegate( "li:not(.ui-disabled, .ui-li-divider)", "click", function( event ) {
// index of option tag to be selected
var oldIndex = self.select[ 0 ].selectedIndex,
newIndex = self.list.find( "li:not(.ui-li-divider)" ).index( this ),
- option = self.optionElems.eq( newIndex )[ 0 ];
+ option = self.selectOptions.eq( newIndex )[ 0 ];
// toggle selected status on the tag for multi selects
option.selected = self.isMultiple ? !option.selected : true;
@@ -174,7 +174,7 @@
// If enter or space is pressed, trigger click
case 13:
case 32:
- target.trigger( "vclick" );
+ target.trigger( "click" );
return false;
break;
@@ -206,7 +206,7 @@
var self = this,
select = this.element,
isMultiple = this.isMultiple,
- options = this.optionElems = select.find( "option" ),
+ options = this.selectOptions = select.find( "option" ),
selected = this.selected(),
// return an array of all selected index's
indicies = this.selectedIndices();
@@ -224,14 +224,16 @@
.each(function( i ) {
if ( $.inArray( i, indicies ) > -1 ) {
- var item = $( this ).addClass( $.mobile.activeBtnClass );
+ var item = $( this );
// Aria selected attr
- item.find( "a" ).attr( "aria-selected", true );
+ item.attr( "aria-selected", true );
// Multiple selects: add the "on" checkbox state to the icon
if ( self.isMultiple ) {
item.find( ".ui-icon" ).removeClass( "ui-icon-checkbox-off" ).addClass( "ui-icon-checkbox-on" );
+ } else {
+ item.addClass( $.mobile.activeBtnClass );
}
}
});
@@ -245,6 +247,9 @@
var self = this;
if ( self.menuType == "page" ) {
+ // TODO centralize page removal binding / handling in the page plugin.
+ // Suggestion from @jblas to do refcounting
+ //
// rebind the page remove that was unbound in the open function
// to allow for the parent page removal from actions other than the use
// of a dialog sized custom select
View
18 js/jquery.mobile.forms.slider.js
@@ -71,7 +71,8 @@ $.widget( "mobile.slider", $.mobile.widget, {
slider: slider,
handle: handle,
dragging: false,
- beforeStart: null
+ beforeStart: null,
+ userModified: false
});
if ( cType == "select" ) {
@@ -113,12 +114,14 @@ $.widget( "mobile.slider", $.mobile.widget, {
$( document ).bind( "vmousemove", function( event ) {
if ( self.dragging ) {
self.refresh( event );
+ self.userModified = self.userModified || self.beforeStart !== control[0].selectedIndex;
return false;
}
});
slider.bind( "vmousedown", function( event ) {
self.dragging = true;
+ self.userModified = false;
if ( cType === "select" ) {
self.beforeStart = control[0].selectedIndex;
@@ -135,18 +138,11 @@ $.widget( "mobile.slider", $.mobile.widget, {
if ( cType === "select" ) {
- if ( self.beforeStart === control[ 0 ].selectedIndex ) {
+ if ( !self.userModified ) {
//tap occurred, but value didn't change. flip it!
+ handle.addClass( "ui-slider-handle-snapping" );
self.refresh( !self.beforeStart ? 1 : 0 );
}
- var curval = val();
- var snapped = Math.round( curval / ( max - min ) * 100 );
- handle
- .addClass( "ui-slider-handle-snapping" )
- .css( "left", snapped + "%" )
- .animationComplete( function() {
- handle.removeClass( "ui-slider-handle-snapping" );
- });
}
return false;
}
@@ -323,4 +319,4 @@ $( document ).bind( "pagecreate create", function( e ){
});
-})( jQuery );
+})( jQuery );
View
4 js/jquery.mobile.init.js
@@ -83,9 +83,9 @@
$pages.add( ":jqmData(role='dialog')" ).each(function() {
var $this = $(this);
- // unless the data url is already set set it to the id
+ // unless the data url is already set set it to the pathname
if ( !$this.jqmData("url") ) {
- $this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) );
+ $this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname );
}
});
View
2  js/jquery.mobile.media.classes.js
@@ -77,7 +77,7 @@ $( document ).bind( "mobileinit.htmlclass", function() {
var ev = $.support.orientation;
- $window.bind( "orientationchange.htmlclass throttledResize.htmlclass", function( event ) {
+ $window.bind( "orientationchange.htmlclass throttledresize.htmlclass", function( event ) {
// add orientation class to HTML element on flip/resize.
if ( event.orientation ) {
View
7 js/jquery.mobile.navigation.js
@@ -38,7 +38,7 @@
// [15]: ?msg=1234&type=unread
// [16]: #msg-content
//
- urlParseRE: /^(((([^:\/#\?]+:)?(?:\/\/((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?]+)(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
+ urlParseRE: /^(((([^:\/#\?]+:)?(?:\/\/((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
//Parse a URL into a structure that allows easy access to
//all of the URL components by name.
@@ -293,9 +293,9 @@
this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex;
if( back ) {
- (opts.either || opts.isBack)( back );
+ ( opts.either || opts.isBack )( true );
} else if( forward ) {
- (opts.either || opts.isForward)( back );
+ ( opts.either || opts.isForward )( false );
}
},
@@ -1074,6 +1074,7 @@
var link = findClosestLink( event.target );
if ( link ) {
if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) {
+ removeActiveLinkClass( true );
$activeClickedLink = $( link ).closest( ".ui-btn" ).not( ".ui-disabled" );
$activeClickedLink.addClass( $.mobile.activeBtnClass );
$( "." + $.mobile.activePageClass + " .ui-btn" ).not( link ).blur();
View
23 js/jquery.mobile.vmouse.js
@@ -164,8 +164,7 @@ function clearResetTimer() {
}
function triggerVirtualEvent( eventType, event, flags ) {
- var defaultPrevented = false,
- ve;
+ var ve;
if ( ( flags && flags[ eventType ] ) ||
( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) {
@@ -173,18 +172,27 @@ function triggerVirtualEvent( eventType, event, flags ) {
ve = createVirtualEvent( event, eventType );
$( event.target).trigger( ve );
-
- defaultPrevented = ve.isDefaultPrevented();
}
- return defaultPrevented;
+ return ve;
}
function mouseEventCallback( event ) {
var touchID = $.data(event.target, touchTargetPropertyName);
if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ){
- triggerVirtualEvent( "v" + event.type, event );
+ var ve = triggerVirtualEvent( "v" + event.type, event );
+ if ( ve ) {
+ if ( ve.isDefaultPrevented() ) {
+ event.preventDefault();
+ }
+ if ( ve.isPropagationStopped() ) {
+ event.stopPropagation();
+ }
+ if ( ve.isImmediatePropagationStopped() ) {
+ event.stopImmediatePropagation();
+ }
+ }
}
}
@@ -264,7 +272,8 @@ function handleTouchEnd( event ) {
triggerVirtualEvent( "vmouseup", event, flags );
if ( !didScroll ) {
- if ( triggerVirtualEvent( "vclick", event, flags ) ) {
+ var ve = triggerVirtualEvent( "vclick", event, flags );
+ if ( ve && ve.isDefaultPrevented() ) {
// The target of the mouse events that follow the touchend
// event don't necessarily match the target used during the
// touch. This means we need to rely on coordinates for blocking
View
169 tests/unit/event/event_core.js
@@ -14,14 +14,8 @@
setup: function(){
// ensure bindings are removed
- $.each(events, function(i, name){
- $.each([$("#qunit-fixture"),
- $($.event.special.scrollstart),
- $($.event.special.tap),
- $($.event.special.tap),
- $($.event.special.swipe)], function(j, obj){
- obj.unbind(name);
- });
+ $.each(events + "vmouseup vmousedown".split(" "), function(i, name){
+ $("#qunit-fixture").unbind();
});
//NOTE unmock
@@ -29,6 +23,10 @@
$.Event.prototype.originalEvent = originalEventFn;
$.Event.prototype.preventDefault = preventDefaultFn;
+ // make sure the event objects respond to touches to simulate
+ // the collections existence in non touch enabled test browsers
+ $.Event.prototype.touches = [{pageX: 1, pageY: 1 }];
+
$($.mobile.pageContainer).unbind( "throttledresize" );
}
});
@@ -43,7 +41,7 @@
$.testHelper.reloadLib(libName);
$.each(events, function( i, name ) {
- ok($.fn[name] !== undefined, name + "is not undefined");
+ ok($.fn[name] !== undefined, name + " is not undefined");
});
});
});
@@ -88,40 +86,40 @@
expect( 1 );
$.event.special.scrollstart.enabled = false;
- $($.event.special.scrollstart).bind("scrollstart", function(){
+ $( "#qunit-fixture" ).bind("scrollstart", function(){
ok(false, "scrollstart fired");
});
- $($.event.special.scrollstart).bind("touchmove", function(){
+ $( "#qunit-fixture" ).bind("touchmove", function(){
ok(true, "touchmove fired");
start();
});
- $($.event.special.scrollstart).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchmove");
});
asyncTest( "scrollstart setup binds a function that triggers scroll start when enabled", function(){
$.event.special.scrollstart.enabled = true;
- $($.event.special.scrollstart).bind("scrollstart", function(){
+ $( "#qunit-fixture" ).bind("scrollstart", function(){
ok(true, "scrollstart fired");
start();
});
- $($.event.special.scrollstart).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchmove");
});
asyncTest( "scrollstart setup binds a function that triggers scroll stop after 50 ms", function(){
var triggered = false;
$.event.special.scrollstart.enabled = true;
- $($.event.special.scrollstart).bind("scrollstop", function(){
+ $( "#qunit-fixture" ).bind("scrollstop", function(){
triggered = true;
});
ok(!triggered, "not triggered");
- $($.event.special.scrollstart).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchmove");
setTimeout(function(){
ok(triggered, "triggered");
@@ -144,11 +142,11 @@
forceTouchSupport();
- $($.event.special.tap).bind("taphold", function(){
+ $( "#qunit-fixture" ).bind("taphold", function(){
taphold = true;
});
- $($.event.special.tap).trigger("vmousedown");
+ $( "#qunit-fixture" ).trigger("vmousedown");
setTimeout(function(){
ok(taphold);
@@ -172,17 +170,17 @@
mockAbs(100);
//NOTE record taphold event
- $($.event.special.tap).bind("taphold", function(){
+ $( "#qunit-fixture" ).bind("taphold", function(){
ok(false, "taphold fired");
taphold = true;
});
//NOTE start the touch events
- $($.event.special.tap).trigger("vmousedown");
+ $( "#qunit-fixture" ).trigger("vmousedown");
//NOTE fire touchmove to push back taphold
setTimeout(function(){
- $($.event.special.tap).trigger("vmousecancel");
+ $( "#qunit-fixture" ).trigger("vmousecancel");
}, 100);
//NOTE verify that the taphold hasn't been fired
@@ -203,11 +201,11 @@
forceTouchSupport();
//NOTE record the tap event
- $($.event.special.tap).bind("tap", checkTap);
+ $( "#qunit-fixture" ).bind("tap", checkTap);
- $($.event.special.tap).trigger("vmousedown");
- $($.event.special.tap).trigger("vmouseup");
- $($.event.special.tap).trigger("vclick");
+ $( "#qunit-fixture" ).trigger("vmousedown");
+ $( "#qunit-fixture" ).trigger("vmouseup");
+ $( "#qunit-fixture" ).trigger("vclick");
setTimeout(function(){
start();
@@ -220,7 +218,7 @@
forceTouchSupport();
//NOTE record tap event
- $($.event.special.tap).bind("tap", function(){
+ $( "#qunit-fixture" ).bind("tap", function(){
ok(false, "tap fired");
tap = true;
});
@@ -229,12 +227,12 @@
mockAbs(100);
//NOTE start and move right away
- $($.event.special.tap).trigger("touchstart");
- $($.event.special.tap).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchstart");
+ $( "#qunit-fixture" ).trigger("touchmove");
//NOTE end touch sequence after 20 ms
setTimeout(function(){
- $($.event.special.tap).trigger("touchend");
+ $( "#qunit-fixture" ).trigger("touchend");
}, 20);
setTimeout(function(){
@@ -243,12 +241,101 @@
}, 40);
});
+ asyncTest( "tap event propagates up DOM tree", function(){
+ var tap = 0,
+ $qf = $( "#qunit-fixture" ),
+ $doc = $( document ),
+ docTapCB = function(){
+ same(++tap, 2, "document tap callback called once after #qunit-fixture callback");
+ };
+
+ $qf.bind( "tap", function() {
+ same(++tap, 1, "#qunit-fixture tap callback called once");
+ });
+
+ $doc.bind( "tap", docTapCB );
+
+ $qf.trigger( "vmousedown" )
+ .trigger( "vmouseup" )
+ .trigger( "vclick" );
+
+ // tap binding should be triggered twice, once for
+ // #qunit-fixture, and a second time for document.
+ same( tap, 2, "final tap callback count is 2" );
+
+ $doc.unbind( "tap", docTapCB );
+
+ start();
+ });
+
+ asyncTest( "stopPropagation() prevents tap from propagating up DOM tree", function(){
+ var tap = 0,
+ $qf = $( "#qunit-fixture" ),
+ $doc = $( document ),
+ docTapCB = function(){
+ ok(false, "tap should NOT be triggered on document");
+ };
+
+ $qf.bind( "tap", function(e) {
+ same(++tap, 1, "tap callback 1 triggered once on #qunit-fixture");
+ e.stopPropagation();
+ })
+ .bind( "tap", function(e) {
+ same(++tap, 2, "tap callback 2 triggered once on #qunit-fixture");
+ });
+
+ $doc.bind( "tap", docTapCB);
+
+ $qf.trigger( "vmousedown" )
+ .trigger( "vmouseup" )
+ .trigger( "vclick" );
+
+ // tap binding should be triggered twice.
+ same( tap, 2, "final tap count is 2" );
+
+ $doc.unbind( "tap", docTapCB );
+
+ start();
+ });
+
+ asyncTest( "stopImmediatePropagation() prevents tap propagation and execution of 2nd handler", function(){
+ var tap = 0,
+ $cf = $( "#qunit-fixture" );
+ $doc = $( document ),
+ docTapCB = function(){
+ ok(false, "tap should NOT be triggered on document");
+ };
+
+ // Bind 2 tap callbacks on qunit-fixture. Only the first
+ // one should ever be called.
+ $cf.bind( "tap", function(e) {
+ same(++tap, 1, "tap callback 1 triggered once on #qunit-fixture");
+ e.stopImmediatePropagation();
+ })
+ .bind( "tap", function(e) {
+ ok(false, "tap callback 2 should NOT be triggered on #qunit-fixture");
+ });
+
+ $doc.bind( "tap", docTapCB);
+
+ $cf.trigger( "vmousedown" )
+ .trigger( "vmouseup" )
+ .trigger( "vclick" );
+
+ // tap binding should be triggered once.
+ same( tap, 1, "final tap count is 1" );
+
+ $doc.unbind( "tap", docTapCB );
+
+ start();
+ });
+
var swipeTimedTest = function(opts){
var swipe = false;
forceTouchSupport();
- $($.event.special.swipe).bind('swipe', function(){
+ $( "#qunit-fixture" ).bind('swipe', function(){
swipe = true;
});
@@ -257,15 +344,15 @@
touches: false
};
- $($.event.special.swipe).trigger("touchstart");
+ $( "#qunit-fixture" ).trigger("touchstart");
//NOTE make sure the coordinates are calculated within range
// to be registered as a swipe
mockAbs(opts.coordChange);
setTimeout(function(){
- $($.event.special.swipe).trigger("touchmove");
- $($.event.special.swipe).trigger("touchend");
+ $( "#qunit-fixture" ).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchend");
}, opts.timeout + 100);
setTimeout(function(){
@@ -298,7 +385,7 @@
forceTouchSupport();
// ensure the swipe custome event is setup
- $($.event.special.swipe).bind('swipe', function(){});
+ $( "#qunit-fixture" ).bind('swipe', function(){});
//NOTE bypass the trigger source check
$.Event.prototype.originalEvent = {
@@ -312,8 +399,8 @@
mockAbs(11);
- $($.event.special.swipe).trigger("touchstart");
- $($.event.special.swipe).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchstart");
+ $( "#qunit-fixture" ).trigger("touchmove");
});
asyncTest( "move handler returns when touchstart has been fired since touchstop", function(){
@@ -327,12 +414,12 @@
forceTouchSupport();
// ensure the swipe custome event is setup
- $($.event.special.swipe).bind('swipe', function(){});
+ $( "#qunit-fixture" ).bind('swipe', function(){});
- $($.event.special.swipe).trigger("touchstart");
- $($.event.special.swipe).trigger("touchend");
+ $( "#qunit-fixture" ).trigger("touchstart");
+ $( "#qunit-fixture" ).trigger("touchend");
- $($.event.special.swipe).bind("touchmove", function(){
+ $( "#qunit-fixture" ).bind("touchmove", function(){
ok(true, "touchmove bound functions are fired");
start();
});
@@ -341,7 +428,7 @@
ok(false, "shouldn't compare coordinates");
};
- $($.event.special.swipe).trigger("touchmove");
+ $( "#qunit-fixture" ).trigger("touchmove");
});
var nativeSupportTest = function(opts){
View
2  tests/unit/navigation/index.html
@@ -18,7 +18,7 @@
<script type="text/javascript">
$.testHelper.setPushStateFor([
"navigation_transitions.js",
- "navigation_helper.js",
+ "navigation_helpers.js",
"navigation_core.js",
"navigation_paths.js"
]);
View
155 tests/unit/navigation/navigation_helpers.js
@@ -63,69 +63,94 @@
p15 = "http://jqm.com/dir1/dir2/test.php#spaz",
p16 = "http://jqm.com/dir1/dir2/test.php?foo=1&bar=2#spaz";
- // Test URL conversion against an absolute URL to the site root.
-
- // 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" );
-
- 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 URL conversion against an absolute URL to the site root.
+ // 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" );
+
+ 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" );
+ });
+
+ // https://github.com/jquery/jquery-mobile/issues/2362
+ test( "ipv6 host support", function(){
+ // http://www.ietf.org/rfc/rfc2732.txt ipv6 examples for tests
+ // most definitely not comprehensive
+ var ipv6_1 = "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html",
+ ipv6_2 = "http://[1080:0:0:0:8:800:200C:417A]/index.html",
+ ipv6_3 = "http://[3ffe:2a00:100:7031::1]",
+ ipv6_4 = "http://[1080::8:800:200C:417A]/foo",
+ ipv6_5 = "http://[::192.9.5.5]/ipng",
+ ipv6_6 = "http://[::FFFF:129.144.52.38]:80/index.html",
+ ipv6_7 = "http://[2010:836B:4179::836B:4179]",
+ fromIssue = "http://[3fff:cafe:babe::]:443/foo";
+
+ same( $.mobile.path.parseUrl(ipv6_1).host, "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80");
+ same( $.mobile.path.parseUrl(ipv6_1).hostname, "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]");
+ same( $.mobile.path.parseUrl(ipv6_2).host, "[1080:0:0:0:8:800:200C:417A]");
+ same( $.mobile.path.parseUrl(ipv6_3).host, "[3ffe:2a00:100:7031::1]");
+ same( $.mobile.path.parseUrl(ipv6_4).host, "[1080::8:800:200C:417A]");
+ same( $.mobile.path.parseUrl(ipv6_5).host, "[::192.9.5.5]");
+ same( $.mobile.path.parseUrl(ipv6_6).host, "[::FFFF:129.144.52.38]:80");
+ same( $.mobile.path.parseUrl(ipv6_6).hostname, "[::FFFF:129.144.52.38]");
+ same( $.mobile.path.parseUrl(ipv6_7).host, "[2010:836B:4179::836B:4179]");
+ same( $.mobile.path.parseUrl(fromIssue).host, "[3fff:cafe:babe::]:443");
+ same( $.mobile.path.parseUrl(fromIssue).hostname, "[3fff:cafe:babe::]");
});
test( "path.clean is working properly", function(){
@@ -156,12 +181,12 @@
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" );
View
12 tests/unit/support/support_core.js
@@ -24,7 +24,9 @@ $.testHelper.excludeFileProtocol(function(){
document.ontouchend = true;
- history.pushState = function(){};
+ window.history.pushState = function(){};
+ window.history.replaceState = function(){};
+
$.mobile.media = function(){ return true; };
$.testHelper.reloadLib(libName);
@@ -69,15 +71,15 @@ $.testHelper.excludeFileProtocol(function(){
$.testHelper.reloadLib(libName);
ok(!$.support.dynamicBaseTag);
});
-
+
test( "jQM's IE browser check properly detects IE versions", function(){
$.testHelper.reloadLib(libName);
-
+
//here we're just comparing our version to what the conditional compilation finds
var ie = !!$.browser.msie, //get a boolean
version = parseInt( $.browser.version, 10),
jqmdetectedver = $.mobile.browser.ie;
-
+
if( ie ){
same(version, jqmdetectedver, "It's IE and the version is correct");
}
@@ -85,7 +87,7 @@ $.testHelper.excludeFileProtocol(function(){
same(ie, jqmdetectedver, "It's not IE");
}
});
-
+
//TODO propExists testing, refactor propExists into mockable method
//TODO scrollTop testing, refactor scrollTop logic into mockable method
View
2  themes/default/jquery.mobile.forms.slider.css
@@ -16,7 +16,7 @@ a.ui-slider-handle .ui-btn-inner { padding-left: 0; padding-right: 0; }
div.ui-slider-switch { height: 32px; overflow: hidden; margin-left: 0; }
div.ui-slider-inneroffset { margin-left: 50%; position: absolute; top: 1px; height: 100%; width: 50%; }
-div.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; }
+a.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; }
div.ui-slider-labelbg { position: absolute; top:0; margin: 0; border-width: 0; }
div.ui-slider-switch div.ui-slider-labelbg-a { width: 60%; height: 100%; left: 0; }
div.ui-slider-switch div.ui-slider-labelbg-b { width: 60%; height: 100%; right: 0; }
View
1  themes/default/jquery.mobile.theme.css
@@ -806,6 +806,7 @@ a.ui-link-inherit {
.ui-icon-radio-off {
background-color: transparent;
}
+.ui-icon-checkbox-on,
.ui-checkbox-on .ui-icon,
.ui-radio-on .ui-icon {
background-color: #4596ce; /* NOTE: this hex should match the active state color. It's repeated here for cascade */
Please sign in to comment.
Something went wrong with that request. Please try again.