2 * jQuery Mobile Widget @VERSION
4 * This software is licensed under the MIT licence (as defined by the OSI at
5 * http://www.opensource.org/licenses/mit-license.php)
7 * ***************************************************************************
8 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
9 * Copyright (c) 2011 by Intel Corporation Ltd.
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 * ***************************************************************************
30 * Authors: Gabriel Schulhof <gabriel.schulhof@intel.com>
31 * Hyunjung Kim <hjnim.kim@samsung.com>
35 * % ContextPopup widget do not use anymore(will be deprecated, internal use only)
37 // This widget is implemented in an extremely ugly way. It should derive from $.tizen.popupwindow, but it doesn't
38 // because there's a bug in jquery.ui.widget.js which was fixed in jquery-ui commit
39 // b9153258b0f0edbff49496ed16d2aa93bec07d95. Once a version of jquery-ui containing that commit is released
40 // (probably >= 1.9m5), and jQuery Mobile picks up the widget from there, this widget needs to be rewritten properly.
41 // The problem is that, when a widget inherits from a superclass and declares an object in its prototype identical in key
42 // to one in the superclass, upon calling $.widget the object is overwritten in both the prototype of the superclass and
43 // the prototype of the subclass. The prototype of the superclass should remain unchanged.
47 The context pop-up widget shows a list of options and automatically optimizes its size within the screen. This widget is intended for a small list of options for a larger list, use the List widget. <br/>The context pop-up widget requires a target button, which must be clicked to open the context pop-up. In the default application theme, an arrow pointer is displayed at the top-left corner of the context pop-up widget when it is opened.<br/><br/> To add a context pop-up widget to the application, use the following code:
50 <a href="#pop_3_icons" id="btn_3_icons" data-role="button" data-inline="true" data-rel="popupwindow">3 Icons</a>
52 <div class="horizontal" id="pop_3_icons" data-role="popupwindow" data-show-arrow="true">
55 <a href="#" data-role="button" data-icon="call"></a>
58 <a href="#" data-role="button" data-icon="favorite"></a>
61 <a href="#">Function</a>
65 The context pop-up can define callbacks for events as described in the [jQueryMobile documentation for pop-up events.][1]
66 You can use methods with the context pop-up as described in the [jQueryMobile documentation for pop-up methods.][2]
67 [1]: http://jquerymobile.com/demos/1.2.0-alpha.1/docs/pages/popup/events.html
68 [2]: http://jquerymobile.com/demos/1.2.0-alpha.1/docs/pages/popup/methods.html
70 @deprecated 2.0 verisons
73 (function ( $, undefined ) {
74 $.widget( "tizen.ctxpopup", $.tizen.widgetex, {
75 options: $.extend( {}, $.tizen.popupwindow.prototype.options, {
76 initSelector: ":jqmData(show-arrow)"
82 container : "#container", // the key has to have the name "container"
84 all : ":jqmData(role='triangle')",
93 _create: function () {
94 console.warn("ctxpopup() was deprecated. use popup() instead.");
95 if ( !this.element.data( "popupwindow" ) ) {
96 this.element.popupwindow();
99 this.element.data( "popupwindow" )
101 .removeClass( "ui-popupwindow-padding" )
102 .append( this._ui.outer );
103 this._ui.outer.trigger( "create" ); // Creates the triangle widgets
105 .addClass( "ui-popupwindow-padding" )
106 .append( this.element );
109 _setOption: function ( key, value ) {
110 $.tizen.popupwindow.prototype._setOption.apply( this.element.data( "popupwindow" ), arguments );
111 this.options[key] = value;
115 var origOpen = $.tizen.popupwindow.prototype.open,
116 orig_setOption = $.tizen.popupwindow.prototype._setOption,
117 orig_placementCoords = $.tizen.popupwindow.prototype._placementCoords;
119 $.tizen.popupwindow.prototype._setOption = function ( key, value ) {
120 var ctxpopup = this.element.data( "ctxpopup" ),
121 needsApplying = true,
124 if ( "shadow" === key || "overlayTheme" === key || "corners" === key ) {
125 origContainer = this._ui.container;
127 this._ui.container = ctxpopup._ui.container;
128 orig_setOption.apply( this, arguments );
129 this._ui.container = origContainer;
130 needsApplying = false;
132 ctxpopup.options[key] = value;
135 if ( needsApplying ) {
136 orig_setOption.apply(this, arguments);
140 $.tizen.popupwindow.prototype._placementCoords = function ( x, y, cx, cy ) {
141 var ctxpopup = this.element.data( "ctxpopup" ),
147 function getCoords( arrow, x_factor, y_factor ) {
148 // Unhide the arrow we want to test to take it into account
149 ctxpopup._ui.arrow.all.hide();
150 ctxpopup._ui.arrow[arrow].show();
152 var isHorizontal = ( "b" === arrow || "t" === arrow ),
153 // Names of keys used in calculations depend on whether things are horizontal or not
154 coord = ( isHorizontal
155 ? { point: "x", size: "cx", beg: "left", outerSize: "outerWidth", niceSize: "width", triangleSize : "height" }
156 : { point: "y", size: "cy", beg: "top", outerSize: "outerHeight", niceSize: "height", triangleSize : "width" } ),
158 cx : self._ui.container.width(),
159 cy : self._ui.container.height()
166 "x" : x + halfSize.cx * x_factor,
167 "y" : y + halfSize.cy * y_factor
169 orig = orig_placementCoords.call( self, desired.x, desired.y, size.cx, size.cy ),
171 // The triangleOffset must be clamped to the range described below:
176 // ----+--+-,-----...
177 //lowerDiff -->____| |/ <-- possible rounded corner
178 //triangle size --> | /|
180 // ^ |\ | <-- lowest possible offset for triangle
181 // actual range of | | \|
182 // arrow offset | | |
183 // values due to | . . Payload table cell looks like
184 // possible rounded | . . a popup window, and it may have
185 // corners and arrow | . . arbitrary things like borders,
186 // triangle size - | | | shadows, and rounded corners.
187 // our clamp range | | /|
189 //triangle size --> |\ | <-- highest possible offset for triangle
191 //upperDiff --> | |\ <-- possible rounded corner
192 // ----+--+-'-----...
197 // We calculate lowerDiff and upperDiff by considering the offset and width of the payload (this.element)
198 // versus the offset and width of the element enclosing the triangle, because the payload is inside
199 // whatever decorations (such as borders, shadow, rounded corners) and thus can give a reliable indication
200 // of the thickness of the combined decorations
202 arrowBeg = ctxpopup._ui.arrow[arrow].offset()[coord.beg],
203 arrowSize = ctxpopup._ui.arrow[arrow][coord.outerSize]( true ),
204 payloadBeg = self.element.offset()[coord.beg],
205 payloadSize = self.element[coord.outerSize]( true ),
206 triangleSize = ctxpopup._ui.arrow[arrow][coord.triangleSize](),
209 triangleSize // triangle size
210 + Math.max( 0, payloadBeg - arrowBeg ), // lowerDiff
213 - triangleSize // triangle size
214 - Math.max( 0, arrowBeg + arrowSize - ( payloadBeg + payloadSize ) ), // upperDiff
215 arrowSize / 2 // arrow unrestricted offset
216 + desired[coord.point]
218 - halfSize[coord.size]
221 // Triangle points here
223 "x": orig.x + ( isHorizontal ? triangleOffset : 0) + ("r" === arrow ? size.cx : 0),
224 "y": orig.y + (!isHorizontal ? triangleOffset : 0) + ("b" === arrow ? size.cy : 0)
228 triangleOffset : triangleOffset,
229 absDiff : Math.abs( x - final.x ) + Math.abs( y - final.y )
233 ctxpopup._ui.arrow[arrow].hide();
242 // triangleOffset: int
243 // actual: { x: int, y: int }
247 l : getCoords( "l", 1, 0 ),
248 r : getCoords( "r", -1, 0 ),
249 t : getCoords( "t", 0, 1 ),
250 b : getCoords( "b", 0, -1 )
253 $.each( coords, function ( key, value ) {
254 if ( minDiff === undefined || value.absDiff < minDiff ) {
255 minDiff = value.absDiff;
260 // Side-effect: show the appropriate arrow and move it to the right offset
261 ctxpopup._ui.arrow[minDiffIdx]
263 .triangle( "option", "offset", coords[minDiffIdx].triangleOffset );
264 return coords[minDiffIdx].actual;
267 return orig_placementCoords.call( this, x, y, cx, cy );
270 $.tizen.popupwindow.prototype.open = function ( x, y ) {
271 var ctxpopup = this.element.data( "ctxpopup" );
274 this._setFade( false );
275 this._setShadow( false );
276 this._setCorners( false );
277 this._setOverlayTheme( null );
278 this._setOption( "overlayTheme", ctxpopup.options.overlayTheme );
279 ctxpopup._ui.arrow.all.triangle( "option", "color", ctxpopup._ui.container.css( "background-color" ) );
282 $( '.ui-popupwindow' ).css( 'background', 'none' );
285 origOpen.call( this, x, y, true );
288 //auto self-init widgets
289 $( document ).bind( "pagecreate create", function ( e ) {
290 var ctxpopups = $( $.tizen.ctxpopup.prototype.options.initSelector, e.target );
291 $.tizen.ctxpopup.prototype.enhanceWithin( e.target );