Merge branch 'master' into tizen_2.1
[platform/framework/web/web-ui-fw.git] / src / js / widgets / jquery.mobile.tizen.fastscroll.js
1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Shows list index and scroll to the index directly
3 //>>label: Fastscroll
4 //>>group: Tizen:Widgets
5
6 define( [ '../jquery.mobile.tizen.scrollview' ], function ( ) {
7 //>>excludeEnd("jqmBuildExclude");
8
9 /*
10  * jQuery Mobile Widget @VERSION
11  *
12  * This software is licensed under the MIT licence (as defined by the OSI at
13  * http://www.opensource.org/licenses/mit-license.php)
14  *
15  * ***************************************************************************
16  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
17  * Copyright (c) 2011 by Intel Corporation Ltd.
18  *
19  * Permission is hereby granted, free of charge, to any person obtaining a
20  * copy of this software and associated documentation files (the "Software"),
21  * to deal in the Software without restriction, including without limitation
22  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
23  * and/or sell copies of the Software, and to permit persons to whom the
24  * Software is furnished to do so, subject to the following conditions:
25  *
26  * The above copyright notice and this permission notice shall be included in
27  * all copies or substantial portions of the Software.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35  * DEALINGS IN THE SOFTWARE.
36  * ***************************************************************************
37  *
38  * Authors: Elliot Smith <elliot.smith@intel.com>
39  *               Yonghwi Park <yonghwi0324.park@samsung.com>
40  */
41
42 // fastscroll is a scrollview controller, which binds
43 // a scrollview to a a list of short cuts; the shortcuts are built
44 // from the text on dividers in the list. Clicking on a shortcut
45 // instantaneously jumps the scrollview to the selected list divider;
46 // mouse movements on the shortcut column move the scrollview to the
47 // list divider matching the text currently under the touch; a popup
48 // with the text currently under the touch is also displayed.
49 //
50 // To apply, add the attribute data-fastscroll="true" to a listview
51 // (a <ul> or <ol> element inside a page). Alternatively, call
52 // fastscroll() on an element.
53 //
54 // The closest element with class ui-scrollview-clip is used as the
55 // scrollview to be controlled.
56 //
57 // If a listview has no dividers or a single divider, the widget won't
58 // display.
59
60 /**
61         @class fastscroll
62         The shortcut scroll widget shows a shortcut list that is bound to its parent scroll bar and respective list view. This widget is displayed as a text pop-up representing shortcuts to different list dividers in the list view. If you select a shortcut text from the shortcut scroll, the parent list view is moved to the location representing the selected shortcut.
63
64         To add a shortcut scroll widget to the application, use the following code:
65
66                 <div class="content" data-role="content" data-scroll="y">
67                         <ul id="contacts" data-role="listview" data-fastscroll="true">
68                                 <li>Anton</li>
69                         </ul>
70                 </div>
71
72         For the shortcut scroll widget to be visible, the parent list view must have multiple list dividers.
73 */
74
75 /**
76         @property {Boolean}  data-fastscroll
77         When set to true, creates a shortcut scroll using the HTML unordered list (&lt;ul&gt;) element.
78 */
79 /**
80         @method fastscroll
81         The shortcut scroll is created for the closest list view with the ui-scrollview-clip class.
82 */
83 /**
84         @method indexString
85         The indexString method is used to get (if no value is defined) or set the string to present the index.
86
87                 <div class="content" data-role="content" data-scroll="y">
88                         ul id="contacts" data-role="listview" data-fastscroll="true">
89                                 <li data-role="list-divider">A</li>
90                                 <li>Anton</li>
91                         </ul>
92                 </div>
93
94                 $(".selector").fastscroll( "indexString" [, indexAlphabet] );
95 */
96 (function ( $, undefined ) {
97
98         $.widget( "tizen.fastscroll", $.mobile.widget, {
99                 options: {
100                         initSelector: ":jqmData(fastscroll)"
101                 },
102
103                 _primaryLanguage: null,
104                 _secondLanguage: null,
105                 _dividerMap: {},
106                 _defaultTime: 500,
107                 _defaultDuration: 500,
108                 _timer: null,
109                 _isFadeOut: false,
110
111                 _create: function () {
112                         var $el = this.element,
113                                 self = this,
114                                 $popup,
115                                 page = $el.closest( ':jqmData(role="page")' ),
116                                 jumpToDivider;
117
118                         this.scrollview = $el.addClass( 'ui-fastscroll-target' ).closest( '.ui-scrollview-clip' );
119                         this.shortcutsContainer = $( '<div class="ui-fastscroll" aria-label="Fast scroll bar, double tap to fast scroll mode" tabindex="0"/>' );
120                         this.shortcutsList = $( '<ul aria-hidden="true"></ul>' );
121
122                         // popup for the hovering character
123                         this.scrollview.append($( '<div class="ui-fastscroll-popup"></div>' ) );
124                         $popup = this.scrollview.find( '.ui-fastscroll-popup' );
125
126                         this.shortcutsContainer.append( this.shortcutsList );
127                         this.scrollview.append( this.shortcutsContainer );
128
129                         // find the bottom of the last item in the listview
130                         this.lastListItem = $el.children().last();
131
132                         // remove scrollbars from scrollview
133                         this.scrollview.find( '.ui-scrollbar' ).hide();
134
135                         this.jumpToDivider = function ( divider ) {
136                                 // get the vertical position of the divider (so we can scroll to it)
137                                 var dividerY = $( divider ).position().top,
138                                         // find the bottom of the last list item
139                                         bottomOffset = self.lastListItem.outerHeight( true ) + self.lastListItem.position().top,
140                                         scrollviewHeight = self.scrollview.height(),
141
142                                 // check that after the candidate scroll, the bottom of the
143                                 // last item will still be at the bottom of the scroll view
144                                 // and not some way up the page
145                                         maxScroll = bottomOffset - scrollviewHeight,
146                                         dstOffset;
147
148                                 dividerY = ( dividerY > maxScroll ? maxScroll : dividerY );
149
150                                 // don't apply a negative scroll, as this means the
151                                 // divider should already be visible
152                                 dividerY = Math.max( dividerY, 0 );
153
154                                 // apply the scroll
155                                 self.scrollview.scrollview( 'scrollTo', 0, -dividerY );
156
157                                 dstOffset = self.scrollview.offset();
158                         };
159
160                         this.shortcutsList
161                         // bind mouse over so it moves the scroller to the divider
162                                 .bind( 'touchstart mousedown vmousedown touchmove vmousemove vmouseover', function ( e ) {
163                                         // Get coords relative to the element
164                                         var coords = $.mobile.tizen.targetRelativeCoordsFromEvent( e ),
165                                                 shortcutsListOffset = self.shortcutsList.offset();
166
167                                         if ( self._isFadeOut === true ) {
168                                                 return;
169                                         }
170
171                                         // If the element is a list item, get coordinates relative to the shortcuts list
172                                         if ( e.target.tagName.toLowerCase() === "li" ) {
173                                                 coords.x += $( e.target ).offset().left - shortcutsListOffset.left;
174                                                 coords.y += $( e.target ).offset().top  - shortcutsListOffset.top;
175                                         }
176
177                                         if ( e.target.tagName.toLowerCase() === "span" ) {
178                                                 coords.x += $( e.target ).parent().offset().left - shortcutsListOffset.left;
179                                                 coords.y += $( e.target ).parent().offset().top  - shortcutsListOffset.top;
180                                         }
181
182                                         self.shortcutsList.find( 'li' ).each( function () {
183                                                 var listItem = $( this );
184                                                 $( listItem )
185                                                         .removeClass( "ui-fastscroll-hover" )
186                                                         .removeClass( "ui-fastscroll-hover-down" );
187                                         });
188                                         // Hit test each list item
189                                         self.shortcutsList.find( 'li' ).each( function () {
190                                                 var listItem = $( this ),
191                                                         l = listItem.offset().left - shortcutsListOffset.left,
192                                                         t = listItem.offset().top  - shortcutsListOffset.top,
193                                                         r = l + Math.abs(listItem.outerWidth( true ) ),
194                                                         b = t + Math.abs(listItem.outerHeight( true ) ),
195                                                         unit,
196                                                         baseTop,
197                                                         baseBottom,
198                                                         omitSet,
199                                                         i;
200
201                                                 if ( coords.x >= l && coords.x <= r && coords.y >= t && coords.y <= b ) {
202                                                         if ( listItem.text() !== "." ) {
203                                                                 self._hitItem( listItem );
204                                                         } else {
205                                                                 omitSet = listItem.data( "omitSet" );
206                                                                 unit = ( b - t ) / omitSet.length;
207                                                                 for ( i = 0; i < omitSet.length; i++ ) {
208                                                                         baseTop = t + ( i * unit );
209                                                                         baseBottom = baseTop + unit;
210                                                                         if ( coords.y >= baseTop && coords.y <= baseBottom ) {
211                                                                                 self._hitOmitItem( listItem, omitSet.charAt( i ) );
212                                                                         }
213                                                                 }
214                                                         }
215                                                         return false;
216                                                 }
217                                                 return true;
218                                         } );
219
220                                         self._setTimer( false );
221
222                                         e.preventDefault();
223                                         e.stopPropagation();
224                                 } )
225                                 // bind mouseout of the fastscroll container to remove popup
226                                 .bind( 'touchend mouseup vmouseup vmouseout', function () {
227                                         $popup.hide();
228                                         $( ".ui-fastscroll-hover" ).removeClass( "ui-fastscroll-hover" );
229                                         $( ".ui-fastscroll-hover-first-item" ).removeClass( "ui-fastscroll-hover-first-item" );
230                                         $( ".ui-fastscroll-hover-down" ).removeClass( "ui-fastscroll-hover-down" );
231                                         self._setTimer( true );
232                                 } );
233
234                         if ( page && !( page.is( ':visible' ) ) ) {
235                                 page.bind( 'pageshow', function () { self.refresh(); } );
236                         } else {
237                                 self.refresh();
238                         }
239
240                         // refresh the list when dividers are filtered out
241                         $el.bind( 'updatelayout', function () {
242                                 self.refresh();
243                         } );
244
245                         self.scrollview.bind( "scrollstart", function ( e ) {
246                                 self._setTimer( false );
247                         }).bind( "scrollstop", function ( e ) {
248                                 self._setTimer( true );
249                         });
250                 },
251
252                 _hitOmitItem: function ( listItem, text ) {
253                         var self = this,
254                                 $popup = self.scrollview.find( '.ui-fastscroll-popup' ),
255                                 divider = self._dividerMap[ text ];
256
257                         if ( typeof divider !== "undefined" ) {
258                                 self.jumpToDivider( $( divider ) );
259                         }
260
261                         $popup.text( text )
262                                 .css( { marginLeft: -( $popup.outerWidth() / 2 ),
263                                         marginTop: -( $popup.outerHeight() / 2 ),
264                                         padding: $popup.css( "paddingTop" ) } )
265                                 .width( $popup.height() )
266                                 .show();
267
268                         $( listItem ).addClass( "ui-fastscroll-hover" );
269                         if ( listItem.index() === 0 ) {
270                                 $( listItem ).addClass( "ui-fastscroll-hover-first-item" );
271                         }
272                         $( listItem ).siblings().eq( listItem.index() ).addClass( "ui-fastscroll-hover-down" );
273                 },
274
275                 _hitItem: function ( listItem  ) {
276                         var self = this,
277                                 $popup = self.scrollview.find( '.ui-fastscroll-popup' ),
278                                 text = listItem.text(),
279                                 divider;
280
281                         if ( text === "#" ) {
282                                 divider = self._dividerMap.number;
283                         } else {
284                                 divider = self._dividerMap[ text ];
285                         }
286
287                         if ( typeof divider !== "undefined" ) {
288                                 self.jumpToDivider( $( divider ) );
289                         }
290
291                         $popup.text( text )
292                                 .css( { marginLeft: -( $popup.outerWidth() / 2 ),
293                                         marginTop: -( $popup.outerHeight() / 2 ),
294                                         padding: $popup.css( "paddingTop" ) } )
295                                 .width( $popup.height() )
296                                 .show();
297
298                         $( listItem ).addClass( "ui-fastscroll-hover" );
299                         if ( listItem.index() === 0 ) {
300                                 $( listItem ).addClass( "ui-fastscroll-hover-first-item" );
301                         }
302                         $( listItem ).siblings().eq( listItem.index() ).addClass( "ui-fastscroll-hover-down" );
303                 },
304
305                 _focusItem: function ( listItem ) {
306                         var self = this,
307                                 $popup = self.scrollview.find( '.ui-fastscroll-popup' );
308
309                         listItem.focusin( function ( e ) {
310                                 self.shortcutsList.attr( "aria-hidden", false );
311                                 self._hitItem( listItem );
312                                 self._setTimer( false );
313                         }).focusout( function ( e ) {
314                                 self.shortcutsList.attr( "aria-hidden", true );
315                                 $popup.hide();
316                                 $( ".ui-fastscroll-hover" ).removeClass( "ui-fastscroll-hover" );
317                                 $( ".ui-fastscroll-hover-first-item" ).removeClass( "ui-fastscroll-hover-first-item" );
318                                 $( ".ui-fastscroll-hover-down" ).removeClass( "ui-fastscroll-hover-down" );
319                                 self._setTimer( true );
320                         });
321                 },
322
323                 _contentHeight: function () {
324                         var self = this,
325                                 $content = $( '.ui-scrollview-clip' ),
326                                 header = null,
327                                 footer = null,
328                                 paddingValue = 0,
329                                 clipSize = $( window ).height();
330
331                         if ( $content.hasClass( "ui-content" ) ) {
332                                 paddingValue = parseInt( $content.css( "padding-top" ), 10 );
333                                 clipSize = clipSize - ( paddingValue || 0 );
334                                 paddingValue = parseInt( $content.css( "padding-bottom" ), 10 );
335                                 clipSize = clipSize - ( paddingValue || 0 );
336                                 header = $content.siblings( ".ui-header:visible" );
337                                 footer = $content.siblings( ".ui-footer:visible" );
338
339                                 if ( header ) {
340                                         if ( header.outerHeight( true ) === null ) {
341                                                 clipSize = clipSize - ( $( ".ui-header" ).outerHeight() || 0 );
342                                         } else {
343                                                 clipSize = clipSize - header.outerHeight( true );
344                                         }
345                                 }
346                                 if ( footer ) {
347                                         clipSize = clipSize - footer.outerHeight( true );
348                                 }
349                         } else {
350                                 clipSize = $content.height();
351                         }
352                         return clipSize;
353                 },
354
355                 _omit: function ( numOfItems, maxNumOfItems ) {
356                         var maxGroupNum = parseInt( ( maxNumOfItems - 1 ) / 2, 10 ),
357                                 numOfExtraItems = numOfItems - maxNumOfItems,
358                                 groupPos = [],
359                                 omitInfo = [],
360                                 groupPosLength,
361                                 group,
362                                 size,
363                                 i;
364
365                         if ( ( maxNumOfItems < 3 ) || ( numOfItems <= maxNumOfItems ) ) {
366                                 return;
367                         }
368
369                         if ( numOfExtraItems >= maxGroupNum ) {
370                                 size = 2;
371                                 group = 1;
372                                 groupPosLength = maxGroupNum;
373                         } else {
374                                 size = maxNumOfItems / ( numOfExtraItems + 1 );
375                                 group = size;
376                                 groupPosLength = numOfExtraItems;
377                         }
378
379                         for ( i = 0; i < groupPosLength; i++ ) {
380                                 groupPos.push( parseInt( group, 10 ) );
381                                 group += size;
382                         }
383
384                         for ( i = 0; i < maxNumOfItems; i++ ) {
385                                 omitInfo.push( 1 );
386                         }
387
388                         for ( i = 0; i < numOfExtraItems; i++ ) {
389                                 omitInfo[ groupPos[ i % maxGroupNum ] ]++;
390                         }
391
392                         return omitInfo;
393                 },
394
395                 _createDividerMap: function () {
396                         var self = this,
397                                 primaryCharacterSet = self._primaryLanguage ? self._primaryLanguage.replace( /,/g, "" ) : null,
398                                 secondCharacterSet = self._secondLanguage ? self._secondLanguage.replace( /,/g, "" ) : null,
399                                 numberSet = "0123456789",
400                                 dividers = self.element.find( '.ui-li-divider' ),
401                                 map = {},
402                                 matchToDivider,
403                                 makeCharacterSet,
404                                 indexChar,
405                                 i;
406
407                         matchToDivider = function ( index, divider ) {
408                                 if ( $( divider ).text() === indexChar ) {
409                                         map[ indexChar ] = divider;
410                                 }
411                         };
412
413                         makeCharacterSet = function ( index, divider ) {
414                                 primaryCharacterSet += $( divider ).text();
415                         };
416
417                         if ( primaryCharacterSet === null ) {
418                                 primaryCharacterSet = "";
419                                 dividers.each( makeCharacterSet );
420                         }
421
422                         for ( i = 0; i < primaryCharacterSet.length; i++ ) {
423                                 indexChar = primaryCharacterSet.charAt( i );
424                                 dividers.each( matchToDivider );
425                         }
426
427                         if ( secondCharacterSet !== null ) {
428                                 for ( i = 0; i < secondCharacterSet.length; i++ ) {
429                                         indexChar = secondCharacterSet.charAt( i );
430                                         dividers.each( matchToDivider );
431                                 }
432                         }
433
434                         dividers.each( function ( index, divider ) {
435                                 if (  numberSet.search( $( divider ).text() ) !== -1  ) {
436                                         map.number = divider;
437                                         return false;
438                                 }
439                         });
440
441                         self._dividerMap = map;
442                 },
443
444                 _setTimer: function ( start ) {
445                         var self = this;
446
447                         if ( start === true ) {
448                                 self._timer = setTimeout( function () {
449                                         self._isFadeOut = true;
450                                         self.shortcutsContainer.fadeOut( self._defaultDuration, function () {
451                                                 self._isFadeOut = false;
452                                         });
453                                 }, self._defaultTime );
454                         } else {
455                                 if ( self._timer !== null ) {
456                                         clearTimeout( self._timer );
457                                 }
458                                 self.shortcutsContainer.show();
459                         }
460                 },
461
462                 indexString: function ( indexAlphabet ) {
463                         var self = this,
464                                 characterSet = [];
465
466                         if ( typeof indexAlphabet === "undefined" ) {
467                                 return self._primaryLanguage + ":" + self._secondLanguage;
468                         }
469
470                         characterSet = indexAlphabet.split( ":" );
471                         self._primaryLanguage = characterSet[ 0 ];
472                         if ( characterSet.length === 2 ) {
473                                 self._secondLanguage = characterSet[ 1 ];
474                         }
475                 },
476
477                 refresh: function () {
478                         var self = this,
479                                 primaryCharacterSet = self._primaryLanguage ? self._primaryLanguage.replace( /,/g, "" ) : null,
480                                 secondCharacterSet = self._secondLanguage ? self._secondLanguage.replace( /,/g, "" ) : null,
481                                 contentHeight = self._contentHeight(),
482                                 shapItem = $( '<li tabindex="0" aria-label="double to move Number list"><span aria-hidden="true">#</span><span aria-label="Number"/></li>' ),
483                                 omitIndex = 0,
484                                 makeCharacterSet,
485                                 makeOmitSet,
486                                 itemHandler,
487                                 containerHeight,
488                                 shortcutsItems,
489                                 shortcutItem,
490                                 shortcutsTop,
491                                 minClipHeight,
492                                 maxNumOfItems,
493                                 numOfItems,
494                                 minHeight,
495                                 padding,
496                                 omitInfo,
497                                 dividers,
498                                 listItems,
499                                 emptySize,
500                                 correction,
501                                 indexChar,
502                                 lastIndex,
503                                 seconds,
504                                 height,
505                                 size,
506                                 i;
507
508                         makeCharacterSet = function ( index, divider ) {
509                                 primaryCharacterSet += $( divider ).text();
510                         };
511
512                         makeOmitSet = function ( index, length ) {
513                                 var count,
514                                         omitSet = "";
515
516                                 for ( count = 0; count < length; count++ ) {
517                                         omitSet += primaryCharacterSet[ index + count ];
518                                 }
519
520                                 return omitSet;
521                         };
522
523                         itemHandler = function ( e ) {
524                                 var text = $( this ).text(),
525                                         matchDivider = self._dividerMap[ text ];
526
527                                 if ( typeof matchDivider !== "undefined" ) {
528                                         $( matchDivider ).next().focus();
529                                 }
530                         };
531
532                         self._createDividerMap();
533
534                         self.shortcutsList.find( 'li' ).remove();
535
536                         // get all the dividers from the list and turn them into shortcuts
537                         dividers = self.element.find( '.ui-li-divider' );
538
539                         // get all the list items
540                         listItems = self.element.find('li').not('.ui-li-divider');
541
542                         // only use visible dividers
543                         dividers = dividers.filter( ':visible' );
544                         listItems = listItems.filter( ':visible' );
545
546                         if ( dividers.length < 2 ) {
547                                 self.shortcutsList.hide();
548                                 return;
549                         }
550
551                         self.shortcutsList.show();
552                         self.lastListItem = listItems.last();
553                         self.shortcutsList.append( shapItem );
554                         self._focusItem( shapItem );
555
556                         if ( primaryCharacterSet === null ) {
557                                 primaryCharacterSet = "";
558                                 dividers.each( makeCharacterSet );
559                         }
560
561                         padding = parseInt( shapItem.css( "padding" ), 10 );
562                         minHeight = shapItem.height() + ( padding * 2 );
563                         maxNumOfItems = parseInt( ( contentHeight / minHeight ) - 1, 10 );
564                         numOfItems = primaryCharacterSet.length;
565
566                         maxNumOfItems = secondCharacterSet ? maxNumOfItems - 2 : maxNumOfItems;
567
568                         if ( maxNumOfItems < 3 ) {
569                                 shapItem.remove();
570                                 return;
571                         }
572
573                         omitInfo = self._omit( numOfItems, maxNumOfItems );
574
575                         for ( i = 0; i < primaryCharacterSet.length; i++ ) {
576                                 indexChar = primaryCharacterSet.charAt( i );
577                                 shortcutItem = $( '<li tabindex="0" aria-label="double to move ' + indexChar + ' list">' + indexChar + '</li>' );
578
579                                 self._focusItem( shortcutItem );
580
581                                 if ( typeof omitInfo !== "undefined" && omitInfo[ omitIndex ] > 1 ) {
582                                         shortcutItem = $( '<li>.</li>' );
583                                         shortcutItem.data( "omitSet",  makeOmitSet( i, omitInfo[ omitIndex ] ) );
584                                         i += omitInfo[ omitIndex ] - 1;
585                                 } else {
586                                         shortcutItem.bind( 'vclick', itemHandler );
587                                 }
588
589                                 shapItem.before( shortcutItem );
590                                 omitIndex++;
591                         }
592
593                         if ( secondCharacterSet !== null ) {
594                                 lastIndex = secondCharacterSet.length - 1;
595                                 seconds = [];
596
597                                 seconds.push( secondCharacterSet.charAt( 0 ) );
598                                 seconds.push( secondCharacterSet.charAt( lastIndex ) );
599
600                                 for ( i = 0; i < seconds.length; i++ ) {
601                                         indexChar = seconds[ i ];
602                                         shortcutItem = $( '<li tabindex="0" aria-label="double to move ' + indexChar + ' list">' + indexChar + '</li>' );
603
604                                         self._focusItem( shortcutItem );
605                                         shortcutItem.bind( 'vclick', itemHandler );
606                                         shapItem.before( shortcutItem );
607                                 }
608                         }
609
610                         containerHeight = self.shortcutsContainer.outerHeight();
611                         emptySize = contentHeight - containerHeight;
612                         shortcutsItems = self.shortcutsList.children();
613                         size = parseInt( emptySize / shortcutsItems.length, 10 );
614                         correction = emptySize - ( shortcutsItems.length * size );
615
616                         if ( emptySize > 0 ) {
617                                 shortcutsItems.each( function ( index, item ) {
618                                         height = $( item ).height() + size;
619                                         if ( correction !== 0 ) {
620                                                 height += 1;
621                                                 correction -= 1;
622                                         }
623                                         $( item ).css( {
624                                                 height: height,
625                                                 lineHeight: height + "px"
626                                         } );
627                                 } );
628                         }
629
630                         // position the shortcut flush with the top of the first list divider
631                         shortcutsTop = dividers.first().position().top;
632                         self.shortcutsContainer.css( 'top', shortcutsTop );
633
634                         // make the scrollview clip tall enough to show the whole of the shortcutslist
635                         minClipHeight = shortcutsTop + self.shortcutsContainer.outerHeight() + 'px';
636                         self.scrollview.css( 'min-height', minClipHeight );
637
638                         self._setTimer( false );
639                         self._setTimer( true );
640                 }
641         } );
642
643         $( document ).bind( "pagecreate create", function ( e ) {
644                 $( $.tizen.fastscroll.prototype.options.initSelector, e.target )
645                         .not( ":jqmData(role='none'), :jqmData(role='nojs')" )
646                         .fastscroll();
647         } );
648
649         $( window ).bind( "resize orientationchange", function ( e ) {
650                 $( ".ui-page-active .ui-fastscroll-target" ).fastscroll( "refresh" );
651         } );
652 } ( jQuery ) );
653
654 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
655 } );
656 //>>excludeEnd("jqmBuildExclude");