cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pplaque...@apache.org
Subject [16/51] [partial] [cordova-tizen] Tizen SDK 2.2 support mores samples
Date Tue, 10 Sep 2013 18:04:21 GMT
http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.pinch.js
----------------------------------------------------------------------
diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.pinch.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.pinch.js
new file mode 100644
index 0000000..cece62a
--- /dev/null
+++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.pinch.js
@@ -0,0 +1,373 @@
+/* ***************************************************************************
+	Flora License
+
+	Version 1.1, April, 2013
+
+	http://floralicense.org/license/
+
+	TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+	1. Definitions.
+
+	"License" shall mean the terms and conditions for use, reproduction,
+	and distribution as defined by Sections 1 through 9 of this document.
+
+	"Licensor" shall mean the copyright owner or entity authorized by
+	the copyright owner that is granting the License.
+
+	"Legal Entity" shall mean the union of the acting entity and
+	all other entities that control, are controlled by, or are
+	under common control with that entity. For the purposes of
+	this definition, "control" means (i) the power, direct or indirect,
+	to cause the direction or management of such entity,
+	whether by contract or otherwise, or (ii) ownership of fifty percent (50%)
+	or more of the outstanding shares, or (iii) beneficial ownership of
+	such entity.
+
+	"You" (or "Your") shall mean an individual or Legal Entity
+	exercising permissions granted by this License.
+
+	"Source" form shall mean the preferred form for making modifications,
+	including but not limited to software source code, documentation source,
+	and configuration files.
+
+	"Object" form shall mean any form resulting from mechanical
+	transformation or translation of a Source form, including but
+	not limited to compiled object code, generated documentation,
+	and conversions to other media types.
+
+	"Work" shall mean the work of authorship, whether in Source or Object form,
+	made available under the License, as indicated by a copyright notice
+	that is included in or attached to the work (an example is provided
+	in the Appendix below).
+
+	"Derivative Works" shall mean any work, whether in Source or Object form,
+	that is based on (or derived from) the Work and for which the editorial
+	revisions, annotations, elaborations, or other modifications represent,
+	as a whole, an original work of authorship. For the purposes of this License,
+	Derivative Works shall not include works that remain separable from,
+	or merely link (or bind by name) to the interfaces of, the Work and
+	Derivative Works thereof.
+
+	"Contribution" shall mean any work of authorship, including the original
+	version of the Work and any modifications or additions to that Work or
+	Derivative Works thereof, that is intentionally submitted to Licensor
+	for inclusion in the Work by the copyright owner or by an individual or
+	Legal Entity authorized to submit on behalf of the copyright owner.
+	For the purposes of this definition, "submitted" means any form of
+	electronic, verbal, or written communication sent to the Licensor or
+	its representatives, including but not limited to communication on
+	electronic mailing lists, source code control systems, and issue
+	tracking systems that are managed by, or on behalf of, the Licensor
+	for the purpose of discussing and improving the Work, but excluding
+	communication that is conspicuously marked or otherwise designated
+	in writing by the copyright owner as "Not a Contribution."
+
+	"Contributor" shall mean Licensor and any individual or Legal Entity
+	on behalf of whom a Contribution has been received by Licensor and
+	subsequently incorporated within the Work.
+
+	"Tizen Certified Platform" shall mean a software platform that complies
+	with the standards set forth in the Tizen Compliance Specification
+	and passes the Tizen Compliance Tests as defined from time to time
+	by the Tizen Technical Steering Group and certified by the Tizen
+	Association or its designated agent.
+
+	2. Grant of Copyright License.  Subject to the terms and conditions of
+	this License, each Contributor hereby grants to You a perpetual,
+	worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+	copyright license to reproduce, prepare Derivative Works of,
+	publicly display, publicly perform, sublicense, and distribute the
+	Work and such Derivative Works in Source or Object form.
+
+	3. Grant of Patent License.  Subject to the terms and conditions of
+	this License, each Contributor hereby grants to You a perpetual,
+	worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+	(except as stated in this section) patent license to make, have made,
+	use, offer to sell, sell, import, and otherwise transfer the Work
+	solely as incorporated into a Tizen Certified Platform, where such
+	license applies only to those patent claims licensable by such
+	Contributor that are necessarily infringed by their Contribution(s)
+	alone or by combination of their Contribution(s) with the Work solely
+	as incorporated into a Tizen Certified Platform to which such
+	Contribution(s) was submitted. If You institute patent litigation
+	against any entity (including a cross-claim or counterclaim
+	in a lawsuit) alleging that the Work or a Contribution incorporated
+	within the Work constitutes direct or contributory patent infringement,
+	then any patent licenses granted to You under this License for that
+	Work shall terminate as of the date such litigation is filed.
+
+	4. Redistribution.  You may reproduce and distribute copies of the
+	Work or Derivative Works thereof pursuant to the copyright license
+	above, in any medium, with or without modifications, and in Source or
+	Object form, provided that You meet the following conditions:
+
+	  1. You must give any other recipients of the Work or Derivative Works
+		 a copy of this License; and
+	  2. You must cause any modified files to carry prominent notices stating
+		 that You changed the files; and
+	  3. You must retain, in the Source form of any Derivative Works that
+		 You distribute, all copyright, patent, trademark, and attribution
+		 notices from the Source form of the Work, excluding those notices
+		 that do not pertain to any part of the Derivative Works; and
+	  4. If the Work includes a "NOTICE" text file as part of its distribution,
+		 then any Derivative Works that You distribute must include a readable
+		 copy of the attribution notices contained within such NOTICE file,
+		 excluding those notices that do not pertain to any part of
+		 the Derivative Works, in at least one of the following places:
+		 within a NOTICE text file distributed as part of the Derivative Works;
+		 within the Source form or documentation, if provided along with the
+		 Derivative Works; or, within a display generated by the Derivative Works,
+		 if and wherever such third-party notices normally appear.
+		 The contents of the NOTICE file are for informational purposes only
+		 and do not modify the License.
+
+	You may add Your own attribution notices within Derivative Works
+	that You distribute, alongside or as an addendum to the NOTICE text
+	from the Work, provided that such additional attribution notices
+	cannot be construed as modifying the License. You may add Your own
+	copyright statement to Your modifications and may provide additional or
+	different license terms and conditions for use, reproduction, or
+	distribution of Your modifications, or for any such Derivative Works
+	as a whole, provided Your use, reproduction, and distribution of
+	the Work otherwise complies with the conditions stated in this License.
+
+	5. Submission of Contributions. Unless You explicitly state otherwise,
+	any Contribution intentionally submitted for inclusion in the Work
+	by You to the Licensor shall be under the terms and conditions of
+	this License, without any additional terms or conditions.
+	Notwithstanding the above, nothing herein shall supersede or modify
+	the terms of any separate license agreement you may have executed
+	with Licensor regarding such Contributions.
+
+	6. Trademarks.  This License does not grant permission to use the trade
+	names, trademarks, service marks, or product names of the Licensor,
+	except as required for reasonable and customary use in describing the
+	origin of the Work and reproducing the content of the NOTICE file.
+
+	7. Disclaimer of Warranty. Unless required by applicable law or
+	agreed to in writing, Licensor provides the Work (and each
+	Contributor provides its Contributions) on an "AS IS" BASIS,
+	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+	implied, including, without limitation, any warranties or conditions
+	of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+	PARTICULAR PURPOSE. You are solely responsible for determining the
+	appropriateness of using or redistributing the Work and assume any
+	risks associated with Your exercise of permissions under this License.
+
+	8. Limitation of Liability. In no event and under no legal theory,
+	whether in tort (including negligence), contract, or otherwise,
+	unless required by applicable law (such as deliberate and grossly
+	negligent acts) or agreed to in writing, shall any Contributor be
+	liable to You for damages, including any direct, indirect, special,
+	incidental, or consequential damages of any character arising as a
+	result of this License or out of the use or inability to use the
+	Work (including but not limited to damages for loss of goodwill,
+	work stoppage, computer failure or malfunction, or any and all
+	other commercial damages or losses), even if such Contributor
+	has been advised of the possibility of such damages.
+
+	9. Accepting Warranty or Additional Liability. While redistributing
+	the Work or Derivative Works thereof, You may choose to offer,
+	and charge a fee for, acceptance of support, warranty, indemnity,
+	or other liability obligations and/or rights consistent with this
+	License. However, in accepting such obligations, You may act only
+	on Your own behalf and on Your sole responsibility, not on behalf
+	of any other Contributor, and only if You agree to indemnify,
+	defend, and hold each Contributor harmless for any liability
+	incurred by, or claims asserted against, such Contributor by reason
+	of your accepting any such warranty or additional liability.
+
+	END OF TERMS AND CONDITIONS
+
+	APPENDIX: How to apply the Flora License to your work
+
+	To apply the Flora License to your work, attach the following
+	boilerplate notice, with the fields enclosed by brackets "[]"
+	replaced with your own identifying information. (Don't include
+	the brackets!) The text should be enclosed in the appropriate
+	comment syntax for the file format. We also recommend that a
+	file or class name and description of purpose be included on the
+	same "printed page" as the copyright notice for easier
+	identification within third-party archives.
+
+	   Copyright [yyyy] [name of copyright owner]
+
+	   Licensed under the Flora License, Version 1.1 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		   http://floralicense.org/license/
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+
+ *	Author: Minkyu Kang <mk7.kang@samsung.com>
+ */
+
+/*
+ * Pinch Event
+ *
+ * Events
+ *	pinchstart: triggered when start the touched two points
+ *	pinch: triggered when move the touch point after pinchstart event occured
+ *	pinchend: triggered when touchend event after pinchstart event occured
+ *
+ * Parameters
+ *	point: touched points
+ *	ratio: origin point-to-current point ratio for moving distance
+ *
+ *	$("#pinch").bind("pinch", function (e, p) {
+ *		console.log("point[0].x: " + p.point[0].x);
+ *		console.log("point[0].y: " + p.point[0].y);
+ *		console.log("point[1].x: " + p.point[1].x);
+ *		console.log("point[1].y: " + p.point[1].y);
+ *		console.log("ratio: " + p.ratio);
+ *	});
+ *
+ * Options
+ *	$.mobile.pinch.enabled: true or false
+ *	$.mobile.pinch.min: minimum value of ratio
+ *	$.mobile.pinch.max: maximum value of ratio
+ *	$.mobile.pinch.factor: scale factor of ratio
+ *	$.mobile.pinch.threshold: move threshold of ratio
+ *	$.mobile.pinch.interval: interval for pinch event
+ */
+
+//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
+//>>description: Pinch Event
+//>>label: Pinch Event
+//>>group: Tizen:Core
+
+define( [ 
+	'jquery',
+	'jqm/jquery.mobile.core'
+	], function ( jQuery ) {
+
+//>>excludeEnd("jqmBuildExclude");
+
+( function( $, window, undefined ) {
+
+pinch_event = {
+	setup: function () {
+		var thisObject = this,
+			$this = $( thisObject );
+
+		if ( !$.mobile.support.touch ) {
+			return;
+		}
+
+		function getSize( point ) {
+			var x = point[0].x - point[1].x,
+				y = point[0].y - point[1].y;
+
+			return Math.abs( x * y );
+		}
+
+		function getParameter( point, ratio ) {
+			return { point: point, ratio: ratio };
+		}
+
+		$this.bind( "touchstart", function ( event ) {
+			var data = event.originalEvent.touches,
+				origin,
+				last_ratio = 1,
+				processing = false;
+
+			if ( !$.mobile.pinch.enabled ) {
+				return;
+			}
+
+			if ( data.length != 2 ) {
+				return;
+			}
+
+			origin = [
+					{ x: data[0].pageX, y: data[0].pageY },
+					{ x: data[1].pageX, y: data[1].pageY }
+			];
+
+			$( event.target ).trigger( "pinchstart", getParameter( origin, undefined ) );
+
+			function pinchHandler( event ) {
+				var data = event.originalEvent.touches,
+					current,
+					ratio,
+					delta,
+					factor = $( window ).width() / $.mobile.pinch.factor;
+
+				if ( processing ) {
+					return;
+				}
+
+				if ( !origin ) {
+					return;
+				}
+
+				current = [
+						{ x: data[0].pageX, y: data[0].pageY },
+						{ x: data[1].pageX, y: data[1].pageY }
+				];
+
+				delta = Math.sqrt( getSize( current ) / getSize( origin )  ) ;
+				if( delta ) {
+					ratio = delta;
+				}
+
+				if ( ratio < $.mobile.pinch.min ) {
+					ratio = $.mobile.pinch.min;
+				} else if ( ratio > $.mobile.pinch.max ) {
+					ratio = $.mobile.pinch.max;
+				}
+
+				if ( Math.abs( ratio - last_ratio ) < $.mobile.pinch.threshold ) {
+					return;
+				}
+
+				$( event.target ).trigger( "pinch", getParameter( current, ratio ) );
+
+				last_ratio = ratio;
+
+				if ( $.mobile.pinch.interval ) {
+					processing = true;
+
+					setTimeout( function () {
+						processing = false;
+					}, $.mobile.pinch.interval );
+				}
+			}
+
+			$this.bind( "touchmove", pinchHandler )
+				.one( "touchend", function ( event ) {
+					$this.unbind( "touchmove", pinchHandler );
+					$( event.target ).trigger( "pinchend",
+								getParameter( undefined, last_ratio ) );
+
+					origin = undefined;
+					current = undefined;
+					last_ratio = 1;
+					processing = false;
+				});
+		});
+	}
+};
+
+$.event.special["pinch"] = pinch_event;
+
+$.mobile.pinch = {
+	enabled: true,
+	min: 0.1,
+	max: 3,
+	factor: 4,
+	threshold: 0.01,
+	interval: 50
+};
+
+})( jQuery, this );
+
+//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
+} );
+//>>excludeEnd("jqmBuildExclude");

http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.scrollview.js
----------------------------------------------------------------------
diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.scrollview.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.scrollview.js
new file mode 100644
index 0000000..baeb51b
--- /dev/null
+++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/jquery.mobile.tizen.scrollview.js
@@ -0,0 +1,1942 @@
+//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
+//>>description: Implements scroll by javascript
+//>>label: Scrollview
+//>>group: Tizen:Core
+
+define( [ 
+	"jquery",
+	"jqm/jquery.mobile.widget",
+	'libs/jquery.easing.1.3'
+	], function ( jQuery ) {
+
+//>>excludeEnd("jqmBuildExclude");
+
+/*
+* jQuery Mobile Framework : scrollview plugin
+* Copyright (c) 2010 Adobe Systems Incorporated - Kin Blas (jblas@adobe.com)
+* Licensed under the MIT (MIT-LICENSE.txt) license.
+* Note: Code is in draft form and is subject to change
+* Modified by Koeun Choi <koeun.choi@samsung.com>
+* Modified by Minkyu Kang <mk7.kang@samsung.com>
+*/
+
+(function ( $, window, document, undefined ) {
+
+	/**
+	 * Resizes page content height according to footer
+	 * header elements, and page padding
+	 * @param {HTMLElement|jQuery} page
+	 */
+	function resizePageContentHeight( page ) {
+		var $page = $( page ),
+			$content = $page.children(".ui-content"),
+			hh = $page.children(".ui-header").outerHeight() || 0,
+			fh = $page.children(".ui-footer").outerHeight() || 0,
+			pt = parseFloat( $content.css("padding-top") ),
+			pb = parseFloat( $content.css("padding-bottom") ),
+			wh = $( window ).height();
+
+		$content.height( wh - (hh + fh) - (pt + pb) );
+	}
+
+	/**
+	 * MomentumTracker - helper class to ease momentum
+	 * movement calculations
+	 * @class
+	 * @param {Object} options
+	 */
+	function MomentumTracker( options ) {
+		this.options = $.extend( {}, options );
+		this.easing = "easeOutQuad";
+		this.reset();
+	}
+
+	/**
+	 * Scroll states dictionary
+	 * @type {Object}
+	 */
+	var tstates = {
+		scrolling: 0,
+		overshot:  1,
+		snapback:  2,
+		done:      3
+	};
+
+	/**
+	 * Returns current time in miliseconds
+	 * @return {number}
+	 */
+	function getCurrentTime() {
+		return Date.now();
+	};
+
+	function bitwiseAbs( e ) {
+		return ( e ^ (e>>31)) - (e>>31);
+	}
+
+	jQuery.widget( "tizen.scrollview", jQuery.mobile.widget, {
+		/**
+		 * Default options
+		 * @type {Object}
+		 */
+		options: {
+			/**
+			 * Direction of scroll, can be:
+			 * "x" for horizontal scroll
+			 * "y" for vertical scroll
+			 * null for horizontal and vertical scroll
+			 * @type {string|null}
+			 */
+			direction:         null,  // "x", "y", or null for both.
+
+			/**
+			 * Internal timer inteval
+			 * @type {number}
+			 */
+			timerInterval:     10,
+
+			/**
+			 * Duration of the scrolling animation in miliseconds
+			 * @type {number}
+			 */
+			scrollDuration:    1000,
+
+			/**
+			 * Duration of the overshoot animation in miliseconds
+			 * @type {number}
+			 */
+			overshootDuration: 250,
+
+			/**
+			 * Duration of snapback animation in miliseconds
+			 * @type {number}
+			 */
+			snapbackDuration:  500,
+
+			/**
+			 * Scroll detection threshold
+			 * @type {number}
+			 */
+			moveThreshold:     10,
+
+			/**
+			 * Maximal time between mouse movements while scrolling
+			 * @type {number}
+			 */
+			moveIntervalThreshold:     150,
+
+			/**
+			 * Scroll method type, can be "translate" or "position"
+			 * @type {string}
+			 */
+			scrollMethod:      "translate",
+
+			/**
+			 * The event fired when started scrolling
+			 * @type {string}
+			 */
+			startEventName:    "scrollstart",
+
+			/**
+			 * The event fired on each scroll update (movement)
+			 * @type {string}
+			 */
+			updateEventName:   "scrollupdate",
+
+			/**
+			 * The event fired after scroll stopped
+			 * @type {string}
+			 */
+			stopEventName:     "scrollstop",
+
+			/**
+			 * Determines the event group for detecting scroll
+			 * if $.support.touch has truthy value the group
+			 * that starts scroll will be touch events, otherwise
+			 * mouse events will be used
+			 * @type {string}
+			 */
+			eventType:         $.support.touch ? "touch" : "mouse",
+
+			/**
+			 * Determines if we should show the scrollbars
+			 * @type {boolean}
+			 */
+			showScrollBars:    true,
+
+			/**
+			 * Determines if overshoot animation is enabled
+			 * @type {boolean}
+			 */
+			overshootEnable:   false,
+
+			/**
+			 * Determines if we enable the window scroll
+			 * @type {boolean}
+			 */
+			outerScrollEnable: false,
+
+			/**
+			 * Determines if the overflow animation is enabled
+			 * @type {boolean}
+			 */
+			overflowEnable:    true,
+
+			/**
+			 * Determines if we allow scroll jumps
+			 * @type {boolean}
+			 */
+			scrollJump:        false
+		},
+
+		/**
+		 * Returns view height
+		 * @private
+		 * @return {number}
+		 */
+		_getViewHeight: function () {
+			return this._$view.height();
+		},
+
+		/**
+		 * Returns view width
+		 * @private
+		 * @return {number}
+		 */
+		_getViewWidth: function () {
+			return this._$view.width();
+		},
+
+		/**
+		 * Changes specified elements position to relative if
+		 * previous position state was static
+		 * @private
+		 * @param {jQuery} $ele
+		 */
+		_makePositioned: function ( $ele ) {
+			if ( $ele.css("position") === "static" ) {
+				$ele.css( "position", "relative" );
+			}
+		},
+
+		/**
+		 * Creates scrollview widget,
+		 * binds events and initiaties timers
+		 * @private
+		 */
+		_create: function () {
+			var direction,
+				self = this;
+
+			this._$clip = $( this.element ).addClass("ui-scrollview-clip");
+
+			if ( this._$clip.children(".ui-scrollview-view").length ) {
+				this._$view = this._$clip.children(".ui-scrollview-view");
+			} else {
+				this._$view = this._$clip.wrapInner("<div></div>").children()
+							.addClass("ui-scrollview-view");
+			}
+
+			if ( this.options.scrollMethod === "translate" ) {
+				if ( this._$view.css("transform") === undefined ) {
+					this.options.scrollMethod = "position";
+				}
+			}
+
+			this._$clip.css( "overflow", "hidden" );
+			this._makePositioned( this._$clip );
+
+			this._makePositioned( this._$view );
+			this._$view.css( { left: 0, top: 0 } );
+
+			this._view_height = this._getViewHeight();
+
+			this._sx = 0;
+			this._sy = 0;
+
+			direction = this.options.direction;
+
+			this._hTracker = ( direction !== "y" ) ?
+					new MomentumTracker( this.options ) : null;
+			this._vTracker = ( direction !== "x" ) ?
+					new MomentumTracker( this.options ) : null;
+
+			this._timerInterval = this.options.timerInterval;
+			this._timerID = 0;
+
+			this._timerCB = function () {
+				self._handleMomentumScroll();
+			};
+
+			this._add_event();
+			this._add_scrollbar();
+			this._add_scroll_jump();
+			this._add_overflow_indicator();
+			this._moveInterval = 10; /* Add Interval */
+			this._clipHeight = 0;
+		},
+
+		/**
+		 * Starts momentum scroll after user stopped
+		 * scrolling
+		 * @private
+		 * @param {number} speedX Horizontal speed
+		 * @param {number} speedY Vertical speed
+		 */
+		_startMScroll: function ( speedX, speedY ) {
+			var keepGoing = false,
+				duration = this.options.scrollDuration,
+				ht = this._hTracker,
+				vt = this._vTracker,
+				c,
+				v;
+
+			this._$clip.trigger( this.options.startEventName );
+
+			if ( ht ) {
+				c = this._$clip.width();
+				v = this._getViewWidth();
+
+				if ( (( this._sx === 0 && speedX > 0 ) ||
+					( this._sx === -(v - c) && speedX < 0 )) &&
+						v > c ) {
+					return;
+				}
+
+				ht.start( this._sx, speedX,
+					duration, (v > c) ? -(v - c) : 0, 0 );
+				keepGoing = !ht.done();
+			}
+
+			if ( vt ) {
+				c = this._$clip.height();
+				v = this._getViewHeight();
+
+				if ( (( this._sy === 0 && speedY > 0 ) ||
+					( this._sy === -(v - c) && speedY < 0 )) &&
+						v > c ) {
+					return;
+				}
+
+				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();
+			}
+		},
+
+		/**
+		 * Ends momentum scroll
+		 * @private
+		 */
+		_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();
+			this._hideOverflowIndicator();
+		},
+
+		/**
+		 * Updates scroll while in momentum scroll mode
+		 * @private
+		 */
+		_handleMomentumScroll: function () {
+			var keepGoing = false,
+				x = 0,
+				y = 0,
+				scroll_height = 0,
+				self = this,
+				vt = this._vTracker,
+				ht = this._hTracker;
+
+			if ( this._outerScrolling ) {
+				return;
+			}
+
+			if ( vt ) {
+				vt.update( this.options.overshootEnable );
+				y = vt.getPosition();
+				keepGoing = !vt.done();
+
+				if ( vt.getRemained() > this.options.overshootDuration ) {
+					scroll_height = this._getViewHeight() - this._$clip.height();
+
+					if ( !vt.isAvail() ) {
+						if ( this._speedY > 0 ) {
+							this._outerScroll( vt.getRemained() / 3, scroll_height );
+						} else {
+							this._outerScroll( y - vt.getRemained() / 3, scroll_height );
+						}
+					} else if ( vt.isMin() ) {
+						this._outerScroll( y - vt.getRemained() / 3, scroll_height );
+
+					} else if ( vt.isMax() ) {
+						this._outerScroll( vt.getRemained() / 3, scroll_height );
+					}
+				}
+			}
+
+			if ( ht ) {
+				ht.update( this.options.overshootEnable );
+				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();
+			}
+		},
+
+		/**
+		 * Sets css translate transformation for element
+		 * @param {jQuery} $ele
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		_setElementTransform: function ( $ele, x, y, duration ) {
+			var translate,
+				transition;
+
+			if ( !duration || duration === undefined ) {
+				transition = "none";
+			} else {
+				transition =  "-webkit-transform " + duration / 1000 + "s ease-out";
+			}
+
+			if ( $.support.cssTransform3d ) {
+				translate = "translate3d(" + x + "," + y + ", 0px)";
+			} else {
+				translate = "translate(" + x + "," + y + ")";
+			}
+
+			$ele.css({
+				"-moz-transform": translate,
+				"-webkit-transform": translate,
+				"-ms-transform": translate,
+				"-o-transform": translate,
+				"transform": translate,
+				"-webkit-transition": transition
+			});
+		},
+
+		/**
+		 * Applies scroll end effect according to direction
+		 * @param {string} dir Direction, can be "in" or "out"
+		 */
+		_setEndEffect: function ( dir ) {
+			var scroll_height = this._getViewHeight() - this._$clip.height();
+
+			if ( this._softkeyboard ) {
+				if ( this._effect_dir ) {
+					this._outerScroll( -scroll_height - this._softkeyboardHeight,
+							scroll_height );
+				} else {
+					this._outerScroll( this._softkeyboardHeight, scroll_height );
+				}
+				return;
+			}
+
+			if ( dir === "in" ) {
+				if ( this._endEffect ) {
+					return;
+				}
+
+				this._endEffect = true;
+				this._setOverflowIndicator( this._effect_dir );
+				this._showOverflowIndicator();
+			} else if ( dir === "out" ) {
+				if ( !this._endEffect ) {
+					return;
+				}
+
+				this._endEffect = false;
+			} else {
+				this._endEffect = false;
+				this._setOverflowIndicator();
+				this._showOverflowIndicator();
+			}
+		},
+
+		/**
+		 * Calibrates scroll position and scroll end effect
+		 * @private
+		 * @param {number} x
+		 * @param {number} y
+		 */
+		_setCalibration: function ( x, y ) {
+			if ( this.options.overshootEnable ) {
+				this._sx = x;
+				this._sy = y;
+				return;
+			}
+
+			var $v = this._$view,
+				$c = this._$clip,
+				dirLock = this._directionLock,
+				scroll_height = 0,
+				scroll_width = 0,
+				vh,
+				ch;
+
+			if ( dirLock !== "y" && this._hTracker ) {
+				scroll_width = $v.width() - $c.width();
+
+				if ( x >= 0 ) {
+					this._sx = 0;
+				} else if ( x < -scroll_width ) {
+					this._sx = -scroll_width;
+				} else {
+					this._sx = x;
+				}
+
+				if ( scroll_width < 0 ) {
+					this._sx = 0;
+				}
+			}
+
+			if ( dirLock !== "x" && this._vTracker ) {
+				vh = this._getViewHeight();
+				ch = $c.height();
+				/*
+				When used changePage() function, this._getViewHeight() value set 0.
+				So scroll_height has incorrect value and showed indicator incorrectly.
+				Below condition is exception handling that avoid this situation.
+				*/
+				if ( vh != 0 && ch > 0 ) {
+					scroll_height = vh - ch;
+				}
+
+				if ( y > 0 ) {
+					this._sy = 0;
+
+					this._effect_dir = 0;
+					this._setEndEffect( "in" );
+				} else if ( y < -scroll_height ) {
+					this._sy = -scroll_height;
+
+					this._effect_dir = 1;
+					this._setEndEffect( "in" );
+				} else {
+					if ( this._endEffect && this._sy !== y ) {
+						this._setEndEffect();
+					}
+
+					this._sy = y;
+				}
+
+				if ( scroll_height < 0 ) {
+					this._sy = 0;
+				}
+			}
+		},
+
+		/**
+		 * Moves scroll to specified position
+		 * @private
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		_setScrollPosition: function ( x, y, duration ) {
+			var $v = this._$view,
+				sm = this.options.scrollMethod,
+				$vsb = this._$vScrollBar,
+				$hsb = this._$hScrollBar,
+				$sbt;
+
+			this._setCalibration( x, y );
+
+			x = this._sx;
+			y = this._sy;
+
+			if ( sm === "translate" ) {
+				this._setElementTransform( $v, x + "px", y + "px", duration );
+			} else {
+				$v.css( {left: x + "px", top: y + "px"} );
+			}
+
+			if ( $vsb ) {
+				$sbt = $vsb.find(".ui-scrollbar-thumb");
+
+				if ( sm === "translate" ) {
+					if ( bitwiseAbs( this._moveInterval - bitwiseAbs(y)) > 20 ) {
+						/* update scrollbar every 20(clientY) move*/
+						/* Add Interval */
+						this._setElementTransform( $sbt, "0px",
+							-y / this._getViewHeight() * this._clipHeight + "px",
+							duration );
+					}
+				} else {
+					$sbt.css( "top", -y / this._getViewHeight() * 100 + "%" );
+				}
+			}
+
+			if ( $hsb ) {
+				$sbt = $hsb.find(".ui-scrollbar-thumb");
+
+				if ( sm === "translate" ) {
+					this._setElementTransform( $sbt,
+						-x / $v.outerWidth() * $sbt.parent().width() + "px", "0px",
+						duration);
+				} else {
+					$sbt.css("left", -x / $v.width() * 100 + "%");
+				}
+			}
+		},
+
+		/**
+		 * Handles window scrolling
+		 * @private
+		 * @param {number} y
+		 * @param {number} scroll_height
+		 */
+		_outerScroll: function ( y, scroll_height ) {
+			var self = this,
+				top = $( window ).scrollTop() - window.screenTop,
+				sy = 0,
+				duration = this.options.snapbackDuration,
+				start = getCurrentTime(),
+				tfunc;
+
+			if ( !this.options.outerScrollEnable ) {
+				return;
+			}
+
+			if ( this._$clip.jqmData("scroll") !== "y" ) {
+				return;
+			}
+
+			if ( this._outerScrolling ) {
+				return;
+			}
+
+			if ( y > 0 ) {
+				sy = ( window.screenTop ? window.screenTop : -y );
+			} else if ( y < -scroll_height ) {
+				sy = -y - scroll_height;
+			} else {
+				return;
+			}
+
+			tfunc = function () {
+				var elapsed = getCurrentTime() - start;
+
+				if ( elapsed >= duration ) {
+					window.scrollTo( 0, top + sy );
+					self._outerScrolling = undefined;
+
+					self._stopMScroll();
+				} else {
+					ec = $.easing.easeOutQuad( elapsed / duration,
+							elapsed, 0, 1, duration );
+
+					window.scrollTo( 0, top + ( sy * ec ) );
+					self._outerScrolling = setTimeout( tfunc, self._timerInterval );
+				}
+			};
+			this._outerScrolling = setTimeout( tfunc, self._timerInterval );
+		},
+
+		/**
+		 * Scrolls to specified position with easeOutQuad calculations
+		 * @private
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		_scrollTo: function ( x, y, duration ) {
+			var self = this,
+				start = getCurrentTime(),
+				efunc = $.easing.easeOutQuad,
+				sx = this._sx,
+				sy = this._sy,
+				dx = x - sx,
+				dy = y - sy,
+				tfunc;
+
+			x = -x;
+			y = -y;
+
+			tfunc = function () {
+				var elapsed = getCurrentTime() - start,
+				    ec;
+
+				if ( elapsed >= duration ) {
+					self._timerID = 0;
+					self._setScrollPosition( x, y );
+				} else {
+					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 );
+		},
+
+		/**
+		 * Scrolls to specified position
+		 * If scroll method is css translation or duration is a
+		 * falsy value, the position is changed via translation,
+		 * otherwise it's animated to that position
+		 * @param {number} x
+		 * @param {number} y
+		 * @param {number} duration
+		 */
+		scrollTo: function ( x, y, duration ) {
+			this._stopMScroll();
+			this._didDrag = false;
+
+			if ( !duration || this.options.scrollMethod === "translate" ) {
+				this._setScrollPosition( x, y, duration );
+			} else {
+				this._scrollTo( x, y, duration );
+			}
+		},
+
+		/**
+		 * Centers scroll to view the specified child element
+		 * @param {Element|jQuery} target
+		 */
+		centerToElement: function ( element ) {
+			var $clip = this._$clip,
+				$view = this._$view,
+				$element = element.get ? element : $( element ),
+				delta = ( $clip.height() / 2 ) - ( element.height() / 2 ),
+				elementPosition = element.position().top;
+
+			element.parentsUntil( $view ).each( function () {
+				var $parent = $( this );
+				elementPosition += ( $parent.position().top + parseFloat( $parent.css( "marginTop" ) ) + parseFloat( $parent.css( "paddingTop" ) ) );
+			});
+
+			this.scrollTo( this._sx, -( elementPosition - delta ) );
+		},
+
+		/**
+		 * Checks if the specified child element is visible
+		 * and centers the scroll on it if it's not visible
+		 * @param {Element|jQuery}
+		 */
+		ensureElementIsVisible: function ( element ) {
+			var $element = element.get ? element : $( element ),
+				$clip = this._$clip,
+				clipHeight = $clip.height(),
+				clipTop = $clip.offset().top,
+				clipBottom = clipTop + clipHeight,
+				elementHeight = $element.height(),
+				elementTop = $element.offset().top,
+				elementBottom = elementTop + elementHeight,
+				elementFits = clipHeight > elementHeight,
+				$anchor,
+				anchorPosition = 0,
+				findPositionAnchor = function ( input ) {
+					var $label,
+						id = input.attr( "id" );
+					if ( input.is( ":input" ) && id ) {
+						$label = input.siblings( "label[for=" + id + "]" );
+						if ( $label.length > 0 ) {
+							return $label.eq( 0 );
+						}
+					}
+					return input;
+				};
+
+			switch( true ) {
+				case elementFits && clipTop < elementTop && clipBottom > elementBottom: // element fits in view is inside clip area
+					// pass, element position is ok
+					break;
+				case elementFits && clipTop < elementTop && clipBottom < elementBottom: // element fits in view but its visible only at top
+				case elementFits && clipTop > elementTop && clipBottom > elementBottom: // element fits in view but its visible only at bottom
+				case elementFits: // element fits in view but is not visible
+					this.centerToElement(element);
+					break;
+				case clipTop < elementTop && clipBottom < elementBottom: // element visible only at top
+				case clipTop > elementTop && clipBottom > elementBottom: // element visible only at bottom
+					// pass, we cant do anything, if we move the scroll
+					// the user could lost view of something he scrolled to
+					break;
+				default: // element is not visible
+					$anchor = findPositionAnchor( $element );
+					anchorPosition = $anchor.position().top + parseFloat( $anchor.css("marginTop" ) );
+					$anchor.parentsUntil($view).each(function () {
+						var $p = $( this );
+						anchorPosition += ( $p.position().top + parseFloat( $p.css("marginTop" ) ) );
+					});
+					this.scrollTo( self._sx, -anchorPosition );
+					break;
+			}
+		},
+
+		/**
+		 * Returns current scroll position {x,y}
+		 * @return {Object}
+		 */
+		getScrollPosition: function () {
+			return { x: -this._sx, y: -this._sy };
+		},
+
+		/**
+		 * Skipps dragging
+		 * @param {Boolean}
+		 */
+		skipDragging: function ( value ) {
+			this._skip_dragging = value;
+		},
+
+		/**
+		 * Returns scroll hierarchy in an array of elements
+		 * @private
+		 * @return {Array}
+		 */
+		_getScrollHierarchy: function () {
+			var svh = [],
+				d;
+
+			this._$clip.parents( ".ui-scrollview-clip").each( function () {
+				d = $( this ).jqmData("scrollview");
+				if ( d ) {
+					svh.unshift( d );
+				}
+			} );
+			return svh;
+		},
+
+		/**
+		 * Returns ancestor for specified direction
+		 * @private
+		 * @param {string} dir
+		 */
+		_getAncestorByDirection: function ( dir ) {
+			var svh = this._getScrollHierarchy(),
+				n = svh.length,
+				sv,
+				svdir;
+
+			while ( 0 < n-- ) {
+				sv = svh[n];
+				svdir = sv.options.direction;
+
+				if (!svdir || svdir === dir) {
+					return sv;
+				}
+			}
+			return null;
+		},
+
+		/**
+		 * Handles dragstart event
+		 * @private
+		 * @param {Event} e
+		 * @param {number} ex Event x position
+		 * @param {number} ey Event y position
+		 */
+		_handleDragStart: function ( e, ex, ey ) {
+			this._stopMScroll();
+
+			this._didDrag = false;
+			this._skip_dragging = false;
+			this._clipHeight = this._$clip.height();
+			var target = $( e.target ),
+				self = this,
+				$c = this._$clip,
+				svdir = this.options.direction;
+
+			/* should prevent the default behavior when click the button */
+			this._is_button = target.is( '.ui-btn' ) ||
+					target.is( '.ui-btn-text' ) ||
+					target.is( '.ui-btn-inner' ) ||
+					target.is( '.ui-btn-inner .ui-icon' );
+
+			/* should prevent the default behavior when click the slider */
+			if ( target.parents('.ui-slider').length || target.is('.ui-slider') ) {
+				this._skip_dragging = true;
+				return;
+			}
+
+			if ( target.is('textarea') ) {
+				target.bind( "scroll", function () {
+					self._skip_dragging = true;
+					target.unbind("scroll");
+				});
+			}
+
+			/*
+			 * We need to prevent the default behavior to
+			 * suppress accidental selection of text, etc.
+			 */
+			this._is_inputbox = target.is(':input') ||
+					target.parents(':input').length > 0;
+
+			if ( this._is_inputbox ) {
+				target.one( "resize.scrollview", function () {
+					if ( ey > $c.height() ) {
+						self.scrollTo( -ex, self._sy - ey + $c.height(),
+							self.options.snapbackDuration );
+					}
+				});
+			}
+
+			if ( this.options.eventType === "mouse" && !this._is_inputbox && !this._is_button ) {
+				e.preventDefault();
+			}
+
+			this._lastX = ex;
+			this._lastY = ey;
+			this._startY = ey;
+			this._doSnapBackX = false;
+			this._doSnapBackY = false;
+			this._speedX = 0;
+			this._speedY = 0;
+			this._directionLock = "";
+
+			this._lastMove = 0;
+			this._enableTracking();
+
+			this._set_scrollbar_size();
+		},
+
+		/**
+		 * Propagates dragging
+		 * @private
+		 * @param {jQuery} sv
+		 * @param {Event} e
+		 * @param {number} ex
+		 * @param {number} ey
+		 * @param {string} dir
+		 */
+		_propagateDragMove: function ( sv, e, ex, ey, dir ) {
+			this._hideScrollBars();
+			this._hideOverflowIndicator();
+			this._disableTracking();
+			sv._handleDragStart( e, ex, ey );
+			sv._directionLock = dir;
+			sv._didDrag = this._didDrag;
+		},
+
+		/**
+		 * Handles drag event
+		 * @private
+		 * @param {Event}
+		 * @param {number} ex
+		 * @param {number} ey
+		 * @return {boolean|undefined}
+		 */
+		_handleDragMove: function ( e, ex, ey ) {
+			this._moveInterval = ey;
+			if ( this._skip_dragging ) {
+				return;
+			}
+
+			if ( !this._dragging ) {
+				return;
+			}
+
+			if ( !this._is_inputbox && !this._is_button ) {
+				e.preventDefault();
+			}
+
+			var mt = this.options.moveThreshold,
+				dx = ex - this._lastX,
+				dy = ey - this._lastY,
+				svdir = this.options.direction,
+				dir = null,
+				x,
+				y,
+				sv,
+				scope,
+				newX,
+				newY,
+				dirLock;
+
+			this._lastMove = getCurrentTime();
+
+			if ( !this._directionLock ) {
+				x = Math.abs( dx );
+				y = Math.abs( dy );
+
+				if ( x < mt && y < mt ) {
+					return false;
+				}
+
+				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.
+					 */
+
+					sv = this._getAncestorByDirection( dir );
+					if ( sv ) {
+						this._propagateDragMove( sv, e, ex, ey, dir );
+						return false;
+					}
+				}
+
+				this._directionLock = svdir || (dir || "none");
+			}
+
+			newX = this._sx;
+			newY = this._sy;
+			dirLock = this._directionLock;
+
+			if ( dirLock !== "y" && this._hTracker ) {
+				x = this._sx;
+				this._speedX = dx;
+				newX = x + dx;
+
+				this._doSnapBackX = false;
+
+				scope = ( newX > 0 || newX < this._maxX );
+
+				if ( scope && dirLock === "x" ) {
+					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 ( dirLock !== "x" && this._vTracker ) {
+				if ( Math.abs( this._startY - ey ) < mt && dirLock !== "xy" && this._didDrag === false ) {
+					return;
+				}
+
+				y = this._sy;
+				this._speedY = dy;
+				newY = y + dy;
+
+				this._doSnapBackY = false;
+
+				scope = ( newY > 0 || newY < this._maxY );
+
+				if ( scope && dirLock === "y" ) {
+					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.overshootEnable === false ) {
+				this._doSnapBackX = false;
+				this._doSnapBackY = false;
+			}
+
+			this._lastX = ex;
+			this._lastY = ey;
+
+			this._setScrollPosition( newX, newY );
+
+			if ( this._didDrag === false ) {
+				this._didDrag = true;
+				this._showScrollBars();
+				this._showOverflowIndicator();
+
+				this._$clip.parents(".ui-scrollview-clip").each( function () {
+					$( this ).scrollview( "skipDragging", true );
+				} );
+			}
+		},
+
+		/**
+		 * Handles drag stop event, and returns drag status
+		 * @param {Event} e
+		 * @return {Boolean|undefined}
+		 */
+		_handleDragStop: function ( e ) {
+			var self = this;
+
+			if ( this._skip_dragging ) {
+				return;
+			}
+
+			var l = this._lastMove,
+				t = getCurrentTime(),
+				doScroll = (l && (t - l) <= this.options.moveIntervalThreshold),
+				sx = ( this._hTracker && this._speedX && doScroll ) ?
+						this._speedX : ( this._doSnapBackX ? 1 : 0 ),
+				sy = ( this._vTracker && this._speedY && doScroll ) ?
+						this._speedY : ( this._doSnapBackY ? 1 : 0 ),
+				svdir = this.options.direction,
+				x,
+				y;
+
+			if ( sx || sy ) {
+				if ( !this._setGestureScroll( sx, sy ) ) {
+					this._startMScroll( sx, sy );
+				}
+			} else {
+				this._hideScrollBars();
+				this._hideOverflowIndicator();
+			}
+
+			this._disableTracking();
+
+			if ( this._endEffect ) {
+				setTimeout( function () {
+					self._setEndEffect( "out" );
+					self._hideScrollBars();
+					self._hideOverflowIndicator();
+				}, 300 );
+			}
+
+			return !this._didDrag;
+		},
+
+		/**
+		 * Detects gestures and sets proper gesture direction
+		 * @private
+		 * @param {number} sx
+		 * @param {number} sy
+		 * @return {boolean}
+		 */
+		_setGestureScroll: function ( sx, sy ) {
+			var self = this,
+				reset = function () {
+					clearTimeout( self._gesture_timer );
+					self._gesture_dir = 0;
+					self._gesture_timer = undefined;
+				},
+				direction = {
+					top: 0,
+					bottom: 1,
+					left: 2,
+					right: 3
+				};
+
+			if ( !sy && !sx ) {
+				return false;
+			}
+
+			if ( Math.abs( sx ) > Math.abs( sy ) ) {
+				dir = sx > 0 ? direction.left : direction.right;
+			} else {
+				dir = sy > 0 ? direction.top : direction.bottom;
+			}
+
+			if ( !this._gesture_timer ) {
+				this._gesture_dir = dir;
+
+				this._gesture_timer = setTimeout( function () {
+					reset();
+				}, 1000 );
+
+				return false;
+			}
+
+			if ( this._gesture_dir !== dir ) {
+				reset();
+				return false;
+			}
+
+			return false;
+		},
+
+		/**
+		 * Enables dragging
+		 * @private
+		 */
+		_enableTracking: function () {
+			this._dragging = true;
+		},
+
+		/**
+		 * Disables dragging
+		 * @private
+		 */
+		_disableTracking: function () {
+			this._dragging = false;
+		},
+
+		/**
+		 * Shows scrollbars
+		 * When interval is specified, the scrollbars will be
+		 * hidden after the specified time in miliseconds
+		 * @private
+		 * @param {number} [interval]
+		 */
+		_showScrollBars: function ( interval ) {
+			var vclass = "ui-scrollbar-visible",
+				self = this;
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+			if ( this._scrollbar_showed ) {
+				return;
+			}
+
+			if ( this._$vScrollBar ) {
+				this._$vScrollBar.addClass( vclass );
+			}
+			if ( this._$hScrollBar ) {
+				this._$hScrollBar.addClass( vclass );
+			}
+
+			this._scrollbar_showed = true;
+
+			if ( interval ) {
+				setTimeout( function () {
+					self._hideScrollBars();
+				}, interval );
+			}
+		},
+
+		/**
+		 * Hides scrollbars
+		 * @private
+		 */
+		_hideScrollBars: function () {
+			var vclass = "ui-scrollbar-visible";
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+			if ( !this._scrollbar_showed ) {
+				return;
+			}
+
+			if ( this._$vScrollBar ) {
+				this._$vScrollBar.removeClass( vclass );
+			}
+			if ( this._$hScrollBar ) {
+				this._$hScrollBar.removeClass( vclass );
+			}
+
+			this._scrollbar_showed = false;
+		},
+
+		/**
+		 * Sets opacities for the oveflow indicator
+		 * according to specified direction. The direction
+		 * is optional. Specify 1 for top, 0 for bottom, and
+		 * a falsy value for both
+		 * @private
+		 * @param {number} [dir] 0
+		 */
+		_setOverflowIndicator: function ( dir ) {
+			if ( dir === 1 ) {
+				this._display_indicator_top = "none";
+				this._display_indicator_bottom = "block";
+			} else if ( dir === 0 ) {
+				this._display_indicator_top = "block";
+				this._display_indicator_bottom = "none";
+			} else {
+				this._display_indicator_top = "block";
+				this._display_indicator_bottom = "block";
+			}
+		},
+
+		/**
+		 * Display overflow indicator
+		 * @private
+		 */
+		_showOverflowIndicator: function () {
+			if ( !$( this.element ).is( ".ui-content" ) ) {
+				return true;
+			}
+
+			if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
+				return;
+			}
+
+			this._overflow_top.css( "display", this._display_indicator_top );
+			this._overflow_bottom.css( "display", this._display_indicator_bottom );
+
+			this._overflow_showed = true;
+		},
+
+		/**
+		 * Hide overflow indicator
+		 * @private
+		 */
+		_hideOverflowIndicator: function () {
+			if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
+				return;
+			}
+
+			if ( this._overflow_showed === false ) {
+				return;
+			}
+
+			this._overflow_top.css( "display", "none" );
+			this._overflow_bottom.css( "display", "none" );
+
+			this._overflow_showed = false;
+			this._setOverflowIndicator();
+		},
+
+		/**
+		 * Bind events
+		 * @private
+		 * @return {boolean|undefined}
+		 */
+		_add_event: function () {
+			var self = this,
+				$c = this._$clip,
+				$v = this._$view;
+
+			if ( this.options.eventType === "mouse" ) {
+				this._dragEvt = "mousedown mousemove mouseup click mousewheel";
+
+				this._dragCB = function ( e ) {
+					switch ( e.type ) {
+					case "mousedown":
+						return self._handleDragStart( e,
+								e.clientX, e.clientY );
+
+					case "mousemove":
+						return self._handleDragMove( e,
+								e.clientX, e.clientY );
+
+					case "mouseup":
+						return self._handleDragStop( e );
+
+					case "click":
+						return !self._didDrag;
+
+					case "mousewheel":
+						var old = self.getScrollPosition();
+						self.scrollTo( -old.x,
+							-(old.y - e.originalEvent.wheelDelta) );
+						break;
+					}
+				};
+			} else {
+				this._dragEvt = "touchstart touchmove touchend";
+				var _in_progress = false;
+				this._dragCB = function ( e ) {
+					var touches = e.originalEvent.touches;
+
+					switch ( e.type ) {
+					case "touchstart":
+						if ( touches.length != 1 || _in_progress ) {
+							return;
+						}
+
+						_in_progress = true;
+
+						return self._handleDragStart( e,
+								touches[0].pageX, touches[0].pageY );
+
+					case "touchmove":
+						if ( !_in_progress || touches.length != 1) {
+							return;
+						}
+
+						return self._handleDragMove( e,
+								touches[0].pageX, touches[0].pageY );
+
+					case "touchend":
+						if ( !_in_progress ) {
+							return;
+						}
+
+						_in_progress = false;
+
+						if ( touches.length != 0 ) {
+							return;
+						}
+
+						return self._handleDragStop( e );
+					}
+				};
+			};
+
+			$v.bind( this._dragEvt, this._dragCB );
+
+			// N_SE-35696 / N_SE-35800
+			var clipScrollDelta = 0,
+				clipScrollLast = 0;
+			$c.on( "scroll", function () {
+				var clipScrollTop = $c.scrollTop(),
+					currentPositon = self.getScrollPosition(),
+					inputs;
+
+				clipScrollDelta = clipScrollTop - clipScrollLast;
+				clipScrollLast = clipScrollTop;
+
+				if ( clipScrollDelta > 0 ) {
+					inputs = $v.find( ":input.ui-focus" );
+					$c.scrollTop( 0 );
+					if ( inputs.length ) {
+						// CHECK WHERE WE ARE IN THE INPUTS
+						clipScrollDelta = 0;
+					}
+					self.scrollTo( -currentPositon.x, -( currentPositon.y + clipScrollDelta ) );
+				}
+			} );
+
+			$v.bind( "keydown", function ( e ) {
+				var $focusedElement;
+
+				if ( e.keyCode == 9 ) {
+					return false;
+				}
+
+				$focusedElement = $c.find( ".ui-focus" );
+				if ( !$focusedElement.length ) {
+					return;
+				}
+				self.ensureElementIsVisible( $focusedElement );
+
+				return;
+			});
+
+			$v.bind( "keyup", function ( e ) {
+				var $input;
+
+				if ( e.keyCode !== 9 ) {
+					return;
+				}
+
+				/* Tab Key */
+				$input = $( this ).find( ":input.ui-focus" ).eq( 0 );
+				if ( !$input ) {
+					return;
+				}
+				self.ensureElementIsVisible( $input );
+				$input.focus();
+
+				return false;
+			});
+
+			$c.bind( "updatelayout", function ( e ) {
+				var sy,
+					vh,
+					view_h = self._getViewHeight();
+
+				if ( !$c.height() || !view_h ) {
+					self.scrollTo( 0, 0, 0 );
+					return;
+				}
+
+				sy = $c.height() - view_h;
+				vh = view_h - self._view_height;
+
+				self._view_height = view_h;
+
+				if ( vh == 0 || vh > $c.height() / 2 ) {
+					return;
+				}
+
+				if ( sy > 0 ) {
+					self.scrollTo( 0, 0, 0 );
+				} else if ( self._sy - sy <= -vh ) {
+					self.scrollTo( 0, self._sy,
+						self.options.snapbackDuration );
+				} else if ( self._sy - sy <= vh + self.options.moveThreshold ) {
+					self.scrollTo( 0, sy,
+						self.options.snapbackDuration );
+				}
+			});
+
+			$( window ).bind( "resize", function ( e ) {
+				var focused,
+					view_h = self._getViewHeight();
+
+				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
+					return;
+				}
+
+				if ( !$c.height() || !view_h ) {
+					return;
+				}
+
+				focused = $c.find(".ui-focus");
+
+				if ( focused ) {
+					focused.trigger("resize.scrollview");
+				}
+
+				/* calibration - after triggered throttledresize */
+				setTimeout( function () {
+					var view_w = $v.outerWidth(),
+						cw = $c.outerWidth(),
+						scroll_x,
+						scroll_y;
+					if ( self._sy < $c.height() - self._getViewHeight() ) {
+						scroll_y = $c.height() - self._getViewHeight();
+						scroll_x = 0;
+					}
+					if ( self._sx < cw - view_w ) {
+						scroll_x = cw - view_w;
+						scroll_y = scroll_y || 0;
+					}
+					if (scroll_x || scroll_y) {
+						self.scrollTo( scroll_x, scroll_y, self.options.overshootDuration );
+					}
+				}, 260 );
+
+				self._view_height = view_h;
+				self._clipHeight = self._$clip.height();
+			});
+
+			$( window ).bind( "vmouseout", function ( e ) {
+				var drag_stop = false;
+
+				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
+					return;
+				}
+
+				if ( !self._dragging ) {
+					return;
+				}
+
+				if ( e.pageX < 0 || e.pageX > $( window ).width() ) {
+					drag_stop = true;
+				}
+
+				if ( e.pageY < 0 || e.pageY > $( window ).height() ) {
+					drag_stop = true;
+				}
+
+				if ( drag_stop ) {
+					self._hideScrollBars();
+					self._hideOverflowIndicator();
+					self._disableTracking();
+				}
+			});
+
+			this._softkeyboard = false;
+			this._softkeyboardHeight = 0;
+
+			window.addEventListener( "softkeyboardchange", function ( e ) {
+				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
+					return;
+				}
+
+				self._softkeyboard = ( e.state === "on" ? true : false );
+				self._softkeyboardHeight = parseInt( e.height ) *
+						( $( window ).width() / window.screen.availWidth );
+			});
+
+			$c.closest(".ui-page")
+				.bind( "pageshow", function ( e ) {
+					self._view_height = self._$view.height();
+
+					/* should be called after pagelayout */
+					setTimeout( function () {
+						self._view_height = self._getViewHeight();
+						self._set_scrollbar_size();
+						self._setScrollPosition( self._sx, self._sy );
+						self._showScrollBars( 2000 );
+					}, 0 );
+				});
+
+			$c.closest(".ui-page").find( ".ui-popup" )
+				.bind( "popupafteropen", function ( e ) {
+					if ( !$( self.element ).parents().is( ".ui-ctxpopup" ) ) {
+						return true;
+					}
+
+                                        setTimeout( function () {
+                                                self._setScrollPosition( self._sx, self._sy );
+						self._showScrollBars( 2000 );
+                                        }, 0 );
+				});
+		},
+
+		/**
+		 * Adds scrollbar elements to DOM
+		 * @private
+		 */
+		_add_scrollbar: function () {
+			var $c = this._$clip,
+				prefix = "<div class=\"ui-scrollbar ui-scrollbar-",
+				suffix = "\"><div class=\"ui-scrollbar-track\"><div class=\"ui-scrollbar-thumb\"></div></div></div>";
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+
+			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");
+			}
+
+			this._scrollbar_showed = false;
+		},
+
+		/**
+		 * Adds scroll jump button to DOM
+		 * @private
+		 */
+		_add_scroll_jump: function () {
+			var $c = this._$clip,
+				self = this,
+				top_btn,
+				left_btn;
+
+			if ( !this.options.scrollJump ) {
+				return;
+			}
+
+			if ( this._vTracker ) {
+				top_btn = $( '<div class="ui-scroll-jump-top-bg">' +
+						'<div data-role="button" data-inline="true" data-icon="scrolltop" data-style="box"></div></div>' );
+				$c.append( top_btn ).trigger("create");
+
+				top_btn.bind( "vclick", function () {
+					self.scrollTo( 0, 0, self.options.overshootDuration );
+				} );
+			}
+
+			if ( this._hTracker ) {
+				left_btn = $( '<div class="ui-scroll-jump-left-bg">' +
+						'<div data-role="button" data-inline="true" data-icon="scrollleft" data-style="box"></div></div>' );
+				$c.append( left_btn ).trigger("create");
+
+				left_btn.bind( "vclick", function () {
+					self.scrollTo( 0, 0, self.options.overshootDuration );
+				} );
+			}
+		},
+
+		/**
+		 * Adds overflow indicator to DOM
+		 * @private
+		 */
+		_add_overflow_indicator: function () {
+			if ( !this.options.overflowEnable ) {
+				return;
+			}
+
+			this._overflow_top = $( '<div class="ui-overflow-indicator-top"></div>' );
+			this._overflow_bottom = $( '<div class="ui-overflow-indicator-bottom"></div>' );
+
+			this._$clip.append( this._overflow_top );
+			this._$clip.append( this._overflow_bottom );
+
+			this._display_indicator_top = "block";
+			this._display_indicator_bottom = "block";
+			this._overflow_showed = false;
+		},
+
+		/**
+		 * Sets the size of the scrollbars
+		 * @private
+		 */
+		_set_scrollbar_size: function () {
+			var $c = this._$clip,
+				$v = this._$view,
+				cw = 0,
+				vw = 0,
+				ch = 0,
+				vh = 0,
+				thumb;
+
+			if ( !this.options.showScrollBars ) {
+				return;
+			}
+
+			if ( this._hTracker ) {
+				cw = $c.width();
+				vw = $v.width();
+				this._maxX = cw - vw;
+
+				if ( this._maxX > 0 ) {
+					this._maxX = 0;
+				}
+				if ( this._$hScrollBar && vw ) {
+					thumb = this._$hScrollBar.find(".ui-scrollbar-thumb");
+					thumb.css( "width", (cw >= vw ? "0" :
+							(Math.floor(cw / vw * 100) || 1) + "%") );
+				}
+			}
+
+			if ( this._vTracker ) {
+				ch = $c.height();
+				vh = this._getViewHeight();
+				this._maxY = ch - vh;
+
+				if ( this._maxY > 0 || vh === 0 ) {
+					this._maxY = 0;
+				}
+				if ( ( this._$vScrollBar && vh ) || vh === 0 ) {
+					thumb = this._$vScrollBar.find(".ui-scrollbar-thumb");
+					thumb.css( "height", (ch >= vh ? "0" :
+							(Math.floor(ch / vh * 100) || 1) + "%") );
+
+					this._overflowAvail = !!thumb.height();
+				}
+			}
+		}
+	});
+
+	/**
+	 * Momentum tracker
+	 */
+	$.extend( MomentumTracker.prototype, {
+		/**
+		 * Starts momentum callculations
+		 * @param {number} pos
+		 * @param {number} speed
+		 * @param {number} duration
+		 * @param {number} minPos
+		 * @param {number} maxPos
+		 */
+		start: function ( pos, speed, duration, minPos, maxPos ) {
+			var tstate = ( pos < minPos || pos > maxPos ) ?
+					tstates.snapback : tstates.scrolling,
+				pos_temp;
+
+			this.state = ( speed !== 0 ) ? tstate : 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;
+			pos_temp = ( this.pos < this.minPos ) ? this.minPos : this.maxPos;
+			this.toPos = ( this.state === tstates.snapback ) ? pos_temp : 0;
+
+			this.startTime = getCurrentTime();
+		},
+
+		/**
+		 * Resets momentum tracker calculations and sets
+		 * state to done
+		 */
+		reset: function () {
+			this.state = tstates.done;
+			this.pos = 0;
+			this.speed = 0;
+			this.minPos = 0;
+			this.maxPos = 0;
+			this.duration = 0;
+			this.remained = 0;
+		},
+
+		/**
+		 * Recalculate momentum tracker estimates
+		 * @param {boolean} overshootEnable
+		 * @return {number} position
+		 */
+		update: function ( overshootEnable ) {
+			var state = this.state,
+				cur_time = getCurrentTime(),
+				duration = this.duration,
+				elapsed =  cur_time - this.startTime,
+				dx,
+				x,
+				didOverShoot;
+
+			if ( state === tstates.done ) {
+				return this.pos;
+			}
+
+			elapsed = elapsed > duration ? duration : elapsed;
+
+			this.remained = duration - elapsed;
+
+			if ( state === tstates.scrolling || state === tstates.overshot ) {
+				dx = this.speed *
+					( 1 - $.easing[this.easing]( elapsed / duration,
+								elapsed, 0, 1, duration ) );
+
+				x = this.pos + dx;
+
+				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 ( !overshootEnable ) {
+						this.state = tstates.done;
+					}
+					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 = cur_time;
+						elapsed = 0;
+					}
+				} else if ( state === tstates.scrolling ) {
+					if ( didOverShoot && overshootEnable ) {
+						this.state = tstates.overshot;
+						this.speed = dx / 2;
+						this.duration = this.options.overshootDuration;
+						this.startTime = cur_time;
+					} 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;
+		},
+
+		/**
+		 * Checks if momentum state is done
+		 * @return {boolean}
+		 */
+		done: function () {
+			return this.state === tstates.done;
+		},
+
+		/**
+		 * Checks if the position is minimal
+		 * @return {boolean}
+		 */
+		isMin: function () {
+			return this.pos === this.minPos;
+		},
+
+		/**
+		 * Checks if the position is maximal
+		 * @return {boolean}
+		 */
+		isMax: function () {
+			return this.pos === this.maxPos;
+		},
+
+		/**
+		 * Check if momentum tracking is available
+		 * @return {boolean}
+		 */
+		isAvail: function () {
+			return !( this.minPos === this.maxPos );
+		},
+
+		/**
+		 * Returns remaining time
+		 * @return {number}
+		 */
+		getRemained: function () {
+			return this.remained;
+		},
+
+		/**
+		 * Returns current position
+		 * @return {number}
+		 */
+		getPosition: function () {
+			return this.pos;
+		}
+	});
+
+	$( document ).bind( 'pagecreate create', function ( e ) {
+		var $page = $( e.target ),
+			content_scroll = $page.find(".ui-content").jqmData("scroll");
+
+		/* content scroll */
+		if ( $.support.scrollview === undefined ) {
+			$.support.scrollview = true;
+		}
+
+		if ( $.support.scrollview === true && content_scroll === undefined ) {
+			content_scroll = "y";
+		}
+
+		if ( content_scroll !== "y" ) {
+			content_scroll = "none";
+		}
+
+		$page.find(".ui-content").attr( "data-scroll", content_scroll );
+
+		$page.find(":jqmData(scroll)").not(".ui-scrollview-clip").each( function () {
+			if ( $( this ).hasClass("ui-scrolllistview") ) {
+				$( this ).scrolllistview();
+			} else {
+				var st = $( this ).jqmData("scroll"),
+					dir = st && ( st.search(/^[xy]/) !== -1 ) ? st : null,
+					content = $(this).hasClass("ui-content"),
+					opts;
+
+				if ( st === "none" ) {
+					return;
+				}
+
+				opts = {
+					direction: dir || undefined,
+					overflowEnable: content,
+					scrollMethod: $( this ).jqmData("scroll-method") || undefined,
+					scrollJump: $( this ).jqmData("scroll-jump") || undefined
+				};
+
+				$( this ).scrollview( opts );
+			}
+		});
+	});
+
+	$( document ).bind( 'pageshow', function ( e ) {
+		var $page = $( e.target ),
+			scroll = $page.find(".ui-content").jqmData("scroll");
+
+		if ( scroll === "y" ) {
+			resizePageContentHeight( e.target );
+		}
+	});
+
+}( jQuery, window, document ) );
+
+//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
+} );
+//>>excludeEnd("jqmBuildExclude");


Mime
View raw message