modify wrong changelog date
[platform/framework/web/web-ui-fw.git] / src / js / widgets / jquery.mobile.tizen.splitview.js
1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Show different HTML contents at the same time on each divided pane.
3 //>>label: Split view
4 //>>group: Tizen:Widgets
5
6 define( [ '../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  *  Author: Sanghee Lee <sang-hee.lee@samsung.com>
32 */
33
34 /**
35  *  Splitview is a widget which can show different HTML contents at the same time on each divided pane.
36  *  A user can place Splitview controls on JQuery Mobile's Content area and arrange two panes on the widget.
37  *  And HTML fragments or another Splitview also can be placed on the pane.
38  *  The number of panes inside of Splitview is restricted as two.
39  *  If a user define only one pane in Splitview, a empty pane will be added automatically,
40  *  on the other hand, if 3 or more panes are defined in Splitview, the panes after two will be ignored and removed from the DOM tree.
41  *  The HTML fragments of a pane should be composed of elements describing a part of Web page (e.g. <div>...</div>).
42  *  Also widgets can be included in the HTML fragments.
43  *
44  *  HTML Attributes:
45  *
46  *      data-fixed : The resizing mode of panes - fixed and flexible mode.
47  *              If the value is true, the panes' sizes will be fixed, or if not, it will be flexible. (Default : false)
48  *      data-divider-vertical : The direction of dividers.
49  *              If the value is true, the panes will be placed in horizontal direction,
50  *              or if not, it will be placed in vertical direction. (Default : "true")
51  *      data-ratio : The ratio of two panes' widths or heights. (Default : [ 1/2, 1/2 ]
52  *
53  *  APIs:
54  *
55  *      pane ( id [ , element ] )
56  *          : This method replaces child contents of a pane indicated by id attribute with contents of inputted element.
57  *            If second argument is not specified, it will act as a getter method.
58  *            The string of id has to be started with "#" which means "id" of CSS selectors.
59  *      maximize ( id )
60  *          : This method maximizes a pane's size indicated by id.
61  *            The string of id has to be started with "#" which means "id" of CSS selectors.
62  *      restore ()
63  *          : This method restores all panes' sizes to the ratio prior to maximization.
64  *
65  *  Examples:
66  *
67  *      <div data-role="splitview" data-fixed="false" data-divider-vertical="true" data-ratio="0.5, 0.5">
68  *          <div class="ui-pane">pane0</div>
69  *          <div class="ui-pane">pane1</div>
70  *      </div>
71  *
72  */
73
74
75 /**
76         @class Splitview
77         Splitview widget enables a user to place and arrange several panes. Each divided pane can show repective HTML contents.
78
79         To add a Splitview widget to the application, use the following code:
80
81                 <div data-role="splitview" data-fixed="false" data-divider-vertical="true" data-ratio="0.5, 0.5">
82                         <div class="ui-pane">pane0</div>
83                         <div class="ui-pane">pane1</div>
84                 </div>
85 */
86
87 /**
88         @property {Boolean} data-fixed
89         The resizing mode of panes - fixed and flexible mode.
90 */
91
92 /**
93         @property {Boolean} data-divider-vertical
94         The direction of dividers - horizontal or vertical.
95  */
96
97 /**
98         @property {Array} data-ratio
99         The ratio of two panes' widths or heights.
100 */
101
102 /**
103         @method pane
104         This method replaces child contents of a pane indicated by id attribute with contents of inputted element.
105         If second argument is not specified, it will act as a getter method.
106
107                 <div data-role="splitview">
108                         <div class="ui-pane" id="pane0">pane0</div>
109                         <div class="ui-pane" id="pane1">pane1</div>
110                 </div>
111                 $(".selector").splitview("pane", id, element);
112 */
113
114 /**
115         @method maximize
116         This method maximizes a pane's size indicated by id.
117
118                 <div data-role="splitview">
119                         <div class="ui-pane" id="pane0">pane0</div>
120                         <div class="ui-pane" id="pane1">pane1</div>
121                 </div>
122                 $(".selector").splitview("maximize", id);
123 */
124
125 /**
126         @method restore
127         This method restores all panes' sizes to the ratio prior to maximization.
128
129                 <div data-role="splitview">
130                         <div class="ui-pane" id="pane0">pane0</div>
131                         <div class="ui-pane" id="pane1">pane1</div>
132                 </div>
133                 $(".selector").splitview("restore");
134 */
135
136 ( function ( $, window, document, undefined ) {
137         $.widget( "tizen.splitview", $.mobile.widget, {
138                 options : {
139                         fixed : false,
140                         dividerVertical : true,
141                         ratio : [],
142                         initSelector : ":jqmData(role='splitview')"
143                 },
144
145                 _create : function () {
146                         var self = this,
147                                 $el = self.element,
148                                 opt = self.options,
149                                 $panes = $el.children( ".ui-pane" ),
150                                 panesLength = $panes.length,
151                                 spliters = [],
152                                 spliterBars = [],
153                                 ratioAttr = this.element.attr( "data-ratio" ),
154                                 containerSize = [ 0, 0 ],
155                                 resizeTimer = null,
156                                 i = 0;
157
158                         if ( panesLength !== 2 ) {
159                                 if ( panesLength < 2 ) {
160                                         for ( i = panesLength ; i < 2 ; ++i ) {
161                                                 self._addEmptyPanes();
162                                         }
163                                 } else {
164                                         $panes.slice( 2 ).remove();
165                                 }
166
167                                 $panes = $el.children( ".ui-pane" );
168                                 panesLength = $panes.length;
169                         }
170
171                         spliters[ 0 ] = $( "<a href='#' class='ui-spliter' aria-label='Drag scroll, double tap and move to adjust split area'></a>" ).insertAfter( $panes[ 0 ] );
172                         spliterBars[ 0 ] = $( "<div class='ui-spliter-bar'></div>" ).appendTo( spliters[ 0 ] );
173                         $( "<div class='ui-spliter-handle'></div>" ).appendTo( spliterBars[ 0 ] );
174
175                         $.extend( this, {
176                                 moveTarget : null,
177                                 moveData : {},
178                                 spliters : spliters,
179                                 spliterBars : spliterBars,
180                                 panes : $panes,
181                                 containerSize : containerSize,
182                                 touchStatus : false,
183                                 minPaneWidth : 50,
184                                 savedRatio : []
185                         });
186
187                         self._bindTouchEvents();
188                         self._convertRatio( ratioAttr, $panes.length );
189
190                         $el.addClass( "ui-splitview ui-direction-" + self._direction( opt.dividerVertical ) );
191
192                         self._refresh();
193
194                         $( window ).unbind( ".splitview" )
195                                 .bind( "pagechange.splitview resize.splitview", function ( event ) {
196                                         $( ".ui-page-active .ui-splitview" ).each( function () {
197                                                 $( this ).data( "splitview" )._refresh();
198                                         });
199                                 });
200                 },
201
202                 _addEmptyPanes : function () {
203                         var self = this,
204                                 $el = self.element,
205                                 opt = self.options,
206                                 $panes = $el.children( ".ui-pane" ),
207                                 scrollAttribute = ( $.support.scrollview ) ? "data-scroll='y'" : "",
208                                 pane = $( "<div class='ui-pane' " + scrollAttribute + "></div>" );
209
210                         if ( scrollAttribute.length ) {
211                                 pane.scrollview( { direction: "y" } );
212                         }
213
214                         if ( !$panes.length ) {
215                                 $el.append( pane );
216                         } else {
217                                 $panes.last().after( pane );
218                         }
219                 },
220
221                 _direction : function ( isHorizontal ) {
222                         return isHorizontal ? "horizontal" : "vertical";
223                 },
224
225                 _isStyleSpecified : function ( cssString ) {
226                         return ( typeof cssString !== "undefined" && cssString.length );
227                 },
228
229                 _getContainerSize : function ( widthString, heightString ) {
230                         var self = this,
231                                 $el = self.element,
232                                 widthSpecified = self._isStyleSpecified( widthString ),
233                                 heightSpecified = self._isStyleSpecified( heightString );
234
235                         self.containerSize[ 0 ] = ( widthSpecified ) ? $el.outerWidth( true ) : self._parentWidth();
236                         self.containerSize[ 1 ] = ( heightSpecified ) ? $el.outerHeight( true ) : self._parentHeight();
237
238                         if ( !self.containerSize[ 0 ] || !self.containerSize[ 1 ] ) {
239                                 return false;
240                         }
241
242                         return true;
243                 },
244
245                 _parentWidth : function () {
246                         var $parent = this.element.parent();
247
248                         if ( !$parent && typeof $parent === "undefined" && !$parent.length ) {
249                                 return $( window ).width();
250                         }
251
252                         return $parent.width();
253                 },
254
255                 _parentHeight : function () {
256                         var $parent = this.element.parent(),
257                                 heightString = "",
258                                 heightSpecified = false,
259                                 parentHeight = 0;
260
261                         while ( $parent && typeof $parent !== "undefined" && $parent.length ) {
262                                 if ( typeof $parent[ 0 ].style !== "undefined" ) {
263                                         heightString = $parent[ 0 ].style.height;
264                                         heightSpecified = ( typeof heightString !== "undefined" && heightString.length );
265                                         if ( heightSpecified ) {
266                                                 parentHeight = $parent.height();
267                                                 break;
268                                         }
269                                 }
270
271                                 $parent = $parent.parent();
272                         }
273
274                         if ( !heightSpecified ) {
275                                 parentHeight = $(window).height();
276                         }
277
278                         return parentHeight;
279                 },
280
281                 _convertRatio : function ( ratioParam, panesLength ) {
282                         var self = this,
283                                 ratio = [],
284                                 loop = 0,
285                                 type = typeof ratioParam,
286                                 ratioArray = null,
287                                 i;
288
289                         for ( i = 0; i < panesLength; ++i ) {
290                                 ratio.push( 0 );
291                         }
292
293                         switch ( type ) {
294                         case "number":
295                                 if ( panesLength ) {
296                                         ratio[ 0 ] = ratioParam;
297                                 }
298                                 break;
299
300                         case "string":
301                                 ratioArray = ratioParam.split( "," );
302                                 loop = Math.min( ratioArray.length, panesLength );
303                                 for ( i = 0; i < loop; ++i ) {
304                                         ratio[ i ] = parseFloat( ratioArray[ i ] );
305                                 }
306                                 break;
307
308                         case "object":
309                                 if ( !$.isArray( ratioParam ) ) {
310                                         break;
311                                 }
312
313                                 loop = Math.min( ratioParam.length, panesLength );
314                                 for ( i = 0; i < loop; ++i ) {
315                                         type = typeof ratioParam[ i ];
316                                         ratio[ i ] = ( type === "string" ) ? parseFloat( ratioParam[ i ] ) :
317                                                                 ( type === "number" ) ? ratioParam[ i ] : 0;
318                                 }
319                                 break;
320                         }
321
322                         self.options.ratio = ratio;
323                         self._adjustRatio( panesLength );
324                 },
325
326                 _adjustRatio : function ( panesLength ) {
327                         var self = this,
328                                 ratio = self.options.ratio,
329                                 sum = 0,
330                                 remain = 0,
331                                 value = 0,
332                                 subValue = 0,
333                                 subRemain = 0,
334                                 i;
335
336                         if ( !panesLength ) {
337                                 self.options.ratio = [];
338                                 return;
339                         }
340
341                         for ( i in ratio ) {
342                                 sum += ratio[ i ];
343                         }
344
345                         if ( sum !== 1 ) {
346                                 remain = 1 - sum;
347                                 value = remain / panesLength;
348
349                                 for ( i in ratio ) {
350                                         if ( value >= 0 ) {
351                                                 ratio[ i ] += value;
352                                                 remain = Math.max( 0, remain - value );
353                                         } else {
354                                                 subRemain += value;
355                                                 subValue = Math.max( subRemain, ratio[ i ] * -1 );
356                                                 ratio[ i ] = Math.max( 0, ratio[ i ] + subValue );
357                                                 remain = Math.min( 0, remain - subValue );
358                                                 subRemain -= subValue;
359                                         }
360                                 }
361
362                                 if ( remain ) {
363                                         if ( remain > 0 ) {
364                                                 ratio[ ratio.length - 1 ] += remain;
365                                         } else {
366                                                 for ( i = ratio.length - 1; i >= 0; --i ) {
367                                                         subValue = Math.max( remain, ratio[ i ] * -1 );
368                                                         ratio[ i ] = Math.max( 0, ratio[ i ] + subValue );
369                                                         remain = Math.min( 0, remain - subValue );
370                                                         if ( !remain ) {
371                                                                 break;
372                                                         }
373                                                 }
374                                         }
375                                 }
376
377                                 self.options.ratio = ratio;
378                         }
379                 },
380
381                 _setOption : function ( key, value ) {
382                         var self = this,
383                                 orgValue = self.options[ key ];
384
385                         if ( orgValue === value ) {
386                                 return;
387                         }
388
389                         $.Widget.prototype._setOption.apply( this, arguments );
390
391                         switch ( key ) {
392                         case "fixed":
393                                 self._fixed( value );
394                                 break;
395
396                         case "dividerVertical":
397                                 self._dividerVertical( value );
398                                 break;
399
400                         case "ratio":
401                                 self._ratio( value );
402                                 break;
403                         }
404                 },
405
406                 _subtractDiffWidth : function ( width, diff ) {
407                         var self = this;
408
409                         if ( width <= self.minPaneWidth ) {
410                                 return {
411                                         width: width,
412                                         diff: diff
413                                 };
414                         }
415
416                         width += diff;
417                         if ( width >= self.minPaneWidth ) {
418                                 return {
419                                         width: width,
420                                         diff: 0
421                                 };
422                         }
423
424                         return {
425                                 width: self.minPaneWidth,
426                                 diff: width - self.minPaneWidth
427                         };
428                 },
429
430                 _initRatio : function ( fromFirstPane, panes, isHorizontal, availableWidth ) {
431                         var self = this,
432                                 sum = 0,
433                                 widths = [],
434                                 diff = 0,
435                                 panesLength = panes.length,
436                                 ret,
437                                 i;
438
439                         panes.each( function ( i ) {
440                                 var pane = $( this );
441                                 widths.push( isHorizontal ? pane.width() : pane.height() );
442                                 sum += widths[ i ];
443                         });
444
445                         diff = availableWidth - sum;
446                         if ( !diff ) {
447                                 return widths;
448                         }
449
450                         if ( diff > 0 ) {
451                                 widths[ fromFirstPane ? 0 : panesLength - 1 ] += diff;
452                         } else {
453                                 if ( fromFirstPane ) {
454                                         for ( i = 0; i < panesLength; ++i ) {
455                                                 ret = self._subtractDiffWidth( widths[ i ], diff );
456                                                 widths[ i ] = ret.width;
457                                                 diff = ret.diff;
458                                                 if ( !diff ) {
459                                                         break;
460                                                 }
461                                         }
462                                 } else {
463                                         for ( i = panesLength - 1; i >= 0; --i ) {
464                                                 diff = self._subtractDiffWidth( widths[ i ], diff );
465                                                 widths[ i ] = ret.width;
466                                                 diff = ret.diff;
467                                                 if ( !diff ) {
468                                                         break;
469                                                 }
470                                         }
471                                 }
472                         }
473
474                         sum = 0;
475                         for ( i in widths ) {
476                                 sum += widths[ i ];
477                         }
478
479                         for ( i in self.options.ratio ) {
480                                 self.options.ratio[ i ] = widths[ i ] / sum;
481                         }
482
483                         return widths;
484                 },
485
486                 _horizontalBoundary : function () {
487                         var self = this,
488                                 $el = self.element;
489
490                         return $el.outerWidth( true ) - $el.width();
491                 },
492
493                 _verticalBoundary : function () {
494                         var self = this,
495                                 $el = self.element;
496
497                         return $el.outerHeight( true ) - $el.height();
498                 },
499
500                 _boundary : function ( type ) {
501                         var self = this,
502                                 $el = self.element,
503                                 computedStyle = window.getComputedStyle( $el[ 0 ], null ),
504                                 margin = parseFloat( computedStyle[ "margin" + type ] ),
505                                 border = parseFloat( computedStyle[ "border" + type + "Width" ] ),
506                                 padding = parseFloat( computedStyle[ "padding" + type ] );
507
508                         return {
509                                 margin: margin,
510                                 border: border,
511                                 padding: padding
512                         };
513                 },
514
515                 _layout : function ( initRatio, fromFirstPane ) {
516                         var self = this,
517                                 $el = self.element,
518                                 opt = self.options,
519                                 isHorizontal = opt.dividerVertical,
520                                 $panes = self.panes,
521                                 spliters = self.spliters,
522                                 spliterBars = self.spliterBars,
523                                 spliterBar = self.spliterBars.length ? $( spliterBars[ 0 ] ) : null,
524                                 spliterWidth = !spliterBar ? 0 :
525                                                                 isHorizontal ? spliterBar.outerWidth() :
526                                                                                                 spliterBar.outerHeight(),
527                                 spliterBarMargin = !spliterBar ? 0 :
528                                                                         isHorizontal ?
529                                                                                 spliterBar.outerWidth( true ) - spliterBar.outerWidth() :
530                                                                                 spliterBar.outerHeight( true ) - spliterBar.outerHeight(),
531                                 panesLength = $panes.length,
532                                 currentAvailable = 0,
533                                 spliterSize = spliterWidth * ( panesLength - 1 ),
534                                 parentWidth = self.containerSize[ 0 ],
535                                 parentHeight = self.containerSize[ 1 ],
536                                 width = parentWidth - self._horizontalBoundary(),
537                                 height = parentHeight - self._verticalBoundary(),
538                                 innerSize = isHorizontal ? height : width,
539                                 availableWidth = isHorizontal ? width - spliterSize :
540                                                                                                 height - spliterSize,
541                                 initializedWidth = [],
542                                 widthSum = 0,
543                                 childSplitview = null;
544
545                         initRatio = !!initRatio;
546                         fromFirstPane = !!fromFirstPane;
547
548                         $el.css( {
549                                 "min-width" : width,
550                                 "min-height" : height
551                         });
552
553                         if ( initRatio ) {
554                                 initializedWidth = self._initRatio( fromFirstPane, $panes, isHorizontal, availableWidth );
555                         }
556
557                         currentAvailable = availableWidth;
558                         $panes.each( function ( i ) {
559                                 var $pane = $( this ),
560                                         paneWidth = initRatio ? initializedWidth[ i ] :
561                                                                                 Math.floor( availableWidth * self.options.ratio[i] ),
562                                         prevPane = ( ( i ) ? $panes.eq( i - 1 ) : null ),
563                                         posValue = 0,
564                                         widthValue = 0,
565                                         heightValue = 0,
566                                         boundary = 0;
567
568                                 currentAvailable -= paneWidth;
569                                 if ( i === ( panesLength - 1 ) ) {
570                                         paneWidth = Math.max( Math.min( paneWidth, self.minPaneWidth ), paneWidth + currentAvailable );
571                                 }
572
573                                 widthSum += paneWidth;
574
575                                 if ( !prevPane ) {
576                                         boundary = self._boundary( isHorizontal ? "Left" : "Top" );
577                                         posValue = boundary.padding;
578                                 } else {
579                                         posValue = parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 );
580                                         posValue += isHorizontal ? prevPane.width() : prevPane.height();
581                                         posValue += spliterWidth;
582                                 }
583
584                                 widthValue = isHorizontal ? paneWidth : innerSize;
585                                 heightValue = isHorizontal ? innerSize : paneWidth;
586
587                                 $pane.css( {
588                                         "width" : widthValue ,
589                                         "height" : heightValue
590                                 } );
591
592                                 $pane.css( ( isHorizontal ? "left" : "top" ), posValue );
593                         });
594
595                         $panes.each( function ( i ) {
596                                 var $pane = $( this ),
597                                         paneWidth = isHorizontal ? $pane.width() : $pane.height();
598
599                                 self.options.ratio[ i ] = paneWidth / widthSum;
600                         });
601
602                         $.each( spliters, function ( i ) {
603                                 var spliter = $( this ),
604                                         prevPane = $panes.eq( i ),
605                                         bar = spliter.children( ".ui-spliter-bar" ),
606                                         handle = bar.children( ".ui-spliter-handle" ),
607                                         posValue = 0;
608
609                                 if ( isHorizontal ) {
610                                         posValue = parseInt( prevPane.css( "left" ), 10 ) + prevPane.width() - spliterBarMargin;
611                                         spliter.outerHeight( innerSize ).css( "left", posValue );
612                                 } else {
613                                         posValue = parseInt( prevPane.css( "top" ), 10 ) + prevPane.height() - spliterBarMargin;
614                                         spliter.outerWidth( innerSize ).css( "top", posValue );
615                                 }
616
617                                 if ( bar.length ) {
618                                         bar[ isHorizontal ? "outerHeight" : "outerWidth" ]( innerSize );
619                                 }
620                                 if ( handle.length ) {
621                                         handle.css( isHorizontal ? "top" : "left", ( innerSize - spliterWidth ) / 2 );
622                                 }
623                         });
624
625                         childSplitview = $el.find( ".ui-splitview:first" );
626                         if ( !childSplitview.length ) {
627                                 return;
628                         }
629
630                         childSplitview = childSplitview.data( "splitview" );
631                         if ( childSplitview ) {
632                                 childSplitview._refresh();
633                         }
634                 },
635
636                 _bindTouchEvents : function () {
637                         var self = this,
638                                 $el = self.element,
639                                 $panes = self.panes,
640                                 spliters = self.spliters;
641
642                         $.each( spliters, function ( i ) {
643                                 var spliter = $( this );
644                                 self._bindSpliterTouchEvents.call( self, spliter );
645                         });
646                 },
647
648                 _bindSpliterTouchEvents : function ( spliter ) {
649                         var self = this,
650                                 $el = self.element,
651                                 opt = self.options,
652                                 touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ),
653                                 touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".splitview",
654                                 touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".splitview";
655
656                         spliter.bind( touchStartEvt, { e : spliter }, function ( event ) {
657                                 if ( self.options.fixed ) {
658                                         return;
659                                 }
660
661                                 var realEvent = $.support.touch ? event.originalEvent.changedTouches[0] : event,
662                                         targetSpliter = event.data.e,
663                                         prevPane = targetSpliter.prev(),
664                                         nextPane = targetSpliter.next(),
665                                         splitviewInPrev = prevPane.find( ".ui-splitview:first" ),
666                                         splitviewInNext = nextPane.find( ".ui-splitview:first" ),
667                                         isHorizontal = opt.dividerVertical,
668                                         spliterWidth = isHorizontal ?
669                                                                         $( self.spliterBars[0] ).outerWidth() :
670                                                                         $( self.spliterBars[0] ).outerHeight();
671
672                                 self.moveTarget = targetSpliter;
673                                 self.moveData = {
674                                         spliterWidth : spliterWidth || 0,
675                                         prevPane : prevPane,
676                                         nextPane : nextPane,
677                                         splitviewInPrev : splitviewInPrev,
678                                         splitviewInNext : splitviewInNext,
679                                         prevPanePos : parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
680                                         prevPaneWidth : parseInt( prevPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0,
681                                         nextPanePos : parseInt( nextPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
682                                         nextPaneWidth : parseInt( nextPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0,
683                                         targetPos : parseInt( targetSpliter.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
684                                         pagePos : isHorizontal ? realEvent.pageX : realEvent.pageY
685                                 };
686
687                                 targetSpliter.addClass( "ui-spliter-active" );
688
689                                 $el.bind( touchMoveEvt, function ( event ) {
690                                         if ( !self.touchStatus ) {
691                                                 return;
692                                         }
693                                         event.stopPropagation();
694                                         self._drag( $.support.touch ? event.originalEvent.changedTouches[0] : event );
695                                 }).bind( touchEndEvt, function ( event ) {
696                                         event.stopPropagation();
697                                         self._stop( $.support.touch ? event.originalEvent.changedTouches[0] : event );
698                                         self.touchStatus = false;
699                                         $el.unbind( ".splitview" );
700                                         $( document ).unbind( ".splitview" );
701                                 });
702
703                                 $( document ).bind( touchMoveEvt + " " + touchEndEvt, function() {
704                                         $el.trigger( touchEndEvt );
705                                 });
706
707                                 event.preventDefault();
708                                 self.touchStatus = true;
709                         });
710                 },
711
712                 _drag : function ( e ) {
713                         if ( !this.moveData || typeof this.moveData === "undefined" ) {
714                                 return;
715                         }
716
717                         var self = this,
718                                 $el = self.element,
719                                 opt = self.options,
720                                 isHorizontal = opt.dividerVertical,
721                                 moveData = self.moveData,
722                                 moveTarget = self.moveTarget,
723                                 prevPane = moveData.prevPane,
724                                 nextPane = moveData.nextPane,
725                                 splitviewInPrev = moveData.splitviewInPrev,
726                                 splitviewInNext = moveData.splitviewInNext,
727                                 spliterWidth = moveData.spliterWidth,
728                                 movement = null,
729                                 targetPos = null,
730                                 nextPanePos = null,
731                                 prevPaneWidth = null,
732                                 nextPaneWidth = null,
733                                 pagePos = isHorizontal ? e.pageX : e.pageY,
734                                 splitview = null;
735
736                         movement = pagePos - moveData.pagePos;
737                         if ( movement > 0 ) {
738                                 movement = Math.min( Math.max( moveData.nextPaneWidth - self.minPaneWidth, 0 ), movement );
739                         } else {
740                                 movement = Math.max( Math.max( moveData.prevPaneWidth - self.minPaneWidth, 0 ) * -1, movement );
741                         }
742
743                         nextPanePos = moveData.nextPanePos + movement;
744                         prevPaneWidth = Math.max( moveData.prevPaneWidth + movement, 0 );
745                         nextPaneWidth = Math.max( moveData.nextPaneWidth - movement, 0 );
746                         targetPos = moveData.targetPos + movement;
747
748                         moveTarget.css( isHorizontal ? { left : targetPos } : { top : targetPos } );
749                         prevPane.css( isHorizontal ? { width : prevPaneWidth } : { height : prevPaneWidth } );
750                         nextPane.css( isHorizontal ? { width : nextPaneWidth, left : nextPanePos } :
751                                                                                         { height : nextPaneWidth, top : nextPanePos } );
752
753                         if ( splitviewInPrev.length ) {
754                                 splitview = splitviewInPrev.data( "splitview" );
755                                 splitview._refresh( true, false );
756                         }
757
758                         if ( splitviewInNext.length ) {
759                                 splitview = splitviewInNext.data( "splitview" );
760                                 splitview._refresh( true, true );
761                         }
762                 },
763
764                 _stop : function ( e ) {
765                         if ( !this.moveData || !this.moveTarget ) {
766                                 return;
767                         }
768
769                         var self = this,
770                                 $el = self.element,
771                                 opt = self.options,
772                                 $panes = self.panes,
773                                 panesLength = $panes.length,
774                                 isHorizontal = opt.dividerVertical,
775                                 moveData = self.moveData,
776                                 moveTarget = self.moveTarget,
777                                 prevPane = moveData.prevPane,
778                                 nextPane = moveData.nextPane,
779                                 splitviewInPrev = moveData.splitviewInPrev,
780                                 splitviewInNext = moveData.splitviewInNext,
781                                 spliterWidth = moveData.spliterWidth,
782                                 spliterSize = spliterWidth * ( panesLength - 1 ),
783                                 movement = null,
784                                 targetPos = null,
785                                 nextPanePos = null,
786                                 prevPaneWidth = null,
787                                 nextPaneWidth = null,
788                                 displayStyle = $el.css( "display" ),
789                                 parentWidth = self.containerSize[ 0 ],
790                                 parentHeight = self.containerSize[ 1 ],
791                                 width = parentWidth - self._horizontalBoundary(),
792                                 height = parentHeight - self._verticalBoundary(),
793                                 availableWidth = isHorizontal ?
794                                                                         ( width - spliterSize ) :
795                                                                         ( height - spliterSize ),
796                                 sum = 0;
797
798                         moveTarget.removeClass( "ui-spliter-active" );
799
800                         // ratio calculation
801                         $panes.each( function ( i ) {
802                                 var $pane = $( this ),
803                                         paneWidth = isHorizontal ? $pane.width() : $pane.height();
804
805                                 sum += paneWidth;
806                         });
807
808                         $panes.each( function ( i ) {
809                                 var $pane = $( this ),
810                                         paneWidth = isHorizontal ? $pane.width() : $pane.height();
811
812                                 self.options.ratio[ i ] = paneWidth / sum;
813                         });
814
815                         self.moveData = null;
816                 },
817
818                 _fixed : function ( isFix ) {
819                         var self = this,
820                                 spliters = self.spliters;
821
822                         $.each( spliters, function ( i ) {
823                                 var $spliter = $( this );
824
825                                 if ( isFix ) {
826                                         $spliter.addClass( "ui-fixed" );
827                                 } else {
828                                         $spliter.removeClass( "ui-fixed" );
829                                 }
830                         });
831
832                         self._layout();
833                 },
834
835                 _dividerVertical : function ( isDividerVertical ) {
836                         var self = this,
837                                 $el = self.element,
838                                 isHorizontal = isDividerVertical,
839                                 $panes = null,
840                                 $spliters = null,
841                                 $bar = null,
842                                 $handle = null;
843
844                         $panes = $el.children( ".ui-pane" );
845                         $spliters = $el.children( ".ui-spliter" );
846                         $bar = $spliters.children( ".ui-spliter-bar" );
847                         $handle = $bar.children( ".ui-spliter-handle" );
848
849                         $el.removeClass( "ui-direction-vertical" );
850                         $el.removeClass( "ui-direction-horizontal" );
851                         $el.addClass( "ui-splitview ui-direction-" + self._direction( isHorizontal ) );
852
853                         $panes.css( {
854                                 "left" : "",
855                                 "top" : "",
856                                 "width" : "",
857                                 "height" : ""
858                         });
859
860                         $spliters.css( {
861                                 "left" : "",
862                                 "top" : "",
863                                 "width" : "",
864                                 "height" : ""
865                         });
866
867                         $bar.css( {
868                                 "width" : "",
869                                 "height" : ""
870                         });
871
872                         $handle.css( {
873                                 "left" : "",
874                                 "top" : ""
875                         });
876
877                         if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) {
878                                 self._layout();
879                         }
880                 },
881
882                 _ratio : function ( ratioParam ) {
883                         var self = this,
884                                 $el = self.element,
885                                 $panes = $el.children( ".ui-pane" ),
886                                 panesLength = $panes.length;
887
888                         self._convertRatio( ratioParam, panesLength );
889                         self._layout();
890                 },
891
892                 _refresh : function ( initRatio, fromFirstPane ) {
893                         var self = this,
894                                 $el = self.element;
895
896                         initRatio = !!initRatio;
897                         fromFirstPane = !!fromFirstPane;
898
899                         if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) {
900                                 self._layout( initRatio, fromFirstPane );
901                         }
902                 },
903
904                 pane : function ( id, element ) {
905                         if ( typeof id !== "string" ) {
906                                 return null;
907                         }
908
909                         var self = this,
910                                 $el = self.element,
911                                 $targetPane = $el.children( id ),
912                                 $targetView = null,
913                                 elementParent = null;
914
915                         if ( !$targetPane.hasClass( "ui-pane" ) ) {
916                                 return null;
917                         }
918
919                         // getter
920                         if ( !element ) {
921                                 return $targetPane.contents();
922                         }
923
924                         // setter
925                         if ( $targetPane.hasClass( "ui-scrollview-clip" ) ) {
926                                 $targetPane.scrollview( "scrollTo", 0, 0, 0 );
927
928                                 $targetView = $targetPane.children( ".ui-scrollview-view" );
929                                 if ( !$targetView.length ) {
930                                         return null;
931                                 }
932                         } else {
933                                 $targetView = $targetPane;
934                         }
935
936                         elementParent = element.parent();
937                         if ( elementParent.length && elementParent[ 0 ] === $targetView[ 0 ] ) {
938                                 return;
939                         }
940
941                         $targetView.empty().append( element ).trigger( "create" );
942                         $targetView.fadeIn( 'fast' );
943                 },
944
945                 maximize : function ( id ) {
946                         if ( typeof id !== "string" ) {
947                                 return;
948                         }
949
950                         var self = this,
951                                 $el = self.element,
952                                 $panes = self.panes,
953                                 $targetPane = $el.children( id );
954
955                         if ( !$targetPane.hasClass( "ui-pane" ) ) {
956                                 return;
957                         }
958
959                         self.savedRatio = self.options.ratio.slice();
960
961                         self.options.ratio = [];
962                         $panes.each( function ( i ) {
963                                 self.options.ratio.push( ( this === $targetPane[ 0 ] ) ? 1 : 0 );
964                         });
965
966                         self._layout();
967                 },
968
969                 restore : function () {
970                         var self = this;
971
972                         if ( !self.savedRatio.length ) {
973                                 return;
974                         }
975
976                         self.options.ratio = self.savedRatio.slice();
977                         self._adjustRatio( self.panes.length );
978
979                         self._layout();
980                 }
981         });
982
983         $( document ).bind( "pagecreate create", function ( e ) {
984                 $.tizen.splitview.prototype.enhanceWithin( e.target );
985         });
986 } ( jQuery, window, document ) );
987
988 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
989 } );
990 //>>excludeEnd("jqmBuildExclude");