build: Module build implementation
[platform/framework/web/web-ui-fw.git] / src / js / widgets / jquery.mobile.tizen.scrollview.handler.js
1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Shows a scroll-handler with a scrollview
3 //>>label: Scrollview Handler
4 //>>group: Tizen:Widgets
5
6 define( [ '../jquery.mobile.tizen.core', '../jquery.mobile.tizen.scrollview' ], function ( ) {
7 //>>excludeEnd("jqmBuildExclude");
8
9 /* ***************************************************************************
10  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  * ***************************************************************************
30  *
31  * Authors: Wonseop Kim ( wonseop.kim@samsung.com )
32 */
33
34 /**
35  * "Handler" is a widget helping a user to scroll a window or panel.
36  * It is different from the scrollview feature in that the handler has a fixed size
37  * and disappears when a scroll size is smaller than a parent window's size.
38  * If the handler widget is activated, a scroll bar on the screen will be deactivated.
39  * The handler widget supports scrolling up and down and indicates the position of the scrolled window.
40  *
41  * HTML Attributes:
42  *
43  *              data-handler : This attribute is indicating that whether enable.
44  *                                              If you want to use, you will set 'true'.
45  *              data-handler-theme : Set the widget theme ( optional )
46  *
47  * APIs:
48  *
49  *              enableHandler ( boolean )
50  *                      : Get or set the use of handler widget.
51  *                      If the value is "true", it will be run handler widget.
52  *                      If the value is "false", it will be not run handler widget.
53  *                      If no value is specified, will act as a getter.
54  *
55  * Events:
56  *
57  * Examples:
58  *
59  *              <div data-role="content" data-scroll="y" data-handler="true">
60  *                      <ul data-role="listview">
61  *                              <li data-role="list-divider">A</li>
62  *                              <li><a href="#">Adam Kinkaid</a></li>
63  *                                      ...
64  *                      </ul>
65  *              </div>
66  */
67
68 /**
69         @class handler
70         The handler widget enables the user to vertically scroll through a page or panel using a fixed-size handle. The widget indicates the position of the scrolled window, and only appears on the screen if the parent page or panel's scroll size is larger than the screen size. <br/> To add a handler widget to the application, use the following code:
71
72                 <div data-role="content" data-scroll="y" data-handler="true">
73                         <ul data-role="listview">
74                                 <li data-role="list-divider">A</li>
75                                 <li><a href="#">Adam Kinkaid</a></li>
76                                         ...
77                         </ul>
78                 </div>
79         
80         You can use the enableHandler method with the handler widget to get (if no value is defined) or set the handler usage status. If the [enable] value is true, the handler is enabled; otherwise the handler is not used.
81
82                 $("#.selector").scrollview("enableHandler", [enable]);
83 */
84 /**
85         @property {Boolean} data-handler
86         Enables the handler widget. The value must be set to true.
87 */
88 /**
89         @property {String} data-handler-theme
90         Sets the handler widget theme.
91 */
92 ( function ( $, document, undefined ) {
93         // The options of handler in scrollview
94         $.tizen.scrollview.prototype.options.handler = false;
95         $.tizen.scrollview.prototype.options.handlerTheme = "s";
96
97         var originSetOption = $.tizen.scrollview.prototype._setOption,
98                 createHandler = function ( target ) {
99                         var $view = target,
100                                 prefix = "<div class=\"ui-handler ui-handler-direction-",
101                                 suffix = "\"><div class=\"ui-handler-track\"><div class=\"ui-handler-thumb\"></div></div></div>",
102                                 scrollview = $view.data( "scrollview" ),
103                                 options = scrollview.options,
104                                 direction = options.direction,
105                                 parentTheme = $.mobile.getInheritedTheme( scrollview, "s" ),
106                                 theme = options.theme || parentTheme,
107                                 isHorizontal = ( scrollview.options.direction === "x" ),
108                                 _$view = scrollview._$view,
109                                 _$clip = scrollview._$clip,
110                                 scrollbar = $view.find( ".ui-scrollbar" ),
111                                 handler = null,
112                                 handlerThumb = null,
113                                 viewLength = 0,
114                                 clipLength = 0,
115                                 handlerHeight = 0,
116                                 handlerMargin = 0,
117                                 trackLength = 0,
118                                 moveTimer,
119                                 isTouchable = $.support.touch,
120                                 dragStartEvt = ( isTouchable ? "touchstart" : "mousedown" ) + ".handler",
121                                 dragMoveEvt = ( isTouchable ? "touchmove" : "mousemove" ) + ".handler",
122                                 dragStopEvt = ( isTouchable ? "touchend" : "mouseup" ) + ".handler",
123                                 dragLeaveEvt = ( isTouchable ? " touchleave" : " mouseleave" ) + ".handler",
124                                 calculateLength = function () {
125                                         clipLength = ( isHorizontal ? _$clip.width() : _$clip.height() );
126                                         viewLength = ( isHorizontal ? _$view.width() : _$view.height() ) - clipLength;
127                                         trackLength = clipLength - handlerHeight - handlerMargin * 2;
128                                 },
129                                 setHanderPostion = function ( scrollPos ) {
130                                         var handlerPos = Math.round( ( isHorizontal ? scrollPos.x : scrollPos.y ) / viewLength * trackLength );
131                                         handlerThumb[0].style[ ( isHorizontal ? "left" : "top" ) ] = handlerPos + "px";
132                                 },
133                                 stopHandlerScroll = function () {
134                                         $( document ).unbind( ".handler" );
135                                         $view.moveData = null;
136                                         _$view.trigger( "scrollstop" );
137                                 };
138
139                         if ( $view.find( ".ui-handler-thumb" ).length !== 0 || typeof direction !== "string" ) {
140                                 return;
141                         }
142
143                         handler = $( [ prefix, direction, suffix ].join( "" ) ).appendTo( $view.addClass( " ui-handler-" + theme ) );
144                         handlerThumb = $view.find( ".ui-handler-thumb" ).hide();
145                         handlerHeight = ( isHorizontal ? handlerThumb.width() : handlerThumb.height() );
146                         handlerMargin = ( isHorizontal ? parseInt( handler.css( "right" ), 10 ) : parseInt( handler.css( "bottom" ), 10 ) );
147
148                         $.extend( $view, {
149                                 moveData : null
150                         });
151
152                         // handler drag
153                         handlerThumb.bind( dragStartEvt, {
154                                 e : handlerThumb[0]
155                         }, function ( event ) {
156                                 scrollview._stopMScroll();
157
158                                 var target = event.data.e,
159                                         t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );
160
161                                 target.style.opacity = 1.0;
162
163                                 $view.moveData = {
164                                         target : target,
165                                         X : parseInt( target.style.left, 10 ) || 0,
166                                         Y : parseInt( target.style.top, 10 ) || 0,
167                                         pX : t.pageX,
168                                         pY : t.pageY
169                                 };
170                                 calculateLength();
171
172                                 _$view.trigger( "scrollstart" );
173
174                                 if ( !isTouchable ) {
175                                         event.preventDefault();
176                                 }
177
178                                 $( document ).bind( dragMoveEvt, function ( event ) {
179                                         var moveData = $view.moveData,
180                                                 target = moveData.target,
181                                                 handlePos = 0,
182                                                 scrollPos = 0,
183                                                 t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );
184
185                                         handlePos = ( isHorizontal ? moveData.X + t.pageX - moveData.pX : moveData.Y + t.pageY - moveData.pY );
186
187                                         if ( handlePos < 0 ) {
188                                                 handlePos = 0;
189                                         }
190
191                                         if ( handlePos > trackLength ) {
192                                                 handlePos = trackLength;
193                                         }
194                                         scrollPos = - Math.round( handlePos / trackLength * viewLength );
195
196                                         if ( isHorizontal ) {
197                                                 scrollview._setScrollPosition( scrollPos, 0 );
198                                                 target.style.left = handlePos + "px";
199                                         } else {
200                                                 scrollview._setScrollPosition( 0, scrollPos );
201                                                 target.style.top = handlePos + "px";
202                                         }
203
204                                         event.preventDefault();
205                                 }).bind( dragStopEvt + dragLeaveEvt, function ( event ) {
206                                         stopHandlerScroll();
207                                 });
208                         });
209
210                         _$view.bind( dragStopEvt, function ( event ) {
211                                 stopHandlerScroll();
212                         });
213
214                         $view.bind( "scrollstart", function ( event ) {
215                                 if ( !scrollview.enableHandler() ) {
216                                         return;
217                                 }
218
219                                 calculateLength();
220
221                                 if ( viewLength < 0 || clipLength < handlerHeight ) {
222                                         if ( scrollbar.is( ":hidden" ) ) {
223                                                 scrollbar.show();
224                                         }
225                                         return;
226                                 }
227
228                                 if ( scrollbar.is( ":visible" ) ) {
229                                         scrollbar.hide();
230                                 }
231
232                                 if ( moveTimer ) {
233                                         clearInterval( moveTimer );
234                                         moveTimer = undefined;
235                                 }
236
237                                 handler.addClass( "ui-handler-visible" );
238                                 handlerThumb.stop( true, true )
239                                                         .fadeIn();
240                         }).bind( "scrollupdate", function ( event, data ) {
241                                 if ( !scrollview.enableHandler() || viewLength < 0 || clipLength < handlerHeight ) {
242                                         return;
243                                 }
244
245                                 setHanderPostion( scrollview.getScrollPosition() );
246                         }).bind( "scrollstop", function ( event ) {
247                                 if ( !scrollview.enableHandler() || viewLength < 0 || clipLength < handlerHeight ) {
248                                         return;
249                                 }
250
251                                 moveTimer = setInterval( function () {
252                                         setHanderPostion( scrollview.getScrollPosition() );
253                                         if ( !scrollview._gesture_timer ) {
254                                                 clearInterval( moveTimer );
255                                                 moveTimer = undefined;
256                                         }
257                                 }, 10 );
258
259                                 if ( scrollview._handlerTimer ) {
260                                         clearTimeout( scrollview._handlerTimer );
261                                         scrollview._handlerTimer = 0;
262                                 }
263                                 scrollview._handlerTimer = setTimeout( function () {
264                                         if ( scrollview._timerID === 0 && $view.moveData === null ) {
265                                                 handlerThumb.stop( true, true )
266                                                         .css( "opacity", 1.0 )
267                                                         .fadeOut( function () {
268                                                                 handler.removeClass( "ui-handler-visible" );
269                                                         });
270                                                 scrollview._handlerTimer = 0;
271                                         }
272                                 }, 1000 );
273                         }).bind( "mousewheel", function ( event ) {
274                                 handler.removeClass( "ui-handler-visible" );
275                                 setHanderPostion( scrollview.getScrollPosition() );
276                         });
277                 };
278
279         $.extend( $.tizen.scrollview.prototype, {
280                 enableHandler: function ( enabled ) {
281                         if ( typeof enabled === 'undefined' ) {
282                                 return this.options.handler;
283                         }
284
285                         this.options.handler = !!enabled;
286
287                         var $view = this.element;
288                         if ( this.options.handler ) {
289                                 if ( $view.find( ".ui-handler" ).length === 0 ) {
290                                         createHandler( $view );
291                                 }
292
293                                 $view.find( ".ui-scrollbar" ).hide();
294                                 $view.find( ".ui-handler" ).show();
295                         } else {
296                                 $view.find( ".ui-handler" ).removeClass( "ui-handler-visible" ).hide();
297                                 $view.find( ".ui-scrollbar" ).show();
298                         }
299                 },
300
301                 _setHandlerTheme: function ( handlerTheme ) {
302                         if ( !handlerTheme ) {
303                                 return;
304                         }
305
306                         var oldClass = "ui-handler-" + this.options.handlerTheme,
307                                 newClass = "ui-handler-" + handlerTheme;
308
309                         this.element.removeClass( oldClass ).addClass( newClass );
310                         this.options.handlerTheme = handlerTheme;
311                 },
312
313                 _setOption: function ( key, value ) {
314                         switch ( key ) {
315                         case "handler":
316                                 this.enableHandler( value );
317                                 break;
318                         case "handlerTheme":
319                                 this._setHandlerTheme( value );
320                                 break;
321                         default:
322                                 originSetOption.call( this, key, value );
323                         }
324                 },
325
326                 _handlerTimer : 0
327         });
328
329         $( document ).delegate( ":jqmData(scroll)", "scrollviewcreate", function () {
330                 var widget = $( this );
331                 if ( widget.attr( "data-" + $.mobile.ns + "scroll" ) === "none"
332                                 || widget.attr( "data-" + $.mobile.ns + "handler" ) !== "true" ) {
333                         return;
334                 }
335                 widget.scrollview( "enableHandler", "true" );
336         });
337 } ( jQuery, document ) );
338
339 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
340 } );
341 //>>excludeEnd("jqmBuildExclude");