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