1ec7d70fe22b016c04ac7ff716a767d26ae864f2
[platform/framework/web/web-ui-fw.git] / src / widgets / common / js / jquery.mobile.tizen.scrollview.js
1 /*
2 * jQuery Mobile Framework : scrollview plugin
3 * Copyright (c) 2010 Adobe Systems Incorporated - Kin Blas (jblas@adobe.com)
4 * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
5 * Note: Code is in draft form and is subject to change
6 * Modified by Koeun Choi <koeun.choi@samsung.com>
7 * Modified by Minkyu Kang <mk7.kang@samsung.com>
8 */
9
10 (function ( $, window, document, undefined ) {
11
12         function resizePageContentHeight( page ) {
13                 var $page = $( page ),
14                         $content = $page.children(".ui-content"),
15                         hh = $page.children(".ui-header").outerHeight() || 0,
16                         fh = $page.children(".ui-footer").outerHeight() || 0,
17                         pt = parseFloat( $content.css("padding-top") ),
18                         pb = parseFloat( $content.css("padding-bottom") ),
19                         wh = $( window ).height();
20
21                 $content.height( wh - (hh + fh) - (pt + pb) );
22         }
23
24         function MomentumTracker( options ) {
25                 this.options = $.extend( {}, options );
26                 this.easing = "easeOutQuad";
27                 this.reset();
28         }
29
30         var tstates = {
31                 scrolling: 0,
32                 overshot:  1,
33                 snapback:  2,
34                 done:      3
35         };
36
37         function getCurrentTime() {
38                 return Date.now();
39         }
40
41         jQuery.widget( "tizen.scrollview", jQuery.mobile.widget, {
42                 options: {
43                         direction:         null,  // "x", "y", or null for both.
44
45                         timerInterval:     10,
46                         scrollDuration:    1000,  // Duration of the scrolling animation in msecs.
47                         overshootDuration: 250,   // Duration of the overshoot animation in msecs.
48                         snapbackDuration:  500,   // Duration of the snapback animation in msecs.
49
50                         moveThreshold:     30,   // User must move this many pixels in any direction to trigger a scroll.
51                         moveIntervalThreshold:     150,   // Time between mousemoves must not exceed this threshold.
52
53                         scrollMethod:      "translate",  // "translate", "position"
54                         startEventName:    "scrollstart",
55                         updateEventName:   "scrollupdate",
56                         stopEventName:     "scrollstop",
57
58                         eventType:         $.support.touch ? "touch" : "mouse",
59
60                         showScrollBars:    true,
61                         overshootEnable:   false,
62                         outerScrollEnable: true,
63                         overflowEnable:    true,
64                         scrollJump:        false,
65                 },
66
67                 _getViewHeight: function () {
68                         return this._$view.height() + this._view_offset;
69                 },
70
71                 _makePositioned: function ( $ele ) {
72                         if ( $ele.css("position") === "static" ) {
73                                 $ele.css( "position", "relative" );
74                         }
75                 },
76
77                 _create: function () {
78                         var direction,
79                                 self = this;
80
81                         this._$clip = $( this.element ).addClass("ui-scrollview-clip");
82
83                         if ( this._$clip.children(".ui-scrollview-view").length ) {
84                                 this._$view = this._$clip.children(".ui-scrollview-view");
85                         } else {
86                                 this._$view = this._$clip.wrapInner("<div></div>").children()
87                                                         .addClass("ui-scrollview-view");
88                         }
89
90                         if ( this.options.scrollMethod === "translate" ) {
91                                 if ( this._$view.css("transform") === undefined ) {
92                                         this.options.scrollMethod = "position";
93                                 }
94                         }
95
96                         this._$clip.css( "overflow", "hidden" );
97                         this._makePositioned( this._$clip );
98
99                         this._makePositioned( this._$view );
100                         this._$view.css( { left: 0, top: 0 } );
101
102                         this._view_offset = this._$view.offset().top - this._$clip.offset().top;
103                         this._view_height = this._getViewHeight();
104
105                         this._sx = 0;
106                         this._sy = 0;
107
108                         direction = this.options.direction;
109
110                         this._hTracker = ( direction !== "y" ) ?
111                                         new MomentumTracker( this.options ) : null;
112                         this._vTracker = ( direction !== "x" ) ?
113                                         new MomentumTracker( this.options ) : null;
114
115                         this._timerInterval = this.options.timerInterval;
116                         this._timerID = 0;
117
118                         this._timerCB = function () {
119                                 self._handleMomentumScroll();
120                         };
121
122                         this._add_event();
123                         this._add_scrollbar();
124                         this._add_scroll_jump();
125                         this._add_overflow_indicator();
126                 },
127
128                 _startMScroll: function ( speedX, speedY ) {
129                         var keepGoing = false,
130                                 duration = this.options.scrollDuration,
131                                 ht = this._hTracker,
132                                 vt = this._vTracker,
133                                 c,
134                                 v;
135
136                         this._stopMScroll();
137                         this._showScrollBars();
138                         this._showOverflowIndicator();
139
140                         this._$clip.trigger( this.options.startEventName );
141
142                         if ( ht ) {
143                                 c = this._$clip.width();
144                                 v = this._$view.width();
145
146                                 if ( (( this._sx === 0 && speedX > 0 ) ||
147                                         ( this._sx === -(v - c) && speedX < 0 )) &&
148                                                 v > c ) {
149                                         return;
150                                 }
151
152                                 ht.start( this._sx, speedX,
153                                         duration, (v > c) ? -(v - c) : 0, 0 );
154                                 keepGoing = !ht.done();
155                         }
156
157                         if ( vt ) {
158                                 c = this._$clip.height();
159                                 v = this._getViewHeight();
160
161                                 if ( (( this._sy === 0 && speedY > 0 ) ||
162                                         ( this._sy === -(v - c) && speedY < 0 )) &&
163                                                 v > c ) {
164                                         return;
165                                 }
166
167                                 vt.start( this._sy, speedY,
168                                         duration, (v > c) ? -(v - c) : 0, 0 );
169                                 keepGoing = keepGoing || !vt.done();
170                         }
171
172                         if ( keepGoing ) {
173                                 this._timerID = setTimeout( this._timerCB, this._timerInterval );
174                         } else {
175                                 this._stopMScroll();
176                         }
177                 },
178
179                 _stopMScroll: function () {
180                         if ( this._timerID ) {
181                                 this._$clip.trigger( this.options.stopEventName );
182                                 clearTimeout( this._timerID );
183                         }
184                         this._timerID = 0;
185
186                         if ( this._vTracker ) {
187                                 this._vTracker.reset();
188                         }
189
190                         if ( this._hTracker ) {
191                                 this._hTracker.reset();
192                         }
193
194                         this._hideScrollBars();
195                         this._hideOverflowIndicator();
196                 },
197
198                 _handleMomentumScroll: function () {
199                         var keepGoing = false,
200                                 x = 0,
201                                 y = 0,
202                                 scroll_height = 0,
203                                 self = this,
204                                 bouncing = function ( dir ) {
205                                         setTimeout( function () {
206                                                 self._bouncing_dir = dir;
207                                                 self._setBouncing( self._$view, "in" );
208                                         }, 100 );
209
210                                         setTimeout( function () {
211                                                 self._setBouncing( self._$view, "out" );
212                                         }, 350 );
213                                 },
214                                 vt = this._vTracker,
215                                 ht = this._hTracker;
216
217                         if ( this._outerScrolling ) {
218                                 return;
219                         }
220
221                         if ( vt ) {
222                                 vt.update( this.options.overshootEnable );
223                                 y = vt.getPosition();
224                                 keepGoing = !vt.done();
225
226                                 if ( vt.getRemained() > this.options.overshootDuration ) {
227                                         scroll_height = this._getViewHeight() - this._$clip.height();
228
229                                         if ( !vt.isAvail() ) {
230                                                 if ( this._speedY > 0 ) {
231                                                         this._outerScroll( vt.getRemained() / 3, scroll_height );
232                                                 } else {
233                                                         this._outerScroll( y - vt.getRemained() / 3, scroll_height );
234                                                 }
235                                         } else if ( vt.isMin() ) {
236                                                 this._outerScroll( y - vt.getRemained() / 3, scroll_height );
237
238                                                 if ( scroll_height > 0 ) {
239                                                         bouncing( 1 );
240                                                 }
241                                         } else if ( vt.isMax() ) {
242                                                 this._outerScroll( vt.getRemained() / 3, scroll_height );
243
244                                                 if ( scroll_height > 0 ) {
245                                                         bouncing( 0 );
246                                                 }
247                                         }
248                                 }
249                         }
250
251                         if ( ht ) {
252                                 ht.update( this.options.overshootEnable );
253                                 x = ht.getPosition();
254                                 keepGoing = keepGoing || !ht.done();
255                         }
256
257                         this._setScrollPosition( x, y );
258                         this._$clip.trigger( this.options.updateEventName,
259                                         [ { x: x, y: y } ] );
260
261                         if ( keepGoing ) {
262                                 this._timerID = setTimeout( this._timerCB, this._timerInterval );
263                         } else {
264                                 this._stopMScroll();
265                         }
266                 },
267
268                 _setElementTransform: function ( $ele, x, y, duration ) {
269                         var translate,
270                                 transition;
271
272                         if ( this._bouncing ) {
273                                 return;
274                         }
275
276                         if ( !duration || duration === undefined ) {
277                                 transition = "none";
278                         } else {
279                                 transition =  "-webkit-transform " + duration / 1000 + "s ease-out";
280                         }
281
282                         if ( $.support.cssTransform3d ) {
283                                 translate = "translate3d(" + x + "," + y + ", 0px)";
284                         } else {
285                                 translate = "translate(" + x + "," + y + ")";
286                         }
287
288                         $ele.css({
289                                 "-moz-transform": translate,
290                                 "-webkit-transform": translate,
291                                 "-ms-transform": translate,
292                                 "-o-transform": translate,
293                                 "transform": translate,
294                                 "-webkit-transition": transition
295                         });
296                 },
297
298                 _setBouncing: function ( $ele, dir ) {
299                         var scroll_height = this._getViewHeight() - this._$clip.height();
300
301                         if ( this._softkeyboard ) {
302                                 if ( this._bouncing_dir ) {
303                                         this._outerScroll( -scroll_height - this._softkeyboardHeight,
304                                                         scroll_height );
305                                 } else {
306                                         this._outerScroll( this._softkeyboardHeight, scroll_height );
307                                 }
308                                 return;
309                         }
310
311                         if ( dir === "in" ) {
312                                 if ( this._bouncing ) {
313                                         return;
314                                 }
315
316                                 this._bouncing = true;
317                                 this._bouncing_count = 1;
318
319                                 this._bouncing_org_x = 1;
320                                 this._bouncing_org_y = 1;
321
322                                 this._bouncing_x = 0.99;
323                                 this._bouncing_y = 0.99;
324
325                                 this._setOverflowIndicator( this._bouncing_dir );
326                         } else if ( dir === "out" ) {
327                                 if ( !this._bouncing ) {
328                                         return;
329                                 }
330
331                                 this._bouncing = false;
332                                 this._bouncing_count = 1;
333
334                                 this._bouncing_org_x = this._bouncing_x;
335                                 this._bouncing_org_y = this._bouncing_y;
336
337                                 this._bouncing_x = 1;
338                                 this._bouncing_y = 1;
339                                 this._setOverflowIndicator( this._bouncing_dir );
340                         } else {
341                                 return;
342                         }
343
344                         this._doBouncing( $ele, dir );
345                 },
346
347                 _doBouncing: function ( $ele, dir ) {
348                         var translate,
349                                 origin,
350                                 x_rate,
351                                 y_rate,
352                                 frame = 10,
353                                 self = this;
354
355                         if ( $.support.cssTransform3d ) {
356                                 translate = "translate3d(" + this._sx + "px," + this._sy + "px, 0px)";
357                         } else {
358                                 translate = "translate(" + this._sx + "px," + this._sy + "px)";
359                         }
360
361                         if ( dir === "in" ) {
362                                 x_rate = this._bouncing_org_x - ( this._bouncing_org_x -
363                                                 this._bouncing_x ) / frame * this._bouncing_count;
364                                 y_rate = this._bouncing_org_y - ( this._bouncing_org_y -
365                                                 this._bouncing_y ) / frame * this._bouncing_count;
366
367                                 translate += " scale(" + x_rate + "," + y_rate + ")";
368                         } else if ( dir === "out" ) {
369                                 x_rate = this._bouncing_org_x + ( this._bouncing_x -
370                                                 this._bouncing_org_x ) / frame * this._bouncing_count;
371                                 y_rate = this._bouncing_org_y + ( this._bouncing_y -
372                                                 this._bouncing_org_y ) / frame * this._bouncing_count;
373
374                                 translate += " scale(" + x_rate + "," + y_rate + ")";
375                         } else {
376                                 return;
377                         }
378
379                         if ( this._bouncing_dir ) {
380                                 origin = "50% " + ( this._bouncing_y * 100 - 10 ) + "%";
381                         } else {
382                                 origin = "50% 10%";
383                         }
384
385                         $ele.css({
386                                 "-moz-transform": translate,
387                                 "-webkit-transform": translate,
388                                 "-ms-transform": translate,
389                                 "-o-transform": translate,
390                                 "transform": translate,
391                                 "-webkit-transform-origin": origin,
392                         });
393
394                         this._bouncing_count++;
395
396                         if ( this._bouncing_count > frame ) {
397                                 return;
398                         }
399
400                         setTimeout( function () {
401                                 self._doBouncing( $ele, dir );
402                         }, this._timerInterval );
403                 },
404
405                 _setCalibration: function ( x, y ) {
406                         if ( this.options.overshootEnable ) {
407                                 this._sx = x;
408                                 this._sy = y;
409                                 return;
410                         }
411
412                         var $v = this._$view,
413                                 $c = this._$clip,
414                                 dirLock = this._directionLock,
415                                 scroll_height = 0,
416                                 scroll_width = 0;
417
418                         if ( dirLock !== "y" && this._hTracker ) {
419                                 scroll_width = $v.width() - $c.width();
420
421                                 if ( x >= 0 ) {
422                                         this._sx = 0;
423                                 } else if ( x < -scroll_width ) {
424                                         this._sx = -scroll_width;
425                                 } else {
426                                         this._sx = x;
427                                 }
428
429                                 if ( scroll_width < 0 ) {
430                                         this._sx = 0;
431                                 }
432                         }
433
434                         if ( dirLock !== "x" && this._vTracker ) {
435                                 scroll_height = this._getViewHeight() - $c.height();
436
437                                 if ( y > 0 ) {
438                                         this._sy = 0;
439
440                                         if ( scroll_height > 0 ) {
441                                                 this._bouncing_dir = 0;
442                                                 this._setBouncing( this._$view, "in" );
443                                         }
444                                 } else if ( y < -scroll_height ) {
445                                         this._sy = -scroll_height;
446
447                                         if ( scroll_height > 0 ) {
448                                                 this._bouncing_dir = 1;
449                                                 this._setBouncing( this._$view, "in" );
450                                         }
451                                 } else {
452                                         if ( this._bouncing && this._sy !== y ) {
453                                                 this._bouncing = false;
454                                         }
455
456                                         this._sy = y;
457                                 }
458
459                                 if ( scroll_height < 0 ) {
460                                         this._sy = 0;
461                                 }
462                         }
463                 },
464
465                 _setScrollPosition: function ( x, y, duration ) {
466                         var $v = this._$view,
467                                 sm = this.options.scrollMethod,
468                                 $vsb = this._$vScrollBar,
469                                 $hsb = this._$hScrollBar,
470                                 $sbt;
471
472                         this._setCalibration( x, y );
473
474                         x = this._sx;
475                         y = this._sy;
476
477                         if ( sm === "translate" ) {
478                                 this._setElementTransform( $v, x + "px", y + "px", duration );
479                         } else {
480                                 $v.css( {left: x + "px", top: y + "px"} );
481                         }
482
483                         if ( $vsb ) {
484                                 $sbt = $vsb.find(".ui-scrollbar-thumb");
485
486                                 if ( sm === "translate" ) {
487                                         this._setElementTransform( $sbt, "0px",
488                                                 -y / this._getViewHeight() * $sbt.parent().height() + "px",
489                                                 duration );
490                                 } else {
491                                         $sbt.css( "top", -y / this._getViewHeight() * 100 + "%" );
492                                 }
493                         }
494
495                         if ( $hsb ) {
496                                 $sbt = $hsb.find(".ui-scrollbar-thumb");
497
498                                 if ( sm === "translate" ) {
499                                         this._setElementTransform( $sbt,
500                                                 -x / $v.width() * $sbt.parent().width() + "px", "0px",
501                                                 duration);
502                                 } else {
503                                         $sbt.css("left", -x / $v.width() * 100 + "%");
504                                 }
505                         }
506                 },
507
508                 _outerScroll: function ( y, scroll_height ) {
509                         var self = this,
510                                 top = $( window ).scrollTop() - window.screenTop,
511                                 sy = 0,
512                                 duration = this.options.snapbackDuration,
513                                 start = getCurrentTime(),
514                                 tfunc;
515
516                         if ( !this.options.outerScrollEnable ) {
517                                 return;
518                         }
519
520                         if ( this._$clip.jqmData("scroll") !== "y" ) {
521                                 return;
522                         }
523
524                         if ( this._outerScrolling ) {
525                                 return;
526                         }
527
528                         if ( y > 0 ) {
529                                 sy = ( window.screenTop ? window.screenTop : -y );
530                         } else if ( y < -scroll_height ) {
531                                 sy = -y - scroll_height;
532                         } else {
533                                 return;
534                         }
535
536                         tfunc = function () {
537                                 var elapsed = getCurrentTime() - start;
538
539                                 if ( elapsed >= duration ) {
540                                         window.scrollTo( 0, top + sy );
541                                         self._outerScrolling = undefined;
542
543                                         self._stopMScroll();
544                                 } else {
545                                         ec = $.easing.easeOutQuad( elapsed / duration,
546                                                         elapsed, 0, 1, duration );
547
548                                         window.scrollTo( 0, top + ( sy * ec ) );
549                                         self._outerScrolling = setTimeout( tfunc, self._timerInterval );
550                                 }
551                         };
552                         this._outerScrolling = setTimeout( tfunc, self._timerInterval );
553                 },
554
555                 _scrollTo: function ( x, y, duration ) {
556                         var self = this,
557                                 start = getCurrentTime(),
558                                 efunc = $.easing.easeOutQuad,
559                                 sx = this._sx,
560                                 sy = this._sy,
561                                 dx = x - sx,
562                                 dy = y - sy,
563                                 tfunc;
564
565                         x = -x;
566                         y = -y;
567
568                         tfunc = function () {
569                                 var elapsed = getCurrentTime() - start,
570                                     ec;
571
572                                 if ( elapsed >= duration ) {
573                                         self._timerID = 0;
574                                         self._setScrollPosition( x, y );
575                                 } else {
576                                         ec = efunc( elapsed / duration, elapsed, 0, 1, duration );
577
578                                         self._setScrollPosition( sx + ( dx * ec ), sy + ( dy * ec ) );
579                                         self._timerID = setTimeout( tfunc, self._timerInterval );
580                                 }
581                         };
582
583                         this._timerID = setTimeout( tfunc, this._timerInterval );
584                 },
585
586                 scrollTo: function ( x, y, duration ) {
587                         this._stopMScroll();
588
589                         if ( !duration || this.options.scrollMethod === "translate" ) {
590                                 this._setScrollPosition( x, y, duration );
591                         } else {
592                                 this._scrollTo( x, y, duration );
593                         }
594                 },
595
596                 getScrollPosition: function () {
597                         return { x: -this._sx, y: -this._sy };
598                 },
599
600                 _getScrollHierarchy: function () {
601                         var svh = [],
602                                 d;
603
604                         this._$clip.parents( ".ui-scrollview-clip").each( function () {
605                                 d = $( this ).jqmData("scrollview");
606                                 if ( d ) {
607                                         svh.unshift( d );
608                                 }
609                         } );
610                         return svh;
611                 },
612
613                 _getAncestorByDirection: function ( dir ) {
614                         var svh = this._getScrollHierarchy(),
615                                 n = svh.length,
616                                 sv,
617                                 svdir;
618
619                         while ( 0 < n-- ) {
620                                 sv = svh[n];
621                                 svdir = sv.options.direction;
622
623                                 if (!svdir || svdir === dir) {
624                                         return sv;
625                                 }
626                         }
627                         return null;
628                 },
629
630                 _handleDragStart: function ( e, ex, ey ) {
631                         this._stopMScroll();
632
633                         this._didDrag = false;
634                         this._skip_dragging = false;
635
636                         var target = $( e.target ),
637                                 self = this,
638                                 $c = this._$clip,
639                                 svdir = this.options.direction;
640
641                         /* should prevent the default behavior when click the button */
642                         this._is_button = target.is( '.ui-btn-text' ) ||
643                                         target.is( '.ui-btn-inner' ) ||
644                                         target.is( '.ui-btn-inner .ui-icon' );
645
646                         if ( this._is_button ) {
647                                 if ( target.parents('.ui-slider-handle').length ) {
648                                         this._skip_dragging = true;
649                                         return;
650                                 }
651                         }
652
653                         /*
654                          * We need to prevent the default behavior to
655                          * suppress accidental selection of text, etc.
656                          */
657                         this._is_inputbox = target.is(':input') ||
658                                         target.parents(':input').length > 0;
659
660                         if ( this._is_inputbox ) {
661                                 target.one( "resize.scrollview", function () {
662                                         if ( ey > $c.height() ) {
663                                                 self.scrollTo( -ex, self._sy - ey + $c.height(),
664                                                         self.options.snapbackDuration );
665                                         }
666                                 });
667                         }
668
669                         if ( this.options.eventType === "mouse" && !this._is_inputbox && !this._is_button ) {
670                                 e.preventDefault();
671                         }
672
673                         this._lastX = ex;
674                         this._lastY = ey;
675                         this._startY = ey;
676                         this._doSnapBackX = false;
677                         this._doSnapBackY = false;
678                         this._speedX = 0;
679                         this._speedY = 0;
680                         this._directionLock = "";
681
682                         this._lastMove = 0;
683                         this._enableTracking();
684
685                         this._set_scrollbar_size();
686                 },
687
688                 _propagateDragMove: function ( sv, e, ex, ey, dir ) {
689                         this._hideScrollBars();
690                         this._hideOverflowIndicator();
691                         this._disableTracking();
692                         sv._handleDragStart( e, ex, ey );
693                         sv._directionLock = dir;
694                         sv._didDrag = this._didDrag;
695                 },
696
697                 _handleDragMove: function ( e, ex, ey ) {
698                         if ( this._skip_dragging ) {
699                                 return;
700                         }
701
702                         if ( !this._dragging ) {
703                                 return;
704                         }
705
706                         if ( !this._is_inputbox && !this._is_button ) {
707                                 e.preventDefault();
708                         }
709
710                         var mt = this.options.moveThreshold,
711                                 dx = ex - this._lastX,
712                                 dy = ey - this._lastY,
713                                 svdir = this.options.direction,
714                                 dir = null,
715                                 x,
716                                 y,
717                                 sv,
718                                 scope,
719                                 newX,
720                                 newY,
721                                 dirLock;
722
723                         this._lastMove = getCurrentTime();
724
725                         if ( !this._directionLock ) {
726                                 x = Math.abs( dx );
727                                 y = Math.abs( dy );
728
729                                 if ( x < mt && y < mt ) {
730                                         return false;
731                                 }
732
733                                 if ( x < y && (x / y) < 0.5 ) {
734                                         dir = "y";
735                                 } else if ( x > y && (y / x) < 0.5 ) {
736                                         dir = "x";
737                                 }
738
739                                 if ( svdir && dir && svdir !== dir ) {
740                                         /*
741                                          * This scrollview can't handle the direction the user
742                                          * is attempting to scroll. Find an ancestor scrollview
743                                          * that can handle the request.
744                                          */
745
746                                         sv = this._getAncestorByDirection( dir );
747                                         if ( sv ) {
748                                                 this._propagateDragMove( sv, e, ex, ey, dir );
749                                                 return false;
750                                         }
751                                 }
752
753                                 this._directionLock = svdir || (dir || "none");
754                         }
755
756                         newX = this._sx;
757                         newY = this._sy;
758                         dirLock = this._directionLock;
759
760                         if ( dirLock !== "y" && this._hTracker ) {
761                                 x = this._sx;
762                                 this._speedX = dx;
763                                 newX = x + dx;
764
765                                 this._doSnapBackX = false;
766
767                                 scope = ( newX > 0 || newX < this._maxX );
768
769                                 if ( scope && dirLock === "x" ) {
770                                         sv = this._getAncestorByDirection("x");
771                                         if ( sv ) {
772                                                 this._setScrollPosition( newX > 0 ?
773                                                                 0 : this._maxX, newY );
774                                                 this._propagateDragMove( sv, e, ex, ey, dir );
775                                                 return false;
776                                         }
777
778                                         newX = x + ( dx / 2 );
779                                         this._doSnapBackX = true;
780                                 }
781                         }
782
783                         if ( dirLock !== "x" && this._vTracker ) {
784                                 if ( Math.abs( this._startY - ey ) < mt && dirLock !== "xy" ) {
785                                         return;
786                                 }
787
788                                 y = this._sy;
789                                 this._speedY = dy;
790                                 newY = y + dy;
791
792                                 this._doSnapBackY = false;
793
794                                 scope = ( newY > 0 || newY < this._maxY );
795
796                                 if ( scope && dirLock === "y" ) {
797                                         sv = this._getAncestorByDirection("y");
798                                         if ( sv ) {
799                                                 this._setScrollPosition( newX,
800                                                                 newY > 0 ? 0 : this._maxY );
801                                                 this._propagateDragMove( sv, e, ex, ey, dir );
802                                                 return false;
803                                         }
804
805                                         newY = y + ( dy / 2 );
806                                         this._doSnapBackY = true;
807                                 }
808                         }
809
810                         if ( this.options.overshootEnable === false ) {
811                                 this._doSnapBackX = false;
812                                 this._doSnapBackY = false;
813                         }
814
815                         this._didDrag = true;
816                         this._lastX = ex;
817                         this._lastY = ey;
818
819                         this._setScrollPosition( newX, newY );
820
821                         this._showScrollBars();
822                         this._showOverflowIndicator();
823                 },
824
825                 _handleDragStop: function ( e ) {
826                         if ( this._skip_dragging ) {
827                                 return;
828                         }
829
830                         var l = this._lastMove,
831                                 t = getCurrentTime(),
832                                 doScroll = (l && (t - l) <= this.options.moveIntervalThreshold),
833                                 sx = ( this._hTracker && this._speedX && doScroll ) ?
834                                                 this._speedX : ( this._doSnapBackX ? 1 : 0 ),
835                                 sy = ( this._vTracker && this._speedY && doScroll ) ?
836                                                 this._speedY : ( this._doSnapBackY ? 1 : 0 ),
837                                 svdir = this.options.direction,
838                                 x,
839                                 y;
840
841                         if ( sx || sy ) {
842                                 if ( !this._setGestureScroll( sx, sy ) ) {
843                                         this._startMScroll( sx, sy );
844                                 }
845                         } else {
846                                 this._hideScrollBars();
847                                 this._hideOverflowIndicator();
848                         }
849
850                         this._disableTracking();
851
852                         if ( this._bouncing ) {
853                                 this._setBouncing( this._$view, "out" );
854                                 this._hideScrollBars();
855                                 this._hideOverflowIndicator();
856                         }
857
858                         return !this._didDrag;
859                 },
860
861                 _setGestureScroll: function ( sx, sy ) {
862                         var self = this,
863                                 reset = function () {
864                                         clearTimeout( self._gesture_timer );
865                                         self._gesture_dir = 0;
866                                         self._gesture_count = 0;
867                                         self._gesture_timer = undefined;
868                                 };
869
870                         if ( !sy ) {
871                                 return false;
872                         }
873
874                         dir = sy > 0 ? 1 : -1;
875
876                         if ( !this._gesture_timer ) {
877                                 this._gesture_count = 1;
878                                 this._gesture_dir = dir;
879
880                                 this._gesture_timer = setTimeout( function () {
881                                         reset();
882                                 }, 1000 );
883
884                                 return false;
885                         }
886
887                         if ( this._gesture_dir !== dir ) {
888                                 reset();
889                                 return false;
890                         }
891
892                         this._gesture_count++;
893
894                         if ( this._gesture_count === 3 ) {
895                                 if ( dir > 0 ) {
896                                         this.scrollTo( 0, 0, this.options.overshootDuration );
897                                 } else {
898                                         this.scrollTo( 0, -( this._getViewHeight() - this._$clip.height() ),
899                                                         this.options.overshootDuration );
900                                 }
901                                 reset();
902
903                                 return true;
904                         }
905
906                         return false;
907                 },
908
909                 _enableTracking: function () {
910                         this._dragging = true;
911                 },
912
913                 _disableTracking: function () {
914                         this._dragging = false;
915                 },
916
917                 _showScrollBars: function ( interval ) {
918                         var vclass = "ui-scrollbar-visible",
919                                 self = this;
920
921                         if ( !this.options.showScrollBars ) {
922                                 return;
923                         }
924                         if ( this._scrollbar_showed ) {
925                                 return;
926                         }
927
928                         if ( this._$vScrollBar ) {
929                                 this._$vScrollBar.addClass( vclass );
930                         }
931                         if ( this._$hScrollBar ) {
932                                 this._$hScrollBar.addClass( vclass );
933                         }
934
935                         this._scrollbar_showed = true;
936
937                         if ( interval ) {
938                                 setTimeout( function () {
939                                         self._hideScrollBars();
940                                 }, interval );
941                         }
942                 },
943
944                 _hideScrollBars: function () {
945                         var vclass = "ui-scrollbar-visible";
946
947                         if ( !this.options.showScrollBars ) {
948                                 return;
949                         }
950                         if ( !this._scrollbar_showed ) {
951                                 return;
952                         }
953
954                         if ( this._$vScrollBar ) {
955                                 this._$vScrollBar.removeClass( vclass );
956                         }
957                         if ( this._$hScrollBar ) {
958                                 this._$hScrollBar.removeClass( vclass );
959                         }
960
961                         this._scrollbar_showed = false;
962                 },
963
964                 _resetOverflowIndicator: function () {
965                         if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
966                                 return;
967                         }
968
969                         this._overflow_top.css( "-webkit-animation", "" );
970                         this._overflow_bottom.css( "-webkit-animation", "" );
971                 },
972
973                 _setOverflowIndicator: function ( dir ) {
974                         if ( dir === 1 ) {
975                                 this._opacity_top = "0.2";
976                                 this._opacity_bottom = "0.8";
977                         } else if ( dir === 0 ) {
978                                 this._opacity_top = "0.8";
979                                 this._opacity_bottom = "0.2";
980                         } else {
981                                 this._opacity_top = "0.5";
982                                 this._opacity_bottom = "0.5";
983                         }
984                 },
985
986                 _getOverflowIndicator: function ( opacity ) {
987                         if ( opacity === "0.2" ) {
988                                 return "-lite";
989                         } else if ( opacity === "0.8" ) {
990                                 return "-dark";
991                         }
992                         return "";
993                 },
994
995                 _showOverflowIndicator: function () {
996                         if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
997                                 return;
998                         }
999
1000                         this._overflow_top.css( "opacity", this._opacity_top );
1001                         this._overflow_bottom.css( "opacity", this._opacity_bottom );
1002
1003                         if ( this._overflow_showed === true ) {
1004                                 return;
1005                         }
1006
1007                         this._overflow_top.css( "-webkit-animation", "ui-overflow-show" +
1008                                         this._getOverflowIndicator( this._opacity_top ) + " 0.3s 1 ease" );
1009                         this._overflow_bottom.css( "-webkit-animation", "ui-overflow-show" +
1010                                         this._getOverflowIndicator( this._opacity_bottom ) + " 0.3s 1 ease" );
1011
1012                         this._overflow_showed = true;
1013                 },
1014
1015                 _hideOverflowIndicator: function () {
1016                         var opacity_top,
1017                                 opacity_bottom;
1018
1019                         if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
1020                                 return;
1021                         }
1022
1023                         if ( this._overflow_showed === false ) {
1024                                 return;
1025                         }
1026
1027                         opacity_top = this._overflow_top.css( "opacity" );
1028                         opacity_bottom = this._overflow_bottom.css( "opacity" );
1029
1030                         this._overflow_top.css( "opacity", "0" );
1031                         this._overflow_bottom.css( "opacity", "0" );
1032
1033                         this._overflow_top.css( "-webkit-animation", "ui-overflow-hide" +
1034                                         this._getOverflowIndicator( opacity_top ) + " 0.5s 1 ease" );
1035                         this._overflow_bottom.css( "-webkit-animation", "ui-overflow-hide" +
1036                                         this._getOverflowIndicator( opacity_bottom ) + " 0.5s 1 ease" );
1037
1038                         this._overflow_showed = false;
1039                         this._setOverflowIndicator();
1040                 },
1041
1042                 _add_event: function () {
1043                         var self = this,
1044                                 $c = this._$clip,
1045                                 $v = this._$view;
1046
1047                         if ( this.options.eventType === "mouse" ) {
1048                                 this._dragEvt = "mousedown mousemove mouseup click mousewheel";
1049
1050                                 this._dragCB = function ( e ) {
1051                                         switch ( e.type ) {
1052                                         case "mousedown":
1053                                                 return self._handleDragStart( e,
1054                                                                 e.clientX, e.clientY );
1055
1056                                         case "mousemove":
1057                                                 return self._handleDragMove( e,
1058                                                                 e.clientX, e.clientY );
1059
1060                                         case "mouseup":
1061                                                 return self._handleDragStop( e );
1062
1063                                         case "click":
1064                                                 return !self._didDrag;
1065
1066                                         case "mousewheel":
1067                                                 var old = self.getScrollPosition();
1068                                                 self.scrollTo( -old.x,
1069                                                         -(old.y - e.originalEvent.wheelDelta) );
1070                                                 break;
1071                                         }
1072                                 };
1073                         } else {
1074                                 this._dragEvt = "touchstart touchmove touchend click";
1075
1076                                 this._dragCB = function ( e ) {
1077                                         var t;
1078
1079                                         switch ( e.type ) {
1080                                         case "touchstart":
1081                                                 t = e.originalEvent.targetTouches[0];
1082                                                 return self._handleDragStart( e,
1083                                                                 t.pageX, t.pageY );
1084
1085                                         case "touchmove":
1086                                                 t = e.originalEvent.targetTouches[0];
1087                                                 return self._handleDragMove( e,
1088                                                                 t.pageX, t.pageY );
1089
1090                                         case "touchend":
1091                                                 return self._handleDragStop( e );
1092
1093                                         case "click":
1094                                                 return !self._didDrag;
1095                                         }
1096                                 };
1097                         }
1098
1099                         $v.bind( this._dragEvt, this._dragCB );
1100
1101                         $c.bind( "updatelayout", function ( e ) {
1102                                 var sy,
1103                                         vh,
1104                                         view_h = self._getViewHeight();
1105
1106                                 if ( !$c.height() || !view_h ) {
1107                                         self.scrollTo( 0, 0, 0 );
1108                                         return;
1109                                 }
1110
1111                                 sy = $c.height() - view_h;
1112                                 vh = view_h - self._view_height;
1113
1114                                 self._view_height = view_h;
1115
1116                                 if ( vh == 0 || vh > $c.height() / 2 ) {
1117                                         return;
1118                                 }
1119
1120                                 if ( self._sy - sy <= -vh ) {
1121                                         self.scrollTo( 0, sy,
1122                                                 self.options.snapbackDuration );
1123                                 } else if ( self._sy - sy <= vh + self.options.moveThreshold ) {
1124                                         self.scrollTo( 0, sy,
1125                                                 self.options.snapbackDuration );
1126                                 }
1127                         });
1128
1129                         $( window ).bind( "resize", function ( e ) {
1130                                 var focused,
1131                                         view_h = self._getViewHeight();
1132
1133                                 if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
1134                                         return;
1135                                 }
1136
1137                                 if ( !$c.height() || !view_h ) {
1138                                         return;
1139                                 }
1140
1141                                 focused = $c.find(".ui-focus");
1142
1143                                 if ( focused ) {
1144                                         focused.trigger("resize.scrollview");
1145                                 }
1146
1147                                 /* calibration - after triggered throttledresize */
1148                                 setTimeout( function () {
1149                                         if ( self._sy < $c.height() - self._getViewHeight() ) {
1150                                                 self.scrollTo( 0, $c.height() - self._getViewHeight(),
1151                                                         self.options.overshootDuration );
1152                                         }
1153                                 }, 260 );
1154
1155                                 self._view_height = view_h;
1156                         });
1157
1158                         $( window ).bind( "vmouseout", function ( e ) {
1159                                 var drag_stop = false;
1160
1161                                 if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
1162                                         return;
1163                                 }
1164
1165                                 if ( !self._dragging ) {
1166                                         return;
1167                                 }
1168
1169                                 if ( e.pageX < 0 || e.pageX > $( window ).width() ) {
1170                                         drag_stop = true;
1171                                 }
1172
1173                                 if ( e.pageY < 0 || e.pageY > $( window ).height() ) {
1174                                         drag_stop = true;
1175                                 }
1176
1177                                 if ( drag_stop ) {
1178                                         self._hideScrollBars();
1179                                         self._hideOverflowIndicator();
1180                                         self._disableTracking();
1181                                 }
1182                         });
1183
1184                         this._softkeyboard = false;
1185                         this._softkeyboardHeight = 0;
1186
1187                         window.addEventListener( "softkeyboardchange", function ( e ) {
1188                                 if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
1189                                         return;
1190                                 }
1191
1192                                 self._softkeyboard = ( e.state === "on" ? true : false );
1193                                 self._softkeyboardHeight = e.height;
1194                         });
1195
1196                         $c.closest(".ui-page")
1197                                 .one( "pageshow", function ( e ) {
1198                                         self._view_offset = self._$view.offset().top - self._$clip.offset().top;
1199                                         self._view_height = self._getViewHeight();
1200                                 })
1201                                 .bind( "pageshow", function ( e ) {
1202                                         /* should be called after pagelayout */
1203                                         setTimeout( function () {
1204                                                 self._set_scrollbar_size();
1205                                                 self._setScrollPosition( self._sx, self._sy );
1206                                                 self._showScrollBars( 2000 );
1207                                                 self._resetOverflowIndicator();
1208                                         }, 0 );
1209                                 });
1210                 },
1211
1212                 _add_scrollbar: function () {
1213                         var $c = this._$clip,
1214                                 prefix = "<div class=\"ui-scrollbar ui-scrollbar-",
1215                                 suffix = "\"><div class=\"ui-scrollbar-track\"><div class=\"ui-scrollbar-thumb\"></div></div></div>";
1216
1217                         if ( !this.options.showScrollBars ) {
1218                                 return;
1219                         }
1220
1221                         if ( this._vTracker ) {
1222                                 $c.append( prefix + "y" + suffix );
1223                                 this._$vScrollBar = $c.children(".ui-scrollbar-y");
1224                         }
1225                         if ( this._hTracker ) {
1226                                 $c.append( prefix + "x" + suffix );
1227                                 this._$hScrollBar = $c.children(".ui-scrollbar-x");
1228                         }
1229
1230                         this._scrollbar_showed = false;
1231                 },
1232
1233                 _add_scroll_jump: function () {
1234                         var $c = this._$clip,
1235                                 self = this,
1236                                 top_btn,
1237                                 left_btn;
1238
1239                         if ( !this.options.scrollJump ) {
1240                                 return;
1241                         }
1242
1243                         if ( this._vTracker ) {
1244                                 top_btn = $( '<div class="ui-scroll-jump-top-bg">' +
1245                                                 '<div data-role="button" data-inline="true" data-icon="jumptop" style="width:37px;height:37px">.</div></div>' );
1246                                 $c.append( top_btn ).trigger("create");
1247
1248                                 top_btn.bind( "vclick", function () {
1249                                         self.scrollTo( 0, 0, self.options.overshootDuration );
1250                                 } );
1251                         }
1252
1253                         if ( this._hTracker ) {
1254                                 left_btn = $( '<div class="ui-scroll-jump-left-bg">' +
1255                                                 '<div data-role="button" data-inline="true" data-icon="jumpleft" style="width:37px;height:37px">.</div></div>' );
1256                                 $c.append( left_btn ).trigger("create");
1257
1258                                 left_btn.bind( "vclick", function () {
1259                                         self.scrollTo( 0, 0, self.options.overshootDuration );
1260                                 } );
1261                         }
1262                 },
1263
1264                 _add_overflow_indicator: function () {
1265                         if ( !this.options.overflowEnable ) {
1266                                 return;
1267                         }
1268
1269                         this._overflow_top = $( '<div class="ui-overflow-indicator-top"></div>' );
1270                         this._overflow_bottom = $( '<div class="ui-overflow-indicator-bottom"></div>' );
1271
1272                         this._$clip.append( this._overflow_top );
1273                         this._$clip.append( this._overflow_bottom );
1274
1275                         this._opacity_top = "0.5";
1276                         this._opacity_bottom = "0.5";
1277                         this._overflow_showed = false;
1278                 },
1279
1280                 _set_scrollbar_size: function () {
1281                         var $c = this._$clip,
1282                                 $v = this._$view,
1283                                 cw = 0,
1284                                 vw = 0,
1285                                 ch = 0,
1286                                 vh = 0,
1287                                 thumb;
1288
1289                         if ( !this.options.showScrollBars ) {
1290                                 return;
1291                         }
1292
1293                         if ( this._hTracker ) {
1294                                 cw = $c.width();
1295                                 vw = $v.width();
1296                                 this._maxX = cw - vw;
1297
1298                                 if ( this._maxX > 0 ) {
1299                                         this._maxX = 0;
1300                                 }
1301                                 if ( this._$hScrollBar && vw ) {
1302                                         thumb = this._$hScrollBar.find(".ui-scrollbar-thumb");
1303                                         thumb.css( "width", (cw >= vw ? "0" :
1304                                                         (Math.floor(cw / vw * 100) || 1) + "%") );
1305                                 }
1306                         }
1307
1308                         if ( this._vTracker ) {
1309                                 ch = $c.height();
1310                                 vh = this._getViewHeight();
1311                                 this._maxY = ch - vh;
1312
1313                                 if ( this._maxY > 0 ) {
1314                                         this._maxY = 0;
1315                                 }
1316                                 if ( this._$vScrollBar && vh ) {
1317                                         thumb = this._$vScrollBar.find(".ui-scrollbar-thumb");
1318                                         thumb.css( "height", (ch >= vh ? "0" :
1319                                                         (Math.floor(ch / vh * 100) || 1) + "%") );
1320
1321                                         this._overflowAvail = !!thumb.height();
1322                                 }
1323                         }
1324                 }
1325         });
1326
1327         $.extend( MomentumTracker.prototype, {
1328                 start: function ( pos, speed, duration, minPos, maxPos ) {
1329                         var tstate = ( pos < minPos || pos > maxPos ) ?
1330                                         tstates.snapback : tstates.scrolling,
1331                                 pos_temp;
1332
1333                         this.state = ( speed !== 0 ) ? tstate : tstates.done;
1334                         this.pos = pos;
1335                         this.speed = speed;
1336                         this.duration = ( this.state === tstates.snapback ) ?
1337                                         this.options.snapbackDuration : duration;
1338                         this.minPos = minPos;
1339                         this.maxPos = maxPos;
1340
1341                         this.fromPos = ( this.state === tstates.snapback ) ? this.pos : 0;
1342                         pos_temp = ( this.pos < this.minPos ) ? this.minPos : this.maxPos;
1343                         this.toPos = ( this.state === tstates.snapback ) ? pos_temp : 0;
1344
1345                         this.startTime = getCurrentTime();
1346                 },
1347
1348                 reset: function () {
1349                         this.state = tstates.done;
1350                         this.pos = 0;
1351                         this.speed = 0;
1352                         this.minPos = 0;
1353                         this.maxPos = 0;
1354                         this.duration = 0;
1355                         this.remained = 0;
1356                 },
1357
1358                 update: function ( overshootEnable ) {
1359                         var state = this.state,
1360                                 cur_time = getCurrentTime(),
1361                                 duration = this.duration,
1362                                 elapsed =  cur_time - this.startTime,
1363                                 dx,
1364                                 x,
1365                                 didOverShoot;
1366
1367                         if ( state === tstates.done ) {
1368                                 return this.pos;
1369                         }
1370
1371                         elapsed = elapsed > duration ? duration : elapsed;
1372
1373                         this.remained = duration - elapsed;
1374
1375                         if ( state === tstates.scrolling || state === tstates.overshot ) {
1376                                 dx = this.speed *
1377                                         ( 1 - $.easing[this.easing]( elapsed / duration,
1378                                                                 elapsed, 0, 1, duration ) );
1379
1380                                 x = this.pos + dx;
1381
1382                                 didOverShoot = ( state === tstates.scrolling ) &&
1383                                         ( x < this.minPos || x > this.maxPos );
1384
1385                                 if ( didOverShoot ) {
1386                                         x = ( x < this.minPos ) ? this.minPos : this.maxPos;
1387                                 }
1388
1389                                 this.pos = x;
1390
1391                                 if ( state === tstates.overshot ) {
1392                                         if ( !overshootEnable ) {
1393                                                 this.state = tstates.done;
1394                                         }
1395                                         if ( elapsed >= duration ) {
1396                                                 this.state = tstates.snapback;
1397                                                 this.fromPos = this.pos;
1398                                                 this.toPos = ( x < this.minPos ) ?
1399                                                                 this.minPos : this.maxPos;
1400                                                 this.duration = this.options.snapbackDuration;
1401                                                 this.startTime = cur_time;
1402                                                 elapsed = 0;
1403                                         }
1404                                 } else if ( state === tstates.scrolling ) {
1405                                         if ( didOverShoot && overshootEnable ) {
1406                                                 this.state = tstates.overshot;
1407                                                 this.speed = dx / 2;
1408                                                 this.duration = this.options.overshootDuration;
1409                                                 this.startTime = cur_time;
1410                                         } else if ( elapsed >= duration ) {
1411                                                 this.state = tstates.done;
1412                                         }
1413                                 }
1414                         } else if ( state === tstates.snapback ) {
1415                                 if ( elapsed >= duration ) {
1416                                         this.pos = this.toPos;
1417                                         this.state = tstates.done;
1418                                 } else {
1419                                         this.pos = this.fromPos + (( this.toPos - this.fromPos ) *
1420                                                 $.easing[this.easing]( elapsed / duration,
1421                                                         elapsed, 0, 1, duration ));
1422                                 }
1423                         }
1424
1425                         return this.pos;
1426                 },
1427
1428                 done: function () {
1429                         return this.state === tstates.done;
1430                 },
1431
1432                 isMin: function () {
1433                         return this.pos === this.minPos;
1434                 },
1435
1436                 isMax: function () {
1437                         return this.pos === this.maxPos;
1438                 },
1439
1440                 isAvail: function () {
1441                         return !( this.minPos === this.maxPos );
1442                 },
1443
1444                 getRemained: function () {
1445                         return this.remained;
1446                 },
1447
1448                 getPosition: function () {
1449                         return this.pos;
1450                 }
1451         });
1452
1453         $( document ).bind( 'pagecreate create', function ( e ) {
1454                 var $page = $( e.target ),
1455                         content_scroll = $page.find(".ui-content").jqmData("scroll");
1456
1457                 /* content scroll */
1458                 if ( $.support.scrollview === undefined ) {
1459                         $.support.scrollview = true;
1460                 }
1461
1462                 if ( $.support.scrollview === true && content_scroll === undefined ) {
1463                         content_scroll = "y";
1464                 }
1465
1466                 if ( content_scroll !== "y" ) {
1467                         content_scroll = "none";
1468                 }
1469
1470                 $page.find(".ui-content").attr( "data-scroll", content_scroll );
1471
1472                 $page.find(":jqmData(scroll):not(.ui-scrollview-clip)").each( function () {
1473                         if ( $( this ).hasClass("ui-scrolllistview") ) {
1474                                 $( this ).scrolllistview();
1475                         } else {
1476                                 var st = $( this ).jqmData("scroll"),
1477                                         dir = st && ( st.search(/^[xy]/) !== -1 ) ? st : null,
1478                                         content = $(this).hasClass("ui-content"),
1479                                         opts;
1480
1481                                 if ( st === "none" ) {
1482                                         return;
1483                                 }
1484
1485                                 opts = {
1486                                         direction: dir || undefined,
1487                                         overflowEnable: content,
1488                                         scrollMethod: $( this ).jqmData("scroll-method") || undefined,
1489                                         scrollJump: $( this ).jqmData("scroll-jump") || undefined
1490                                 };
1491
1492                                 $( this ).scrollview( opts );
1493                         }
1494                 });
1495         });
1496
1497         $( document ).bind( 'pageshow', function ( e ) {
1498                 var $page = $( e.target ),
1499                         scroll = $page.find(".ui-content").jqmData("scroll");
1500
1501                 if ( scroll === "y" ) {
1502                         resizePageContentHeight( e.target );
1503                 }
1504         });
1505
1506 }( jQuery, window, document ) );