diff --git a/experiments/splitview/eventlog.js b/experiments/splitview/eventlog.js new file mode 100644 index 00000000000..ab0ecb99803 --- /dev/null +++ b/experiments/splitview/eventlog.js @@ -0,0 +1,26 @@ + + // $(document).bind('mobileinit',function(event){ + // console.log( event.type + 'event triggered'); + //}); + + var $pages = $("div[data-role='page']"); + + $(window).bind('orientationchange orientationchange.htmlclass', function(event){ + if (window.console) { + console.log(event.type + ' event triggered'); + } + }); + + $(window.document).bind('mobileinit', function(event){ + if (window.console) { + console.log(event.type + ' event triggered'); + } + }); + + $pages.live('pagebeforecreate pagecreate pagebeforehide pagebeforeshow pageshow pagehide',function(event){ + if (window.console) { + console.log( event.type + ' event triggered for ' + $(this).attr('id')); + } + }); + + diff --git a/experiments/splitview/images/ajax-loader.png b/experiments/splitview/images/ajax-loader.png new file mode 100644 index 00000000000..811a2cdd1b4 Binary files /dev/null and b/experiments/splitview/images/ajax-loader.png differ diff --git a/experiments/splitview/images/icon-search-black.png b/experiments/splitview/images/icon-search-black.png new file mode 100644 index 00000000000..5721120f8df Binary files /dev/null and b/experiments/splitview/images/icon-search-black.png differ diff --git a/experiments/splitview/images/icons-18-black.png b/experiments/splitview/images/icons-18-black.png new file mode 100644 index 00000000000..71268bdf70f Binary files /dev/null and b/experiments/splitview/images/icons-18-black.png differ diff --git a/experiments/splitview/images/icons-18-white.png b/experiments/splitview/images/icons-18-white.png new file mode 100644 index 00000000000..dadc6af5870 Binary files /dev/null and b/experiments/splitview/images/icons-18-white.png differ diff --git a/experiments/splitview/images/icons-36-black.png b/experiments/splitview/images/icons-36-black.png new file mode 100644 index 00000000000..8c35ae3fb03 Binary files /dev/null and b/experiments/splitview/images/icons-36-black.png differ diff --git a/experiments/splitview/images/icons-36-white.png b/experiments/splitview/images/icons-36-white.png new file mode 100644 index 00000000000..7e559b8163f Binary files /dev/null and b/experiments/splitview/images/icons-36-white.png differ diff --git a/experiments/splitview/index.html b/experiments/splitview/index.html new file mode 100644 index 00000000000..5a444e46ce8 --- /dev/null +++ b/experiments/splitview/index.html @@ -0,0 +1,396 @@ + + + + Jquery Mobile Splitview + + + + + + + + + + +
+ +
+ +
+

Main

+
+ +
+ +
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + + + +
+ +
+

Demos

+
+ +
+ +
+ +
+
+ +
+

Engineworks © CS8

+
+
+ +
+ +
+ +
+ +
+

About SplitView

+
+ +
+

We first started to look into jQuery Mobile when had a project that needed us to build web applications that would work great on all platforms: Desktop, Tablets(iPad), and Mobile

+ +

Although jQuery Mobile was still in alpha 1 at that time, we felt that it provided the most in terms of what we needed. so we set ahead trying to see if we could help others who had the same interest as we did: get it to work well on the Desktop/iPad - as a SplitView

+ +

A few months later, around alpha 3, we finally got our first splitview to work, and thanks to support from jQuery Mobile's own core team members, Splitview for jQMobile is what it is today

+ +

There are still a lot of things to do, but we hope you enjoy using this plugin, and contribute back to it by reporting bugs, requesting features, and best of all, submitting your own code contributions. Thanks!

+ +

NOTE: keep in mind that I added some namespacing to event handlers in jQMobile core. use the version of jQuerymobile found in the experiments/splitview/ folder of my fork.

+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ +
+

About Us

+
+ +
+

CS8

+

We're a bunch of guys who love to code. Ruby on Rails, Wordpress, Drupal, and OpenERP - we love 'em all... and we'll soon be introducing our own open-source project, based on jQueryMobile, and Ruby on Rails.

+ +

So stay tuned, check back here often, or follow us on facebook or twitter! details below: + +

Twitter: asyraf9

+

Facebook: asyraf9

+

Website: www.cs8.my

+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ +
+

Panels

+
+ +
+

In order for splitview to work, we defined two more <div> tags to enclose the pages - one called 'main', the right hand panel, and 'menu' which is the left sidebar panel

+ +

This provides us with a few advantages:

+ +

1. It allows us to define the area new pages should be loaded in. We do this by using data-panel attributes on anchor tags. example:

+ <a href="some_other_page" data-panel="main"> +

+

2. It allows us to define if a panel's page transitions should be tracked in history or not.

+

+ This uses the data-hash attribute on the panels. It takes three options - 'true','false', and 'crumbs' with true as default. + The 'crumbs' setting changes the panel's back button into a button that points to the previous page, and disables jQMobile from tracking the panel's history +

+

3. It allows us to hide and show the panel depending on screen orientation, and unobtrusively disable it when the site is viewed on mobile browsers

+ +
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ +
+

Orientation and Resize

+
+ +
+

Very simply put, SplitView dynamically lays out the pages based on your tablet's (iPad, etc) orientation, as well as your desktop's screen size. Try it out, resize your browser, or turn your iPad to see it in portrait and landscape modes!

+ +

NOTE: you may have to refresh the view if you scale the browser window down to a mobile size - less than 480px - Splitview determines upon page load if it should lay the pages out in splitview mode or mobile mode (the default jQmobile implementation)

+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ +
+

Scrolling

+
+ +
+

Splitview detects if your device is touch enabled or not. it will then implement the proper scrolling mechanism for your device. This is possible thanks to the jQuery Mobile team's experimental momentum scroll implementation, which the team promptly pointed us to. Thanks! +

+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ +
+

Credits

+
+ +
+

We could not have made Splitview possible without the work of the following folks:

+ +

The jQuery Mobile team

+

For such a wonderfully well thought piece of code that allows us to plug into it. the core that makes Splitview possible. Thank you! especially to Todd Parker, who pointed us to scrollview.js and supported us the whole way.

+ +

@naugtur from the Jquery Forums

+

naugtur's initial work on a splitview version of jQuery Mobile helped provide the foundation for us to begin our work on this plugin. You can find his work at: http://jquerymobiledictionary.dyndns.org/dualColumn.html Thanks!

+ +

The FellowshipTech Team

+

Fellowshiptech's work on slablet provided us with the foundation to produce the CSS that worked well for a double column layout. You can find their work at: https://github.com/fellowshiptech/slablet Thanks!

+ +

Folks at Cagintranet

+

We couldn't have done the iPad style popover without some help from the tutorial these guys provided at http://www.cagintranet.com/archive/create-an-ipad-like-dropdown-popover/ Thanks!

+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ +
+ +
+

Source@Github

+
+ +
+

Get our source at our fork of jquery-mobile at github:

+ +

https://github.com/asyraf9/jquery-mobile/

+ +

codes and this sample html file are located in the /experiments/splitview folder. Splitview still needs work, so help us make it better by submitting bug reports, feature request and patches!

+ +

To report bugs (and there are still a few of them!), file an issue under our fork of jquery-mobile at github. Thanks!

+ +

NOTE: keep in mind that I added some namespacing to event handlers in jQMobile core. use the version of jQuerymobile found in the experiments/splitview/ folder of my fork.

+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ +
+

Bar

+
+ +
+

I'm first in the source order so I'm shown as the page.

+

Back to badz

+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + + +
+ +
+

badz

+
+ +
+
+

I'm first in the source order so I'm shown as the page.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque consectetur, ligula quis convallis gravida, tortor odio mattis purus, a fringilla mauris velit eu nisi. Vivamus laoreet tincidunt diam, sit amet tristique purus lobortis ac. Etiam commodo placerat elit. In aliquam dapibus felis, molestie molestie purus scelerisque sit amet. Donec vitae varius arcu. Aliquam dapibus dolor magna, nec posuere felis. Nullam in suscipit massa. Duis nec nulla nec urna sollicitudin fringilla. Proin at rutrum mi. Maecenas vitae urna ante, ac gravida tortor.

+ +

Vestibulum porta pretium nunc, at adipiscing tortor fringilla sit amet. Sed venenatis varius turpis, vel fringilla purus egestas in. Curabitur interdum mauris nec velit vehicula sed aliquam nulla convallis. Nulla id magna libero, sagittis fringilla metus. Suspendisse dapibus tincidunt tristique. Fusce interdum tincidunt tincidunt. Phasellus tempus fringilla augue eget tincidunt. Donec facilisis mauris ut metus eleifend eget scelerisque nulla sagittis. Ut vel elit non risus dapibus luctus. Pellentesque vel nibh tortor.

+
+

Fusce a nisi at dolor rutrum tristique. Donec faucibus metus vitae lorem scelerisque malesuada scelerisque enim imperdiet. Aliquam in erat orci. Ut ultrices, erat eu luctus accumsan, lorem nibh cursus purus, in laoreet nisi tellus interdum sem. Nulla fringilla molestie lectus nec hendrerit. In in mollis tortor. Nunc lectus tortor, porttitor vitae viverra non, dignissim ac ligula. In tincidunt libero id turpis gravida iaculis rhoncus dolor aliquam. Vestibulum congue massa nec nibh sagittis tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque quis urna arcu. Quisque feugiat ante id turpis ultrices vel imperdiet ipsum volutpat. Donec enim magna, pretium eu scelerisque ut, pretium placerat risus.

Sed sed lacinia ante. Aenean non quam in ipsum pharetra condimentum. + +

Donec turpis lacus, pharetra ac viverra sit amet, lobortis eu nisl. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur porttitor dignissim orci ut feugiat. Praesent quis auctor purus. Suspendisse non elit accumsan mi pellentesque laoreet. Nullam et sapien sed nibh dictum tempor sit amet ut velit. Vestibulum varius ultricies lorem sed ultricies. Vestibulum auctor velit vitae ante eleifend eget bibendum metus rutrum. Nulla facilisis luctus mi laoreet rutrum. Nunc accumsan urna at elit pellentesque ut venenatis lectus adipiscing. Ut et arcu urna. Aliquam eros leo, ultricies vel porta nec, tempor sit amet leo. Quisque imperdiet facilisis orci ut malesuada. Nunc eget elit mauris. Mauris sed felis lectus.

+ +

Duis purus sem, condimentum eget posuere sed, vulputate non lorem. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras risus urna, commodo quis interdum sit amet, elementum vitae lacus. Ut tempor hendrerit ante et facilisis. Vivamus elementum purus justo, ut auctor arcu. Cras varius rhoncus venenatis. Nulla dignissim velit a erat euismod pretium. In sed leo orci, et consectetur justo. Vestibulum ipsum urna, cursus in placerat in, malesuada eu odio. Nunc eget ullamcorper tortor. In commodo, turpis sed egestas egestas, dolor sem mattis nulla, eu semper lectus metus at eros. Sed cursus nisl id risus fermentum quis aliquam odio pretium. Quisque justo eros, blandit gravida tristique eget, rhoncus in magna. Integer volutpat faucibus dolor, sit amet tempor metus ornare consequat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nunc et lacus enim, sit amet consequat turpis.

+

Back to foo

+
+
+
+ +
+
+ +
+

Engineworks © CS8

+
+
+ + +
+ + + + + + + + + + diff --git a/experiments/splitview/iscroll-lite.js b/experiments/splitview/iscroll-lite.js new file mode 100644 index 00000000000..08adc381c9b --- /dev/null +++ b/experiments/splitview/iscroll-lite.js @@ -0,0 +1,567 @@ +/** + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * iScroll Lite Edition based on iScroll v4.0 Beta 4 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Copyright (c) 2010 Matteo Spinelli, http://cubiq.org/ + * Released under MIT license + * http://cubiq.org/dropbox/mit-license.txt + * + * Last updated: 2011.03.10 + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + */ + +;(function(){ +function iScroll (el, options) { + var that = this, doc = document, i; + + that.wrapper = typeof el == 'object' ? el : doc.getElementById(el); + that.wrapper.style.overflow = 'hidden'; + that.scroller = that.wrapper.children[0]; + that.scroller.style.cssText += '-webkit-transition-property:-webkit-transform;-webkit-transform-origin:0 0;-webkit-transform:' + trnOpen + '0,0' + trnClose; + that.scroller.style.cssText += '-webkit-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-webkit-transition-duration:0;'; + + // Default options + that.options = { + hScroll: true, + vScroll: true, + bounce: has3d, + bounceLock: false, + momentum: has3d, + lockDirection: true, + hScrollbar: true, + vScrollbar: true, + fixedScrollbar: isAndroid, + fadeScrollbar: (isIDevice && has3d) || !hasTouch, + hideScrollbar: isIDevice || !hasTouch, + scrollbarClass: '', + onScrollStart: null, + onScrollEnd: null, + }; + + // User defined options + for (i in options) { + that.options[i] = options[i]; + } + + that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar; + that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar; + + that.refresh(); + + that._bind(RESIZE_EV, window); + that._bind(START_EV); +/* that._bind(MOVE_EV); + that._bind(END_EV); + that._bind(CANCEL_EV);*/ +} + +iScroll.prototype = { + x: 0, y: 0, + + handleEvent: function (e) { + var that = this; + + switch(e.type) { + case START_EV: that._start(e); break; + case MOVE_EV: that._move(e); break; + case END_EV: + case CANCEL_EV: that._end(e); break; + case 'webkitTransitionEnd': that._transitionEnd(e); break; + case RESIZE_EV: that._resize(); break; + } + }, + + _scrollbar: function (dir) { + var that = this, + doc = document, + bar; + + if (!that[dir + 'Scrollbar']) { + if (that[dir + 'ScrollbarWrapper']) { + that[dir + 'ScrollbarIndicator'].style.webkitTransform = ''; // Should free some mem + that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']); + that[dir + 'ScrollbarWrapper'] = null; + that[dir + 'ScrollbarIndicator'] = null; + } + + return; + } + + if (!that[dir + 'ScrollbarWrapper']) { + // Create the scrollbar wrapper + bar = doc.createElement('div'); + if (that.options.scrollbarClass) { + bar.className = that.options.scrollbarClass + dir.toUpperCase(); + } else { + bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px;left:2px;right:7px' : 'width:7px;bottom:7px;top:2px;right:1px'); + } + bar.style.cssText += 'pointer-events:none;-webkit-transition-property:opacity;-webkit-transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + ';overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1'); + + that.wrapper.appendChild(bar); + that[dir + 'ScrollbarWrapper'] = bar; + + // Create the scrollbar indicator + bar = doc.createElement('div'); + if (!that.options.scrollbarClass) { + bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);-webkit-background-clip:padding-box;-webkit-box-sizing:border-box;' + (dir == 'h' ? 'height:100%;-webkit-border-radius:4px 3px;' : 'width:100%;-webkit-border-radius:3px 4px;'); + } + bar.style.cssText += 'pointer-events:none;-webkit-transition-property:-webkit-transform;-webkit-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-webkit-transition-duration:0;-webkit-transform:' + trnOpen + '0,0' + trnClose; + + that[dir + 'ScrollbarWrapper'].appendChild(bar); + that[dir + 'ScrollbarIndicator'] = bar; + } + + if (dir == 'h') { + that.hScrollbarSize = that.hScrollbarWrapper.clientWidth; + that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8); + that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px'; + that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize; + that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX; + } else { + that.vScrollbarSize = that.vScrollbarWrapper.clientHeight; + that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8); + that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px'; + that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize; + that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY; + } + + // Reset position + that._indicatorPos(dir, true); + }, + + _resize: function () { + var that = this; + + //if (that.options.momentum) that._unbind('webkitTransitionEnd'); + + setTimeout(function () { + that.refresh(); + }, 0); + }, + + _pos: function (x, y) { + var that = this; + + that.x = that.hScroll ? x : 0; + that.y = that.vScroll ? y : 0; + + that.scroller.style.webkitTransform = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose; + + that._indicatorPos('h'); + that._indicatorPos('v'); + }, + + _indicatorPos: function (dir, hidden) { + var that = this, + pos = dir == 'h' ? that.x : that.y; + + if (!that[dir + 'Scrollbar']) return; + + pos = that[dir + 'ScrollbarProp'] * pos; + + if (pos < 0) { + pos = that.options.fixedScrollbar ? 0 : pos + pos*3; + if (that[dir + 'ScrollbarIndicatorSize'] + pos < 9) pos = -that[dir + 'ScrollbarIndicatorSize'] + 8; + } else if (pos > that[dir + 'ScrollbarMaxScroll']) { + pos = that.options.fixedScrollbar ? that[dir + 'ScrollbarMaxScroll'] : pos + (pos - that[dir + 'ScrollbarMaxScroll'])*3; + if (that[dir + 'ScrollbarIndicatorSize'] + that[dir + 'ScrollbarMaxScroll'] - pos < 9) pos = that[dir + 'ScrollbarIndicatorSize'] + that[dir + 'ScrollbarMaxScroll'] - 8; + } + that[dir + 'ScrollbarWrapper'].style.webkitTransitionDelay = '0'; + that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1'; + that[dir + 'ScrollbarIndicator'].style.webkitTransform = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose; + }, + + _transitionTime: function (time) { + var that = this; + + time += 'ms'; + that.scroller.style.webkitTransitionDuration = time; + + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionDuration = time; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionDuration = time; + }, + + _start: function (e) { + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + matrix; + + that.moved = false; + + e.preventDefault(); + + that.moved = false; + that.distX = 0; + that.distY = 0; + that.absDistX = 0; + that.absDistY = 0; + that.dirX = 0; + that.dirY = 0; + that.returnTime = 0; + + that._transitionTime(0); + + if (that.options.momentum) { + matrix = new WebKitCSSMatrix(window.getComputedStyle(that.scroller, null).webkitTransform); + if (matrix.m41 != that.x || matrix.m42 != that.y) { + that._unbind('webkitTransitionEnd'); + that._pos(matrix.m41, matrix.m42); + } + } + + that.scroller.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.66,1)'; + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.66,1)'; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.66,1)'; + that.startX = that.x; + that.startY = that.y; + that.pointX = point.pageX; + that.pointY = point.pageY; + + that.startTime = e.timeStamp; + + if (that.options.onScrollStart) that.options.onScrollStart.call(that); + + // Registering/unregistering of events is done to preserve resources on Android +// setTimeout(function () { +// that._unbind(START_EV); + that._bind(MOVE_EV); + that._bind(END_EV); + that._bind(CANCEL_EV); +// }, 0); + }, + + _move: function (e) { + if (hasTouch && e.touches.length > 1) return; + + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + deltaX = point.pageX - that.pointX, + deltaY = point.pageY - that.pointY, + newX = that.x + deltaX, + newY = that.y + deltaY; + + e.preventDefault(); + + that.pointX = point.pageX; + that.pointY = point.pageY; + + // Slow down if outside of the boundaries + if (newX > 0 || newX < that.maxScrollX) { + newX = that.options.bounce ? that.x + (deltaX / 2.4) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX; + } + if (newY > 0 || newY < that.maxScrollY) { + newY = that.options.bounce ? that.y + (deltaY / 2.4) : newY >= 0 || that.maxScrollY >= 0 ? 0 : that.maxScrollY; + } + + if (that.absDistX < 4 && that.absDistY < 4) { + that.distX += deltaX; + that.distY += deltaY; + that.absDistX = m.abs(that.distX); + that.absDistY = m.abs(that.distY); + return; + } + + // Lock direction + if (that.options.lockDirection) { + if (that.absDistX > that.absDistY+3) { + newY = that.y; + deltaY = 0; + } else if (that.absDistY > that.absDistX+3) { + newX = that.x; + deltaX = 0; + } + } + + that.moved = true; + that._pos(newX, newY); + that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + if (e.timeStamp - that.startTime > 300) { + that.startTime = e.timeStamp; + that.startX = that.x; + that.startY = that.y; + } + }, + + _end: function (e) { + if (hasTouch && e.touches.length != 0) return; + + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + target, ev, + momentumX = { dist:0, time:0 }, + momentumY = { dist:0, time:0 }, + duration = e.timeStamp - that.startTime, + newPosX = that.x, newPosY = that.y, + newDuration; + +// that._bind(START_EV); + that._unbind(MOVE_EV); + that._unbind(END_EV); + that._unbind(CANCEL_EV); + + if (!that.moved) { + if (hasTouch) { + that.doubleTapTimer = null; + + // Find the last touched element + target = point.target; + while (target.nodeType != 1) { + target = target.parentNode; + } + + ev = document.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + point.screenX, point.screenY, point.clientX, point.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + ev._fake = true; + target.dispatchEvent(ev); + } + + that._resetPos(); + return; + } + + if (duration < 300 && that.options.momentum) { + momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX; + momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y : 0), that.options.bounce ? that.wrapperH : 0) : momentumY; + + newPosX = that.x + momentumX.dist; + newPosY = that.y + momentumY.dist; + + if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 }; + if ((that.y > 0 && newPosY > 0) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 }; + } + + if (momentumX.dist || momentumY.dist) { + newDuration = m.max(m.max(momentumX.time, momentumY.time), 10); + +/* if (newPosX > 0 || newPosX < that.maxScrollX || newPosY > 0 || newPosY < that.maxScrollY) { + // Subtle change of scroller motion + that.scroller.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.5,1)'; + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.5,1)'; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.5,1)'; + }*/ + + that.scrollTo(newPosX, newPosY, newDuration); + return; + } + + that._resetPos(200); + }, + + _resetPos: function (time) { + var that = this, + resetX = that.x, + resetY = that.y; + + if (that.x >= 0) resetX = 0; + else if (that.x < that.maxScrollX) resetX = that.maxScrollX; + + if (that.y >= 0 || that.maxScrollY > 0) resetY = 0; + else if (that.y < that.maxScrollY) resetY = that.maxScrollY; + + if (resetX == that.x && resetY == that.y) { + if (that.moved) { + if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end + that.moved = false; + } + + if (that.hScrollbar && that.options.hideScrollbar) { + that.hScrollbarWrapper.style.webkitTransitionDelay = '300ms'; + that.hScrollbarWrapper.style.opacity = '0'; + } + if (that.vScrollbar && that.options.hideScrollbar) { + that.vScrollbarWrapper.style.webkitTransitionDelay = '300ms'; + that.vScrollbarWrapper.style.opacity = '0'; + } + + return; + } + + // Invert ease + if (time) { + that.scroller.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.0,0.33,1)'; + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.0,0.33,1)'; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.0,0.33,1)'; + } + + that.scrollTo(resetX, resetY, time || 0); + }, + + _transitionEnd: function (e) { + var that = this; + + if (e) e.stopPropagation(); + + that._unbind('webkitTransitionEnd'); + + that._resetPos(that.returnTime); + that.returnTime = 0; + }, + + + /** + * + * Utilities + * + */ + _momentum: function (dist, time, maxDistUpper, maxDistLower, size) { + var that = this, + deceleration = 0.0006, + speed = m.abs(dist) / time, + newDist = (speed * speed) / (2 * deceleration), + newTime = 0, outsideDist = 0; + + // Proportinally reduce speed if we are outside of the boundaries + if (dist > 0 && newDist > maxDistUpper) { + outsideDist = size / (6 / (newDist / speed * deceleration)); + maxDistUpper = maxDistUpper + outsideDist; + that.returnTime = 800 / size * outsideDist + 100; + speed = speed * maxDistUpper / newDist; + newDist = maxDistUpper; + } else if (dist < 0 && newDist > maxDistLower) { + outsideDist = size / (6 / (newDist / speed * deceleration)); + maxDistLower = maxDistLower + outsideDist; + that.returnTime = 800 / size * outsideDist + 100; + speed = speed * maxDistLower / newDist; + newDist = maxDistLower; + } + + newDist = newDist * (dist < 0 ? -1 : 1); + newTime = speed / deceleration; + + return { dist: newDist, time: m.round(newTime) }; + }, + + _offset: function (el, tree) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + if (!tree) return { x: left, y: top }; + + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + + return { x: left, y: top }; + }, + + _bind: function (type, el) { + (el || this.scroller).addEventListener(type, this, false); + }, + + _unbind: function (type, el) { + (el || this.scroller).removeEventListener(type, this, false); + }, + + + /** + * + * Public methods + * + */ + destroy: function () { + var that = this; + + // Remove the scrollbars + that.hScrollbar = false; + that.vScrollbar = false; + that._scrollbar('h'); + that._scrollbar('v'); + + // Free some mem + that.scroller.style.webkitTransform = ''; + + // Remove the event listeners + that._unbind('webkitTransitionEnd'); + that._unbind(RESIZE_EV); + that._unbind(START_EV); + that._unbind(MOVE_EV); + that._unbind(END_EV); + that._unbind(CANCEL_EV); + }, + + refresh: function () { + var that = this; + + that.wrapperW = that.wrapper.clientWidth; + that.wrapperH = that.wrapper.clientHeight; + that.scrollerW = that.scroller.offsetWidth; + that.scrollerH = that.scroller.offsetHeight; + that.maxScrollX = that.wrapperW - that.scrollerW; + that.maxScrollY = that.wrapperH - that.scrollerH; + that.dirX = 0; + that.dirY = 0; + + that._transitionTime(0); + + that.hScroll = that.options.hScroll && that.maxScrollX < 0; + that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH); + that.hScrollbar = that.hScroll && that.options.hScrollbar; + that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH; + + // Prepare the scrollbars + that._scrollbar('h'); + that._scrollbar('v'); + + that._resetPos(); + }, + + scrollTo: function (x, y, time, relative) { + var that = this; + + if (relative) { + x = that.x - x; + y = that.y - y; + } + + time = !time || (m.round(that.x) == m.round(x) && m.round(that.y) == m.round(y)) ? 0 : time; + + that.moved = true; + + if (time) that._bind('webkitTransitionEnd'); + that._transitionTime(time); + that._pos(x, y); + if (!time) setTimeout(function () { that._transitionEnd(); }, 0); + }, + + scrollToElement: function (el, time) { + var that = this, pos; + el = el.nodeType ? el : that.scroller.querySelector(el); + if (!el) return; + + pos = that._offset(el); + pos.x = pos.x > 0 ? 0 : pos.x < that.maxScrollX ? that.maxScrollX : pos.x; + pos.y = pos.y > 0 ? 0 : pos.y < that.maxScrollY ? that.maxScrollY : pos.y; + time = time === undefined ? m.max(m.abs(pos.x)*2, m.abs(pos.y)*2) : time; + + that.scrollTo(pos.x, pos.y, time); + } +}; + + +var has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(), + hasTouch = 'ontouchstart' in window, + isIDevice = (/iphone|ipad/gi).test(navigator.appVersion), + isAndroid = (/android/gi).test(navigator.appVersion), + RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize', + START_EV = hasTouch ? 'touchstart' : 'mousedown', + MOVE_EV = hasTouch ? 'touchmove' : 'mousemove', + END_EV = hasTouch ? 'touchend' : 'mouseup', + CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup', + trnOpen = 'translate' + (has3d ? '3d(' : '('), + trnClose = has3d ? ',0)' : ')', + m = Math; + +if (typeof exports !== 'undefined') exports.iScroll = iScroll; +else window.iScroll = iScroll; + +})(); \ No newline at end of file diff --git a/experiments/splitview/iscroll.js b/experiments/splitview/iscroll.js new file mode 100644 index 00000000000..d8357393d00 --- /dev/null +++ b/experiments/splitview/iscroll.js @@ -0,0 +1,1049 @@ +/** + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * iScroll v4.0 Beta 4 + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Copyright (c) 2010 Matteo Spinelli, http://cubiq.org/ + * Released under MIT license + * http://cubiq.org/dropbox/mit-license.txt + * + * Last updated: 2011.03.10 + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + */ + +(function(){ +function iScroll (el, options) { + var that = this, doc = document, div, i; + + that.wrapper = typeof el == 'object' ? el : doc.getElementById(el); + that.wrapper.style.overflow = 'hidden'; + that.scroller = that.wrapper.children[0]; + + // Default options + that.options = { + HWTransition: true, // Experimental, internal use only + HWCompositing: true, // Experimental, internal use only + hScroll: true, + vScroll: true, + hScrollbar: true, + vScrollbar: true, + fixedScrollbar: isAndroid, + fadeScrollbar: (isIDevice && has3d) || !hasTouch, + hideScrollbar: isIDevice || !hasTouch, + scrollbarClass: '', + bounce: has3d, + bounceLock: false, + momentum: has3d, + lockDirection: true, + zoom: false, + zoomMin: 1, + zoomMax: 4, + snap: false, + pullToRefresh: false, + pullDownLabel: ['Pull down to refresh...', 'Release to refresh...', 'Loading...'], + pullUpLabel: ['Pull up to refresh...', 'Release to refresh...', 'Loading...'], + onPullDown: function () {}, + onPullUp: function () {}, + onScrollStart: null, + onScrollEnd: null, + onZoomStart: null, + onZoomEnd: null, + checkDOMChange: false // Experimental + }; + + // User defined options + for (i in options) { + that.options[i] = options[i]; + } + + that.options.HWCompositing = that.options.HWCompositing && hasCompositing; + that.options.HWTransition = that.options.HWTransition && hasCompositing; + + if (that.options.HWCompositing) { + that.scroller.style.cssText += '-webkit-transition-property:-webkit-transform;-webkit-transform-origin:0 0;-webkit-transform:' + trnOpen + '0,0' + trnClose; + } else { + that.scroller.style.cssText += '-webkit-transition-property:top,left;-webkit-transform-origin:0 0;top:0;left:0'; + } + + if (that.options.HWTransition) { + that.scroller.style.cssText += '-webkit-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-webkit-transition-duration:0;'; + } + + that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar; + that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar; + + that.pullDownToRefresh = that.options.pullToRefresh == 'down' || that.options.pullToRefresh == 'both'; + that.pullUpToRefresh = that.options.pullToRefresh == 'up' || that.options.pullToRefresh == 'both'; + + if (that.pullDownToRefresh) { + div = doc.createElement('div'); + div.className = 'iScrollPullDown'; + div.innerHTML = '' + that.options.pullDownLabel[0] + '\n'; + that.scroller.insertBefore(div, that.scroller.children[0]); + that.options.bounce = true; + that.pullDownEl = div; + that.pullDownLabel = div.getElementsByTagName('span')[1]; + } + + if (that.pullUpToRefresh) { + div = doc.createElement('div'); + div.className = 'iScrollPullUp'; + div.innerHTML = '' + that.options.pullUpLabel[0] + '\n'; + that.scroller.appendChild(div); + that.options.bounce = true; + that.pullUpEl = div; + that.pullUpLabel = div.getElementsByTagName('span')[1]; + } + + that.refresh(); + + that._bind(RESIZE_EV, window); + that._bind(START_EV); +/* that._bind(MOVE_EV); + that._bind(END_EV); + that._bind(CANCEL_EV);*/ + + if (hasGesture && that.options.zoom) { + that._bind('gesturestart'); + that.scroller.style.webkitTransform = that.scroller.style.webkitTransform + ' scale(1)'; + } + + if (!hasTouch) { + that._bind('mousewheel'); + } + + if (that.options.checkDOMChange) { + that.DOMChangeInterval = setInterval(function () { that._checkSize(); }, 250); + } +} + +iScroll.prototype = { + x: 0, y: 0, + currPageX: 0, currPageY: 0, + pagesX: [], pagesY: [], + offsetBottom: 0, + offsetTop: 0, + scale: 1, lastScale: 1, + contentReady: true, + + handleEvent: function (e) { + var that = this; + + switch(e.type) { + case START_EV: that._start(e); break; + case MOVE_EV: that._move(e); break; + case END_EV: + case CANCEL_EV: that._end(e); break; + case 'webkitTransitionEnd': that._transitionEnd(e); break; + case RESIZE_EV: that._resize(); break; + case 'gesturestart': that._gestStart(e); break; + case 'gesturechange': that._gestChange(e); break; + case 'gestureend': + case 'gesturecancel': that._gestEnd(e); break; + case 'mousewheel': that._wheel(e); break; + } + }, + + _scrollbar: function (dir) { + var that = this, + doc = document, + bar; + + if (!that[dir + 'Scrollbar']) { + if (that[dir + 'ScrollbarWrapper']) { + that[dir + 'ScrollbarIndicator'].style.webkitTransform = ''; // Should free some mem + that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']); + that[dir + 'ScrollbarWrapper'] = null; + that[dir + 'ScrollbarIndicator'] = null; + } + + return; + } + + if (!that[dir + 'ScrollbarWrapper']) { + // Create the scrollbar wrapper + bar = doc.createElement('div'); + if (that.options.scrollbarClass) { + bar.className = that.options.scrollbarClass + dir.toUpperCase(); + } else { + bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px;left:2px;right:7px' : 'width:7px;bottom:7px;top:2px;right:1px'); + } + bar.style.cssText += 'pointer-events:none;-webkit-transition-property:opacity;-webkit-transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + ';overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1'); + + that.wrapper.appendChild(bar); + that[dir + 'ScrollbarWrapper'] = bar; + + // Create the scrollbar indicator + bar = doc.createElement('div'); + if (!that.options.scrollbarClass) { + bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);-webkit-background-clip:padding-box;-webkit-box-sizing:border-box;' + (dir == 'h' ? 'height:100%;-webkit-border-radius:4px 3px;' : 'width:100%;-webkit-border-radius:3px 4px;'); + } + bar.style.cssText += 'pointer-events:none;-webkit-transition-property:-webkit-transform;-webkit-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-webkit-transition-duration:0;-webkit-transform:' + trnOpen + '0,0' + trnClose; + + that[dir + 'ScrollbarWrapper'].appendChild(bar); + that[dir + 'ScrollbarIndicator'] = bar; + } + + if (dir == 'h') { + that.hScrollbarSize = that.hScrollbarWrapper.clientWidth; + that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8); + that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px'; + that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize; + that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX; + } else { + that.vScrollbarSize = that.vScrollbarWrapper.clientHeight; + that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8); + that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px'; + that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize; + that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY; + } + + // Reset position + that._indicatorPos(dir, true); + }, + + _resize: function () { + var that = this; + + //if (that.options.momentum) that._unbind('webkitTransitionEnd'); + + setTimeout(function () { + that.refresh(); + }, 0); + }, + + _checkSize: function () { + var that = this, + scrollerW, + scrollerH; + + if (that.moved || that.zoomed || !that.contentReady) return; + + scrollerW = m.round(that.scroller.offsetWidth * that.scale), + scrollerH = m.round((that.scroller.offsetHeight - that.offsetBottom - that.offsetTop) * that.scale); + + if (scrollerW == that.scrollerW && scrollerH == that.scrollerH) return; + + that.refresh(); + }, + + _pos: function (x, y) { + var that = this; + + that.x = that.hScroll ? x : 0; + that.y = that.vScroll ? y : 0; + + that.scroller.style.webkitTransform = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + that.scale + ')'; +// that.scroller.style.left = that.x + 'px'; +// that.scroller.style.top = that.y + 'px'; + + that._indicatorPos('h'); + that._indicatorPos('v'); + }, + + _indicatorPos: function (dir, hidden) { + var that = this, + pos = dir == 'h' ? that.x : that.y; + + if (!that[dir + 'Scrollbar']) return; + + pos = that[dir + 'ScrollbarProp'] * pos; + + if (pos < 0) { + pos = that.options.fixedScrollbar ? 0 : pos + pos*3; + if (that[dir + 'ScrollbarIndicatorSize'] + pos < 9) pos = -that[dir + 'ScrollbarIndicatorSize'] + 8; + } else if (pos > that[dir + 'ScrollbarMaxScroll']) { + pos = that.options.fixedScrollbar ? that[dir + 'ScrollbarMaxScroll'] : pos + (pos - that[dir + 'ScrollbarMaxScroll'])*3; + if (that[dir + 'ScrollbarIndicatorSize'] + that[dir + 'ScrollbarMaxScroll'] - pos < 9) pos = that[dir + 'ScrollbarIndicatorSize'] + that[dir + 'ScrollbarMaxScroll'] - 8; + } + that[dir + 'ScrollbarWrapper'].style.webkitTransitionDelay = '0'; + that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1'; + that[dir + 'ScrollbarIndicator'].style.webkitTransform = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose; + }, + + _transitionTime: function (time) { + var that = this; + + time += 'ms'; + that.scroller.style.webkitTransitionDuration = time; + + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionDuration = time; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionDuration = time; + }, + + _start: function (e) { + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + matrix; + + that.moved = false; + + e.preventDefault(); + + if (hasTouch && e.touches.length == 2 && that.options.zoom && hasGesture && !that.zoomed) { + that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft*2) / 2 - that.x; + that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop*2) / 2 - that.y; + } + + that.moved = false; + that.distX = 0; + that.distY = 0; + that.absDistX = 0; + that.absDistY = 0; + that.dirX = 0; + that.dirY = 0; + that.returnTime = 0; + + that._transitionTime(0); + + if (that.options.momentum) { + if (that.scrollInterval) { + clearInterval(that.scrollInterval); + that.scrollInterval = null; + } + + if (that.options.HWCompositing) { + matrix = new WebKitCSSMatrix(window.getComputedStyle(that.scroller, null).webkitTransform); + if (matrix.m41 != that.x || matrix.m42 != that.y) { + that._unbind('webkitTransitionEnd'); + that._pos(matrix.m41, matrix.m42); + } + } else { + matrix = window.getComputedStyle(that.scroller, null); + if (that.x + 'px' != matrix.left || that.y + 'px' != matrix.top) { + that._unbind('webkitTransitionEnd'); + that._pos(matrix.left.replace(/[^0-9]/g)*1, matrix.top.replace(/[^0-9]/g)*1); + } + } + + } + + that.scroller.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.66,1)'; + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.66,1)'; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.66,1)'; + that.startX = that.x; + that.startY = that.y; + that.pointX = point.pageX; + that.pointY = point.pageY; + + that.startTime = e.timeStamp; + + if (that.options.onScrollStart) that.options.onScrollStart.call(that); + + // Registering/unregistering of events is done to preserve resources on Android +// setTimeout(function () { +// that._unbind(START_EV); + that._bind(MOVE_EV); + that._bind(END_EV); + that._bind(CANCEL_EV); +// }, 0); + }, + + _move: function (e) { + if (hasTouch && e.touches.length > 1) return; + + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + deltaX = point.pageX - that.pointX, + deltaY = point.pageY - that.pointY, + newX = that.x + deltaX, + newY = that.y + deltaY; + + e.preventDefault(); + + that.pointX = point.pageX; + that.pointY = point.pageY; + + // Slow down if outside of the boundaries + if (newX > 0 || newX < that.maxScrollX) { + newX = that.options.bounce ? that.x + (deltaX / 2.4) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX; + } + if (newY > 0 || newY < that.maxScrollY) { + newY = that.options.bounce ? that.y + (deltaY / 2.4) : newY >= 0 || that.maxScrollY >= 0 ? 0 : that.maxScrollY; + + // Pull down to refresh + if (that.options.pullToRefresh && that.contentReady) { + if (that.pullDownToRefresh && newY > that.offsetBottom) { + that.pullDownEl.className = 'iScrollPullDown flip'; + that.pullDownLabel.innerText = that.options.pullDownLabel[1]; + } else if (that.pullDownToRefresh && that.pullDownEl.className.match('flip')) { + that.pullDownEl.className = 'iScrollPullDown'; + that.pullDownLabel.innerText = that.options.pullDownLabel[0]; + } + + if (that.pullUpToRefresh && newY < that.maxScrollY - that.offsetTop) { + that.pullUpEl.className = 'iScrollPullUp flip'; + that.pullUpLabel.innerText = that.options.pullUpLabel[1]; + } else if (that.pullUpToRefresh && that.pullUpEl.className.match('flip')) { + that.pullUpEl.className = 'iScrollPullUp'; + that.pullUpLabel.innerText = that.options.pullUpLabel[0]; + } + } + } + + if (that.absDistX < 4 && that.absDistY < 4) { + that.distX += deltaX; + that.distY += deltaY; + that.absDistX = m.abs(that.distX); + that.absDistY = m.abs(that.distY); + return; + } + + // Lock direction + if (that.options.lockDirection) { + if (that.absDistX > that.absDistY+3) { + newY = that.y; + deltaY = 0; + } else if (that.absDistY > that.absDistX+3) { + newX = that.x; + deltaX = 0; + } + } + + that.moved = true; + that._pos(newX, newY); + that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + if (e.timeStamp - that.startTime > 300) { + that.startTime = e.timeStamp; + that.startX = that.x; + that.startY = that.y; + } + }, + + _end: function (e) { + if (hasTouch && e.touches.length != 0) return; + + var that = this, + point = hasTouch ? e.changedTouches[0] : e, + target, ev, + momentumX = { dist:0, time:0 }, + momentumY = { dist:0, time:0 }, + duration = e.timeStamp - that.startTime, + newPosX = that.x, newPosY = that.y, + newDuration, + snap; + +// that._bind(START_EV); + that._unbind(MOVE_EV); + that._unbind(END_EV); + that._unbind(CANCEL_EV); + + if (that.zoomed) return; + + if (!that.moved) { + if (hasTouch) { + if (that.doubleTapTimer && that.options.zoom) { + // Double tapped + clearTimeout(that.doubleTapTimer); + that.doubleTapTimer = null; + that.zoom(that.pointX, that.pointY, that.scale == 1 ? 2 : 1); + } else { + that.doubleTapTimer = setTimeout(function () { + that.doubleTapTimer = null; + + // Find the last touched element + target = point.target; + while (target.nodeType != 1) { + target = target.parentNode; + } + + ev = document.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + point.screenX, point.screenY, point.clientX, point.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + ev._fake = true; + target.dispatchEvent(ev); + }, that.options.zoom ? 250 : 0); + } + } + + that._resetPos(); + return; + } + + if (that.pullDownToRefresh && that.contentReady && that.pullDownEl.className.match('flip')) { + that.pullDownEl.className = 'iScrollPullDown loading'; + that.pullDownLabel.innerText = that.options.pullDownLabel[2]; + that.scroller.style.marginTop = '0'; + that.offsetBottom = 0; + that.refresh(); + that.contentReady = false; + that.options.onPullDown(); + } + + if (that.pullUpToRefresh && that.contentReady && that.pullUpEl.className.match('flip')) { + that.pullUpEl.className = 'iScrollPullUp loading'; + that.pullUpLabel.innerText = that.options.pullUpLabel[2]; + that.scroller.style.marginBottom = '0'; + that.offsetTop = 0; + that.refresh(); + that.contentReady = false; + that.options.onPullUp(); + } + + if (duration < 300 && that.options.momentum) { + momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX; + momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y : 0), that.options.bounce ? that.wrapperH : 0) : momentumY; + + newPosX = that.x + momentumX.dist; + newPosY = that.y + momentumY.dist; + + if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 }; + if ((that.y > 0 && newPosY > 0) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 }; + } + + if (momentumX.dist || momentumY.dist) { + newDuration = m.max(m.max(momentumX.time, momentumY.time), 10); + + // Do we need to snap? + if (that.options.snap) { + snap = that._snap(newPosX, newPosY); + newPosX = snap.x; + newPosY = snap.y; + newDuration = m.max(snap.time, newDuration); + } + +/* if (newPosX > 0 || newPosX < that.maxScrollX || newPosY > 0 || newPosY < that.maxScrollY) { + // Subtle change of scroller motion + that.scroller.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.5,1)'; + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.5,1)'; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.66,0.5,1)'; + }*/ + + that.scrollTo(newPosX, newPosY, newDuration); + return; + } + + // Do we need to snap? + if (that.options.snap) { + snap = that._snap(that.x, that.y); + if (snap.x != that.x || snap.y != that.y) { + that.scrollTo(snap.x, snap.y, snap.time); + } + return; + } + + that._resetPos(); + }, + + _resetPos: function (time) { + var that = this, + resetX = that.x, + resetY = that.y; + + if (that.x >= 0) resetX = 0; + else if (that.x < that.maxScrollX) resetX = that.maxScrollX; + + if (that.y >= 0 || that.maxScrollY > 0) resetY = 0; + else if (that.y < that.maxScrollY) resetY = that.maxScrollY; + + if (resetX == that.x && resetY == that.y) { + if (that.moved) { + if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end + that.moved = false; + } + + if (that.zoomed) { + if (that.options.onZoomEnd) that.options.onZoomEnd.call(that); // Execute custom code on scroll end + that.zoomed = false; + } + + if (that.hScrollbar && that.options.hideScrollbar) { + that.hScrollbarWrapper.style.webkitTransitionDelay = '300ms'; + that.hScrollbarWrapper.style.opacity = '0'; + } + if (that.vScrollbar && that.options.hideScrollbar) { + that.vScrollbarWrapper.style.webkitTransitionDelay = '300ms'; + that.vScrollbarWrapper.style.opacity = '0'; + } + + return; + } + + if (time === undefined) time = 200; + + // Invert ease + if (time) { + that.scroller.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.0,0.33,1)'; + if (that.hScrollbar) that.hScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.0,0.33,1)'; + if (that.vScrollbar) that.vScrollbarIndicator.style.webkitTransitionTimingFunction = 'cubic-bezier(0.33,0.0,0.33,1)'; + } + + that.scrollTo(resetX, resetY, time); + }, + + _timedScroll: function (destX, destY, runtime) { + var that = this, + startX = that.x, startY = that.y, + startTime = (new Date).getTime(), + easeOut; + + that._transitionTime(0); + + if (that.scrollInterval) { + clearInterval(that.scrollInterval); + that.scrollInterval = null; + } + + that.scrollInterval = setInterval(function () { + var now = (new Date).getTime(), + newX, newY; + + if (now >= startTime + runtime) { + clearInterval(that.scrollInterval); + that.scrollInterval = null; + + that._pos(destX, destY); + that._transitionEnd(); + return; + } + + now = (now - startTime) / runtime - 1; + easeOut = m.sqrt(1 - now * now); + newX = (destX - startX) * easeOut + startX; + newY = (destY - startY) * easeOut + startY; + that._pos(newX, newY); + }, 20); + }, + + _transitionEnd: function (e) { + var that = this; + + if (e) e.stopPropagation(); + + that._unbind('webkitTransitionEnd'); + + that._resetPos(that.returnTime); + that.returnTime = 0; + }, + + + /** + * + * Gestures + * + */ + _gestStart: function (e) { + var that = this; + + that._transitionTime(0); + that.lastScale = 1; + + if (that.options.onZoomStart) that.options.onZoomStart.call(that); + + that._unbind('gesturestart'); + that._bind('gesturechange'); + that._bind('gestureend'); + that._bind('gesturecancel'); + }, + + _gestChange: function (e) { + var that = this, + scale = that.scale * e.scale, + x, y, relScale; + + that.zoomed = true; + + if (scale < that.options.zoomMin) scale = that.options.zoomMin; + else if (scale > that.options.zoomMax) scale = that.options.zoomMax; + + relScale = scale / that.scale; + x = that.originX - that.originX * relScale + that.x; + y = that.originY - that.originY * relScale + that.y; + that.scroller.style.webkitTransform = trnOpen + x + 'px,' + y + 'px' + trnClose + ' scale(' + scale + ')'; + that.lastScale = relScale; + }, + + _gestEnd: function (e) { + var that = this, + scale = that.scale, + lastScale = that.lastScale; + + that.scale = scale * lastScale; + if (that.scale < that.options.zoomMin + 0.05) that.scale = that.options.zoomMin; + else if (that.scale > that.options.zoomMax - 0.05) that.scale = that.options.zoomMax; + lastScale = that.scale / scale; + that.x = that.originX - that.originX * lastScale + that.x; + that.y = that.originY - that.originY * lastScale + that.y; + + that.scroller.style.webkitTransform = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + that.scale + ')'; + + setTimeout(function () { + that.refresh(); + }, 0); + + that._bind('gesturestart'); + that._unbind('gesturechange'); + that._unbind('gestureend'); + that._unbind('gesturecancel'); + }, + + _wheel: function (e) { + var that = this, + deltaX = that.x + e.wheelDeltaX / 12, + deltaY = that.y + e.wheelDeltaY / 12; + + if (deltaX > 0) deltaX = 0; + else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX; + + if (deltaY > 0) deltaY = 0; + else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY; + + that.scrollTo(deltaX, deltaY, 0); + }, + + + /** + * + * Utilities + * + */ + _momentum: function (dist, time, maxDistUpper, maxDistLower, size) { + var that = this, + deceleration = 0.0006, + speed = m.abs(dist) / time, + newDist = (speed * speed) / (2 * deceleration), + newTime = 0, outsideDist = 0; + + // Proportinally reduce speed if we are outside of the boundaries + if (dist > 0 && newDist > maxDistUpper) { + outsideDist = size / (6 / (newDist / speed * deceleration)); + maxDistUpper = maxDistUpper + outsideDist; + that.returnTime = 800 / size * outsideDist + 100; + speed = speed * maxDistUpper / newDist; + newDist = maxDistUpper; + } else if (dist < 0 && newDist > maxDistLower) { + outsideDist = size / (6 / (newDist / speed * deceleration)); + maxDistLower = maxDistLower + outsideDist; + that.returnTime = 800 / size * outsideDist + 100; + speed = speed * maxDistLower / newDist; + newDist = maxDistLower; + } + + newDist = newDist * (dist < 0 ? -1 : 1); + newTime = speed / deceleration; + + return { dist: newDist, time: m.round(newTime) }; + }, + + _offset: function (el, tree) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + if (!tree) return { x: left, y: top }; + + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + + return { x: left, y: top }; + }, + + _snap: function (x, y) { + var that = this, + i, l, + page, time, + sizeX, sizeY; + + // Check page X + page = that.pagesX.length-1; + for (i=0, l=that.pagesX.length; i= that.pagesX[i]) { + page = i; + break; + } + } + if (page == that.currPageX && page > 0 && that.dirX < 0) page--; + x = that.pagesX[page]; + sizeX = m.abs(x - that.pagesX[that.currPageX]); + sizeX = sizeX ? m.abs(that.x - x) / sizeX * 500 : 0; + that.currPageX = page; + + // Check page Y + page = that.pagesY.length-1; + for (i=0; i= that.pagesY[i]) { + page = i; + break; + } + } + if (page == that.currPageY && page > 0 && that.dirY < 0) page--; + y = that.pagesY[page]; + sizeY = m.abs(y - that.pagesY[that.currPageY]); + sizeY = sizeY ? m.abs(that.y - y) / sizeY * 500 : 0; + that.currPageY = page; + + // Snap with constant speed (proportional duration) + time = m.round(m.max(sizeX, sizeY)) || 200; + + return { x: x, y: y, time: time }; + }, + + _bind: function (type, el) { + (el || this.scroller).addEventListener(type, this, false); + }, + + _unbind: function (type, el) { + (el || this.scroller).removeEventListener(type, this, false); + }, + + + /** + * + * Public methods + * + */ + destroy: function () { + var that = this; + + if (that.options.checkDOMChange) clearTimeout(that.DOMChangeInterval); + + // Remove pull to refresh + if (that.pullDownToRefresh) { + that.pullDownEl.parentNode.removeChild(that.pullDownEl); + } + if (that.pullUpToRefresh) { + that.pullUpEl.parentNode.removeChild(that.pullUpEl); + } + + // Remove the scrollbars + that.hScrollbar = false; + that.vScrollbar = false; + that._scrollbar('h'); + that._scrollbar('v'); + + // Free some mem + that.scroller.style.webkitTransform = ''; + + // Remove the event listeners + that._unbind('webkitTransitionEnd'); + that._unbind(RESIZE_EV); + that._unbind(START_EV); + that._unbind(MOVE_EV); + that._unbind(END_EV); + that._unbind(CANCEL_EV); + + if (that.options.zoom) { + that._unbind('gesturestart'); + that._unbind('gesturechange'); + that._unbind('gestureend'); + that._unbind('gesturecancel'); + } + }, + + refresh: function () { + var that = this, + pos = 0, page = 0, + i, l, els, + oldHeight, offsets, + loading; + + if (that.pullDownToRefresh) { + loading = that.pullDownEl.className.match('loading'); + if (loading && !that.contentReady) { + oldHeight = that.scrollerH; + that.contentReady = true; + that.pullDownEl.className = 'iScrollPullDown'; + that.pullDownLabel.innerText = that.options.pullDownLabel[0]; + that.offsetBottom = that.pullDownEl.offsetHeight; + that.scroller.style.marginTop = -that.offsetBottom + 'px'; + } else if (!loading) { + that.offsetBottom = that.pullDownEl.offsetHeight; + that.scroller.style.marginTop = -that.offsetBottom + 'px'; + } + } + + if (that.pullUpToRefresh) { + loading = that.pullUpEl.className.match('loading'); + if (loading && !that.contentReady) { + oldHeight = that.scrollerH; + that.contentReady = true; + that.pullUpEl.className = 'iScrollPullUp'; + that.pullUpLabel.innerText = that.options.pullUpLabel[0]; + that.offsetTop = that.pullUpEl.offsetHeight; + that.scroller.style.marginBottom = -that.offsetTop + 'px'; + } else if (!loading) { + that.offsetTop = that.pullUpEl.offsetHeight; + that.scroller.style.marginBottom = -that.offsetTop + 'px'; + } + } + + that.wrapperW = that.wrapper.clientWidth; + that.wrapperH = that.wrapper.clientHeight; + that.scrollerW = m.round(that.scroller.offsetWidth * that.scale); + that.scrollerH = m.round((that.scroller.offsetHeight - that.offsetBottom - that.offsetTop) * that.scale); + that.maxScrollX = that.wrapperW - that.scrollerW; + that.maxScrollY = that.wrapperH - that.scrollerH; + that.dirX = 0; + that.dirY = 0; + + that._transitionTime(0); + + that.hScroll = that.options.hScroll && that.maxScrollX < 0; + that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH); + that.hScrollbar = that.hScroll && that.options.hScrollbar; + that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH; + + // Prepare the scrollbars + that._scrollbar('h'); + that._scrollbar('v'); + + // Snap + if (typeof that.options.snap == 'string') { + that.pagesX = []; + that.pagesY = []; + els = that.scroller.querySelectorAll(that.options.snap); + for (i=0, l=els.length; i< that.maxScrollX ? that.maxScrollX : pos.x * that.scale; + that.pagesY[i] = pos.y < that.maxScrollY ? that.maxScrollY : pos.y * that.scale; + } + } else if (that.options.snap) { + that.pagesX = []; + while (pos >= that.maxScrollX) { + that.pagesX[page] = pos; + pos = pos - that.wrapperW; + page++; + } + if (that.maxScrollX%that.wrapperW) that.pagesX[that.pagesX.length] = that.maxScrollX - that.pagesX[that.pagesX.length-1] + that.pagesX[that.pagesX.length-1]; + + pos = 0; + page = 0; + that.pagesY = []; + while (pos >= that.maxScrollY) { + that.pagesY[page] = pos; + pos = pos - that.wrapperH; + page++; + } + if (that.maxScrollY%that.wrapperH) that.pagesY[that.pagesY.length] = that.maxScrollY - that.pagesY[that.pagesY.length-1] + that.pagesY[that.pagesY.length-1]; + } + + // Recalculate wrapper offsets + if (that.options.zoom) { + offsets = that._offset(that.wrapper, true); + that.wrapperOffsetLeft = -offsets.x; + that.wrapperOffsetTop = -offsets.y; + } + + if (oldHeight && that.y == 0) { + oldHeight = oldHeight - that.scrollerH + that.y; + that.scrollTo(0, oldHeight, 0); + } + + that._resetPos(); + }, + + scrollTo: function (x, y, time, relative) { + var that = this; + + if (relative) { + x = that.x - x; + y = that.y - y; + } + + time = !time || (m.round(that.x) == m.round(x) && m.round(that.y) == m.round(y)) ? 0 : time; + + that.moved = true; + + if (!that.options.HWTransition) { + that._timedScroll(x, y, time); + return; + } + + if (time) that._bind('webkitTransitionEnd'); + that._transitionTime(time); + that._pos(x, y); + if (!time) setTimeout(function () { that._transitionEnd(); }, 0); + }, + + scrollToElement: function (el, time) { + var that = this, pos; + el = el.nodeType ? el : that.scroller.querySelector(el); + if (!el) return; + + pos = that._offset(el); + pos.x = pos.x > 0 ? 0 : pos.x < that.maxScrollX ? that.maxScrollX : pos.x; + pos.y = pos.y > 0 ? 0 : pos.y < that.maxScrollY ? that.maxScrollY : pos.y; + time = time === undefined ? m.max(m.abs(pos.x)*2, m.abs(pos.y)*2) : time; + + that.scrollTo(pos.x, pos.y, time); + }, + + scrollToPage: function (pageX, pageY, time) { + var that = this, x, y; + + if (that.options.snap) { + pageX = pageX == 'next' ? that.currPageX+1 : pageX == 'prev' ? that.currPageX-1 : pageX; + pageY = pageY == 'next' ? that.currPageY+1 : pageY == 'prev' ? that.currPageY-1 : pageY; + + pageX = pageX < 0 ? 0 : pageX > that.pagesX.length-1 ? that.pagesX.length-1 : pageX; + pageY = pageY < 0 ? 0 : pageY > that.pagesY.length-1 ? that.pagesY.length-1 : pageY; + + that.currPageX = pageX; + that.currPageY = pageY; + x = that.pagesX[pageX]; + y = that.pagesY[pageY]; + } else { + x = -that.wrapperW * pageX; + y = -that.wrapperH * pageY; + if (x < that.maxScrollX) x = that.maxScrollX; + if (y < that.maxScrollY) y = that.maxScrollY; + } + + that.scrollTo(x, y, time || 400); + }, + + zoom: function (x, y, scale) { + var that = this, + relScale = scale / that.scale; + + x = x - that.wrapperOffsetLeft - that.x; + y = y - that.wrapperOffsetTop - that.y; + that.x = x - x * relScale + that.x; + that.y = y - y * relScale + that.y; + + that.scale = scale; + + if (that.options.onZoomStart) that.options.onZoomStart.call(that); + + that.refresh(); + + that._bind('webkitTransitionEnd'); + that._transitionTime(200); + + setTimeout(function () { + that.zoomed = true; + that.scroller.style.webkitTransform = trnOpen + that.x + 'px,' + that.y + 'px' + trnClose + ' scale(' + scale + ')'; + }, 0); + } +}; + + +var has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(), + hasTouch = 'ontouchstart' in window, + hasGesture = 'ongesturestart' in window, +// hasHashChange = 'onhashchange' in window, +// hasTransitionEnd = 'onwebkittransitionend' in window, + hasCompositing = 'WebKitTransitionEvent' in window, + isIDevice = (/iphone|ipad/gi).test(navigator.appVersion), + isAndroid = (/android/gi).test(navigator.appVersion), + RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize', + START_EV = hasTouch ? 'touchstart' : 'mousedown', + MOVE_EV = hasTouch ? 'touchmove' : 'mousemove', + END_EV = hasTouch ? 'touchend' : 'mouseup', + CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup', + trnOpen = 'translate' + (has3d ? '3d(' : '('), + trnClose = has3d ? ',0)' : ')', + m = Math; + +if (typeof exports !== 'undefined') exports.iScroll = iScroll; +else window.iScroll = iScroll; + +})(); \ No newline at end of file diff --git a/experiments/splitview/jquery-1.5.2.min.js b/experiments/splitview/jquery-1.5.2.min.js new file mode 100644 index 00000000000..d5636d70ad2 --- /dev/null +++ b/experiments/splitview/jquery-1.5.2.min.js @@ -0,0 +1,16 @@ +/*! + * jQuery JavaScript Library v1.5.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Thu Mar 31 15:28:23 2011 -0400 + */ +(function(a,b){function ci(a){return d.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cf(a){if(!b_[a]){var b=d("<"+a+">").appendTo("body"),c=b.css("display");b.remove();if(c==="none"||c==="")c="block";b_[a]=c}return b_[a]}function ce(a,b){var c={};d.each(cd.concat.apply([],cd.slice(0,b)),function(){c[this]=a});return c}function b$(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function bZ(){try{return new a.XMLHttpRequest}catch(b){}}function bY(){d(a).unload(function(){for(var a in bW)bW[a](0,1)})}function bS(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var e=a.dataTypes,f={},g,h,i=e.length,j,k=e[0],l,m,n,o,p;for(g=1;g=0===c})}function P(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function H(a,b){return(a&&a!=="*"?a+".":"")+b.replace(t,"`").replace(u,"&")}function G(a){var b,c,e,f,g,h,i,j,k,l,m,n,o,p=[],q=[],s=d._data(this,"events");if(a.liveFired!==this&&s&&s.live&&!a.target.disabled&&(!a.button||a.type!=="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var t=s.live.slice(0);for(i=0;ic)break;a.currentTarget=f.elem,a.data=f.handleObj.data,a.handleObj=f.handleObj,o=f.handleObj.origHandler.apply(f.elem,arguments);if(o===!1||a.isPropagationStopped()){c=f.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function E(a,c,e){var f=d.extend({},e[0]);f.type=a,f.originalEvent={},f.liveFired=b,d.event.handle.call(c,f),f.isDefaultPrevented()&&e[0].preventDefault()}function y(){return!0}function x(){return!1}function i(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function h(a,c,e){if(e===b&&a.nodeType===1){e=a.getAttribute("data-"+c);if(typeof e==="string"){try{e=e==="true"?!0:e==="false"?!1:e==="null"?null:d.isNaN(e)?g.test(e)?d.parseJSON(e):e:parseFloat(e)}catch(f){}d.data(a,c,e)}else e=b}return e}var c=a.document,d=function(){function G(){if(!d.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(G,1);return}d.ready()}}var d=function(a,b){return new d.fn.init(a,b,g)},e=a.jQuery,f=a.$,g,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,i=/\S/,j=/^\s+/,k=/\s+$/,l=/\d/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=navigator.userAgent,w,x,y,z=Object.prototype.toString,A=Object.prototype.hasOwnProperty,B=Array.prototype.push,C=Array.prototype.slice,D=String.prototype.trim,E=Array.prototype.indexOf,F={};d.fn=d.prototype={constructor:d,init:function(a,e,f){var g,i,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!e&&c.body){this.context=c,this[0]=c.body,this.selector="body",this.length=1;return this}if(typeof a==="string"){g=h.exec(a);if(!g||!g[1]&&e)return!e||e.jquery?(e||f).find(a):this.constructor(e).find(a);if(g[1]){e=e instanceof d?e[0]:e,k=e?e.ownerDocument||e:c,j=m.exec(a),j?d.isPlainObject(e)?(a=[c.createElement(j[1])],d.fn.attr.call(a,e,!0)):a=[k.createElement(j[1])]:(j=d.buildFragment([g[1]],[k]),a=(j.cacheable?d.clone(j.fragment):j.fragment).childNodes);return d.merge(this,a)}i=c.getElementById(g[2]);if(i&&i.parentNode){if(i.id!==g[2])return f.find(a);this.length=1,this[0]=i}this.context=c,this.selector=a;return this}if(d.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return d.makeArray(a,this)},selector:"",jquery:"1.5.2",length:0,size:function(){return this.length},toArray:function(){return C.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var e=this.constructor();d.isArray(a)?B.apply(e,a):d.merge(e,a),e.prevObject=this,e.context=this.context,b==="find"?e.selector=this.selector+(this.selector?" ":"")+c:b&&(e.selector=this.selector+"."+b+"("+c+")");return e},each:function(a,b){return d.each(this,a,b)},ready:function(a){d.bindReady(),x.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(C.apply(this,arguments),"slice",C.call(arguments).join(","))},map:function(a){return this.pushStack(d.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:B,sort:[].sort,splice:[].splice},d.fn.init.prototype=d.fn,d.extend=d.fn.extend=function(){var a,c,e,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i==="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!=="object"&&!d.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;x.resolveWith(c,[d]),d.fn.trigger&&d(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!x){x=d._Deferred();if(c.readyState==="complete")return setTimeout(d.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",y,!1),a.addEventListener("load",d.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",y),a.attachEvent("onload",d.ready);var b=!1;try{b=a.frameElement==null}catch(e){}c.documentElement.doScroll&&b&&G()}}},isFunction:function(a){return d.type(a)==="function"},isArray:Array.isArray||function(a){return d.type(a)==="array"},isWindow:function(a){return a&&typeof a==="object"&&"setInterval"in a},isNaN:function(a){return a==null||!l.test(a)||isNaN(a)},type:function(a){return a==null?String(a):F[z.call(a)]||"object"},isPlainObject:function(a){if(!a||d.type(a)!=="object"||a.nodeType||d.isWindow(a))return!1;if(a.constructor&&!A.call(a,"constructor")&&!A.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a){}return c===b||A.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!=="string"||!b)return null;b=d.trim(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return a.JSON&&a.JSON.parse?a.JSON.parse(b):(new Function("return "+b))();d.error("Invalid JSON: "+b)},parseXML:function(b,c,e){a.DOMParser?(e=new DOMParser,c=e.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),e=c.documentElement,(!e||!e.nodeName||e.nodeName==="parsererror")&&d.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(a){if(a&&i.test(a)){var b=c.head||c.getElementsByTagName("head")[0]||c.documentElement,e=c.createElement("script");d.support.scriptEval()?e.appendChild(c.createTextNode(a)):e.text=a,b.insertBefore(e,b.firstChild),b.removeChild(e)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,e){var f,g=0,h=a.length,i=h===b||d.isFunction(a);if(e){if(i){for(f in a)if(c.apply(a[f],e)===!1)break}else for(;g1?f.call(arguments,0):c,--g||h.resolveWith(h,f.call(b,0))}}var b=arguments,c=0,e=b.length,g=e,h=e<=1&&a&&d.isFunction(a.promise)?a:d.Deferred();if(e>1){for(;c
a";var e=b.getElementsByTagName("*"),f=b.getElementsByTagName("a")[0],g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=b.getElementsByTagName("input")[0];if(e&&e.length&&f){d.support={leadingWhitespace:b.firstChild.nodeType===3,tbody:!b.getElementsByTagName("tbody").length,htmlSerialize:!!b.getElementsByTagName("link").length,style:/red/.test(f.getAttribute("style")),hrefNormalized:f.getAttribute("href")==="/a",opacity:/^0.55$/.test(f.style.opacity),cssFloat:!!f.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,deleteExpando:!0,optDisabled:!1,checkClone:!1,noCloneEvent:!0,noCloneChecked:!0,boxModel:null,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableHiddenOffsets:!0,reliableMarginRight:!0},i.checked=!0,d.support.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,d.support.optDisabled=!h.disabled;var j=null;d.support.scriptEval=function(){if(j===null){var b=c.documentElement,e=c.createElement("script"),f="script"+d.now();try{e.appendChild(c.createTextNode("window."+f+"=1;"))}catch(g){}b.insertBefore(e,b.firstChild),a[f]?(j=!0,delete a[f]):j=!1,b.removeChild(e)}return j};try{delete b.test}catch(k){d.support.deleteExpando=!1}!b.addEventListener&&b.attachEvent&&b.fireEvent&&(b.attachEvent("onclick",function l(){d.support.noCloneEvent=!1,b.detachEvent("onclick",l)}),b.cloneNode(!0).fireEvent("onclick")),b=c.createElement("div"),b.innerHTML="";var m=c.createDocumentFragment();m.appendChild(b.firstChild),d.support.checkClone=m.cloneNode(!0).cloneNode(!0).lastChild.checked,d(function(){var a=c.createElement("div"),b=c.getElementsByTagName("body")[0];if(b){a.style.width=a.style.paddingLeft="1px",b.appendChild(a),d.boxModel=d.support.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,d.support.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",d.support.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
";var e=a.getElementsByTagName("td");d.support.reliableHiddenOffsets=e[0].offsetHeight===0,e[0].style.display="",e[1].style.display="none",d.support.reliableHiddenOffsets=d.support.reliableHiddenOffsets&&e[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(a.style.width="1px",a.style.marginRight="0",d.support.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(a,null).marginRight,10)||0)===0),b.removeChild(a).style.display="none",a=e=null}});var n=function(a){var b=c.createElement("div");a="on"+a;if(!b.attachEvent)return!0;var d=a in b;d||(b.setAttribute(a,"return;"),d=typeof b[a]==="function");return d};d.support.submitBubbles=n("submit"),d.support.changeBubbles=n("change"),b=e=f=null}}();var g=/^(?:\{.*\}|\[.*\])$/;d.extend({cache:{},uuid:0,expando:"jQuery"+(d.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?d.cache[a[d.expando]]:a[d.expando];return!!a&&!i(a)},data:function(a,c,e,f){if(d.acceptData(a)){var g=d.expando,h=typeof c==="string",i,j=a.nodeType,k=j?d.cache:a,l=j?a[d.expando]:a[d.expando]&&d.expando;if((!l||f&&l&&!k[l][g])&&h&&e===b)return;l||(j?a[d.expando]=l=++d.uuid:l=d.expando),k[l]||(k[l]={},j||(k[l].toJSON=d.noop));if(typeof c==="object"||typeof c==="function")f?k[l][g]=d.extend(k[l][g],c):k[l]=d.extend(k[l],c);i=k[l],f&&(i[g]||(i[g]={}),i=i[g]),e!==b&&(i[c]=e);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,e){if(d.acceptData(b)){var f=d.expando,g=b.nodeType,h=g?d.cache:b,j=g?b[d.expando]:d.expando;if(!h[j])return;if(c){var k=e?h[j][f]:h[j];if(k){delete k[c];if(!i(k))return}}if(e){delete h[j][f];if(!i(h[j]))return}var l=h[j][f];d.support.deleteExpando||h!=a?delete h[j]:h[j]=null,l?(h[j]={},g||(h[j].toJSON=d.noop),h[j][f]=l):g&&(d.support.deleteExpando?delete b[d.expando]:b.removeAttribute?b.removeAttribute(d.expando):b[d.expando]=null)}},_data:function(a,b,c){return d.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=d.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),d.fn.extend({data:function(a,c){var e=null;if(typeof a==="undefined"){if(this.length){e=d.data(this[0]);if(this[0].nodeType===1){var f=this[0].attributes,g;for(var i=0,j=f.length;i<0&&(h+=" "+b[i]);f.className=d.trim(h)}else f.className=a}}return this},removeClass:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a==="string"||a===b){var c=(a||"").split(k);for(var e=0,f=this.length;e-1)return!0;return!1},val:function(a){if(!arguments.length){var c=this[0];if(c){if(d.nodeName(c,"option")){var e=c.attributes.value;return!e||e.specified?c.value:c.text}if(d.nodeName(c,"select")){var f=c.selectedIndex,g=[],h=c.options,i=c.type==="select-one";if(f<0)return null;for(var j=i?f:0,k=i?f+1:h.length;j=0;else if(d.nodeName(this,"select")){var f=d.makeArray(e);d("option",this).each(function(){this.selected=d.inArray(d(this).val(),f)>=0}),f.length||(this.selectedIndex=-1)}else this.value=e}})}}),d.extend({attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,e,f){if(!a||a.nodeType===3||a.nodeType===8||a.nodeType===2)return b;if(f&&c in d.attrFn)return d(a)[c](e);var g=a.nodeType!==1||!d.isXMLDoc(a),h=e!==b;c=g&&d.props[c]||c;if(a.nodeType===1){var i=m.test(c);if(c==="selected"&&!d.support.optSelected){var j=a.parentNode;j&&(j.selectedIndex,j.parentNode&&j.parentNode.selectedIndex)}if((c in a||a[c]!==b)&&g&&!i){h&&(c==="type"&&n.test(a.nodeName)&&a.parentNode&&d.error("type property can't be changed"),e===null?a.nodeType===1&&a.removeAttribute(c):a[c]=e);if(d.nodeName(a,"form")&&a.getAttributeNode(c))return a.getAttributeNode(c).nodeValue;if(c==="tabIndex"){var k=a.getAttributeNode("tabIndex");return k&&k.specified?k.value:o.test(a.nodeName)||p.test(a.nodeName)&&a.href?0:b}return a[c]}if(!d.support.style&&g&&c==="style"){h&&(a.style.cssText=""+e);return a.style.cssText}h&&a.setAttribute(c,""+e);if(!a.attributes[c]&&(a.hasAttribute&&!a.hasAttribute(c)))return b;var l=!d.support.hrefNormalized&&g&&i?a.getAttribute(c,2):a.getAttribute(c);return l===null?b:l}h&&(a[c]=e);return a[c]}});var r=/\.(.*)$/,s=/^(?:textarea|input|select)$/i,t=/\./g,u=/ /g,v=/[^\w\s.|`]/g,w=function(a){return a.replace(v,"\\$&")};d.event={add:function(c,e,f,g){if(c.nodeType!==3&&c.nodeType!==8){try{d.isWindow(c)&&(c!==a&&!c.frameElement)&&(c=a)}catch(h){}if(f===!1)f=x;else if(!f)return;var i,j;f.handler&&(i=f,f=i.handler),f.guid||(f.guid=d.guid++);var k=d._data(c);if(!k)return;var l=k.events,m=k.handle;l||(k.events=l={}),m||(k.handle=m=function(a){return typeof d!=="undefined"&&d.event.triggered!==a.type?d.event.handle.apply(m.elem,arguments):b}),m.elem=c,e=e.split(" ");var n,o=0,p;while(n=e[o++]){j=i?d.extend({},i):{handler:f,data:g},n.indexOf(".")>-1?(p=n.split("."),n=p.shift(),j.namespace=p.slice(0).sort().join(".")):(p=[],j.namespace=""),j.type=n,j.guid||(j.guid=f.guid);var q=l[n],r=d.event.special[n]||{};if(!q){q=l[n]=[];if(!r.setup||r.setup.call(c,g,p,m)===!1)c.addEventListener?c.addEventListener(n,m,!1):c.attachEvent&&c.attachEvent("on"+n,m)}r.add&&(r.add.call(c,j),j.handler.guid||(j.handler.guid=f.guid)),q.push(j),d.event.global[n]=!0}c=null}},global:{},remove:function(a,c,e,f){if(a.nodeType!==3&&a.nodeType!==8){e===!1&&(e=x);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=d.hasData(a)&&d._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(e=c.handler,c=c.type);if(!c||typeof c==="string"&&c.charAt(0)==="."){c=c||"";for(h in t)d.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+d.map(m.slice(0).sort(),w).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!e){for(j=0;j=0&&(a.type=f=f.slice(0,-1),a.exclusive=!0),e||(a.stopPropagation(),d.event.global[f]&&d.each(d.cache,function(){var b=d.expando,e=this[b];e&&e.events&&e.events[f]&&d.event.trigger(a,c,e.handle.elem)}));if(!e||e.nodeType===3||e.nodeType===8)return b;a.result=b,a.target=e,c=d.makeArray(c),c.unshift(a)}a.currentTarget=e;var h=d._data(e,"handle");h&&h.apply(e,c);var i=e.parentNode||e.ownerDocument;try{e&&e.nodeName&&d.noData[e.nodeName.toLowerCase()]||e["on"+f]&&e["on"+f].apply(e,c)===!1&&(a.result=!1,a.preventDefault())}catch(j){}if(!a.isPropagationStopped()&&i)d.event.trigger(a,c,i,!0);else if(!a.isDefaultPrevented()){var k,l=a.target,m=f.replace(r,""),n=d.nodeName(l,"a")&&m==="click",o=d.event.special[m]||{};if((!o._default||o._default.call(e,a)===!1)&&!n&&!(l&&l.nodeName&&d.noData[l.nodeName.toLowerCase()])){try{l[m]&&(k=l["on"+m],k&&(l["on"+m]=null),d.event.triggered=a.type,l[m]())}catch(p){}k&&(l["on"+m]=k),d.event.triggered=b}}},handle:function(c){var e,f,g,h,i,j=[],k=d.makeArray(arguments);c=k[0]=d.event.fix(c||a.event),c.currentTarget=this,e=c.type.indexOf(".")<0&&!c.exclusive,e||(g=c.type.split("."),c.type=g.shift(),j=g.slice(0).sort(),h=new RegExp("(^|\\.)"+j.join("\\.(?:.*\\.)?")+"(\\.|$)")),c.namespace=c.namespace||j.join("."),i=d._data(this,"events"),f=(i||{})[c.type];if(i&&f){f=f.slice(0);for(var l=0,m=f.length;l-1?d.map(a.options,function(a){return a.selected}).join("-"):"":a.nodeName.toLowerCase()==="select"&&(c=a.selectedIndex);return c},D=function D(a){var c=a.target,e,f;if(s.test(c.nodeName)&&!c.readOnly){e=d._data(c,"_change_data"),f=C(c),(a.type!=="focusout"||c.type!=="radio")&&d._data(c,"_change_data",f);if(e===b||f===e)return;if(e!=null||f)a.type="change",a.liveFired=b,d.event.trigger(a,arguments[1],c)}};d.event.special.change={filters:{focusout:D,beforedeactivate:D,click:function(a){var b=a.target,c=b.type;(c==="radio"||c==="checkbox"||b.nodeName.toLowerCase()==="select")&&D.call(this,a)},keydown:function(a){var b=a.target,c=b.type;(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&D.call(this,a)},beforeactivate:function(a){var b=a.target;d._data(b,"_change_data",C(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in B)d.event.add(this,c+".specialChange",B[c]);return s.test(this.nodeName)},teardown:function(a){d.event.remove(this,".specialChange");return s.test(this.nodeName)}},B=d.event.special.change.filters,B.focus=B.beforeactivate}c.addEventListener&&d.each({focus:"focusin",blur:"focusout"},function(a,b){function f(a){var c=d.event.fix(a);c.type=b,c.originalEvent={},d.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var e=0;d.event.special[b]={setup:function(){e++===0&&c.addEventListener(a,f,!0)},teardown:function(){--e===0&&c.removeEventListener(a,f,!0)}}}),d.each(["bind","one"],function(a,c){d.fn[c]=function(a,e,f){if(typeof a==="object"){for(var g in a)this[c](g,e,a[g],f);return this}if(d.isFunction(e)||e===!1)f=e,e=b;var h=c==="one"?d.proxy(f,function(a){d(this).unbind(a,h);return f.apply(this,arguments)}):f;if(a==="unload"&&c!=="one")this.one(a,e,f);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},d.attrFn&&(d.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,e,g){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!=="string")return e;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(f.call(n)==="[object Array]")if(u)if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&e.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&e.push(j[t]);else e.push.apply(e,n);else p(n,e);o&&(k(o,h,e,g),k.uniqueSort(e));return e};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b==="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return"text"===c&&(b===c||b===null)},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(f.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length==="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!=="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!=="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!=="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!=="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!=="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(var g=c;g0},closest:function(a,b){var c=[],e,f,g=this[0];if(d.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(e=0,f=a.length;e-1:d(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=N.test(a)?d(a,b||this.context):null;for(e=0,f=this.length;e-1:d.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b)break}}c=c.length>1?d.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a==="string")return d.inArray(this[0],a?d(a):this.parent().children());return d.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a==="string"?d(a,b):d.makeArray(a),e=d.merge(this.get(),c);return this.pushStack(P(c[0])||P(e[0])?e:d.unique(e))},andSelf:function(){return this.add(this.prevObject)}}),d.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return d.dir(a,"parentNode")},parentsUntil:function(a,b,c){return d.dir(a,"parentNode",c)},next:function(a){return d.nth(a,2,"nextSibling")},prev:function(a){return d.nth(a,2,"previousSibling")},nextAll:function(a){return d.dir(a,"nextSibling")},prevAll:function(a){return d.dir(a,"previousSibling")},nextUntil:function(a,b,c){return d.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return d.dir(a,"previousSibling",c)},siblings:function(a){return d.sibling(a.parentNode.firstChild,a)},children:function(a){return d.sibling(a.firstChild)},contents:function(a){return d.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:d.makeArray(a.childNodes)}},function(a,b){d.fn[a]=function(c,e){var f=d.map(this,b,c),g=M.call(arguments);I.test(a)||(e=c),e&&typeof e==="string"&&(f=d.filter(e,f)),f=this.length>1&&!O[a]?d.unique(f):f,(this.length>1||K.test(e))&&J.test(a)&&(f=f.reverse());return this.pushStack(f,a,g.join(","))}}),d.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?d.find.matchesSelector(b[0],a)?[b[0]]:[]:d.find.matches(a,b)},dir:function(a,c,e){var f=[],g=a[c];while(g&&g.nodeType!==9&&(e===b||g.nodeType!==1||!d(g).is(e)))g.nodeType===1&&f.push(g),g=g[c];return f},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var R=/ jQuery\d+="(?:\d+|null)"/g,S=/^\s+/,T=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,U=/<([\w:]+)/,V=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};Z.optgroup=Z.option,Z.tbody=Z.tfoot=Z.colgroup=Z.caption=Z.thead,Z.th=Z.td,d.support.htmlSerialize||(Z._default=[1,"div
","
"]),d.fn.extend({text:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.text(a.call(this,b,c.text()))});if(typeof a!=="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return d.text(this)},wrapAll:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapAll(a.call(this,b))});if(this[0]){var b=d(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapInner(a.call(this,b))});return this.each(function(){var b=d(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){d(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){d.nodeName(this,"body")||d(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=d(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,d(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,e;(e=this[c])!=null;c++)if(!a||d.filter(a,[e]).length)!b&&e.nodeType===1&&(d.cleanData(e.getElementsByTagName("*")),d.cleanData([e])),e.parentNode&&e.parentNode.removeChild(e);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&d.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return d.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(R,""):null;if(typeof a!=="string"||X.test(a)||!d.support.leadingWhitespace&&S.test(a)||Z[(U.exec(a)||["",""])[1].toLowerCase()])d.isFunction(a)?this.each(function(b){var c=d(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);else{a=a.replace(T,"<$1>");try{for(var c=0,e=this.length;c1&&l0?this.clone(!0):this).get();d(f[h])[b](j),e=e.concat(j)}return this.pushStack(e,a,f.selector)}}),d.extend({clone:function(a,b,c){var e=a.cloneNode(!0),f,g,h;if((!d.support.noCloneEvent||!d.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!d.isXMLDoc(a)){ba(a,e),f=bb(a),g=bb(e);for(h=0;f[h];++h)ba(f[h],g[h])}if(b){_(a,e);if(c){f=bb(a),g=bb(e);for(h=0;f[h];++h)_(f[h],g[h])}}return e},clean:function(a,b,e,f){b=b||c,typeof b.createElement==="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var g=[];for(var h=0,i;(i=a[h])!=null;h++){typeof i==="number"&&(i+="");if(!i)continue;if(typeof i!=="string"||W.test(i)){if(typeof i==="string"){i=i.replace(T,"<$1>");var j=(U.exec(i)||["",""])[1].toLowerCase(),k=Z[j]||Z._default,l=k[0],m=b.createElement("div");m.innerHTML=k[1]+i+k[2];while(l--)m=m.lastChild;if(!d.support.tbody){var n=V.test(i),o=j==="table"&&!n?m.firstChild&&m.firstChild.childNodes:k[1]===""&&!n?m.childNodes:[];for(var p=o.length-1;p>=0;--p)d.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!d.support.leadingWhitespace&&S.test(i)&&m.insertBefore(b.createTextNode(S.exec(i)[0]),m.firstChild),i=m.childNodes}}else i=b.createTextNode(i);i.nodeType?g.push(i):g=d.merge(g,i)}if(e)for(h=0;g[h];h++)!f||!d.nodeName(g[h],"script")||g[h].type&&g[h].type.toLowerCase()!=="text/javascript"?(g[h].nodeType===1&&g.splice.apply(g,[h+1,0].concat(d.makeArray(g[h].getElementsByTagName("script")))),e.appendChild(g[h])):f.push(g[h].parentNode?g[h].parentNode.removeChild(g[h]):g[h]);return g},cleanData:function(a){var b,c,e=d.cache,f=d.expando,g=d.event.special,h=d.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&d.noData[j.nodeName.toLowerCase()])continue;c=j[d.expando];if(c){b=e[c]&&e[c][f];if(b&&b.events){for(var k in b.events)g[k]?d.event.remove(j,k):d.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[d.expando]:j.removeAttribute&&j.removeAttribute(d.expando),delete e[c]}}}});var bd=/alpha\([^)]*\)/i,be=/opacity=([^)]*)/,bf=/-([a-z])/ig,bg=/([A-Z]|^ms)/g,bh=/^-?\d+(?:px)?$/i,bi=/^-?\d/,bj={position:"absolute",visibility:"hidden",display:"block"},bk=["Left","Right"],bl=["Top","Bottom"],bm,bn,bo,bp=function(a,b){return b.toUpperCase()};d.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return d.access(this,a,c,!0,function(a,c,e){return e!==b?d.style(a,c,e):d.css(a,c)})},d.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bm(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0},cssProps:{"float":d.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,e,f){if(a&&a.nodeType!==3&&a.nodeType!==8&&a.style){var g,h=d.camelCase(c),i=a.style,j=d.cssHooks[h];c=d.cssProps[h]||h;if(e===b){if(j&&"get"in j&&(g=j.get(a,!1,f))!==b)return g;return i[c]}if(typeof e==="number"&&isNaN(e)||e==null)return;typeof e==="number"&&!d.cssNumber[h]&&(e+="px");if(!j||!("set"in j)||(e=j.set(a,e))!==b)try{i[c]=e}catch(k){}}},css:function(a,c,e){var f,g=d.camelCase(c),h=d.cssHooks[g];c=d.cssProps[g]||g;if(h&&"get"in h&&(f=h.get(a,!0,e))!==b)return f;if(bm)return bm(a,c,g)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bf,bp)}}),d.curCSS=d.css,d.each(["height","width"],function(a,b){d.cssHooks[b]={get:function(a,c,e){var f;if(c){a.offsetWidth!==0?f=bq(a,b,e):d.swap(a,bj,function(){f=bq(a,b,e)});if(f<=0){f=bm(a,b,b),f==="0px"&&bo&&(f=bo(a,b,b));if(f!=null)return f===""||f==="auto"?"0px":f}if(f<0||f==null){f=a.style[b];return f===""||f==="auto"?"0px":f}return typeof f==="string"?f:f+"px"}},set:function(a,b){if(!bh.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),d.support.opacity||(d.cssHooks.opacity={get:function(a,b){return be.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style;c.zoom=1;var e=d.isNaN(b)?"":"alpha(opacity="+b*100+")",f=c.filter||"";c.filter=bd.test(f)?f.replace(bd,e):c.filter+" "+e}}),d(function(){d.support.reliableMarginRight||(d.cssHooks.marginRight={get:function(a,b){var c;d.swap(a,{display:"inline-block"},function(){b?c=bm(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bn=function(a,c,e){var f,g,h;e=e.replace(bg,"-$1").toLowerCase();if(!(g=a.ownerDocument.defaultView))return b;if(h=g.getComputedStyle(a,null))f=h.getPropertyValue(e),f===""&&!d.contains(a.ownerDocument.documentElement,a)&&(f=d.style(a,e));return f}),c.documentElement.currentStyle&&(bo=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bh.test(d)&&bi.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bm=bn||bo,d.expr&&d.expr.filters&&(d.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!d.support.reliableHiddenOffsets&&(a.style.display||d.css(a,"display"))==="none"},d.expr.filters.visible=function(a){return!d.expr.filters.hidden(a)});var br=/%20/g,bs=/\[\]$/,bt=/\r?\n/g,bu=/#.*$/,bv=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bw=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bx=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,by=/^(?:GET|HEAD)$/,bz=/^\/\//,bA=/\?/,bB=/<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bC=/^(?:select|textarea)/i,bD=/\s+/,bE=/([?&])_=[^&]*/,bF=/(^|\-)([a-z])/g,bG=function(a,b,c){return b+c.toUpperCase()},bH=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bI=d.fn.load,bJ={},bK={},bL,bM;try{bL=c.location.href}catch(bN){bL=c.createElement("a"),bL.href="",bL=bL.href}bM=bH.exec(bL.toLowerCase())||[],d.fn.extend({load:function(a,c,e){if(typeof a!=="string"&&bI)return bI.apply(this,arguments);if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var g=a.slice(f,a.length);a=a.slice(0,f)}var h="GET";c&&(d.isFunction(c)?(e=c,c=b):typeof c==="object"&&(c=d.param(c,d.ajaxSettings.traditional),h="POST"));var i=this;d.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?d("
").append(c.replace(bB,"")).find(g):c)),e&&i.each(e,[c,b,a])}});return this},serialize:function(){return d.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?d.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bC.test(this.nodeName)||bw.test(this.type))}).map(function(a,b){var c=d(this).val();return c==null?null:d.isArray(c)?d.map(c,function(a,c){return{name:b.name,value:a.replace(bt,"\r\n")}}):{name:b.name,value:c.replace(bt,"\r\n")}}).get()}}),d.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){d.fn[b]=function(a){return this.bind(b,a)}}),d.each(["get","post"],function(a,c){d[c]=function(a,e,f,g){d.isFunction(e)&&(g=g||f,f=e,e=b);return d.ajax({type:c,url:a,data:e,success:f,dataType:g})}}),d.extend({getScript:function(a,c){return d.get(a,b,c,"script")},getJSON:function(a,b,c){return d.get(a,b,c,"json")},ajaxSetup:function(a,b){b?d.extend(!0,a,d.ajaxSettings,b):(b=a,a=d.extend(!0,d.ajaxSettings,b));for(var c in {context:1,url:1})c in b?a[c]=b[c]:c in d.ajaxSettings&&(a[c]=d.ajaxSettings[c]);return a},ajaxSettings:{url:bL,isLocal:bx.test(bM[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":d.parseJSON,"text xml":d.parseXML}},ajaxPrefilter:bO(bJ),ajaxTransport:bO(bK),ajax:function(a,c){function v(a,c,l,n){if(r!==2){r=2,p&&clearTimeout(p),o=b,m=n||"",u.readyState=a?4:0;var q,t,v,w=l?bR(e,u,l):b,x,y;if(a>=200&&a<300||a===304){if(e.ifModified){if(x=u.getResponseHeader("Last-Modified"))d.lastModified[k]=x;if(y=u.getResponseHeader("Etag"))d.etag[k]=y}if(a===304)c="notmodified",q=!0;else try{t=bS(e,w),c="success",q=!0}catch(z){c="parsererror",v=z}}else{v=c;if(!c||a)c="error",a<0&&(a=0)}u.status=a,u.statusText=c,q?h.resolveWith(f,[t,c,u]):h.rejectWith(f,[u,c,v]),u.statusCode(j),j=b,s&&g.trigger("ajax"+(q?"Success":"Error"),[u,e,q?t:v]),i.resolveWith(f,[u,c]),s&&(g.trigger("ajaxComplete",[u,e]),--d.active||d.event.trigger("ajaxStop"))}}typeof a==="object"&&(c=a,a=b),c=c||{};var e=d.ajaxSetup({},c),f=e.context||e,g=f!==e&&(f.nodeType||f instanceof d)?d(f):d.event,h=d.Deferred(),i=d._Deferred(),j=e.statusCode||{},k,l={},m,n,o,p,q,r=0,s,t,u={readyState:0,setRequestHeader:function(a,b){r||(l[a.toLowerCase().replace(bF,bG)]=b);return this},getAllResponseHeaders:function(){return r===2?m:null},getResponseHeader:function(a){var c;if(r===2){if(!n){n={};while(c=bv.exec(m))n[c[1].toLowerCase()]=c[2]}c=n[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){r||(e.mimeType=a);return this},abort:function(a){a=a||"abort",o&&o.abort(a),v(0,a);return this}};h.promise(u),u.success=u.done,u.error=u.fail,u.complete=i.done,u.statusCode=function(a){if(a){var b;if(r<2)for(b in a)j[b]=[j[b],a[b]];else b=a[u.status],u.then(b,b)}return this},e.url=((a||e.url)+"").replace(bu,"").replace(bz,bM[1]+"//"),e.dataTypes=d.trim(e.dataType||"*").toLowerCase().split(bD),e.crossDomain==null&&(q=bH.exec(e.url.toLowerCase()),e.crossDomain=q&&(q[1]!=bM[1]||q[2]!=bM[2]||(q[3]||(q[1]==="http:"?80:443))!=(bM[3]||(bM[1]==="http:"?80:443)))),e.data&&e.processData&&typeof e.data!=="string"&&(e.data=d.param(e.data,e.traditional)),bP(bJ,e,c,u);if(r===2)return!1;s=e.global,e.type=e.type.toUpperCase(),e.hasContent=!by.test(e.type),s&&d.active++===0&&d.event.trigger("ajaxStart");if(!e.hasContent){e.data&&(e.url+=(bA.test(e.url)?"&":"?")+e.data),k=e.url;if(e.cache===!1){var w=d.now(),x=e.url.replace(bE,"$1_="+w);e.url=x+(x===e.url?(bA.test(e.url)?"&":"?")+"_="+w:"")}}if(e.data&&e.hasContent&&e.contentType!==!1||c.contentType)l["Content-Type"]=e.contentType;e.ifModified&&(k=k||e.url,d.lastModified[k]&&(l["If-Modified-Since"]=d.lastModified[k]),d.etag[k]&&(l["If-None-Match"]=d.etag[k])),l.Accept=e.dataTypes[0]&&e.accepts[e.dataTypes[0]]?e.accepts[e.dataTypes[0]]+(e.dataTypes[0]!=="*"?", */*; q=0.01":""):e.accepts["*"];for(t in e.headers)u.setRequestHeader(t,e.headers[t]);if(e.beforeSend&&(e.beforeSend.call(f,u,e)===!1||r===2)){u.abort();return!1}for(t in {success:1,error:1,complete:1})u[t](e[t]);o=bP(bK,e,c,u);if(o){u.readyState=1,s&&g.trigger("ajaxSend",[u,e]),e.async&&e.timeout>0&&(p=setTimeout(function(){u.abort("timeout")},e.timeout));try{r=1,o.send(l,v)}catch(y){status<2?v(-1,y):d.error(y)}}else v(-1,"No Transport");return u},param:function(a,c){var e=[],f=function(a,b){b=d.isFunction(b)?b():b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=d.ajaxSettings.traditional);if(d.isArray(a)||a.jquery&&!d.isPlainObject(a))d.each(a,function(){f(this.name,this.value)});else for(var g in a)bQ(g,a[g],c,f);return e.join("&").replace(br,"+")}}),d.extend({active:0,lastModified:{},etag:{}});var bT=d.now(),bU=/(\=)\?(&|$)|\?\?/i;d.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return d.expando+"_"+bT++}}),d.ajaxPrefilter("json jsonp",function(b,c,e){var f=typeof b.data==="string";if(b.dataTypes[0]==="jsonp"||c.jsonpCallback||c.jsonp!=null||b.jsonp!==!1&&(bU.test(b.url)||f&&bU.test(b.data))){var g,h=b.jsonpCallback=d.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2",m=function(){a[h]=i,g&&d.isFunction(i)&&a[h](g[0])};b.jsonp!==!1&&(j=j.replace(bU,l),b.url===j&&(f&&(k=k.replace(bU,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},e.then(m,m),b.converters["script json"]=function(){g||d.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),d.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){d.globalEval(a);return a}}}),d.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),d.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var bV=d.now(),bW,bX;d.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&bZ()||b$()}:bZ,bX=d.ajaxSettings.xhr(),d.support.ajax=!!bX,d.support.cors=bX&&"withCredentials"in bX,bX=b,d.support.ajax&&d.ajaxTransport(function(a){if(!a.crossDomain||d.support.cors){var c;return{send:function(e,f){var g=a.xhr(),h,i;a.username?g.open(a.type,a.url,a.async,a.username,a.password):g.open(a.type,a.url,a.async);if(a.xhrFields)for(i in a.xhrFields)g[i]=a.xhrFields[i];a.mimeType&&g.overrideMimeType&&g.overrideMimeType(a.mimeType),!a.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(i in e)g.setRequestHeader(i,e[i])}catch(j){}g.send(a.hasContent&&a.data||null),c=function(e,i){var j,k,l,m,n;try{if(c&&(i||g.readyState===4)){c=b,h&&(g.onreadystatechange=d.noop,delete bW[h]);if(i)g.readyState!==4&&g.abort();else{j=g.status,l=g.getAllResponseHeaders(),m={},n=g.responseXML,n&&n.documentElement&&(m.xml=n),m.text=g.responseText;try{k=g.statusText}catch(o){k=""}j||!a.isLocal||a.crossDomain?j===1223&&(j=204):j=m.text?200:404}}}catch(p){i||f(-1,p)}m&&f(j,k,m,l)},a.async&&g.readyState!==4?(bW||(bW={},bY()),h=bV++,g.onreadystatechange=bW[h]=c):c()},abort:function(){c&&c(0,1)}}}});var b_={},ca=/^(?:toggle|show|hide)$/,cb=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cc,cd=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];d.fn.extend({show:function(a,b,c){var e,f;if(a||a===0)return this.animate(ce("show",3),a,b,c);for(var g=0,h=this.length;g=0;a--)c[a].elem===this&&(b&&c[a](!0),c.splice(a,1))}),b||this.dequeue();return this}}),d.each({slideDown:ce("show",1),slideUp:ce("hide",1),slideToggle:ce("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){d.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),d.extend({speed:function(a,b,c){var e=a&&typeof a==="object"?d.extend({},a):{complete:c||!c&&b||d.isFunction(a)&&a,duration:a,easing:c&&b||b&&!d.isFunction(b)&&b};e.duration=d.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in d.fx.speeds?d.fx.speeds[e.duration]:d.fx.speeds._default,e.old=e.complete,e.complete=function(){e.queue!==!1&&d(this).dequeue(),d.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig||(b.orig={})}}),d.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(d.fx.step[this.prop]||d.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=d.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return e.step(a)}var e=this,f=d.fx;this.startTime=d.now(),this.start=a,this.end=b,this.unit=c||this.unit||(d.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&d.timers.push(g)&&!cc&&(cc=setInterval(f.tick,f.interval))},show:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),d(this.elem).show()},hide:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=d.now(),c=!0;if(a||b>=this.options.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),this.options.curAnim[this.prop]=!0;for(var e in this.options.curAnim)this.options.curAnim[e]!==!0&&(c=!1);if(c){if(this.options.overflow!=null&&!d.support.shrinkWrapBlocks){var f=this.elem,g=this.options;d.each(["","X","Y"],function(a,b){f.style["overflow"+b]=g.overflow[a]})}this.options.hide&&d(this.elem).hide();if(this.options.hide||this.options.show)for(var h in this.options.curAnim)d.style(this.elem,h,this.options.orig[h]);this.options.complete.call(this.elem)}return!1}var i=b-this.startTime;this.state=i/this.options.duration;var j=this.options.specialEasing&&this.options.specialEasing[this.prop],k=this.options.easing||(d.easing.swing?"swing":"linear");this.pos=d.easing[j||k](this.state,i,0,1,this.options.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update();return!0}},d.extend(d.fx,{tick:function(){var a=d.timers;for(var b=0;b
";d.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),e=b.firstChild,f=e.firstChild,h=e.nextSibling.firstChild.firstChild,this.doesNotAddBorder=f.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,f.style.position="fixed",f.style.top="20px",this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15,f.style.position=f.style.top="",e.style.overflow="hidden",e.style.position="relative",this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),d.offset.initialize=d.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;d.offset.initialize(),d.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(d.css(a,"marginTop"))||0,c+=parseFloat(d.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var e=d.css(a,"position");e==="static"&&(a.style.position="relative");var f=d(a),g=f.offset(),h=d.css(a,"top"),i=d.css(a,"left"),j=(e==="absolute"||e==="fixed")&&d.inArray("auto",[h,i])>-1,k={},l={},m,n;j&&(l=f.position()),m=j?l.top:parseInt(h,10)||0,n=j?l.left:parseInt(i,10)||0,d.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):f.css(k)}},d.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),e=ch.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(d.css(a,"marginTop"))||0,c.left-=parseFloat(d.css(a,"marginLeft"))||0,e.top+=parseFloat(d.css(b[0],"borderTopWidth"))||0,e.left+=parseFloat(d.css(b[0],"borderLeftWidth"))||0;return{top:c.top-e.top,left:c.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&(!ch.test(a.nodeName)&&d.css(a,"position")==="static"))a=a.offsetParent;return a})}}),d.each(["Left","Top"],function(a,c){var e="scroll"+c;d.fn[e]=function(c){var f=this[0],g;if(!f)return null;if(c!==b)return this.each(function(){g=ci(this),g?g.scrollTo(a?d(g).scrollLeft():c,a?c:d(g).scrollTop()):this[e]=c});g=ci(f);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:d.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]}}),d.each(["Height","Width"],function(a,c){var e=c.toLowerCase();d.fn["inner"+c]=function(){return this[0]?parseFloat(d.css(this[0],e,"padding")):null},d.fn["outer"+c]=function(a){return this[0]?parseFloat(d.css(this[0],e,a?"margin":"border")):null},d.fn[e]=function(a){var f=this[0];if(!f)return a==null?null:this;if(d.isFunction(a))return this.each(function(b){var c=d(this);c[e](a.call(this,b,c[e]()))});if(d.isWindow(f)){var g=f.document.documentElement["client"+c];return f.document.compatMode==="CSS1Compat"&&g||f.document.body["client"+c]||g}if(f.nodeType===9)return Math.max(f.documentElement["client"+c],f.body["scroll"+c],f.documentElement["scroll"+c],f.body["offset"+c],f.documentElement["offset"+c]);if(a===b){var h=d.css(f,e),i=parseFloat(h);return d.isNaN(i)?h:i}return this.css(e,typeof a==="string"?a:a+"px")}}),a.jQuery=a.$=d})(window); \ No newline at end of file diff --git a/experiments/splitview/jquery.easing.1.3.js b/experiments/splitview/jquery.easing.1.3.js new file mode 100644 index 00000000000..ef743210795 --- /dev/null +++ b/experiments/splitview/jquery.easing.1.3.js @@ -0,0 +1,205 @@ +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright © 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +// t: current time, b: begInnIng value, c: change In value, d: duration +jQuery.easing['jswing'] = jQuery.easing['swing']; + +jQuery.extend( jQuery.easing, +{ + def: 'easeOutQuad', + swing: function (x, t, b, c, d) { + //alert(jQuery.easing.default); + return jQuery.easing[jQuery.easing.def](x, t, b, c, d); + }, + easeInQuad: function (x, t, b, c, d) { + return c*(t/=d)*t + b; + }, + easeOutQuad: function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }, + easeInOutQuad: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }, + easeInCubic: function (x, t, b, c, d) { + return c*(t/=d)*t*t + b; + }, + easeOutCubic: function (x, t, b, c, d) { + return c*((t=t/d-1)*t*t + 1) + b; + }, + easeInOutCubic: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t + b; + return c/2*((t-=2)*t*t + 2) + b; + }, + easeInQuart: function (x, t, b, c, d) { + return c*(t/=d)*t*t*t + b; + }, + easeOutQuart: function (x, t, b, c, d) { + return -c * ((t=t/d-1)*t*t*t - 1) + b; + }, + easeInOutQuart: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t + b; + return -c/2 * ((t-=2)*t*t*t - 2) + b; + }, + easeInQuint: function (x, t, b, c, d) { + return c*(t/=d)*t*t*t*t + b; + }, + easeOutQuint: function (x, t, b, c, d) { + return c*((t=t/d-1)*t*t*t*t + 1) + b; + }, + easeInOutQuint: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + return c/2*((t-=2)*t*t*t*t + 2) + b; + }, + easeInSine: function (x, t, b, c, d) { + return -c * Math.cos(t/d * (Math.PI/2)) + c + b; + }, + easeOutSine: function (x, t, b, c, d) { + return c * Math.sin(t/d * (Math.PI/2)) + b; + }, + easeInOutSine: function (x, t, b, c, d) { + return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; + }, + easeInExpo: function (x, t, b, c, d) { + return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; + }, + easeOutExpo: function (x, t, b, c, d) { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; + }, + easeInOutExpo: function (x, t, b, c, d) { + if (t==0) return b; + if (t==d) return b+c; + if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; + return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; + }, + easeInCirc: function (x, t, b, c, d) { + return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; + }, + easeOutCirc: function (x, t, b, c, d) { + return c * Math.sqrt(1 - (t=t/d-1)*t) + b; + }, + easeInOutCirc: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; + return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; + }, + easeInElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + }, + easeOutElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; + }, + easeInOutElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; + }, + easeInBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*(t/=d)*t*((s+1)*t - s) + b; + }, + easeOutBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; + }, + easeInOutBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; + return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; + }, + easeInBounce: function (x, t, b, c, d) { + return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; + }, + easeOutBounce: function (x, t, b, c, d) { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } + }, + easeInOutBounce: function (x, t, b, c, d) { + if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; + return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; + } +}); + +/* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright © 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ \ No newline at end of file diff --git a/experiments/splitview/jquery.mobile.grids.collapsible.css b/experiments/splitview/jquery.mobile.grids.collapsible.css new file mode 100644 index 00000000000..923ad50b8e5 --- /dev/null +++ b/experiments/splitview/jquery.mobile.grids.collapsible.css @@ -0,0 +1,120 @@ +/* my addition to supply convertible grids based on www.cssgrid.net by Andy Taylor */ +/* ==================================================================================================================== */ +/* ! The 1140px Grid V2 by Andy Taylor \ http://cssgrid.net \ http://www.twitter.com/andytlr \ http://www.andytlr.com */ +/* ==================================================================================================================== */ +.row, .fixedrow { +width: 100%; +margin: 0 auto; +overflow: hidden; +} + +.span1, .span2, .span3, .span4, .span5, .span6, .span7, .span8, .span9, .span10, .span11 { +margin-right: 3.8%; +float: left; +min-height: 1px; +} + +.row .span1, .fixedrow .span1 { +width: 4.85%; +} + +.row .span2, .fixedrow .span2 { +width: 13.45%; +} + +.row .span3, .fixedrow .span3 { +width: 22.05%; +} + +.row .span4, .fixedrow .span4 { +width: 30.75%; +} + +.row .span5, .fixedrow .span5 { +width: 39.45%; +} + +.row .span6, .fixedrow .span6 { +width: 48%; +} + +.row .span7, .fixedrow .span7 { +width: 56.75%; +} + +.row .span8, .fixedrow .span8 { +width: 65.4%; +} + +.row .span9, .fixedrow .span9 { +width: 74.05%; +} + +.row .span10, .fixedrow .span10 { +width: 82.7%; +} + +.row .span11, .fixedrow .span11 { +width: 91.35%; +} + +.row .span12, .fixedrow .span12 { +width: 100%; +float: left; +} + +.row .prepend1, .fixedrow .prepend1 { + +} + +.last { +margin-right: 0px; +} + +img, object, embed { +max-width: 100%; +} + +img { + height: auto; +} + + +/* touchscreens */ + +.touch.min-width-768px body { + font-size: 1em; + line-height: normal; + } + + +/* Smaller screens */ +.min-width-768px body { + font-size: 0.9em; + line-height: normal; + } + +/* Mobile */ + +.max-width-480px body { + font-size: 1em; + -webkit-text-size-adjust: none; + } + +.max-width-480px .row, .max-width-480px body { + width: 100%; + min-width: 0; + margin-left: 0px; + margin-right: 0px; + padding-left: 0px; + padding-right: 0px; + } + +.max-width-480px .row .span1, .max-width-480px .row .span2, .max-width-480px .row .span3, .max-width-480px .row .span4, .max-width-480px .row .span5, .max-width-480px .row .span6, .max-width-480px .row .span7, .max-width-480px .row .span8, .max-width-480px .row .span9, .max-width-480px .row .span10, .max-width-480px .row .span11, .max-width-480px .row .span12 { + width: auto; + float: none; + margin-left: 0px; + margin-right: 0px; + padding-left: 20px; + padding-right: 20px; + } \ No newline at end of file diff --git a/experiments/splitview/jquery.mobile.scrollview.css b/experiments/splitview/jquery.mobile.scrollview.css new file mode 100644 index 00000000000..5112e431e31 --- /dev/null +++ b/experiments/splitview/jquery.mobile.scrollview.css @@ -0,0 +1,65 @@ +@charset "utf-8"; + +.ui-scrollview-clip { +} + +.ui-scrollview-view { +} + +.ui-scrolllistview .ui-li-divider { + z-index: 10; +} + +.ui-scrollbar { + position: absolute; + overflow: hidden; + + opacity: 0; + -webkit-transition: opacity 500ms; + -moz-transition: opacity 500ms; + transition: opacity 500ms; +} + +.ui-scrollbar-visible { + opacity: 1; +} + +.ui-scrollbar-y { + top: 2px; + right: 2px; + bottom: 8px; + width: 5px; +} + +.ui-scrollbar-x { + right: 8px; + bottom: 2px; + left: 2px; + height: 5px; +} + +.ui-scrollbar-track { + position: relative; + width: 100%; + height: 100%; +} + +.ui-scrollbar-thumb { + position: absolute; + top: 0; + left: 0; + background-color: rgba(0, 0, 0, 0.3); + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; +} + +.ui-scrollbar-y .ui-scrollbar-thumb { + width: 5px; + height: 100%; +} + +.ui-scrollbar-x .ui-scrollbar-thumb { + width: 100%; + height: 5px; +} diff --git a/experiments/splitview/jquery.mobile.scrollview.js b/experiments/splitview/jquery.mobile.scrollview.js new file mode 100644 index 00000000000..55ea2c66297 --- /dev/null +++ b/experiments/splitview/jquery.mobile.scrollview.js @@ -0,0 +1,803 @@ +/* +* jQuery Mobile Framework : scrollview plugin +* Copyright (c) 2010 Adobe Systems Incorporated - Kin Blas (jblas@adobe.com) +* 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($,window,document,undefined){ + +jQuery.widget( "mobile.scrollview", jQuery.mobile.widget, { + options: { + fps: 60, // Frames per second in msecs. + direction: null, // "x", "y", or null for both. + + scrollDuration: 2000, // Duration of the scrolling animation in msecs. + overshootDuration: 250, // Duration of the overshoot animation in msecs. + snapbackDuration: 500, // Duration of the snapback animation in msecs. + + moveThreshold: 10, // User must move this many pixels in any direction to trigger a scroll. + moveIntervalThreshold: 150, // Time between mousemoves must not exceed this threshold. + + scrollMethod: "translate", // "translate", "position", "scroll" + + startEventName: "scrollstart", + updateEventName: "scrollupdate", + stopEventName: "scrollstop", + + eventType: $.support.touch ? "touch" : "mouse", + + showScrollBars: true, + + pagingEnabled: false, + delayedClickSelector: "a,input,textarea,select,button,.ui-btn", + delayedClickEnabled: true + }, + + _makePositioned: function($ele) + { + if ($ele.css("position") == "static") + $ele.css("position", "relative"); + }, + + _create: function() + { + this._$clip = $(this.element).addClass("ui-scrollview-clip"); + var $child = this._$clip.children(); + if ($child.length > 1) { + $child = this._$clip.wrapInner("
").children(); + $child.addClass("ui-scrollview-container"); + } + this._$view = $child.addClass("ui-scrollview-view"); + + this._$clip.css("overflow", this.options.scrollMethod === "scroll" ? "scroll" : "hidden"); + this._makePositioned(this._$clip); + + this._$view.css("overflow", "hidden"); + + // Turn off our faux scrollbars if we are using native scrolling + // to position the view. + + this.options.showScrollBars = this.options.scrollMethod === "scroll" ? false : this.options.showScrollBars; + + // We really don't need this if we are using a translate transformation + // for scrolling. We set it just in case the user wants to switch methods + // on the fly. + + this._makePositioned(this._$view); + this._$view.css({ left: 0, top: 0 }); + + this._sx = 0; + this._sy = 0; + + var direction = this.options.direction; + this._hTracker = (direction !== "y") ? new MomentumTracker(this.options) : null; + this._vTracker = (direction !== "x") ? new MomentumTracker(this.options) : null; + + this._timerInterval = 1000/this.options.fps; + this._timerID = 0; + + var self = this; + this._timerCB = function(){ self._handleMomentumScroll(); }; + + this._addBehaviors(); + }, + + _startMScroll: function(speedX, speedY) + { + this._stopMScroll(); + this._showScrollBars(); + + var keepGoing = false; + var duration = this.options.scrollDuration; + + this._$clip.trigger(this.options.startEventName); + + var ht = this._hTracker; + if (ht) + { + var c = this._$clip.width(); + var v = this._$view.width(); + ht.start(this._sx, speedX, duration, (v > c) ? -(v - c) : 0, 0); + keepGoing = !ht.done(); + } + + var vt = this._vTracker; + if (vt) + { + var c = this._$clip.height(); + var v = this._$view.height(); + vt.start(this._sy, speedY, duration, (v > c) ? -(v - c) : 0, 0); + keepGoing = keepGoing || !vt.done(); + } + + if (keepGoing) + this._timerID = setTimeout(this._timerCB, this._timerInterval); + else + this._stopMScroll(); + }, + + _stopMScroll: function() + { + if (this._timerID) + { + this._$clip.trigger(this.options.stopEventName); + clearTimeout(this._timerID); + } + this._timerID = 0; + + if (this._vTracker) + this._vTracker.reset(); + + if (this._hTracker) + this._hTracker.reset(); + + this._hideScrollBars(); + }, + + _handleMomentumScroll: function() + { + var keepGoing = false; + var v = this._$view; + + var x = 0, y = 0; + + var vt = this._vTracker; + if (vt) + { + vt.update(); + y = vt.getPosition(); + keepGoing = !vt.done(); + } + + var ht = this._hTracker; + if (ht) + { + ht.update(); + x = ht.getPosition(); + keepGoing = keepGoing || !ht.done(); + } + + this._setScrollPosition(x, y); + this._$clip.trigger(this.options.updateEventName, [ { x: x, y: y } ]); + + if (keepGoing) + this._timerID = setTimeout(this._timerCB, this._timerInterval); + else + this._stopMScroll(); + }, + + _setScrollPosition: function(x, y) + { + this._sx = x; + this._sy = y; + + var $v = this._$view; + + var sm = this.options.scrollMethod; + + switch (sm) + { + case "translate": + setElementTransform($v, x + "px", y + "px"); + break; + case "position": + $v.css({left: x + "px", top: y + "px"}); + break; + case "scroll": + var c = this._$clip[0]; + c.scrollLeft = -x; + c.scrollTop = -y; + break; + } + + var $vsb = this._$vScrollBar; + var $hsb = this._$hScrollBar; + + if ($vsb) + { + var $sbt = $vsb.find(".ui-scrollbar-thumb"); + if (sm === "translate") + setElementTransform($sbt, "0px", -y/$v.height() * $sbt.parent().height() + "px"); + else + $sbt.css("top", -y/$v.height()*100 + "%"); + } + + if ($hsb) + { + var $sbt = $hsb.find(".ui-scrollbar-thumb"); + if (sm === "translate") + setElementTransform($sbt, -x/$v.width() * $sbt.parent().width() + "px", "0px"); + else + $sbt.css("left", -x/$v.width()*100 + "%"); + } + }, + + scrollTo: function(x, y, duration) + { + this._stopMScroll(); + if (!duration) + return this._setScrollPosition(x, y); + + x = -x; + y = -y; + + var self = this; + var start = getCurrentTime(); + var efunc = $.easing["easeOutQuad"]; + var sx = this._sx; + var sy = this._sy; + var dx = x - sx; + var dy = y - sy; + var tfunc = function(){ + var elapsed = getCurrentTime() - start; + if (elapsed >= duration) + { + self._timerID = 0; + self._setScrollPosition(x, y); + } + else + { + var ec = efunc(elapsed/duration, elapsed, 0, 1, duration); + self._setScrollPosition(sx + (dx * ec), sy + (dy * ec)); + self._timerID = setTimeout(tfunc, self._timerInterval); + } + }; + + this._timerID = setTimeout(tfunc, this._timerInterval); + }, + + getScrollPosition: function() + { + return { x: -this._sx, y: -this._sy }; + }, + + _getScrollHierarchy: function() + { + var svh = []; + this._$clip.parents(".ui-scrollview-clip").each(function(){ + var d = $(this).data("scrollview"); + if (d) svh.unshift(d); + }); + return svh; + }, + + _getAncestorByDirection: function(dir) + { + var svh = this._getScrollHierarchy(); + var n = svh.length; + while (0 < n--) + { + var sv = svh[n]; + var svdir = sv.options.direction; + + if (!svdir || svdir == dir) + return sv; + } + return null; + }, + + _handleDragStart: function(e, ex, ey) + { + // Stop any scrolling of elements in our parent hierarcy. + $.each(this._getScrollHierarchy(),function(i,sv){ sv._stopMScroll(); }); + this._stopMScroll(); + + var c = this._$clip; + var v = this._$view; + + if (this.options.delayedClickEnabled) { + this._$clickEle = $(e.target).closest(this.options.delayedClickSelector); + } + this._lastX = ex; + this._lastY = ey; + this._doSnapBackX = false; + this._doSnapBackY = false; + this._speedX = 0; + this._speedY = 0; + this._directionLock = ""; + this._didDrag = false; + + if (this._hTracker) + { + var cw = parseInt(c.css("width"), 10); + var vw = parseInt(v.css("width"), 10); + this._maxX = cw - vw; + if (this._maxX > 0) this._maxX = 0; + if (this._$hScrollBar) + this._$hScrollBar.find(".ui-scrollbar-thumb").css("width", (cw >= vw ? "100%" : Math.floor(cw/vw*100)+ "%")); + } + + if (this._vTracker) + { + var ch = parseInt(c.css("height"), 10); + var vh = parseInt(v.css("height"), 10); + this._maxY = ch - vh; + if (this._maxY > 0) this._maxY = 0; + if (this._$vScrollBar) + this._$vScrollBar.find(".ui-scrollbar-thumb").css("height", (ch >= vh ? "100%" : Math.floor(ch/vh*100)+ "%")); + } + + var svdir = this.options.direction; + + this._pageDelta = 0; + this._pageSize = 0; + this._pagePos = 0; + + if (this.options.pagingEnabled && (svdir === "x" || svdir === "y")) + { + this._pageSize = svdir === "x" ? cw : ch; + this._pagePos = svdir === "x" ? this._sx : this._sy; + this._pagePos -= this._pagePos % this._pageSize; + } + this._lastMove = 0; + this._enableTracking(); + + // If we're using mouse events, we need to prevent the default + // behavior to suppress accidental selection of text, etc. We + // can't do this on touch devices because it will disable the + // generation of "click" events. + // + // XXX: We should test if this has an effect on links! - kin + + if (this.options.eventType == "mouse" || this.options.delayedClickEnabled) + e.preventDefault(); + e.stopPropagation(); + }, + + _propagateDragMove: function(sv, e, ex, ey, dir) + { + this._hideScrollBars(); + this._disableTracking(); + sv._handleDragStart(e,ex,ey); + sv._directionLock = dir; + sv._didDrag = this._didDrag; + }, + + _handleDragMove: function(e, ex, ey) + { + this._lastMove = getCurrentTime(); + + var v = this._$view; + + var dx = ex - this._lastX; + var dy = ey - this._lastY; + var svdir = this.options.direction; + + if (!this._directionLock) + { + var x = Math.abs(dx); + var y = Math.abs(dy); + var mt = this.options.moveThreshold; + + if (x < mt && y < mt) { + return false; + } + + var dir = null; + var r = 0; + if (x < y && (x/y) < 0.5) { + dir = "y"; + } + else if (x > y && (y/x) < 0.5) { + dir = "x"; + } + + if (svdir && dir && svdir != dir) + { + // This scrollview can't handle the direction the user + // is attempting to scroll. Find an ancestor scrollview + // that can handle the request. + + var sv = this._getAncestorByDirection(dir); + if (sv) + { + this._propagateDragMove(sv, e, ex, ey, dir); + return false; + } + } + + this._directionLock = svdir ? svdir : (dir ? dir : "none"); + } + + var newX = this._sx; + var newY = this._sy; + + if (this._directionLock !== "y" && this._hTracker) + { + var x = this._sx; + this._speedX = dx; + newX = x + dx; + + // Simulate resistance. + + this._doSnapBackX = false; + if (newX > 0 || newX < this._maxX) + { + if (this._directionLock === "x") + { + var sv = this._getAncestorByDirection("x"); + if (sv) + { + this._setScrollPosition(newX > 0 ? 0 : this._maxX, newY); + this._propagateDragMove(sv, e, ex, ey, dir); + return false; + } + } + newX = x + (dx/2); + this._doSnapBackX = true; + } + } + + if (this._directionLock !== "x" && this._vTracker) + { + var y = this._sy; + this._speedY = dy; + newY = y + dy; + + // Simulate resistance. + + this._doSnapBackY = false; + if (newY > 0 || newY < this._maxY) + { + if (this._directionLock === "y") + { + var sv = this._getAncestorByDirection("y"); + if (sv) + { + this._setScrollPosition(newX, newY > 0 ? 0 : this._maxY); + this._propagateDragMove(sv, e, ex, ey, dir); + return false; + } + } + + newY = y + (dy/2); + this._doSnapBackY = true; + } + + } + + if (this.options.pagingEnabled && (svdir === "x" || svdir === "y")) + { + if (this._doSnapBackX || this._doSnapBackY) + this._pageDelta = 0; + else + { + var opos = this._pagePos; + var cpos = svdir === "x" ? newX : newY; + var delta = svdir === "x" ? dx : dy; + + this._pageDelta = (opos > cpos && delta < 0) ? this._pageSize : ((opos < cpos && delta > 0) ? -this._pageSize : 0); + } + } + + this._didDrag = true; + this._lastX = ex; + this._lastY = ey; + + this._setScrollPosition(newX, newY); + + this._showScrollBars(); + + // Call preventDefault() to prevent touch devices from + // scrolling the main window. + + // e.preventDefault(); + + return false; + }, + + _handleDragStop: function(e) + { + var l = this._lastMove; + var t = getCurrentTime(); + var doScroll = l && (t - l) <= this.options.moveIntervalThreshold; + + var sx = (this._hTracker && this._speedX && doScroll) ? this._speedX : (this._doSnapBackX ? 1 : 0); + var sy = (this._vTracker && this._speedY && doScroll) ? this._speedY : (this._doSnapBackY ? 1 : 0); + + var svdir = this.options.direction; + if (this.options.pagingEnabled && (svdir === "x" || svdir === "y") && !this._doSnapBackX && !this._doSnapBackY) + { + var x = this._sx; + var y = this._sy; + if (svdir === "x") + x = -this._pagePos + this._pageDelta; + else + y = -this._pagePos + this._pageDelta; + + this.scrollTo(x, y, this.options.snapbackDuration); + } + else if (sx || sy) + this._startMScroll(sx, sy); + else + this._hideScrollBars(); + + this._disableTracking(); + + if (!this._didDrag && this.options.delayedClickEnabled && this._$clickEle.length) { + this._$clickEle + .trigger("mousedown") + //.trigger("focus") + .trigger("mouseup") + .trigger("click"); + } + + // If a view scrolled, then we need to absorb + // the event so that links etc, underneath our + // cursor/finger don't fire. + + return this._didDrag ? false : undefined; + }, + + _enableTracking: function() + { + $(document).bind(this._dragMoveEvt, this._dragMoveCB); + $(document).bind(this._dragStopEvt, this._dragStopCB); + }, + + _disableTracking: function() + { + $(document).unbind(this._dragMoveEvt, this._dragMoveCB); + $(document).unbind(this._dragStopEvt, this._dragStopCB); + }, + + _showScrollBars: function() + { + var vclass = "ui-scrollbar-visible"; + if (this._$vScrollBar) this._$vScrollBar.addClass(vclass); + if (this._$hScrollBar) this._$hScrollBar.addClass(vclass); + }, + + _hideScrollBars: function() + { + var vclass = "ui-scrollbar-visible"; + if (this._$vScrollBar) this._$vScrollBar.removeClass(vclass); + if (this._$hScrollBar) this._$hScrollBar.removeClass(vclass); + }, + + _addBehaviors: function() + { + var self = this; + if (this.options.eventType === "mouse") + { + this._dragStartEvt = "mousedown"; + this._dragStartCB = function(e){ return self._handleDragStart(e, e.clientX, e.clientY); }; + + this._dragMoveEvt = "mousemove"; + this._dragMoveCB = function(e){ return self._handleDragMove(e, e.clientX, e.clientY); }; + + this._dragStopEvt = "mouseup"; + this._dragStopCB = function(e){ return self._handleDragStop(e); }; + } + else // "touch" + { + this._dragStartEvt = "touchstart"; + this._dragStartCB = function(e) + { + var t = e.originalEvent.targetTouches[0]; + return self._handleDragStart(e, t.pageX, t.pageY); + }; + + this._dragMoveEvt = "touchmove"; + this._dragMoveCB = function(e) + { + var t = e.originalEvent.targetTouches[0]; + return self._handleDragMove(e, t.pageX, t.pageY); + }; + + this._dragStopEvt = "touchend"; + this._dragStopCB = function(e){ return self._handleDragStop(e); }; + } + + this._$view.bind(this._dragStartEvt, this._dragStartCB); + + if (this.options.showScrollBars) + { + var $c = this._$clip; + var prefix = "
"; + if (this._vTracker) + { + $c.append(prefix + "y" + suffix); + this._$vScrollBar = $c.children(".ui-scrollbar-y"); + } + if (this._hTracker) + { + $c.append(prefix + "x" + suffix); + this._$hScrollBar = $c.children(".ui-scrollbar-x"); + } + } + } +}); + +function setElementTransform($ele, x, y) +{ + var v = "translate3d(" + x + "," + y + ", 0px)"; + $ele.css({ + "-moz-transform": v, + "-webkit-transform": v, + "transform": v + }); +} + + +function MomentumTracker(options) +{ + this.options = $.extend({}, options); + this.easing = "easeOutQuad"; + this.reset(); +} + +var tstates = { + scrolling: 0, + overshot: 1, + snapback: 2, + done: 3 +}; + +function getCurrentTime() { return (new Date()).getTime(); } + +$.extend(MomentumTracker.prototype, { + start: function(pos, speed, duration, minPos, maxPos) + { + this.state = (speed != 0) ? ((pos < minPos || pos > maxPos) ? tstates.snapback : tstates.scrolling) : tstates.done; + this.pos = pos; + this.speed = speed; + this.duration = (this.state == tstates.snapback) ? this.options.snapbackDuration : duration; + this.minPos = minPos; + this.maxPos = maxPos; + + this.fromPos = (this.state == tstates.snapback) ? this.pos : 0; + this.toPos = (this.state == tstates.snapback) ? ((this.pos < this.minPos) ? this.minPos : this.maxPos) : 0; + + this.startTime = getCurrentTime(); + }, + + reset: function() + { + this.state = tstates.done; + this.pos = 0; + this.speed = 0; + this.minPos = 0; + this.maxPos = 0; + this.duration = 0; + }, + + update: function() + { + var state = this.state; + if (state == tstates.done) + return this.pos; + + var duration = this.duration; + var elapsed = getCurrentTime() - this.startTime; + elapsed = elapsed > duration ? duration : elapsed; + + if (state == tstates.scrolling || state == tstates.overshot) + { + var dx = this.speed * (1 - $.easing[this.easing](elapsed/duration, elapsed, 0, 1, duration)); + + var x = this.pos + dx; + + var didOverShoot = (state == tstates.scrolling) && (x < this.minPos || x > this.maxPos); + if (didOverShoot) + x = (x < this.minPos) ? this.minPos : this.maxPos; + + this.pos = x; + + if (state == tstates.overshot) + { + if (elapsed >= duration) + { + this.state = tstates.snapback; + this.fromPos = this.pos; + this.toPos = (x < this.minPos) ? this.minPos : this.maxPos; + this.duration = this.options.snapbackDuration; + this.startTime = getCurrentTime(); + elapsed = 0; + } + } + else if (state == tstates.scrolling) + { + if (didOverShoot) + { + this.state = tstates.overshot; + this.speed = dx / 2; + this.duration = this.options.overshootDuration; + this.startTime = getCurrentTime(); + } + else if (elapsed >= duration) + this.state = tstates.done; + } + } + else if (state == tstates.snapback) + { + if (elapsed >= duration) + { + this.pos = this.toPos; + this.state = tstates.done; + } + else + this.pos = this.fromPos + ((this.toPos - this.fromPos) * $.easing[this.easing](elapsed/duration, elapsed, 0, 1, duration)); + } + + return this.pos; + }, + + done: function() { return this.state == tstates.done; }, + getPosition: function(){ return this.pos; } +}); + +jQuery.widget( "mobile.scrolllistview", jQuery.mobile.scrollview, { + options: { + direction: "y" + }, + + _create: function() { + $.mobile.scrollview.prototype._create.call(this); + + // Cache the dividers so we don't have to search for them everytime the + // view is scrolled. + // + // XXX: Note that we need to update this cache if we ever support lists + // that can dynamically update their content. + + this._$dividers = this._$view.find("[data-role=list-divider]"); + this._lastDivider = null; + }, + + _setScrollPosition: function(x, y) + { + // Let the view scroll like it normally does. + + $.mobile.scrollview.prototype._setScrollPosition.call(this, x, y); + + y = -y; + + // Find the dividers for the list. + + var $divs = this._$dividers; + var cnt = $divs.length; + var d = null; + var dy = 0; + var nd = null; + + for (var i = 0; i < cnt; i++) + { + nd = $divs.get(i); + var t = nd.offsetTop; + if (y >= t) + { + d = nd; + dy = t; + } + else if (d) + break; + } + + // If we found a divider to move position it at the top of the + // clip view. + + if (d) + { + var h = d.offsetHeight; + var mxy = (d != nd) ? nd.offsetTop : (this._$view.get(0).offsetHeight); + if (y + h >= mxy) + y = (mxy - h) - dy; + else + y = y - dy; + + // XXX: Need to convert this over to using $().css() and supporting the non-transform case. + + var ld = this._lastDivider; + if (ld && d != ld) { + setElementTransform($(ld), 0, 0); + } + setElementTransform($(d), 0, y + "px"); + this._lastDivider = d; + + } + } +}); + +})(jQuery,window,document); // End Component diff --git a/experiments/splitview/jquery.mobile.splitview.css b/experiments/splitview/jquery.mobile.splitview.css new file mode 100644 index 00000000000..5605099a1e4 --- /dev/null +++ b/experiments/splitview/jquery.mobile.splitview.css @@ -0,0 +1,115 @@ +body { + visibility: hidden; +} + +.ui-mobile body { + visibility: visible; +} + +.ui-panel-left { + position:absolute; + left:0; + top:0; + bottom:0; +} + +.ui-panel-right { + position:absolute; + right:0; + top:0; + bottom:0; +} + +.ui-border-right { + border-right: 1px solid; + z-index: 100; +} + +.ui-crumbs { + max-width: 25%; +} + +.splitview .ui-splitview-hidden { + display:none; +} + +.splitview.min-width-480px body { + margin: 0; +} + +.splitview.min-width-480px .ui-page{ + bottom: 0; +} + +.splitview.min-width-480px .ui-header { + position:absolute; + top:0; + bottom:auto; + left:0; + right:0; +} + +.splitview.min-width-480px .ui-footer { + position:absolute; + top:auto; + bottom:0; + left:0; + right:0; +} + +.splitview.min-width-480px .ui-content { + position:absolute; + top:40px; /*TODO: need to dynamically set this and bottom when we use dynamic toolbars later*/ + bottom:0; + left:0; + right:0; + overflow: auto; +} + +/************************************************************************************************************ +popover css for portrait orientation, modified from +http://www.cagintranet.com/archive/create-an-ipad-like-dropdown-popover/ +************************************************************************************************************/ +.panel-popover .popover_triangle {left:7px;} /*adjust this if you change the text in the popover button */ +.panel-popover { + color: black; + display:none; + font-weight: normal; + line-height: 1; + cursor: auto; + position: absolute; + top:55px; + left:10px; + background-color: white; + z-index:5000000; + border: 3px solid black; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + -webkit-transition: opacity 0.25s linear; + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + -moz-transition: opacity 0.25s linear; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + transition: opacity 0.25s linear; + overflow-x:visible; + height:80%; +} + +.panel-popover > .popover_triangle { + position: absolute; + top: -34px; + font-size: 0px; + line-height: 0%; + width: 0px; + border-top: 16px solid rgba(0,0,0,0); + border-left: 16px solid rgba(0,0,0,0); + border-right: 16px solid rgba(0,0,0,0); + border-bottom: 16px solid black; +} + +.panel-popover div[data-role="page"] { + height: inherit; + overflow-y:auto; +} \ No newline at end of file diff --git a/experiments/splitview/jquery.mobile.splitview.js b/experiments/splitview/jquery.mobile.splitview.js new file mode 100644 index 00000000000..299fe421253 --- /dev/null +++ b/experiments/splitview/jquery.mobile.splitview.js @@ -0,0 +1,441 @@ +(function($,window,undefined){ + $( window.document ).bind('mobileinit', function(){ + //some class for css to detect touchscreens + if($.support.touch){ + $('html').addClass('touch'); + } + + //fix for phonegap 0.9.5+ + $(document).bind("orientationchange", function(event){ + $(window).trigger(event); + }); + + if ($.mobile.media("screen and (min-width:480px)")||($.mobile.browser.ie && $(this).width() >= 480)) { + $('html').addClass('splitview'); + $(function() { + $(document).unbind('.toolbar'); + $('.ui-page').die('.toolbar'); + $('div[data-role="panel"]').addClass('ui-mobile-viewport'); + if( !$.mobile.hashListeningEnabled || !$.mobile.path.stripHash( location.hash ) ){ + var firstPage=$('div[data-id="main"] > div[data-role="page"]:first').page().addClass($.mobile.activePageClass); + firstPage.children('div[data-role="content"]').attr('data-scroll', 'y'); + } + $(window).trigger('orientationchange'); + }); + +//---------------------------------------------------------------------------------- +//Main event bindings: click, form submits, hashchange and orientationchange/resize +//---------------------------------------------------------------------------------- + //DONE: link click event binding for changePage + //click routing - direct to HTTP or Ajax, accordingly + function findClosestLink(ele) + { + while (ele){ + if (ele.nodeName.toLowerCase() == "a"){ + break; + } + ele = ele.parentNode; + } + return ele; + } + + $(document).unbind(".linkhandler"); + $(document).bind( "click", function(event) { + var link = findClosestLink(event.target); + if (!link){ + return; + } + + var $link = $(link), + + //get href, if defined, otherwise fall to null # + href = $link.attr( "href" ) || "#", + + //cache a check for whether the link had a protocol + //if this is true and the link was same domain, we won't want + //to prefix the url with a base (esp helpful in IE, where every + //url is absolute + hadProtocol = $.mobile.path.hasProtocol( href ), + + //get href, remove same-domain protocol and host + url = $.mobile.path.clean( href ), + + //rel set to external + isRelExternal = $link.is( "[rel='external']" ), + + //rel set to external + isEmbeddedPage = $.mobile.path.isEmbeddedPage( url ), + + // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR + // requests if the document doing the request was loaded via the file:// protocol. + // This is usually to allow the application to "phone home" and fetch app specific + // data. We normally let the browser handle external/cross-domain urls, but if the + // allowCrossDomainPages option is true, we will allow cross-domain http/https + // requests to go through our page loading logic. + isCrossDomainPageLoad = ($.mobile.allowCrossDomainPages && location.protocol === "file:" && url.search(/^https?:/) != -1), + + //check for protocol or rel and its not an embedded page + //TODO overlap in logic from isExternal, rel=external check should be + // moved into more comprehensive isExternalLink + isExternal = ($.mobile.path.isExternal(url) && !isCrossDomainPageLoad) || (isRelExternal && !isEmbeddedPage), + + //if target attr is specified we mimic _blank... for now + hasTarget = $link.is( "[target]" ), + + //if data-ajax attr is set to false, use the default behavior of a link + hasAjaxDisabled = $link.is(":jqmData(ajax='false')"), + + isRefresh=$link.jqmData('refresh'), + $targetPanel=$link.jqmData('panel'), + $targetContainer=$('div:jqmData(id="'+$targetPanel+'")'), + $targetPanelActivePage=$targetContainer.children('div.'+$.mobile.activePageClass), + $currPanel=$link.parents('div:jqmData(role="panel")'), + //not sure we need this. if you want the container of the element that triggered this event, $currPanel + $currContainer=$.mobile.pageContainer, + $currPanelActivePage=$currPanel.children('div.'+$.mobile.activePageClass), + from = null; + + //if there's a data-rel=back attr, go back in history + if( $link.is( ":jqmData(rel='back')" ) ){ + window.history.back(); + return false; + } + + //prevent # urls from bubbling + //path.get() is replaced to combat abs url prefixing in IE + var replaceRegex = new RegExp($.mobile.path.get()+"(?=#)"); + if( url.replace(replaceRegex, "") == "#" ){ + //for links created purely for interaction - ignore + event.preventDefault(); + return; + } + + //still need this hack apparently: + $('.ui-btn.'+$.mobile.activeBtnClass).removeClass($.mobile.activeBtnClass); + $activeClickedLink = $link.closest( ".ui-btn" ).addClass($.mobile.activeBtnClass); + + if( isExternal || hasAjaxDisabled || hasTarget || !$.mobile.ajaxEnabled || + // TODO: deprecated - remove at 1.0 + !$.mobile.ajaxLinksEnabled ){ + //remove active link class if external (then it won't be there if you come back) + window.setTimeout(function() {removeActiveLinkClass(true);}, 200); + + //use default click handling + return; + } + + //use ajax + var transition = $link.jqmData( "transition" ), + direction = $link.jqmData("direction"), + reverse = (direction && direction === "reverse") || + // deprecated - remove by 1.0 + $link.jqmData( "back" ), + hash = $currPanel.jqmData('hash'); + + + //this may need to be more specific as we use data-rel more + nextPageRole = $link.attr( "data-" + $.mobile.ns + "rel" ); + + //if it's a relative href, prefix href with base url + if( $.mobile.path.isRelative( url ) && !hadProtocol ){ + url = $.mobile.path.makeAbsolute( url ); + } + + url = $.mobile.path.stripHash( url ); + + //if link refers to an already active panel, stop default action and return + if ($targetPanelActivePage.attr('data-url') == url || $currPanelActivePage.attr('data-url') == url) { + if (isRefresh) { //then changePage below because it's a pageRefresh request + $.mobile.changePage([$(':jqmData(url="'+url+'")'),url], 'fade', reverse, false, undefined, $targetContainer, isRefresh ); + } + else { //else preventDefault and return + event.preventDefault(); + return; + } + } + //if link refers to a page on another panel, changePage on that panel + else if ($targetPanel && $targetPanel!=$link.parents('div[data-role="panel"]')) { + var from=$targetPanelActivePage; + // $.mobile.pageContainer=$targetContainer; + $.mobile.changePage([from,url], transition, reverse, true, undefined, $targetContainer); + } + //if link refers to a page inside the same panel, changePage on that panel + else { + var from=$currPanelActivePage; + // $.mobile.pageContainer=$currPanel; + var hashChange= (hash == 'false' || hash == 'crumbs')? false : true; + $.mobile.changePage([from,url], transition, reverse, hashChange, undefined, $currPanel); + //active page must always point to the active page in main - for history purposes. + $.mobile.activePage=$('div[data-id="main"] > div.'+$.mobile.activePageClass); + } + + // $.mobile.changePage( url, transition, reverse ); + event.preventDefault(); + }); + + //DONE: bind form submit with this plugin + $("form").die('submit'); + $("form").live('submit', function(event){ + if( !$.mobile.ajaxEnabled || + //TODO: deprecated - remove at 1.0 + !$.mobile.ajaxFormsEnabled || + $(this).is( "[data-ajax='false']" ) ){ return; } + + var $this = $(this); + type = $this.attr("method"), + url = $.mobile.path.clean( $this.attr( "action" ) ), + $currPanel=$this.parents('div[data-role="panel"]'), + $currPanelActivePage=$currPanel.children('div.'+$.mobile.activePageClass); + + if( $.mobile.path.isExternal( url ) ){ + return; + } + + if( $.mobile.path.isRelative( url ) ){ + url = $.mobile.path.makeAbsolute( url ); + } + + //temporarily put this here- eventually shud just set it immediately instead of an interim var. + $.mobile.activePage=$currPanelActivePage; + // $.mobile.pageContainer=$currPanel; + $.mobile.changePage({ + url: url, + type: type || "get", + data: $this.serialize() + }, + undefined, + undefined, + true, + false, + $currPanel + ); + event.preventDefault(); + }); + + //DONE: bind hashchange with this plugin + //hashchanges are defined only for the main panel - other panels should not support hashchanges to avoid ambiguity + $(window).unbind("hashchange"); + $(window).bind( "hashchange", function( e, triggered ) { + var to = $.mobile.path.stripHash( location.hash ), + transition = $.mobile.urlHistory.stack.length === 0 ? false : undefined, + $mainPanel=$('div[data-id="main"]'), + $mainPanelFirstPage=$mainPanel.children('div[data-role="page"]').first(), + $mainPanelActivePage=$mainPanel.children('div.ui-page-active'), + $menuPanel=$('div[data-id="menu"]'), + $menuPanelFirstPage=$menuPanel.children('div[data-role="page"]').first(), + $menuPanelActivePage=$menuPanel.children('div.ui-page-active'), + //FIX: temp var for dialogHashKey + dialogHashKey = "&ui-state=dialog"; + + if( !$.mobile.hashListeningEnabled || !$.mobile.urlHistory.ignoreNextHashChange ){ + if( !$.mobile.urlHistory.ignoreNextHashChange ){ + $.mobile.urlHistory.ignoreNextHashChange = true; + } + return; + } + + if( $.mobile.urlHistory.stack.length > 1 && + to.indexOf( dialogHashKey ) > -1 && + !$.mobile.activePage.is( ".ui-dialog" ) ){ + + $.mobile.urlHistory.directHashChange({ + currentUrl: to, + isBack: function(){ window.history.back(); }, + isForward: function(){ window.history.forward(); } + }); + + return; + } + + //if to is defined, load it + if ( to ){ + $.mobile.pageContainer=$menuPanel; + //if this is initial deep-linked page setup, then changePage sidemenu as well + if (!$('div.ui-page-active').length) { + $.mobile.changePage($menuPanelFirstPage, transition, true, false, true); + } + // $.mobile.pageContainer=$mainPanel; + $.mobile.activePage=$mainPanelActivePage.length? $mainPanelActivePage : undefined; + $.mobile.changePage(to, transition, undefined, false, true, $mainPanel ); + } + //there's no hash, go to the first page in the main panel. + else { + // $.mobile.pageContainer=$mainPanel; + $.mobile.activePage=$mainPanelActivePage? $mainPanelActivePage : undefined; + $.mobile.changePage($mainPanelFirstPage, transition, undefined, false, true, $mainPanel ); + } + }); + + //DONE: bind orientationchange and resize + $(window).bind('orientationchange resize', function(event){ + var $menu=$('div[data-id="menu"]'), + $main=$('div[data-id="main"]'), + $mainHeader=$main.find('div.'+$.mobile.activePageClass+'> div[data-role="header"]'), + $window=$(window); + + function popoverBtn(header) { + if(!header.children('.popover-btn').length){ + if(header.children('a.ui-btn-left').length){ + header.children('a.ui-btn-left').replaceWith('Menu'); + header.children('a.popover-btn').addClass('ui-btn-left').buttonMarkup(); + } + else{ + header.prepend('Menu'); + header.children('a.popover-btn').addClass('ui-btn-left').buttonMarkup() + } + } + } + + function replaceBackBtn(header) { + if($.mobile.urlstack.length > 0 && !header.children('a:jqmData(rel="back")').length && header.jqmData('backbtn')!=false){ + header.prepend("Back" ); + header.children('a:jqmData(rel="back")').buttonMarkup(); + } + }; + + function popover(){ + $menu.addClass('panel-popover') + .removeClass('ui-panel-left ui-border-right') + .css({'width':'25%', 'min-width':'250px', 'display':''}); + if(!$menu.children('.popover_triangle').length){ + $menu.prepend('
'); + } + $main.removeClass('ui-panel-right') + .css('width', ''); + popoverBtn($mainHeader); + + $main.undelegate('div[data-role="page"]', 'pagebeforeshow.splitview'); + $main.delegate('div[data-role="page"]','pagebeforeshow.popover', function(){ + var $thisHeader=$(this).children('div[data-role="header"]'); + popoverBtn($thisHeader); + }); + }; + + function splitView(){ + $menu.removeClass('panel-popover') + .addClass('ui-panel-left ui-border-right') + .css({'width':'25%', 'min-width':'250px', 'display':''}); + $menu.children('.popover_triangle').remove(); + $main.addClass('ui-panel-right') + .width(function(){ + return $(window).width()-$('div[data-id="menu"]').width(); + }); + $mainHeader.children('.popover-btn').remove(); + + replaceBackBtn($mainHeader); + + $main.undelegate('div[data-role="page"]', 'pagebeforeshow.popover'); + $main.delegate('div[data-role="page"]', 'pagebeforeshow.splitview', function(){ + var $thisHeader=$(this).children('div[data-role="header"]'); + $thisHeader.children('.popover-btn').remove(); + replaceBackBtn($thisHeader); + }); + + } + + if(event.orientation){ + if(event.orientation == 'portrait'){ + popover(); + } + else if(event.orientation == 'landscape') { + splitView(); + } + } + else if($window.width() < 768 && $window.width() > 480){ + popover(); + } + else if($window.width() > 768){ + splitView(); + } + }); + +//---------------------------------------------------------------------------------- +//Other event bindings: scrollview, popover buttons, and toolbar hacks +//---------------------------------------------------------------------------------- + + //DONE: pageshow binding for scrollview + $('div[data-role="page"]').live('pagebeforeshow.scroll', function(event){ + if ($.support.touch) { + var $page = $(this); + $page.find('div[data-role="content"]').attr('data-scroll', 'y'); + $page.find("[data-scroll]:not(.ui-scrollview-clip)").each(function(){ + var $this = $(this); + // XXX: Remove this check for ui-scrolllistview once we've + // integrated list divider support into the main scrollview class. + if ($this.hasClass("ui-scrolllistview")) + $this.scrolllistview(); + else + { + var st = $this.data("scroll") + ""; + var paging = st && st.search(/^[xy]p$/) != -1; + var dir = st && st.search(/^[xy]/) != -1 ? st.charAt(0) : null; + + var opts = {}; + if (dir) + opts.direction = dir; + if (paging) + opts.pagingEnabled = true; + + var method = $this.data("scroll-method"); + if (method) + opts.scrollMethod = method; + + $this.scrollview(opts); + } + }); + } + }); + + //data-hash 'crumbs' handler + //NOTE: if you set data-backbtn to false this WILL not work! will find time to work this thru better. + $('div[data-role="page"]').live('pagebeforeshow.crumbs', function(event, data){ + var $this = $(this), + backBtn = $this.find('a[data-rel="back"]'); + if (backBtn.length && ($this.data('hash') == 'crumbs' || $this.parents('div[data-role="panel"]').data('hash') == 'crumbs') && $.mobile.urlstack.length > 0) { + backBtn.removeAttr('data-rel') + .attr('href','#'+data.prevPage.attr('data-url')) + .jqmData('direction','reverse') + .addClass('ui-crumbs'); + backBtn.find('.ui-btn-text').html(data.prevPage.find('div[data-role="header"] .ui-title').html()); + } + }); + + //data-context handler - a page with a link that has a data-context attribute will load that page after this page loads + //this still needs work - pageTransitionQueue messes everything up. + $('div:jqmData(role="page")').live('pageshow.context', function(){ + var $this=$(this), + panelContextSelector = $this.parents('div[data-role="panel"]').jqmData('context'), + pageContextSelector = $this.jqmData('context'), + contextSelector= pageContextSelector ? pageContextSelector : panelContextSelector; + //if you pass a hash into data-context, you need to specify panel, url and a boolean value for refresh + if($.type(contextSelector) === 'object') { + var $targetContainer=$(':jqmData(id="'+contextSelector.panel+'")'), + $targetPanelActivePage=$targetContainer.children('div.'+$.mobile.activePageClass), + isRefresh = contextSelector.refresh === undefined ? false : contextSelector.refresh; + $.mobile.changePage([$targetPanelActivePage, contextSelector.url],'fade', reverse, false, undefined, $targetContainer, isRefresh); + } + else if(contextSelector && $this.find(contextSelector).length){ + $this.find(contextSelector).trigger('click'); + } + }); + + //popover button click handler - from http://www.cagintranet.com/archive/create-an-ipad-like-dropdown-popover/ + $('.popover-btn').live('click', function(e){ + e.preventDefault(); + $('.panel-popover').fadeToggle('fast'); + if ($('.popover-btn').hasClass($.mobile.activeBtnClass)) { + $('.popover-btn').removeClass($.mobile.activeBtnClass); + } else { + $('.popover-btn').addClass($.mobile.activeBtnClass); + } + }); + + $('body').live('click', function(event) { + if (!$(event.target).closest('.panel-popover').length && !$(event.target).closest('.popover-btn').length) { + $(".panel-popover").stop(true, true).hide(); + $('.popover-btn').removeClass($.mobile.activeBtnClass); + }; + }); + } + }); +})(jQuery,window); \ No newline at end of file diff --git a/js/jquery.mobile.fixHeaderFooter.js b/js/jquery.mobile.fixHeaderFooter.js index 1d2eea0aae0..346d756871f 100644 --- a/js/jquery.mobile.fixHeaderFooter.js +++ b/js/jquery.mobile.fixHeaderFooter.js @@ -28,8 +28,8 @@ $.fixedToolbars = (function(){ toolbarSelector = '.ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last', stickyFooter, //for storing quick references to duplicate footers supportTouch = $.support.touch, - touchStartEvent = supportTouch ? "touchstart" : "mousedown", - touchStopEvent = supportTouch ? "touchend" : "mouseup", + touchStartEvent = supportTouch ? "touchstart.toolbar" : "mousedown.toolbar", + touchStopEvent = supportTouch ? "touchend.toolbar" : "mouseup.toolbar", stateBefore = null, scrollTriggered = false, touchToggleEnabled = true; @@ -54,12 +54,12 @@ $.fixedToolbars = (function(){ $(function() { $(document) - .bind( "vmousedown",function(event){ + .bind( "vmousedown.toolbar",function(event){ if( touchToggleEnabled ) { stateBefore = currentstate; } }) - .bind( "vclick",function(event){ + .bind( "vclick.toolbar",function(event){ if( touchToggleEnabled ) { if( $(event.target).closest(ignoreTargets).length ){ return; } if( !scrollTriggered ){ @@ -68,7 +68,7 @@ $.fixedToolbars = (function(){ } } }) - .bind('scrollstart',function(event){ + .bind('scrollstart.toolbar',function(event){ scrollTriggered = true; if(stateBefore == null){ stateBefore = currentstate; } @@ -85,7 +85,7 @@ $.fixedToolbars = (function(){ } } }) - .bind('scrollstop',function(event){ + .bind('scrollstop.toolbar',function(event){ if( $(event.target).closest(ignoreTargets).length ){ return; } scrollTriggered = false; if (autoHideMode) { @@ -94,13 +94,13 @@ $.fixedToolbars = (function(){ } stateBefore = null; }) - .bind('silentscroll', showEventCallback); + .bind('silentscroll.toolbar', showEventCallback); - $(window).bind('resize', showEventCallback); + $(window).bind('resize.toolbar', showEventCallback); }); //before page is shown, check for duplicate footer - $('.ui-page').live('pagebeforeshow', function(event, ui){ + $('.ui-page').live('pagebeforeshow.toolbar', function(event, ui){ var page = $(event.target), footer = page.find( ":jqmData(role='footer')" ), id = footer.data('id'), @@ -115,7 +115,7 @@ $.fixedToolbars = (function(){ }); //after page is shown, append footer to new page - $('.ui-page').live('pageshow', function(event, ui){ + $('.ui-page').live('pageshow.toolbar', function(event, ui){ var $this = $(this); if( stickyFooter && stickyFooter.length ){ diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js index cd38806592e..5ec5e5095b9 100644 --- a/js/jquery.mobile.navigation.js +++ b/js/jquery.mobile.navigation.js @@ -335,14 +335,13 @@ $.mobile.allowCrossDomainPages = false; // changepage function - $.mobile.changePage = function( to, transition, reverse, changeHash, fromHashChange ){ + $.mobile.changePage = function( targetPage, transition, reverse, changeHash, fromHashChange, container, refresh){ //from is always the currently viewed page - var toType = $.type(to), - toIsArray = toType === "array", - toIsObject = toType === "object", - from = toIsArray ? to[0] : $.mobile.activePage; - - to = toIsArray ? to[1] : to; + var toType = $.type(targetPage), + toIsArray = toType === "array", + toIsObject = toType === "object", + from = toIsArray ? targetPage[0] : $.mobile.activePage; + to = toIsArray ? targetPage[1] : targetPage; var url = $.type(to) === "string" ? path.stripHash( to ) : "", fileUrl = url, @@ -353,7 +352,12 @@ active = urlHistory.getActive(), back = false, forward = false, - pageTitle = document.title; + pageTitle = document.title, + //Test to see if an array is passed for targetPage and if the from and to in the array are the same - this means + //that it is an intentional call to changePage for a page refresh + isPageRefresh = refresh === undefined ? false : refresh; + + $.mobile.pageContainer= container === undefined ? $.mobile.pageContainer : container; // If we are trying to transition to the same page that we are currently on ignore the request. @@ -546,7 +550,7 @@ defaultTransition(); // find the "to" page, either locally existing in the dom or by creating it through ajax - if ( to.length && !isFormRequest ) { + if ( to.length && !isFormRequest && !isPageRefresh ) { if( fileUrl && base ){ base.set( fileUrl ); } @@ -555,6 +559,8 @@ } else { //if to exists in DOM, save a reference to it in duplicateCachedPage for removal after page change + //unless method is post - which in REST case it has a url that is the same as a URL that lists all of a resource + //but upon creation of a new record, you want to point to that particular record after the fact. if( to.length ){ duplicateCachedPage = to; } @@ -584,6 +590,9 @@ // correct url. loading into a temprorary element makes these requests immediately if(pageElemRegex.test(html) && RegExp.$1 && dataUrlRegex.test(RegExp.$1) && RegExp.$1) { redirectLoc = RegExp.$1; + if(redirectLoc != url) { + duplicateCachedPage=null; + } } if( redirectLoc ){ @@ -722,7 +731,7 @@ //click routing - direct to HTTP or Ajax, accordingly - $( document ).bind( "click", function(event) { + $( document ).bind( "click.linkhandler", function(event) { var link = findClosestLink(event.target); if (!link){ return; diff --git a/themes/default/jquery.mobile.grids.css b/themes/default/jquery.mobile.grids.css index 162cb838826..cfc9f556676 100644 --- a/themes/default/jquery.mobile.grids.css +++ b/themes/default/jquery.mobile.grids.css @@ -25,4 +25,4 @@ /* grid d: 20/20/20/20/20 */ .ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 20%; } -.ui-grid-d .ui-block-a { clear: left; } +.ui-grid-d .ui-block-a { clear: left; } \ No newline at end of file