Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 621A7CBC0 for ; Tue, 10 Sep 2013 18:04:23 +0000 (UTC) Received: (qmail 66286 invoked by uid 500); 10 Sep 2013 18:04:16 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 66004 invoked by uid 500); 10 Sep 2013 18:04:13 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 65344 invoked by uid 99); 10 Sep 2013 18:04:07 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 10 Sep 2013 18:04:07 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 88B9189F9F1; Tue, 10 Sep 2013 18:04:06 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: pplaquette@apache.org To: commits@cordova.apache.org Date: Tue, 10 Sep 2013 18:04:12 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [07/51] [partial] [cordova-tizen] Tizen SDK 2.2 support mores samples http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.splitview.js ---------------------------------------------------------------------- diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.splitview.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.splitview.js new file mode 100644 index 0000000..9a3d62e --- /dev/null +++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.splitview.js @@ -0,0 +1,998 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Show different HTML contents at the same time on each divided pane. +//>>label: Split view +//>>group: Tizen:Widgets + +define( [ + 'jquery', + '../jquery.mobile.tizen.scrollview' + ], function ( ) { + +//>>excludeEnd("jqmBuildExclude"); + +/* *************************************************************************** + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * *************************************************************************** + * + * Author: Sanghee Lee +*/ + +/** + * Splitview is a widget which can show different HTML contents at the same time on each divided pane. + * A user can place Splitview controls on JQuery Mobile's Content area and arrange two panes on the widget. + * And HTML fragments or another Splitview also can be placed on the pane. + * The number of panes inside of Splitview is restricted as two. + * If a user define only one pane in Splitview, a empty pane will be added automatically, + * 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. + * The HTML fragments of a pane should be composed of elements describing a part of Web page (e.g.
...
). + * Also widgets can be included in the HTML fragments. + * + * HTML Attributes: + * + * data-fixed : The resizing mode of panes - fixed and flexible mode. + * If the value is true, the panes' sizes will be fixed, or if not, it will be flexible. (Default : false) + * data-divider-vertical : The direction of dividers. + * If the value is true, the panes will be placed in horizontal direction, + * or if not, it will be placed in vertical direction. (Default : "true") + * data-ratio : The ratio of two panes' widths or heights. (Default : [ 1/2, 1/2 ] + * + * APIs: + * + * pane ( id [ , element ] ) + * : This method replaces child contents of a pane indicated by id attribute with contents of inputted element. + * If second argument is not specified, it will act as a getter method. + * The string of id has to be started with "#" which means "id" of CSS selectors. + * maximize ( id ) + * : This method maximizes a pane's size indicated by id. + * The string of id has to be started with "#" which means "id" of CSS selectors. + * restore () + * : This method restores all panes' sizes to the ratio prior to maximization. + * + * Examples: + * + *
+ *
pane0
+ *
pane1
+ *
+ * + */ + + +/** + @class Splitview + Splitview widget enables a user to place and arrange several panes. Each divided pane can show repective HTML contents. + + To add a Splitview widget to the application, use the following code: + +
+
pane0
+
pane1
+
+*/ + +/** + @property {Boolean} data-fixed + The resizing mode of panes - fixed and flexible mode. +*/ + +/** + @property {Boolean} data-divider-vertical + The direction of dividers - horizontal or vertical. + */ + +/** + @property {Array} data-ratio + The ratio of two panes' widths or heights. +*/ + +/** + @method pane + This method replaces child contents of a pane indicated by id attribute with contents of inputted element. + If second argument is not specified, it will act as a getter method. + +
+
pane0
+
pane1
+
+ $(".selector").splitview("pane", id, element); +*/ + +/** + @method maximize + This method maximizes a pane's size indicated by id. + +
+
pane0
+
pane1
+
+ $(".selector").splitview("maximize", id); +*/ + +/** + @method restore + This method restores all panes' sizes to the ratio prior to maximization. + +
+
pane0
+
pane1
+
+ $(".selector").splitview("restore"); +*/ + +( function ( $, window, document, undefined ) { + $.widget( "tizen.splitview", $.mobile.widget, { + options : { + fixed : false, + dividerVertical : true, + ratio : [], + initSelector : ":jqmData(role='splitview')" + }, + + _create : function () { + var self = this, + $el = self.element, + opt = self.options, + $panes = $el.children( ".ui-pane" ), + panesLength = $panes.length, + spliters = [], + spliterBars = [], + ratioAttr = this.element.attr( "data-ratio" ), + containerSize = [ 0, 0 ], + resizeTimer = null, + i = 0; + + if ( panesLength !== 2 ) { + if ( panesLength < 2 ) { + for ( i = panesLength ; i < 2 ; ++i ) { + self._addEmptyPanes(); + } + } else { + $panes.slice( 2 ).remove(); + } + + $panes = $el.children( ".ui-pane" ); + panesLength = $panes.length; + } + + spliters[ 0 ] = $( "" ).insertAfter( $panes[ 0 ] ); + spliterBars[ 0 ] = $( "
" ).appendTo( spliters[ 0 ] ); + $( "
" ).appendTo( spliterBars[ 0 ] ); + + $.extend( this, { + moveTarget : null, + moveData : {}, + spliters : spliters, + spliterBars : spliterBars, + panes : $panes, + containerSize : containerSize, + touchStatus : false, + minPaneWidth : 50, + savedRatio : [] + }); + + self._bindTouchEvents(); + self._convertRatio( ratioAttr, $panes.length ); + + $el.addClass( "ui-splitview ui-direction-" + self._direction( opt.dividerVertical ) ); + + self._refresh(); + + $( window ).unbind( ".splitview" ) + .bind( "pagechange.splitview resize.splitview", function ( event ) { + $( ".ui-page-active .ui-splitview" ).each( function () { + $( this ).data( "splitview" )._refresh(); + }); + }); + }, + + _addEmptyPanes : function () { + var self = this, + $el = self.element, + opt = self.options, + $panes = $el.children( ".ui-pane" ), + scrollAttribute = ( $.support.scrollview ) ? "data-scroll='y'" : "", + pane = $( "
" ); + + if ( scrollAttribute.length ) { + pane.scrollview( { direction: "y" } ); + } + + if ( !$panes.length ) { + $el.append( pane ); + } else { + $panes.last().after( pane ); + } + }, + + _direction : function ( isHorizontal ) { + return isHorizontal ? "horizontal" : "vertical"; + }, + + _isStyleSpecified : function ( cssString ) { + return ( typeof cssString !== "undefined" && cssString.length ); + }, + + _getContainerSize : function ( widthString, heightString ) { + var self = this, + $el = self.element, + widthSpecified = self._isStyleSpecified( widthString ), + heightSpecified = self._isStyleSpecified( heightString ); + + self.containerSize[ 0 ] = ( widthSpecified ) ? $el.outerWidth( true ) : self._parentWidth(); + self.containerSize[ 1 ] = ( heightSpecified ) ? $el.outerHeight( true ) : self._parentHeight(); + + if ( !self.containerSize[ 0 ] || !self.containerSize[ 1 ] ) { + return false; + } + + return true; + }, + + _parentWidth : function () { + var $parent = this.element.parent(); + + if ( !$parent && typeof $parent === "undefined" && !$parent.length ) { + return $( window ).width(); + } + + return $parent.width(); + }, + + _parentHeight : function () { + var $parent = this.element.parent(), + heightString = "", + heightSpecified = false, + parentHeight = 0; + + while ( $parent && typeof $parent !== "undefined" && $parent.length ) { + if ( typeof $parent[ 0 ].style !== "undefined" ) { + heightString = $parent[ 0 ].style.height; + heightSpecified = ( typeof heightString !== "undefined" && heightString.length ); + if ( heightSpecified ) { + parentHeight = $parent.height(); + break; + } + } + + $parent = $parent.parent(); + } + + if ( !heightSpecified ) { + parentHeight = $(window).height(); + } + + return parentHeight; + }, + + _convertRatio : function ( ratioParam, panesLength ) { + var self = this, + ratio = [], + loop = 0, + type = typeof ratioParam, + ratioArray = null, + i; + + for ( i = 0; i < panesLength; ++i ) { + ratio.push( 0 ); + } + + switch ( type ) { + case "number": + if ( panesLength ) { + ratio[ 0 ] = ratioParam; + } + break; + + case "string": + ratioArray = ratioParam.split( "," ); + loop = Math.min( ratioArray.length, panesLength ); + for ( i = 0; i < loop; ++i ) { + ratio[ i ] = parseFloat( ratioArray[ i ] ); + } + break; + + case "object": + if ( !$.isArray( ratioParam ) ) { + break; + } + + loop = Math.min( ratioParam.length, panesLength ); + for ( i = 0; i < loop; ++i ) { + type = typeof ratioParam[ i ]; + ratio[ i ] = ( type === "string" ) ? parseFloat( ratioParam[ i ] ) : + ( type === "number" ) ? ratioParam[ i ] : 0; + } + break; + } + + self.options.ratio = ratio; + self._adjustRatio( panesLength ); + }, + + _adjustRatio : function ( panesLength ) { + var self = this, + ratio = self.options.ratio, + sum = 0, + remain = 0, + value = 0, + subValue = 0, + subRemain = 0, + i; + + if ( !panesLength ) { + self.options.ratio = []; + return; + } + + for ( i in ratio ) { + sum += ratio[ i ]; + } + + if ( sum !== 1 ) { + remain = 1 - sum; + value = remain / panesLength; + + for ( i in ratio ) { + if ( value >= 0 ) { + ratio[ i ] += value; + remain = Math.max( 0, remain - value ); + } else { + subRemain += value; + subValue = Math.max( subRemain, ratio[ i ] * -1 ); + ratio[ i ] = Math.max( 0, ratio[ i ] + subValue ); + remain = Math.min( 0, remain - subValue ); + subRemain -= subValue; + } + } + + if ( remain ) { + if ( remain > 0 ) { + ratio[ ratio.length - 1 ] += remain; + } else { + for ( i = ratio.length - 1; i >= 0; --i ) { + subValue = Math.max( remain, ratio[ i ] * -1 ); + ratio[ i ] = Math.max( 0, ratio[ i ] + subValue ); + remain = Math.min( 0, remain - subValue ); + if ( !remain ) { + break; + } + } + } + } + + self.options.ratio = ratio; + } + }, + + _setOption : function ( key, value ) { + var self = this, + orgValue = self.options[ key ]; + + if ( orgValue === value ) { + return; + } + + $.Widget.prototype._setOption.apply( this, arguments ); + + switch ( key ) { + case "fixed": + self._fixed( value ); + break; + + case "dividerVertical": + self._dividerVertical( value ); + break; + + case "ratio": + self._ratio( value ); + break; + } + }, + + _subtractDiffWidth : function ( width, diff ) { + var self = this; + + if ( width <= self.minPaneWidth ) { + return { + width: width, + diff: diff + }; + } + + width += diff; + if ( width >= self.minPaneWidth ) { + return { + width: width, + diff: 0 + }; + } + + return { + width: self.minPaneWidth, + diff: width - self.minPaneWidth + }; + }, + + _initRatio : function ( fromFirstPane, panes, isHorizontal, availableWidth ) { + var self = this, + sum = 0, + widths = [], + diff = 0, + panesLength = panes.length, + ret, + i; + + panes.each( function ( i ) { + var pane = $( this ); + widths.push( isHorizontal ? pane.width() : pane.height() ); + sum += widths[ i ]; + }); + + diff = availableWidth - sum; + if ( !diff ) { + return widths; + } + + if ( diff > 0 ) { + widths[ fromFirstPane ? 0 : panesLength - 1 ] += diff; + } else { + if ( fromFirstPane ) { + for ( i = 0; i < panesLength; ++i ) { + ret = self._subtractDiffWidth( widths[ i ], diff ); + widths[ i ] = ret.width; + diff = ret.diff; + if ( !diff ) { + break; + } + } + } else { + for ( i = panesLength - 1; i >= 0; --i ) { + diff = self._subtractDiffWidth( widths[ i ], diff ); + widths[ i ] = ret.width; + diff = ret.diff; + if ( !diff ) { + break; + } + } + } + } + + sum = 0; + for ( i in widths ) { + sum += widths[ i ]; + } + + for ( i in self.options.ratio ) { + self.options.ratio[ i ] = widths[ i ] / sum; + } + + return widths; + }, + + _horizontalBoundary : function () { + var self = this, + $el = self.element; + + return $el.outerWidth( true ) - $el.width(); + }, + + _verticalBoundary : function () { + var self = this, + $el = self.element; + + return $el.outerHeight( true ) - $el.height(); + }, + + _boundary : function ( type ) { + var self = this, + $el = self.element, + computedStyle = window.getComputedStyle( $el[ 0 ], null ), + margin = parseFloat( computedStyle[ "margin" + type ] ), + border = parseFloat( computedStyle[ "border" + type + "Width" ] ), + padding = parseFloat( computedStyle[ "padding" + type ] ); + + return { + margin: margin, + border: border, + padding: padding + }; + }, + + _layout : function ( initRatio, fromFirstPane ) { + var self = this, + $el = self.element, + opt = self.options, + isHorizontal = opt.dividerVertical, + $panes = self.panes, + spliters = self.spliters, + spliterBars = self.spliterBars, + spliterBar = self.spliterBars.length ? $( spliterBars[ 0 ] ) : null, + spliterWidth = !spliterBar ? 0 : + isHorizontal ? spliterBar.outerWidth() : + spliterBar.outerHeight(), + spliterBarMargin = !spliterBar ? 0 : + isHorizontal ? + spliterBar.outerWidth( true ) - spliterBar.outerWidth() : + spliterBar.outerHeight( true ) - spliterBar.outerHeight(), + panesLength = $panes.length, + currentAvailable = 0, + spliterSize = spliterWidth * ( panesLength - 1 ), + parentWidth = self.containerSize[ 0 ], + parentHeight = self.containerSize[ 1 ], + width = parentWidth - self._horizontalBoundary(), + height = parentHeight - self._verticalBoundary(), + innerSize = isHorizontal ? height : width, + availableWidth = isHorizontal ? width - spliterSize : + height - spliterSize, + initializedWidth = [], + widthSum = 0, + childSplitview = null; + + initRatio = !!initRatio; + fromFirstPane = !!fromFirstPane; + + $el.css( { + "min-width" : width, + "min-height" : height + }); + + if ( initRatio ) { + initializedWidth = self._initRatio( fromFirstPane, $panes, isHorizontal, availableWidth ); + } + + currentAvailable = availableWidth; + $panes.each( function ( i ) { + var $pane = $( this ), + paneWidth = initRatio ? initializedWidth[ i ] : + Math.floor( availableWidth * self.options.ratio[i] ), + prevPane = ( ( i ) ? $panes.eq( i - 1 ) : null ), + posValue = 0, + widthValue = 0, + heightValue = 0, + boundary = 0; + + currentAvailable -= paneWidth; + if ( i === ( panesLength - 1 ) ) { + if ( self.touchStatus ) { + paneWidth = self.moveData.nextPaneWidth = availableWidth - ( self.moveData.targetPos + spliterWidth ); + } else { + paneWidth = Math.max( Math.min( paneWidth, self.minPaneWidth ), paneWidth + currentAvailable ); + } + } + + widthSum += paneWidth; + + if ( !prevPane ) { + boundary = self._boundary( isHorizontal ? "Left" : "Top" ); + posValue = boundary.padding; + } else { + posValue = parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 ); + posValue += isHorizontal ? prevPane.width() : prevPane.height(); + posValue += spliterWidth; + } + + widthValue = isHorizontal ? paneWidth : innerSize; + heightValue = isHorizontal ? innerSize : paneWidth; + + $pane.css( { + "width" : widthValue , + "height" : heightValue + } ); + + $pane.css( ( isHorizontal ? "left" : "top" ), posValue ); + }); + + $panes.each( function ( i ) { + var $pane = $( this ), + paneWidth = isHorizontal ? $pane.width() : $pane.height(); + + self.options.ratio[ i ] = paneWidth / widthSum; + }); + + $.each( spliters, function ( i ) { + var spliter = $( this ), + prevPane = $panes.eq( i ), + bar = spliter.children( ".ui-spliter-bar" ), + handle = bar.children( ".ui-spliter-handle" ), + posValue = 0; + + if ( isHorizontal ) { + posValue = parseInt( prevPane.css( "left" ), 10 ) + prevPane.width() - spliterBarMargin; + spliter.outerHeight( innerSize ).css( "left", posValue ); + } else { + posValue = parseInt( prevPane.css( "top" ), 10 ) + prevPane.height() - spliterBarMargin; + spliter.outerWidth( innerSize ).css( "top", posValue ); + } + + if ( bar.length ) { + bar[ isHorizontal ? "outerHeight" : "outerWidth" ]( innerSize ); + } + if ( handle.length ) { + handle.css( isHorizontal ? "top" : "left", ( innerSize - spliterWidth ) / 2 ); + } + }); + + childSplitview = $el.find( ".ui-splitview:first" ); + if ( !childSplitview.length ) { + return; + } + + childSplitview = childSplitview.data( "splitview" ); + if ( childSplitview ) { + childSplitview._refresh(); + } + }, + + _bindTouchEvents : function () { + var self = this, + $el = self.element, + $panes = self.panes, + spliters = self.spliters; + + $.each( spliters, function ( i ) { + var spliter = $( this ); + self._bindSpliterTouchEvents.call( self, spliter ); + }); + }, + + _bindSpliterTouchEvents : function ( spliter ) { + var self = this, + $el = self.element, + opt = self.options, + touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ), + touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".splitview", + touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".splitview"; + + spliter.bind( touchStartEvt, { e : spliter }, function ( event ) { + if ( self.options.fixed ) { + return; + } + + var realEvent = $.support.touch ? event.originalEvent.changedTouches[0] : event, + targetSpliter = event.data.e, + prevPane = targetSpliter.prev(), + nextPane = targetSpliter.next(), + splitviewInPrev = prevPane.find( ".ui-splitview:first" ), + splitviewInNext = nextPane.find( ".ui-splitview:first" ), + isHorizontal = opt.dividerVertical, + spliterWidth = isHorizontal ? + $( self.spliterBars[0] ).outerWidth() : + $( self.spliterBars[0] ).outerHeight(); + + self.moveTarget = targetSpliter; + self.moveData = { + spliterWidth : spliterWidth || 0, + prevPane : prevPane, + nextPane : nextPane, + splitviewInPrev : splitviewInPrev, + splitviewInNext : splitviewInNext, + prevPanePos : parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0, + prevPaneWidth : parseInt( prevPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0, + nextPanePos : parseInt( nextPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0, + nextPaneWidth : parseInt( nextPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0, + targetPos : parseInt( targetSpliter.css( isHorizontal ? "left" : "top" ), 10 ) || 0, + pagePos : isHorizontal ? realEvent.pageX : realEvent.pageY + }; + + targetSpliter.addClass( "ui-spliter-active" ); + + $el.bind( touchMoveEvt, function ( event ) { + if ( !self.touchStatus ) { + return; + } + event.stopPropagation(); + self._drag( $.support.touch ? event.originalEvent.changedTouches[0] : event ); + }).bind( touchEndEvt, function ( event ) { + event.stopPropagation(); + self._stop( $.support.touch ? event.originalEvent.changedTouches[0] : event ); + self.touchStatus = false; + $el.unbind( ".splitview" ); + $( document ).unbind( ".splitview" ); + }); + + $( document ).bind( touchMoveEvt + " " + touchEndEvt, function () { + $el.trigger( touchEndEvt ); + }); + + event.preventDefault(); + self.touchStatus = true; + }); + }, + + _drag : function ( e ) { + if ( !this.moveData || typeof this.moveData === "undefined" ) { + return; + } + + var self = this, + $el = self.element, + opt = self.options, + isHorizontal = opt.dividerVertical, + moveData = self.moveData, + moveTarget = self.moveTarget, + prevPane = moveData.prevPane, + nextPane = moveData.nextPane, + splitviewInPrev = moveData.splitviewInPrev, + splitviewInNext = moveData.splitviewInNext, + spliterWidth = moveData.spliterWidth, + movement = null, + targetPos = null, + nextPanePos = null, + prevPaneWidth = null, + nextPaneWidth = null, + pagePos = isHorizontal ? e.pageX : e.pageY, + splitview = null; + + movement = pagePos - moveData.pagePos; + if ( movement > 0 ) { + movement = Math.min( Math.max( moveData.nextPaneWidth - self.minPaneWidth, 0 ), movement ); + } else { + movement = Math.max( Math.max( moveData.prevPaneWidth - self.minPaneWidth, 0 ) * -1, movement ); + } + + nextPanePos = moveData.nextPanePos + movement; + prevPaneWidth = Math.max( moveData.prevPaneWidth + movement, 0 ); + nextPaneWidth = Math.max( moveData.nextPaneWidth - movement, 0 ); + targetPos = moveData.targetPos + movement; + + moveTarget.css( isHorizontal ? { left : targetPos } : { top : targetPos } ); + prevPane.css( isHorizontal ? { width : prevPaneWidth } : { height : prevPaneWidth } ); + nextPane.css( isHorizontal ? { width : nextPaneWidth, left : nextPanePos } : + { height : nextPaneWidth, top : nextPanePos } ); + + if ( splitviewInPrev.length ) { + splitview = splitviewInPrev.data( "splitview" ); + splitview._refresh( true, false ); + } + + if ( splitviewInNext.length ) { + splitview = splitviewInNext.data( "splitview" ); + splitview._refresh( true, true ); + } + }, + + _stop : function ( e ) { + if ( !this.moveData || !this.moveTarget ) { + return; + } + + var self = this, + $el = self.element, + opt = self.options, + $panes = self.panes, + panesLength = $panes.length, + isHorizontal = opt.dividerVertical, + moveData = self.moveData, + moveTarget = self.moveTarget, + prevPane = moveData.prevPane, + nextPane = moveData.nextPane, + splitviewInPrev = moveData.splitviewInPrev, + splitviewInNext = moveData.splitviewInNext, + spliterWidth = moveData.spliterWidth, + spliterSize = spliterWidth * ( panesLength - 1 ), + movement = null, + targetPos = null, + nextPanePos = null, + prevPaneWidth = null, + nextPaneWidth = null, + displayStyle = $el.css( "display" ), + parentWidth = self.containerSize[ 0 ], + parentHeight = self.containerSize[ 1 ], + width = parentWidth - self._horizontalBoundary(), + height = parentHeight - self._verticalBoundary(), + availableWidth = isHorizontal ? + ( width - spliterSize ) : + ( height - spliterSize ), + sum = 0; + + moveTarget.removeClass( "ui-spliter-active" ); + + // ratio calculation + $panes.each( function ( i ) { + var $pane = $( this ), + paneWidth = isHorizontal ? $pane.width() : $pane.height(); + + sum += paneWidth; + }); + + $panes.each( function ( i ) { + var $pane = $( this ), + paneWidth = isHorizontal ? $pane.width() : $pane.height(); + + self.options.ratio[ i ] = paneWidth / sum; + }); + + self.moveData = null; + }, + + _fixed : function ( isFix ) { + var self = this, + spliters = self.spliters; + + $.each( spliters, function ( i ) { + var $spliter = $( this ); + + if ( isFix ) { + $spliter.addClass( "ui-fixed" ); + } else { + $spliter.removeClass( "ui-fixed" ); + } + }); + + self._layout(); + }, + + _dividerVertical : function ( isDividerVertical ) { + var self = this, + $el = self.element, + isHorizontal = isDividerVertical, + $panes = null, + $spliters = null, + $bar = null, + $handle = null; + + $panes = $el.children( ".ui-pane" ); + $spliters = $el.children( ".ui-spliter" ); + $bar = $spliters.children( ".ui-spliter-bar" ); + $handle = $bar.children( ".ui-spliter-handle" ); + + $el.removeClass( "ui-direction-vertical" ); + $el.removeClass( "ui-direction-horizontal" ); + $el.addClass( "ui-splitview ui-direction-" + self._direction( isHorizontal ) ); + + $panes.css( { + "left" : "", + "top" : "", + "width" : "", + "height" : "" + }); + + $spliters.css( { + "left" : "", + "top" : "", + "width" : "", + "height" : "" + }); + + $bar.css( { + "width" : "", + "height" : "" + }); + + $handle.css( { + "left" : "", + "top" : "" + }); + + if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) { + self._layout(); + } + }, + + _ratio : function ( ratioParam ) { + var self = this, + $el = self.element, + $panes = $el.children( ".ui-pane" ), + panesLength = $panes.length; + + self._convertRatio( ratioParam, panesLength ); + self._layout(); + }, + + _refresh : function ( initRatio, fromFirstPane ) { + var self = this, + $el = self.element; + + initRatio = !!initRatio; + fromFirstPane = !!fromFirstPane; + + if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) { + self._layout( initRatio, fromFirstPane ); + } + }, + + pane : function ( id, element ) { + if ( typeof id !== "string" ) { + return null; + } + + var self = this, + $el = self.element, + $targetPane = $el.children( id ), + $targetView = null, + elementParent = null; + + if ( !$targetPane.hasClass( "ui-pane" ) ) { + return null; + } + + // getter + if ( !element ) { + return $targetPane.contents(); + } + + // setter + if ( $targetPane.hasClass( "ui-scrollview-clip" ) ) { + $targetPane.scrollview( "scrollTo", 0, 0, 0 ); + + $targetView = $targetPane.children( ".ui-scrollview-view" ); + if ( !$targetView.length ) { + return null; + } + } else { + $targetView = $targetPane; + } + + elementParent = element.parent(); + if ( elementParent.length && elementParent[ 0 ] === $targetView[ 0 ] ) { + return; + } + + $targetView.empty().append( element ).trigger( "create" ); + $targetView.fadeIn( 'fast' ); + }, + + maximize : function ( id ) { + if ( typeof id !== "string" ) { + return; + } + + var self = this, + $el = self.element, + $panes = self.panes, + $targetPane = $el.children( id ); + + if ( !$targetPane.hasClass( "ui-pane" ) ) { + return; + } + + self.savedRatio = self.options.ratio.slice(); + + self.options.ratio = []; + $panes.each( function ( i ) { + self.options.ratio.push( ( this === $targetPane[ 0 ] ) ? 1 : 0 ); + }); + + self._layout(); + }, + + restore : function () { + var self = this; + + if ( !self.savedRatio.length ) { + return; + } + + self.options.ratio = self.savedRatio.slice(); + self._adjustRatio( self.panes.length ); + + self._layout(); + } + }); + + $( document ).bind( "pagecreate create", function ( e ) { + $.tizen.splitview.prototype.enhanceWithin( e.target ); + }); +} ( jQuery, window, document ) ); + +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +} ); +//>>excludeEnd("jqmBuildExclude"); http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.swipe.js ---------------------------------------------------------------------- diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.swipe.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.swipe.js new file mode 100644 index 0000000..90dc1b5 --- /dev/null +++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.swipe.js @@ -0,0 +1,350 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Shows background listitem by swiping left/right on a listitem +//>>label: Swipe list +//>>group: Tizen:Widgets + +define( [ + 'jquery', + '../jquery.mobile.tizen.core', + "jqm/jquery.mobile.widget" + ], function ( jQuery ) { + +//>>excludeEnd("jqmBuildExclude"); + +/* + * jQuery Mobile Widget @VERSION + * + * This software is licensed under the MIT licence (as defined by the OSI at + * http://www.opensource.org/licenses/mit-license.php) + * + * *************************************************************************** + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * Copyright (c) 2011 by Intel Corporation Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * *************************************************************************** + * + * Authors: Kalyan Kondapally , + * Elliot Smith + * Hyunjung Kim + */ + +// Widget which turns a html element into a "swipe": +// i.e. each list item has a sliding "cover" which can be swiped +// to the right (to reveal buttons underneath) or left (to +// cover the buttons again). Clicking on a button under a swipe +// also moves the cover back to the left. +// +// In this case, the cover is over a grid of buttons; +// but it is should also be possible to use other types of markup under the +// list items. +// +// WARNING: This doesn't work well inside a scrollview widget, as +// the touch events currently interfere with each other badly (e.g. +// a swipe will work but cause a scroll as well). +// +// Theme: default is to use the theme on the target element, +// theme passed in options, parent theme, or 'c' if none of the above. +// If list items are themed individually, the cover will pick up the +// theme of the list item which is its parent. +// + +/** + @class Swipe + The swipe widget shows a view on the screen where the items can be swiped vertically to show a menu. + To add a swipe widget to the application, use the following code: + +
    +
  • +
    +
    OK
    +
    Cancel
    +
    +
    +

    This is a swipe item cover.
    + This will be swiped out when swipe event comes.

    +
    +
  • +
+ + You can use methods with the swipe as described in the jQueryMobile documentation for view methods. +*/ +/** + @property {String} data-role + Creates a swipe using the HTML unordered view (>ul<) element. + The default value is swipe. + + Creates a swipe item cover using an HTML $gt;div$lt; element. This cover can be swiped to show the content beneath it. + The default value is swipe-item-cover. +*/ +/** + @method open + uncover swipe item +*/ +/** + @method close + cover swipe item +*/ +/** + @method opened + return coveritem status( coverd or uncovred ) +*/ +/** + @event animationstart + The swipe can define a callback for the animationstart event, which is fired after a item is swipe and the swipe animation is start: +*/ +/** + @event animationend + The swipe can define a callback for the animationend event, which is fired after a item is swiped and the swipe animation is complete: + +
    +
  • +
    +
    OK
    +
    Cancel
    +
    +
    +

    This is a swipe item cover.
    + This will be swiped out when swipe event comes.

    +
    +
  • +
+ $("#foo").bind("animationend", function (ev) + { + Console.log("Swipe cover's animation is complete."); + }); +*/ +(function ($) { + + $.widget("tizen.swipe", $.mobile.widget, { + options: { + theme: null + }, + + _create: function () { + // use the theme set on the element, set in options, + // the parent theme, or 'c' (in that order of preference) + var theme = this.element.jqmData('theme') || + this.options.theme || + this.element.parent().jqmData('theme') || + 's'; + + this.options.theme = theme; + this._isopen = false; + this.refresh(); + }, + + refresh: function () { + this._cleanupDom(); + + var self = this, + defaultCoverTheme, + covers, + coverTheme, + item, + itemHasThemeClass; + + defaultCoverTheme = 'ui-body-' + this.options.theme; + + if ( !this.element.parent().hasClass('ui-listview') ) { + this.element.parent().listview(); + } + this.element.addClass('ui-swipe'); + + // get the item covers + covers = this.element.find(':jqmData(role="swipe-item-cover")'); + item = this.element.find(':jqmData(role="swipe-item")'); + + this._covers = covers; + this._item = item; + item.addClass('ui-swipe-item'); + coverTheme = defaultCoverTheme; + itemHasThemeClass = item.parent().attr('class') + .match(/ui\-body\-[a-z]|ui\-bar\-[a-z]/); + + covers.each( function () { + var cover = $( this ); + + if ( itemHasThemeClass ) { + coverTheme = itemHasThemeClass[0]; + } + + cover.addClass('ui-swipe-item-cover'); + cover.addClass( coverTheme ); + + if ( cover.has('.ui-swipe-item-cover-inner').length === 0 ) { + cover.wrapInner( $('').addClass('ui-swipe-item-cover-inner') ); + } + + if ( !( cover.data('animateRight') && cover.data('animateLeft') ) ) { + cover.data('animateRight', function () { + self._animateCover( cover, 110, item ); + }); + + cover.data('animateLeft', function () { + self._animateCover( cover, 0, item ); + }); + } + + // bind to synthetic events + item.bind( 'swipeleft', cover.data('animateLeft') ); + cover.bind( 'swiperight', cover.data('animateRight') ); + item.find( '.ui-btn' ).bind( 'vclick', cover.data('animateLeft') ); + } ); + + }, + + _cleanupDom: function () { + var self = this, + defaultCoverTheme, + cover, + coverTheme = defaultCoverTheme, + item, + itemClass, + itemHasThemeClass, + text, + wrapper; + + defaultCoverTheme = 'ui-body-' + this.options.theme; + + this.element.removeClass('ui-swipe'); + + // get the item covers + cover = this.element.find(':jqmData(role="swipe-item-cover")'); + item = this.element.find(':jqmData(role="swipe-item")'); + + item.removeClass('ui-swipe-item'); + cover.removeClass('ui-swipe-item-cover'); + + itemClass = item.attr('class'); + itemHasThemeClass = itemClass && + itemClass.match(/ui\-body\-[a-z]|ui\-bar\-[a-z]/); + + if ( itemHasThemeClass ) { + coverTheme = itemHasThemeClass[0]; + } + + cover.removeClass(coverTheme); + + // remove wrapper HTML + wrapper = cover.find('.ui-swipe-item-cover-inner'); + wrapper.children().unwrap(); + text = wrapper.text(); + + if ( text ) { + cover.append( text ); + wrapper.remove(); + } + + // unbind swipe events + if ( cover.data('animateRight') && cover.data('animateLeft') ) { + cover.unbind( 'swiperight', cover.data('animateRight') ); + item.unbind( 'swipeleft', cover.data('animateLeft') ); + + // unbind clicks on buttons inside the item + item.find('.ui-btn').unbind( 'vclick', cover.data('animateLeft') ); + + cover.data( 'animateRight', null ); + cover.data( 'animateLeft', null ); + } + }, + + // NB I tried to use CSS animations for this, but the performance + // and appearance was terrible on Android 2.2 browser; + // so I reverted to jQuery animations + // + // once the cover animation is done, the cover emits an + // animationComplete event + _animateCover: function ( cover, leftPercentage, item ) { + var self = this, + animationOptions = { + easing: 'linear', + duration: 'normal', + queue: true, + complete: function () { + cover.trigger('animationend'); + } + }; + + $( this.element.parent() ) + .find(":jqmData(role='swipe')") + .each( + function () { + if ( this !== self.element.get(0) && + $( this ).swipe("opened") ) { + $( this ).swipe("close"); + } + } + ); + + if ( leftPercentage == 110 ) { + this._isopen = true; + } else { + this._isopen = false; + } + + cover.stop(); + cover.clearQueue(); + cover.trigger('animationstart'); + cover.clearQueue().animate( { left: leftPercentage + '%' }, animationOptions ); + if ( leftPercentage == 0 ) { + item.clearQueue().animate({ opacity: 0 }, "slow"); + } else { + item.clearQueue().animate({ opacity: 1 }, "slow"); + } + + }, + + destroy: function () { + this._cleanupDom(); + }, + + open: function () { + var self = this; + + $( self._covers ).each( function () { + var cover = $( this ); + self._animateCover( cover, 110, self._item); + } ); + }, + + opened: function () { + return this._isopen; + }, + + close: function () { + var self = this; + + $( self._covers ).each( function () { + var cover = $( this ); + self._animateCover( cover, 0, self._item); + } ); + } + + }); + + $( document ).bind("pagecreate", function ( e ) { + $( e.target ).find(":jqmData(role='swipe')").swipe(); + }); + +}( jQuery )); + +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +} ); +//>>excludeEnd("jqmBuildExclude"); http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tabbar.js ---------------------------------------------------------------------- diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tabbar.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tabbar.js new file mode 100644 index 0000000..13adcb2 --- /dev/null +++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tabbar.js @@ -0,0 +1,287 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Shows buttons divided automatically on the header +//>>label: Tabbar +//>>group: Tizen:Widgets + +define( [ + 'jquery', + '../jquery.mobile.tizen.core', + './jquery.mobile.tizen.pagelayout' + ], function ( jQuery ) { + +//>>excludeEnd("jqmBuildExclude"); + +/* *************************************************************************** + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * *************************************************************************** + * + * jQuery Mobile Framework : "tabbar" plugin + * Copyright (c) jQuery Project + * Licensed under the MIT license. + * http://jquery.org/license + * Authors: Jinhyuk Jun +*/ + +/** + * Tabbar can be created using data-role = "tabbar" inside footer + * Framework determine which tabbar will display with tabbar attribute + * + * Examples: + * + * HTML markup for creating tabbar: ( 2 ~ 5 li item available ) + * icon can be changed data-icon attribute (customized icon need) + *
+ *
+ * + *
+ *
+*/ + +(function ( $, undefined ) { + + $.widget( "tizen.tabbar", $.mobile.widget, { + options: { + iconpos: "top", + grid: null, + defaultList : 4, + initSelector: ":jqmData(role='tabbar')" + }, + + _create: function () { + + var $tabbar = this.element, + $tabbtns, + textpos, + iconpos, + theme = $.mobile.listview.prototype.options.theme, /* Get current theme */ + ww = window.innerWidth || $( window ).width(), + wh = window.innerHeight || $( window ).height(), + tabbarDividerLeft = "
", + tabbarDividerRight = "
", + isLandscape; + + isLandscape = ww > wh && ( ww - wh ); + + if ( isLandscape ) { + $tabbar.removeClass( "ui-portrait-tabbar" ).addClass( "ui-landscape-tabbar" ); + } else { + $tabbar.removeClass( "ui-landscape-tabbar" ).addClass( "ui-portrait-tabbar" ); + } + + if ( $tabbar.find( "a" ).length ) { + $tabbtns = $tabbar.find( "a" ); + iconpos = $tabbtns.filter( ":jqmData(icon)" ).length ? this.options.iconpos : undefined; + textpos = $tabbtns.html().length ? true : false; + } + + if ( $tabbar.parents( ".ui-header" ).length && $tabbar.parents( ".ui-scrollview-view" ).length ) { + $tabbar.find( "li" ).addClass( "tabbar-scroll-li" ); + $tabbar.find( "ul" ).addClass( "tabbar-scroll-ul" ); + + /* add shadow divider */ + $( tabbarDividerLeft ).appendTo( $tabbar.parents( ".ui-scrollview-clip" ) ); + $( tabbarDividerRight ).appendTo( $tabbar.parents( ".ui-scrollview-clip" ) ); + + $( ".ui-tabbar-divider-left" ).hide(); + $( ".ui-tabbar-divider-right" ).hide(); + + /* add width calculation*/ + if ( $tabbar.parents( ".ui-scrollview-view" ).data("default-list") ) { + this.options.defaultList = $tabbar.parents( ".ui-scrollview-view" ).data( "default-list" ); + } + $tabbar.find( "li" ).css( "width", window.innerWidth / this.options.defaultList + "px" ); + } else { + if ( $tabbar.find( "ul" ).children().length ) { + $tabbar.addClass( "ui-navbar" ) + .find( "ul" ) + .grid( { grid: this.options.grid } ); + } + } + + if ( $tabbar.parents( ".ui-footer" ).length ) { + $tabbar.find( "li" ).addClass( "ui-tab-btn-style" ); + } + + /* title tabbar */ + if ( $tabbar.siblings( ".ui-title" ).length ) { + $tabbar.parents( ".ui-header" ).addClass( "ui-title-tabbar" ); + } + + if ( !iconpos ) { + $tabbar.addClass( "ui-tabbar-noicons" ); + } + if ( !textpos ) { + $tabbar.addClass( "ui-tabbar-notext" ); + } + if ( textpos && iconpos ) { + $tabbar.parents( ".ui-header" ).addClass( "ui-title-tabbar-multiline" ); + } + + if ( $tabbar.find( "a" ).length ) { + $tabbtns.buttonMarkup({ + corners: false, + shadow: false, + iconpos: iconpos + }); + } + + if ( $tabbar.find( ".ui-state-persist" ).length ) { + $tabbar.addClass( "ui-tabbar-persist" ); + } + + $tabbar.delegate( "a", "vclick", function ( event ) { + if ( $tabbtns.parents( "ul" ).is( ".tabbar-scroll-ul" ) ) { + $tabbtns.removeClass( "ui-tabbar-active" ); + $( event.target ).parents( "a" ).addClass( "ui-tabbar-active" ); + + } else { + $tabbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass ); + $( this ).addClass( $.mobile.activeBtnClass ); + } + }); + + $tabbar.addClass( "ui-tabbar"); + + $( document ).bind( "pagebeforeshow", function ( event, ui ) { + var footer_filter = $( event.target ).find( ":jqmData(role='footer')" ), + tabbar_filter = footer_filter.find( ":jqmData(role='tabbar')" ), + $elFooterMore = tabbar_filter.siblings( ":jqmData(icon='naviframe-more')" ), + $elFooterBack = tabbar_filter.siblings( ".ui-btn-back" ); + + footer_filter + .css( "position", "fixed" ) + .css( "bottom", 0 ) + .css( "height", tabbar_filter.height() ); + if ( $elFooterMore.length ) { + tabbar_filter.addClass( "ui-tabbar-margin-more" ); + } + if ( $elFooterBack.length ) { + tabbar_filter.addClass( "ui-tabbar-margin-back" ); + } + }); + + $tabbar.bind( "touchstart vmousedown", function ( e ) { + var $tabbarScroll = $( e.target ).parents( ".ui-scrollview-view" ); + if ( $tabbarScroll.offset() ) { + if ( $tabbarScroll.offset().left < 0 ) { + $( ".ui-tabbar-divider-left" ).show(); + } else { + $( ".ui-tabbar-divider-left" ).hide(); + } + if ( ( $tabbarScroll.width() - $tabbarScroll.parents( ".ui-scrollview-clip" ).width() ) == Math.abs( $tabbarScroll.offset().left ) ) { + $( ".ui-tabbar-divider-right" ).hide(); + } else { + $( ".ui-tabbar-divider-right" ).show(); + } + } + }); + + this._bindTabbarEvents(); + this._initTabbarAnimation(); + }, + + _initTabbarAnimation: function () { + var isScrollingStart = false, + isScrollingEnd = false; + $( document ).bind( "scrollstart.tabbar", function ( e ) { + if ( $( e.target ).find( ".ui-tabbar" ).length ) { + isScrollingStart = true; + isScrollingEnd = false; + } + }); + + $( document ).bind( "scrollstop.tabbar", function ( e ) { + var $tabbarScrollview = $( e.target ), + $elTabbar = $( e.target ).find( ".ui-tabbar" ), + $elTabbarLI = $( e.target ).find( ".ui-tabbar li" ), + $minElement = $elTabbarLI.eq( 0 ), + minElementIndexVal, + minElementIndex = -1; + + isScrollingEnd = true; + if ( $elTabbar.length && isScrollingStart == true ) { + minElementIndexVal = Math.abs( $elTabbarLI.eq( 0 ).offset().left ); + $elTabbarLI.each( function ( i ) { + var offset = $elTabbarLI.eq( i ).offset(); + + if ( Math.abs( offset.left ) < minElementIndexVal ) { + minElementIndexVal = Math.abs( offset.left ); + minElementIndex = i; + $minElement = $elTabbarLI.eq( i ); + } + }); + + if ( $tabbarScrollview.length && isScrollingStart == isScrollingEnd && minElementIndex != -1) { + isScrollingStart = false; + $tabbarScrollview.scrollview( "scrollTo", -( window.innerWidth / $elTabbar.data( "defaultList" ) * minElementIndex ) , 0, 357); + } + } + + $( ".ui-tabbar-divider-left" ).hide(); + $( ".ui-tabbar-divider-right" ).hide(); + }); + }, + + _bindTabbarEvents: function () { + var $tabbar = this.element; + + $( window ).bind( "orientationchange", function ( e, ui ) { + var ww = window.innerWidth || $( window ).width(), + wh = window.innerHeight || $( window ).height(), + isLandscape = ww > wh && ( ww - wh ); + + if ( isLandscape ) { + $tabbar.removeClass( "ui-portrait-tabbar" ).addClass( "ui-landscape-tabbar" ); + } else { + $tabbar.removeClass( "ui-landscape-tabbar" ).addClass( "ui-portrait-tabbar" ); + } + }); + }, + + _setDisabled: function ( value, cnt ) { + this.element.find( "li" ).eq( cnt ).attr( "disabled", value ); + this.element.find( "li" ).eq( cnt ).attr( "aria-disabled", value ); + }, + + disable: function ( cnt ) { + this._setDisabled( true, cnt ); + this.element.find( "li" ).eq( cnt ).addClass( "ui-disabled" ); + }, + + enable: function ( cnt ) { + this._setDisabled( false, cnt ); + this.element.find( "li" ).eq( cnt ).removeClass( "ui-disabled" ); + } + }); + + //auto self-init widgets + $( document ).bind( "pagecreate create", function ( e ) { + $( $.tizen.tabbar.prototype.options.initSelector, e.target ).tabbar(); + }); +}( jQuery ) ); + +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +} ); +//>>excludeEnd("jqmBuildExclude"); http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tokentextarea.js ---------------------------------------------------------------------- diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tokentextarea.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tokentextarea.js new file mode 100644 index 0000000..483cc20 --- /dev/null +++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.tokentextarea.js @@ -0,0 +1,813 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Make words to selectable tokens +//>>label: Token textarea +//>>group: Tizen:Widgets + +define( [ + 'jquery', + '../jquery.mobile.tizen.core' + ], function ( jQuery ) { + +//>>excludeEnd("jqmBuildExclude"); + +/* *************************************************************************** + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * *************************************************************************** + * + * Author: Kangsik Kim + * Minkyeong Kim +*/ + +/** + * The TokenTextArea widget changes a text item to a button. It can be comprised of a number of button widgets. + * When a user types text and the text gets a specific event to change from a text to a button, + * the input text is changed to a TokenTextArea widget. + * A user can add the TokenTextArea widget to a contact list, email list, or another list. + * The typical use of this widget is composing a number of contacts or phone numbers in a specific area of the screen. + * + * HTML Attributes: + * + * data-link : Represents the id of the page or the URL of other HTML file. + * The page contains data for the user, for example, an address book. + * If the value is null, anchor button doesn't work. (Default : null) + * data-label: Provide a label for a user-guide. (Default : 'To : ') + * data-description : This attribute is managing message format. + * This message is displayed when widget status was changed to 'focusout'. (Default : '+ {0}') + * + * APIs: + * + * inputtext ( [string] ) + * : If argument is not exist, will get a string from inputbox. + * If argument is exist, will set a string to inputbox. + * select ( [number] ) + * : If no argument exists, gets a string of the selected block. + * If any button isn't selected on a token text area widget, this method returns "null" value. + * When a user call this method with an argument which is a number type, + * this method selects the button which is matched with the argument. + * add ( text, [number] ) + * : If second argument does not exist, will insert to a new button at last position. + * Insert a new button at indexed position. The position is decided by the second argument. + * "index of position" means that the position of inserting a new button is decided by the second argument on "add" method. + * For example, if a user call the method like this "add("Tizen", 2)", + * new button labed "Tizen" will be inserted on the third position. + * remove ( [number] ) + * : If no argument exists, all buttons are removed. + * Remove a button at indexed position. + * The position is decided by the second argument. (index: index of button) + * length ( void ) + * : Get a number of buttons. + * foucsIn ( void ) + * : This method change a status to 'focusin'. + * This status is able to manage a widget. + * focusOut ( void ) + * : Changes the focus status to 'focus out'. + * The status is not able to manage a widget. + * All buttons that contained in the widget are removed and + * summarized message is displayed. + * destroy ( void ) + * : Remove all of the new DOM elements for the current widget that you created. + * + * Events: + * + * select : Occur when a button is selected. + * add : Occur when new button is inserted. (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.) + * remove : Occur when a button is removed. (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.) + * + * Examples: + * + *
+ *
+ * + */ + + +/** + @class TokenTextArea + The TokenTextArea widget enables the user to enter text and convert it to a button. Each button that is created from entered text as a result of a change event forms a token text area widget. This widget is useful in composing an e-mail or SMS message to a group of addresses, each of which is a clickable item for more actions, such as copying, editing, or removing the address. + + To add a token text area widget to the application, use the following code: + +
+
+*/ + +/** + @property {String} data-label + Sets a label as a guide for the user. + For example, while composing an e-mail message, the 'To : ' label is a guide for the user to enter e-mail addresses. + +
+
+*/ + +/** + @property {String} data-decription + Manages the message format. + The message is displayed when the widget status changes to focus out + +
+
+ */ +/** + @property {String} data-link + Sets the ID of the page or the URL of other HTML file to which the button links. + If the data-link is set with the URL of other HTML file, the 'dom-cache' option of both page - a page containing a Tokentextarea and a page in the target HTML file - must be set as 'true'. + +
+
+ +
+
+*/ +/** + @event select + The select event is fired when a token text area widget button is selected: + +
+
+ $(".selector").on("select", function(event, ui) + { + // Handle the select event + }); +*/ +/** + @event add (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.) + The add event is fired when a token text area widget button is created: + +
+
+ $(".selector").on("add", function(event, ui) + { + // Handle the add event + }); +*/ +/** + @event remove (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.) + The remove event is fired when a token text area widget button is removed: + Restriction : "remove" event works under only "bind" event handling. + +
+
+ $(".selector").bind("remove", function(event, ui) + { + // Handle the remove event + }); +*/ +/** + @method destroy + The destroy method is used to remove in the current widget all the new DOM elements that you have created. + +
+
+ $(".selector").tokentextarea("destroy"); + + @since Tizen2.0 +*/ +/** + @method inputText + The inputText method is used to manage the widget input box text. If no parameter is set, the method gets the input box text. If a parameter is set, the parameter text is set in the input box. + +
+
+ $(".selector").tokentextarea("inputText", [text]); +*/ +/** + @method select + The select method is used to select a token text area widget button based on its index value. If no index value is defined, the method returns the string of the selected block. If there are no buttons present in the widget, the method returns null. + +
+
+ $(".selector").tokentextarea("select", [index]); +*/ +/** + @method add + The add method is used to add a new token text area widget button with the specified label text at the specified index position. If the index parameter is not defined, the widget button is added at the bottom of the list. For example, the $(".selector").tokentextarea("add", "Tizen", 2) method call creates a new widget button labeled 'Tizen' at the third position in the widget. + +
+
+ $(".selector").tokentextarea("add", [text], [index]); +*/ +/** + @method remove + The remove method is used to remove a token text area widget button at the specified index position. If the parameter is not defined, all the widget buttons are removed. + +
+
+ $(".selector").tokentextarea("remove", [index]); +*/ +/** + @method length + The length method is used to retrieve the number of buttons in the token text area widget: +
+
+ $(".selector").tokentextarea("length"); +*/ +/** + @method focusIn + The focusIn method is used to set the focus status to "focus in". This focus state enables the user to add or remove buttons in the token text area widget. + +
+
+ $(".selector").tokentextarea("focusIn"); +*/ +/** + @method focusOut + The focusOut method is used to set the focus status to "focus out". In this focus state, the user cannot manage the buttons in the widget, all the buttons are removed, and a message is displayed. + +
+
+ $(".selector").tokentextarea("focusOut"); +*/ +( function ( $, window, document, undefined ) { + $.widget( "tizen.tokentextarea", $.mobile.widget, { + _focusStatus : null, + _items : null, + _viewWidth : 0, + _reservedWidth : 0, + _currentWidth : 0, + _fontSize : 0, + _anchorWidth : 0, + _labelWidth : 0, + _marginWidth : 0, + options : { + label : "To : ", + link : null, + description : "+ {0}" + }, + + _create : function () { + var self = this, + $view = this.element, + role = $view.jqmData( "role" ), + option = this.options, + className = "ui-tokentextarea-link", + inputbox = $( document.createElement( "input" ) ), + labeltag = $( document.createElement( "span" ) ), + moreBlock = $( document.createElement( "a" ) ); + + $view.hide().empty().addClass( "ui-" + role ); + + // create a label tag. + $( labeltag ).text( option.label ).addClass( "ui-tokentextarea-label" ).attr( "tabindex", 0 ); + $view.append( labeltag ); + + // create a input tag + $( inputbox ).addClass( "ui-tokentextarea-input ui-tokentextarea-input-visible ui-input-text ui-body-s" ).attr( "role", "textbox" ); + $view.append( inputbox ); + + // create a anchor tag. + if ( option.link === null || $.trim( option.link ).length < 1 || $( option.link ).length === 0 ) { + className += "-dim"; + } + $( moreBlock ).attr( "data-role", "button" ) + .buttonMarkup( { + inline: true, + icon: "plus", + style: "circle" + }) + .attr( { "href" : $.trim( option.link ), "tabindex" : 0 } ) + .addClass( "ui-tokentextarea-link-base" ) + .addClass( className ) + .find( "span.ui-btn-text" ) + .text( "Add recipient" ); + + // append default htmlelements to main widget. + $view.append( moreBlock ); + + // bind a event + this._bindEvents(); + self._focusStatus = "init"; + // display widget + $view.show(); + + // assign global variables + self._viewWidth = $view.innerWidth(); + self._reservedWidth += self._calcBlockWidth( moreBlock ); + self._reservedWidth += self._calcBlockWidth( labeltag ); + self._fontSize = parseInt( $( moreBlock ).css( "font-size" ), 10 ); + self._currentWidth = self._reservedWidth; + self._modifyInputBoxWidth(); + }, + + // bind events + _bindEvents : function () { + var self = this, + $view = self.element, + option = self.options, + inputbox = $view.find( ".ui-tokentextarea-input" ), + moreBlock = $view.find( ".ui-tokentextarea-link-base" ); + + // delegate a event to HTMLDivElement(each block). + $view.delegate( "div", "click", function ( event ) { + if ( $( this ).hasClass( "ui-tokentextarea-sblock" ) ) { + // If block is selected, it will be removed. + self._removeTextBlock(); + } + + var lockBlock = $view.find( "div.ui-tokentextarea-sblock" ); + if ( typeof lockBlock !== "undefined" ) { + lockBlock.removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" ); + } + $( this ).removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" ); + $view.trigger( "select" ); + }); + + inputbox.bind( "keyup", function ( event ) { + // 8 : backspace + // 13 : Enter + // 186 : semi-colon + // 188 : comma + var keyValue = event.keyCode, + valueString = $( inputbox ).val(), + valueStrings = [], + index, + isSeparator = false; + + if ( keyValue === 8 ) { + if ( valueString.length === 0 ) { + self._validateTargetBlock(); + } + } else if ( keyValue === 13 || keyValue === 186 || keyValue === 188 ) { + if ( valueString.length !== 0 ) { + // split content by separators(',', ';') + valueStrings = valueString.split ( /[,;]/ ); + for ( index = 0; index < valueStrings.length; index++ ) { + if ( valueStrings[index].length !== 0 && valueStrings[index].replace( /\s/g, "" ).length !== 0 ) { + self._addTextBlock( valueStrings[index] ); + } + } + } + inputbox.val( "" ); + isSeparator = true; + } else { + self._unlockTextBlock(); + } + + return !isSeparator; + }); + + moreBlock.click( function () { + if ( $( moreBlock ).hasClass( "ui-tokentextarea-link-dim" ) ) { + return; + } + + $( inputbox ).removeClass( "ui-tokentextarea-input-visible" ).addClass( "ui-tokentextarea-input-invisible" ); + + $.mobile.changePage( option.link, { + transition: "slide", + reverse: false, + changeHash: false + }); + }); + + $( document ).bind( "pagechange.mbe", function ( event ) { + if ( $view.innerWidth() === 0 ) { + return ; + } + self.refresh(); + $( inputbox ).removeClass( "ui-tokentextarea-input-invisible" ).addClass( "ui-tokentextarea-input-visible" ); + }); + + $view.bind( "click", function ( event ) { + if ( self._focusStatus === "focusOut" ) { + self.focusIn(); + } + }); + }, + + // create a textbutton and append this button to parent layer. + // @param arg1 : string + // @param arg2 : index + _addTextBlock : function ( messages, blockIndex ) { + if ( arguments.length === 0 ) { + return; + } + + if ( !messages ) { + return ; + } + + var self = this, + $view = self.element, + content = messages, + index = blockIndex, + blocks = null, + textBlock = null; + + if ( self._viewWidth === 0 ) { + self._viewWidth = $view.innerWidth(); + } + + // Create a new text HTMLDivElement. + textBlock = $( document.createElement( 'div' ) ); + + textBlock.text( content ).addClass( "ui-tokentextarea-block" ).attr( { "aria-label" : "double tap to edit", "tabindex" : 0 } ); + textBlock.css( {'visibility': 'hidden'} ); + + blocks = $view.find( "div" ); + if ( index !== null && index <= blocks.length ) { + $( blocks[index] ).before( textBlock ); + } else { + $view.find( ".ui-tokentextarea-input" ).before( textBlock ); + } + + textBlock = self._ellipsisTextBlock( textBlock ); + textBlock.css( {'visibility': 'visible'} ); + + self._modifyInputBoxWidth(); + + textBlock.hide(); + textBlock.fadeIn( "fast", function () { + self._currentWidth += self._calcBlockWidth( textBlock ); + $view.trigger( "add" ); + }); + }, + + _removeTextBlock : function () { + var self = this, + $view = this.element, + lockBlock = $view.find( "div.ui-tokentextarea-sblock" ), + _temp = null, + _dummy = function () {}; + + if ( lockBlock !== null && lockBlock.length > 0 ) { + self._currentWidth -= self._calcBlockWidth( lockBlock ); + + lockBlock.fadeOut( "fast", function () { + lockBlock.remove(); + self._modifyInputBoxWidth(); + }); + + this._eventRemoveCall = true; + if ( $view[0].remove ) { + _temp = $view[0].remove; + $view[0].remove = _dummy; + } + $view.triggerHandler( "remove" ); + if ( _temp) { + $view[0].remove = _temp; + } + this._eventRemoveCall = false; + } else { + $view.find( "div:last" ).removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" ); + } + }, + + _calcBlockWidth : function ( block ) { + return $( block ).outerWidth( true ); + }, + + _unlockTextBlock : function () { + var $view = this.element, + lockBlock = $view.find( "div.ui-tokentextarea-sblock" ); + if ( lockBlock ) { + lockBlock.removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" ); + } + }, + + // call when remove text block by backspace key. + _validateTargetBlock : function () { + var self = this, + $view = self.element, + lastBlock = $view.find( "div:last" ), + tmpBlock = null; + + if ( lastBlock.hasClass( "ui-tokentextarea-sblock" ) ) { + self._removeTextBlock(); + } else { + tmpBlock = $view.find( "div.ui-tokentextarea-sblock" ); + tmpBlock.removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" ); + lastBlock.removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" ); + } + }, + + _ellipsisTextBlock : function ( textBlock ) { + var self = this, + $view = self.element, + maxWidth = self._viewWidth / 2; + + if ( self._calcBlockWidth( textBlock ) > maxWidth ) { + $( textBlock ).width( maxWidth - self._marginWidth ); + } + + return textBlock; + }, + + _modifyInputBoxWidth : function () { + var self = this, + $view = self.element, + margin = 0, + labelWidth = 0, + anchorWidth = 0, + inputBoxWidth = 0, + blocks = $view.find( "div" ), + blockWidth = 0, + index = 0, + inputBoxMargin = 10, + inputBox = $view.find( ".ui-tokentextarea-input" ); + + if ( $view.width() === 0 ) { + return; + } + + if ( self._labelWidth === 0 ) { + self._labelWidth = $view.find( ".ui-tokentextarea-label" ).outerWidth( true ); + self._anchorWidth = $view.find( ".ui-tokentextarea-link-base" ).outerWidth( true ); + self._marginWidth = parseInt( ( $( inputBox ).css( "margin-left" ) ), 10 ); + self._marginWidth += parseInt( ( $( inputBox ).css( "margin-right" ) ), 10 ); + self._viewWidth = $view.innerWidth(); + } + + margin = self._marginWidth; + labelWidth = self._labelWidth; + anchorWidth = self._anchorWidth; + inputBoxWidth = self._viewWidth - labelWidth; + + for ( index = 0; index < blocks.length; index += 1 ) { + blockWidth = self._calcBlockWidth( blocks[index] ); + + if ( blockWidth >= inputBoxWidth + anchorWidth ) { + if ( blockWidth >= inputBoxWidth ) { + inputBoxWidth = self._viewWidth - blockWidth; + } else { + inputBoxWidth = self._viewWidth; + } + } else { + if ( blockWidth > inputBoxWidth ) { + inputBoxWidth = self._viewWidth - blockWidth; + } else { + inputBoxWidth -= blockWidth; + } + } + } + + inputBoxWidth -= margin; + if ( inputBoxWidth < anchorWidth * 2 ) { + inputBoxWidth = self._viewWidth - margin; + } + $( inputBox ).width( inputBoxWidth - anchorWidth - inputBoxMargin ); + }, + + _stringFormat : function ( expression ) { + var pattern = null, + message = expression, + i = 0; + for ( i = 1; i < arguments.length; i += 1 ) { + pattern = "{" + ( i - 1 ) + "}"; + message = message.replace( pattern, arguments[i] ); + } + return message; + }, + + _resizeBlocks : function () { + var self = this, + $view = self.element, + blocks = $view.find( "div" ), + index = 0; + + for ( index = 0 ; index < blocks.length ; index += 1 ) { + $( blocks[index] ).css( "width", "auto" ); + blocks[index] = self._ellipsisTextBlock( blocks[index] ); + } + }, + + //---------------------------------------------------- // + // Public Method // + //----------------------------------------------------// + // + // Focus In Event + // + focusIn : function () { + if ( this._focusStatus === "focusIn" ) { + return; + } + + var $view = this.element; + + $view.find( ".ui-tokentextarea-label" ).attr( "tabindex", 0 ).show(); + $view.find( ".ui-tokentextarea-desclabel" ).remove(); + $view.find( "div.ui-tokentextarea-sblock" ).removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" ); + $view.find( "div" ).attr( { "aria-label" : "double tap to edit", "tabindex" : 0 } ).show(); + $view.find( ".ui-tokentextarea-input" ).removeClass( "ui-tokentextarea-input-invisible" ).addClass( "ui-tokentextarea-input-visible" ).attr( "tabindex", 0 ); + $view.find( "a" ).attr( "tabindex", 0 ).show(); + + // change focus state. + this._modifyInputBoxWidth(); + this._focusStatus = "focusIn"; + $view.removeClass( "ui-tokentextarea-focusout" ).addClass( "ui-tokentextarea-focusin" ).removeAttr( "tabindex" ); + $view.find( ".ui-tokentextarea-input" ).focus(); + }, + + focusOut : function () { + if ( this._focusStatus === "focusOut" ) { + return; + } + + var self = this, + $view = self.element, + tempBlock = null, + stateBlock = null, + numBlock = null, + statement = "", + index = 0, + lastIndex = 10, + label = $view.find( ".ui-tokentextarea-label" ), + more = $view.find( "span" ), + blocks = $view.find( "div" ), + currentWidth = $view.outerWidth( true ) - more.outerWidth( true ) - label.outerWidth( true ), + blockWidth = 0; + + label.removeAttr( "tabindex" ); + $view.find( ".ui-tokentextarea-input" ).removeClass( "ui-tokentextarea-input-visible" ).addClass( "ui-tokentextarea-input-invisible" ).removeAttr( "tabindex" ); + $view.find( "a" ).removeAttr( "tabindex" ).hide(); + blocks.removeAttr( "aria-label" ).removeAttr( "tabindex" ).hide(); + + currentWidth = currentWidth - self._reservedWidth; + + for ( index = 0; index < blocks.length; index++ ) { + blockWidth = $( blocks[index] ).outerWidth( true ); + if ( currentWidth - blockWidth <= 0 ) { + lastIndex = index - 1; + break; + } + + $( blocks[index] ).show(); + currentWidth -= blockWidth; + } + + if ( lastIndex !== blocks.length ) { + statement = self._stringFormat( self.options.description, blocks.length - lastIndex - 1 ); + tempBlock = $( document.createElement( 'span' ) ); + tempBlock.addClass( "ui-tokentextarea-desclabel" ).attr( { "aria-label" : "more, double tap to edit", "tabindex" : "-1" } ); + stateBlock = $( document.createElement( 'span' ) ).text( statement ).attr( "aria-hidden", "true" ); + numBlock = $( document.createElement( 'span' ) ).text( blocks.length - lastIndex - 1 ).attr( "aria-label", "and" ).css( "visibility", "hidden" ); + tempBlock.append( stateBlock ); + tempBlock.append( numBlock ); + $( blocks[lastIndex] ).after( tempBlock ); + } + + // update focus state + this._focusStatus = "focusOut"; + $view.removeClass( "ui-tokentextarea-focusin" ).addClass( "ui-tokentextarea-focusout" ).attr( "tabindex", 0 ); + }, + + inputText : function ( message ) { + var $view = this.element; + + if ( arguments.length === 0 ) { + return $view.find( ".ui-tokentextarea-input" ).val(); + } + $view.find( ".ui-tokentextarea-input" ).val( message ); + return message; + }, + + select : function ( index ) { + var $view = this.element, + lockBlock = null, + blocks = null; + + if ( this._focusStatus === "focusOut" ) { + return; + } + + if ( arguments.length === 0 ) { + // return a selected block. + lockBlock = $view.find( "div.ui-tokentextarea-sblock" ); + if ( lockBlock ) { + return lockBlock.text(); + } + return null; + } + // 1. unlock all blocks. + this._unlockTextBlock(); + // 2. select pointed block. + blocks = $view.find( "div" ); + if ( blocks.length > index ) { + $( blocks[index] ).removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" ); + $view.trigger( "select" ); + } + return null; + }, + + add : function ( message, position ) { + if ( this._focusStatus === "focusOut" ) { + return; + } + + this._addTextBlock( message, position ); + }, + + remove : function ( position ) { + var self = this, + $view = this.element, + blocks = $view.find( "div" ), + index = 0, + _temp = null, + _dummy = function () {}; + + if ( this._focusStatus === "focusOut" ) { + return; + } + + if ( arguments.length === 0 ) { + blocks.fadeOut( "fast", function () { + blocks.remove(); + self._modifyInputBoxWidth(); + self._trigger( "clear" ); + }); + } else if ( !isNaN( position ) ) { + // remove selected button + index = ( ( position < blocks.length ) ? position : ( blocks.length - 1 ) ); + + $( blocks[index] ).fadeOut( "fast", function () { + $( blocks[index] ).remove(); + self._modifyInputBoxWidth(); + }); + + this._eventRemoveCall = true; + if ( $view[0].remove ) { + _temp = $view[0].remove; + $view[0].remove = _dummy; + } + $view.triggerHandler( "remove" ); + if ( _temp) { + $view[0].remove = _temp; + } + this._eventRemoveCall = false; + } + }, + + length : function () { + return this.element.find( "div" ).length; + }, + + refresh : function () { + var self = this, + viewWidth = this.element.innerWidth(); + + if ( viewWidth && self._viewWidth !== viewWidth ) { + self._viewWidth = viewWidth; + } + self._resizeBlocks(); + self._modifyInputBoxWidth(); + }, + + destroy : function () { + var $view = this.element, + _temp = null, + _dummy = function () {}; + + if ( this._eventRemoveCall ) { + return; + } + + $view.find( ".ui-tokentextarea-label" ).remove(); + $view.find( "div" ).undelegate( "click" ).remove(); + $view.find( "a" ).remove(); + $view.find( ".ui-tokentextarea-input" ).unbind( "keyup" ).remove(); + + this._eventRemoveCall = true; + if ( $view[0].remove ) { + _temp = $view[0].remove; + $view[0].remove = _dummy; + } + $view.remove(); + if ( _temp) { + $view[0].remove = _temp; + } + this._eventRemoveCall = false; + + this._trigger( "destroy" ); + } + }); + + $( document ).bind( "pagecreate create", function () { + $( ":jqmData(role='tokentextarea')" ).tokentextarea(); + }); + + $( window ).bind( "resize", function () { + $( ":jqmData(role='tokentextarea')" ).tokentextarea( "refresh" ); + }); +} ( jQuery, window, document ) ); + +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +} ); +//>>excludeEnd("jqmBuildExclude"); http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/4ebce38e/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.triangle.js ---------------------------------------------------------------------- diff --git a/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.triangle.js b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.triangle.js new file mode 100644 index 0000000..38c5cea --- /dev/null +++ b/samples/TizenWebUI-sample-v1/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.triangle.js @@ -0,0 +1,121 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Shows triangle, used by context popup +//>>label: Triangle +//>>group: Tizen:Widgets + +define( [ + 'jquery', + '../jquery.mobile.tizen.core', + './jquery.mobile.tizen.widgetex' + ], function ( ) { + +//>>excludeEnd("jqmBuildExclude"); + +/* + * This software is licensed under the MIT licence (as defined by the OSI at + * http://www.opensource.org/licenses/mit-license.php) + * + * *************************************************************************** + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. + * Copyright (c) 2011 by Intel Corporation Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * *************************************************************************** + */ + +( function ($, undefined) { + + $.widget( "tizen.triangle", $.tizen.widgetex, { + options: { + extraClass: "", + offset: null, + color: null, + location: "top", + initSelector: ":jqmData(role='triangle')" + }, + + _create: function () { + var triangle = $( "
", {"class" : "ui-triangle"} ); + + $.extend(this, { + _triangle: triangle + }); + + this.element.addClass( "ui-triangle-container" ).append( triangle ); + }, + + _doCSS: function () { + var location = ( this.options.location || "top" ), + offsetCoord = ( ($.inArray(location, ["top", "bottom"]) === -1) ? "top" : "left"), + cssArg = { + "border-bottom-color" : "top" === location ? this.options.color : "transparent", + "border-top-color" : "bottom" === location ? this.options.color : "transparent", + "border-left-color" : "right" === location ? this.options.color : "transparent", + "border-right-color" : "left" === location ? this.options.color : "transparent" + }; + + cssArg[offsetCoord] = this.options.offset; + + this._triangle.removeAttr( "style" ).css( cssArg ); + }, + + _setOffset: function ( value ) { + this.options.offset = value; + this.element.attr( "data-" + ($.mobile.ns || "") + "offset", value ); + this._doCSS(); + }, + + _setExtraClass: function ( value ) { + this._triangle.addClass( value ); + this.options.extraClass = value; + this.element.attr( "data-" + ($.mobile.ns || "") + "extra-class", value ); + }, + + _setColor: function ( value ) { + this.options.color = value; + this.element.attr( "data-" + ($.mobile.ns || "") + "color", value ); + this._doCSS(); + }, + + _setLocation: function ( value ) { + this.element + .removeClass( "ui-triangle-container-" + this.options.location ) + .addClass( "ui-triangle-container-" + value ); + this._triangle + .removeClass( "ui-triangle-" + this.options.location ) + .addClass( "ui-triangle-" + value ); + + this.options.location = value; + this.element.attr( "data-" + ($.mobile.ns || "") + "location", value ); + + this._doCSS(); + } + }); + + $( document ).bind( "pagecreate create", function ( e ) { + $($.tizen.triangle.prototype.options.initSelector, e.target) + .not(":jqmData(role='none'), :jqmData(role='nojs')") + .triangle(); + }); + +}(jQuery) ); + +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +} ); +//>>excludeEnd("jqmBuildExclude");