http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/e21e0780/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.widgetex.js ---------------------------------------------------------------------- diff --git a/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.widgetex.js b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.widgetex.js new file mode 100644 index 0000000..da61b19 --- /dev/null +++ b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/jquery.mobile.tizen.widgetex.js @@ -0,0 +1,376 @@ +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +//>>description: Widget class extending functionality of jQueryMobile widget class +//>>label: Widget extension +//>>group: Tizen:Widgets + +define( [ + 'jquery', + '../jquery.mobile.tizen.core' + ], function ( jQuery ) { + +//>>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) 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. + * *************************************************************************** + */ + +// Base class for widgets that need the following features: +// +// I. HTML prototype loading +// +// This class provides HTML prototype loading for widgets. That is, the widget implementation specifies its HTML portions +// in one continuous HTML snippet, and it optionally provides an object containing selectors into the various parts of the +// HTML snippet. This widget loads the HTML snippet into a jQuery object, and optionally assigns jQuery objects to each of +// the selectors in the optionally provided object. +// +// To use this functionality you can either derive from this class, or you can call its prototype's gtype method. +// +// 1. Widgets deriving from this class should define _htmlProto as part of their prototype declaration. _htmlProto looks like +// this: +// +// _htmlProto: { +// source: string|jQuery object (optional) default: string - The name of the widget +// ui: { +// uiElement1: "#ui-element-1-selector", +// uiElement2: "#ui-element-2-selector", +// ... +// subElement: { +// subElement1: "#sub-element-1-selector", +// subElement2: "#sub-element-2-selector", +// ... +// } +// ... +// } +// } +// +// If neither 'source' nor 'ui' are defined, you must still include an empty _htmlProto key (_htmlProto: {}) to indicate +// that you wish to make use of this feature. This will cause a prototype HTML file named after your widget to be loaded. +// The loaded prototype will be placed into your widget's prototype's _protoHtml.source key. +// +// If 'source' is defined as a string, it is the name of the widget (including namespace). This is the default. If your +// widget's HTML prototype is loaded via AJAX and the name of the AJAX file is different from the name of your widget +// (that is, it is not "<widgetName>.prototype.html", then you should explicitly define 'source' as: +// +// If you wish to load HTML prototypes via AJAX, modify the getProtoPath() function defined below to reflect the directory +// structure holding your widget HTML prototypes. +// +// source: "alternateWidgetName" +// +// If AJAX loading fails, source is set to a jQuery object containing a div with an error message. You can check whether +// loading failed via the jQuery object's jqmData( "tizen.widgetex.ajax.fail" ) data item. If false, then the jQuery object +// is the actual prototype loaded via AJAX or present inline. Otherwise, the jQuery object is the error message div. +// +// If 'source' is defined as a jQuery object, it is considered already loaded. +// +// if 'ui' is defined inside _htmlProto, It is assumed to be an object such that every one of its keys is either a string, +// or another object with the same properties as itself. +// +// When a widget is instantiated, the HTML prototype is loaded if not already present in the prototype. If 'ui' is present +// inside _htmlProto, the prototype is cloned. Then, a new structure is created based on 'ui' with each selector replaced +// by a jQuery object containing the results of performing .find() on the prototype's clone with the filter set to the +// value of the string. In the special case where the selector starts with a '#', the ID is removed from the element after +// it is assigned into the structure being created. This structure is then made accessible from the widget instance via +// the '_ui' key (i.e., this._ui). +// +// 2. Use the loadPrototype method when your widget does not derive from $.tizen.widgetex: +// Add _htmlProto to your widget's prototype as described above. Then, in your widget's _create() method, call +// loadPrototype in the following manner: +// +// $.tizen.widgetex.loadPrototype.call(this, "namespace.widgetName" ); +// +// Thereafter, you may use the HTML prototype from your widget's prototype or, if you have specified a 'ui' key in your +// _htmlProto key, you may use this._ui from your widget instance. +// +// II. realize method +// +// When a widget is created, some of its properties cannot be set immediately, because they depend on the widths/heights +// of its constituent elements. They can only be calculated when the page containing the widget is made visible via the +// "pageshow" event, because widths/heights always evaluate to 0 when retrieved from a widget that is not visible. When +// you inherit from widgetex, you can add a "_realize" function to your prototype. This function will be called once right +// after _create() if the element that anchors your widget is on a visible page. Otherwise, it will be called when the +// page to which the widget belongs emits the "pageshow" event. +// +// NB: If your widget is inside a container which is itself not visible, such as an expandable or a collapsible, your +// widget will remain hidden even though "pageshow" is fired and therefore _realize is called. In this case, widths and +// heights will be unreliable even during _realize. +// +// III. systematic option handling +// +// If a widget has lots of options, the _setOption function can become a long switch for setting each recognized option. +// It is also tempting to allow options to determine the way a widget is created, by basing decisions on various options +// during _create(). Often, the actions based on option values in _create() are the same as those in _setOption. To avoid +// such code duplication, this class calls _setOption once for each option after _create() has completed. +// +// Furthermore, to avoid writing long switches in a widget's _setOption method, this class implements _setOption in such +// a way that, for any given option (e.g. "myOption" ), _setOption looks for a method _setMyOption in the widget's +// implementation, and if found, calls the method with the value of the option. +// +// If your widget does not inherit from widgetex, you can still use widgetex' systematic option handling: +// 1. define the _setOption method for your widget as follows: +// _setOption: $.tizen.widgetex.prototype._setOption +// 2. Call this._setOptions(this.options) from your widget's _create() function. +// 3. As with widgetex-derived widgets, implement a corresponding _setMyOptionName function for each option myOptionName +// you wish to handle. +// +// IV. systematic value handling for input elements +// +// If your widget happens to be constructed from an <input> element, you have to handle the "value" attribute specially, +// and you have to emit the "change" signal whenever it changes, in addition to your widget's normal signals and option +// changes. With widgetex, you can assign one of your widget's "data-*" properties to be synchronized to the "value" +// property whenever your widget is constructed onto an <input> element. To do this, define, in your prototype: +// +// _value: { +// attr: "data-my-attribute", +// signal: "signal-to-emit" +// } +// +// Then, call this._setValue(newValue) whenever you wish to set the value for your widget. This will set the data-* +// attribute, emit the custom signal (if set) with the new value as its parameter, and, if the widget is based on an +// <input> element, it will also set the "value" attribute and emit the "change" signal. +// +// "attr" is required if you choose to define "_value", and identifies the data-attribute to set in addition to "value", +// if your widget's element is an input. +// "signal" is optional, and will be emitted when setting the data-attribute via this._setValue(newValue). +// +// If your widget does not derive from widgetex, you can still define "_value" as described above and call +// $.tizen.widgetex.setValue(widget, newValue). +// +// V. Systematic enabled/disabled handling for input elements +// +// widgetex implements _setDisabled which will disable the input associated with this widget, if any. Thus, if you derive +// from widgetex and you plan on implementing the disabled state, you should chain up to +// $.tizen.widgetex.prototype._setDisabled(value), rather than $.Widget.prototype._setOption( "disabled", value). + +(function ($, undefined) { + +// Framework-specific HTML prototype path for AJAX loads + function getProtoPath() { + var theScriptTag = $( "script[data-framework-version][data-framework-root][data-framework-theme]" ); + + return (theScriptTag.attr( "data-framework-root" ) + "/" + + theScriptTag.attr( "data-framework-version" ) + "/themes/" + + theScriptTag.attr( "data-framework-theme" ) + "/proto-html" ); + } + + $.widget( "tizen.widgetex", $.mobile.widget, { + _createWidget: function () { + $.tizen.widgetex.loadPrototype.call( this, this.namespace + "." + this.widgetName ); + $.mobile.widget.prototype._createWidget.apply( this, arguments ); + }, + + _init: function () { + // TODO THIS IS TEMPORARY PATCH TO AVOID CTXPOPUP PAGE CRASH + if ( this.element === undefined ) { + return; + } + + var page = this.element.closest( ".ui-page" ), + self = this, + myOptions = {}; + + if ( page.is( ":visible" ) ) { + this._realize(); + } else { + page.bind( "pageshow", function () { self._realize(); } ); + } + + $.extend( myOptions, this.options ); + + this.options = {}; + + this._setOptions( myOptions ); + }, + + _getCreateOptions: function () { + // if we're dealing with an <input> element, value takes precedence over corresponding data-* attribute, if a + // mapping has been established via this._value. So, assign the value to the data-* attribute, so that it may + // then be assigned to this.options in the superclass' _getCreateOptions + + if (this.element.is( "input" ) && this._value !== undefined) { + var theValue = + ( ( this.element.attr( "type" ) === "checkbox" || this.element.attr( "type" ) === "radio" ) + ? this.element.is( ":checked" ) + : this.element.is( "[value]" ) + ? this.element.attr( "value" ) + : undefined); + + if ( theValue != undefined ) { + this.element.attr( this._value.attr, theValue ); + } + } + + return $.mobile.widget.prototype._getCreateOptions.apply( this, arguments ); + }, + + _setOption: function ( key, value ) { + var setter = "_set" + key.replace(/^[a-z]/, function (c) { return c.toUpperCase(); } ); + + if ( this[setter] !== undefined ) { + this[setter]( value ); + } else { + $.mobile.widget.prototype._setOption.apply( this, arguments ); + } + }, + + _setDisabled: function ( value ) { + $.Widget.prototype._setOption.call( this, "disabled", value ); + if ( this.element.is( "input" ) ) { + this.element.attr( "disabled", value ); + } + }, + + _setValue: function ( newValue ) { + $.tizen.widgetex.setValue( this, newValue ); + }, + + _realize: function () {} + } ); + + $.tizen.widgetex.setValue = function ( widget, newValue ) { + if ( widget._value !== undefined ) { + var valueString = ( widget._value.makeString ? widget._value.makeString(newValue) : newValue ), + inputType; + + widget.element.attr( widget._value.attr, valueString ); + if ( widget._value.signal !== undefined ) { + widget.element.triggerHandler( widget._value.signal, newValue ); + } + + if ( widget.element.is( "input" ) ) { + inputType = widget.element.attr( "type" ); + + // Special handling for checkboxes and radio buttons, where the presence of the "checked" attribute is really + // the value + if ( inputType === "checkbox" || inputType === "radio" ) { + if ( newValue ) { + widget.element.attr( "checked", true ); + } else { + widget.element.removeAttr( "checked" ); + } + } else { + widget.element.attr( "value", valueString ); + } + + widget.element.trigger( "change" ); + } + } + }; + + $.tizen.widgetex.assignElements = function (proto, obj) { + var ret = {}, + key; + + for ( key in obj ) { + if ( ( typeof obj[key] ) === "string" ) { + ret[key] = proto.find( obj[key] ); + if ( obj[key].match(/^#/) ) { + ret[key].removeAttr( "id" ); + } + } else { + if ( (typeof obj[key]) === "object" ) { + ret[key] = $.tizen.widgetex.assignElements( proto, obj[key] ); + } + } + } + + return ret; + }; + + $.tizen.widgetex.loadPrototype = function ( widget, ui ) { + var ar = widget.split( "." ), + namespace, + widgetName, + source, + noSource = false, + htmlProto, + protoPath; + + if ( ar.length == 2 ) { + namespace = ar[0]; + widgetName = ar[1]; + + // If htmlProto is defined + if ( $[namespace][widgetName].prototype._htmlProto !== undefined ) { + // If no source is defined, use the widget name + source = $[namespace][widgetName].prototype._htmlProto.source; + if ( source === undefined ) { + source = widgetName; + noSource = true; + } + + // Load the HTML prototype via AJAX if not defined inline + if ( typeof source === "string" ) { + if ( noSource ) { // use external htmlproto file + // Establish the path for the proto file + widget = source; + protoPath = getProtoPath(); + + // Make the AJAX call + $.ajax( { + url: protoPath + "/" + widget + ".prototype.html", + async: false, + dataType: "html" + }).success( function (data, textStatus, jqXHR ) { + source = $( "<div></div>" ).html(data).jqmData( "tizen.widgetex.ajax.fail", false ); + } ); + + // Assign the HTML proto to the widget prototype + source = $( "<div></div>" ) + .text( "Failed to load proto for widget " + namespace + "." + widgetName + "!" ) + .css( {background: "red", color: "blue", border: "1px solid black"} ) + .jqmData( "tizen.widgetex.ajax.fail", true ); + + } else { + // inline definition (string) + source = $( source ).jqmData( "tizen.widgetex.ajax.fail", false ); + } + + } else { + // inline definition (object) + // AJAX loading has trivially succeeded, since there was no AJAX loading at all + source.jqmData( "tizen.widgetex.ajax.fail", false ); + } + htmlProto = source; + $[namespace][widgetName].prototype._htmlProto.source = source; + + // If there's a "ui" portion in the HTML proto, copy it over to this instance, and + // replace the selectors with the selected elements from a copy of the HTML prototype + if ( $[namespace][widgetName].prototype._htmlProto.ui !== undefined ) { + // Assign the relevant parts of the proto + $.extend( this, { + _ui: $.tizen.widgetex.assignElements( htmlProto.clone(), $[namespace][widgetName].prototype._htmlProto.ui ) + }); + } + } + } + }; + +}( jQuery ) ); + +//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); +} ); +//>>excludeEnd("jqmBuildExclude");
http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/e21e0780/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/ctxpopup.less ---------------------------------------------------------------------- diff --git a/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/ctxpopup.less b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/ctxpopup.less new file mode 100644 index 0000000..def9e09 --- /dev/null +++ b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/ctxpopup.less @@ -0,0 +1,21 @@ +.ui-ctxpopup { + display: table; + + .ui-ctxpopup-row { + display: table-row; + + .ui-ctxpopup-cell { + display: table-cell; + } + } +} +/* + * The settings in this file are part of the theme. They are not part of the structure of ctxpopup. + * In the default theme, ui-body-* has a border width of 1px. So, to make the triangles cross this border, we set them in + * by 1px. + */ +.ui-ctxpopup-row { + .ui-triangle-top { top: 1px; } + .ui-triangle-left { left: 1px; } + .ui-triangle-right { right: 1px; } + .ui-triangle-bottom { bottom: 1px; } http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/e21e0780/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/popupwindow.less ---------------------------------------------------------------------- diff --git a/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/popupwindow.less b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/popupwindow.less new file mode 100644 index 0000000..ebbd635 --- /dev/null +++ b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/popupwindow.less @@ -0,0 +1,17 @@ +.ui-popupwindow-padding { + padding: 6px; +} + +.ui-popupwindow { + display: inline-block; + position: absolute; + padding: 0; + z-index: 100 !important; +} + +.ui-popupwindow-screen { + background: #000000; + opacity: 0; + box-sizing: border-box; + -moz-box-sizing: border-box; +} http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/e21e0780/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/triangle.less ---------------------------------------------------------------------- diff --git a/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/triangle.less b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/triangle.less new file mode 100644 index 0000000..baa4e5d --- /dev/null +++ b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/less/triangle.less @@ -0,0 +1,64 @@ +@triangle-size: 10px; + +.ui-triangle-container { + position: relative; + + .ui-triangle { + position: absolute; + border-style: solid; + border-color: transparent; + border-width: @triangle-size; + } + + .ui-triangle-top { + top: 0px; + border-top-width: 0px; + border-left-color: transparent; + border-right-color: transparent; + margin-left: -@triangle-size; + } + + .ui-triangle-bottom { + bottom: 0px; + border-bottom-width: 0px; + border-left-color: transparent; + border-right-color: transparent; + margin-left: -@triangle-size; + } + + .ui-triangle-left { + left: 0px; + margin-top: -@triangle-size; + border-left-width: 0px; + border-left-color: transparent; + border-right-color: transparent; + } + + .ui-triangle-right { + right: 0px; + margin-top: -@triangle-size; + border-right-width: 0px; + border-left-color: transparent; + border-right-color: transparent; + } +} + +.ui-triangle-container-top { + height: @triangle-size; + top: 0px; + margin-top: -@triangle-size; +} + +.ui-triangle-container-bottom { + height: @triangle-size; + bottom: 0px; + margin-bottom: -@triangle-size; +} + +.ui-triangle-container-left { + width: @triangle-size; +} + +.ui-triangle-container-right { + width: @triangle-size; +} http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/e21e0780/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/ctxpopup.prototype.html ---------------------------------------------------------------------- diff --git a/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/ctxpopup.prototype.html b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/ctxpopup.prototype.html new file mode 100644 index 0000000..a494376 --- /dev/null +++ b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/ctxpopup.prototype.html @@ -0,0 +1,9 @@ +<div id="outer" class="ui-ctxpopup"> + <div id="top" class="ui-ctxpopup-row" data-role="triangle" data-location="top"></div> + <div class="ui-ctxpopup-row"> + <div id="left" class="ui-ctxpopup-cell" data-role="triangle" data-location="left"></div> + <div id="container" class="ui-ctxpopup-cell"></div> + <div id="right" class="ui-ctxpopup-cell" data-role="triangle" data-location="right"></div> + </div> + <div id="bottom" class="ui-ctxpopup-row" data-role="triangle" data-location="bottom"></div> +</div> http://git-wip-us.apache.org/repos/asf/cordova-tizen/blob/e21e0780/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/popupwindow.prototype.html ---------------------------------------------------------------------- diff --git a/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/popupwindow.prototype.html b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/popupwindow.prototype.html new file mode 100644 index 0000000..580dbaa --- /dev/null +++ b/templates/CordovaTizenWebUIFrameworkTemplate/project/tizen-web-ui-fw/latest/js/modules/widgets/proto-html/popupwindow.prototype.html @@ -0,0 +1,4 @@ +<div> + <div id="popupwindow-screen" class="ui-selectmenu-screen ui-screen-hidden ui-popupwindow-screen"></div> + <div id="popupwindow-container" class="ui-popupwindow ui-popupwindow-padding ui-selectmenu-hidden ui-overlay-shadow ui-corner-all"></div> +</div>
