build: Module build implementation
[platform/framework/web/web-ui-fw.git] / src / js / widgets / jquery.mobile.tizen.popupwindow.js
1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Shows popup on the page
3 //>>label: Popup
4 //>>group: Tizen:Widgets
5
6 define( [ '../jquery.mobile.tizen.core', 'jquery.mobile.tizen.widgetex' ], function ( ) {
7 //>>excludeEnd("jqmBuildExclude");
8
9 /*
10  * jQuery Mobile Widget @VERSION
11  *
12  * This software is licensed under the MIT licence (as defined by the OSI at
13  * http://www.opensource.org/licenses/mit-license.php)
14  *
15  * ***************************************************************************
16  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
17  * Copyright (c) 2011 by Intel Corporation Ltd.
18  *
19  * Permission is hereby granted, free of charge, to any person obtaining a
20  * copy of this software and associated documentation files (the "Software"),
21  * to deal in the Software without restriction, including without limitation
22  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
23  * and/or sell copies of the Software, and to permit persons to whom the
24  * Software is furnished to do so, subject to the following conditions:
25  *
26  * The above copyright notice and this permission notice shall be included in
27  * all copies or substantial portions of the Software.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35  * DEALINGS IN THE SOFTWARE.
36  * ***************************************************************************
37  *
38  * Authors: Gabriel Schulhof <gabriel.schulhof@intel.com>,
39  *          Elliot Smith <elliot.smith@intel.com>
40  *                      Hyunjung Kim <hjnim.kim@samsung.com>
41  */
42
43 /*
44  * % Popupwindow widget do not use anymore(will be deprecated, internal use only)
45  *
46  *
47  * Shows other elements inside a popup window.
48  *
49  * To apply, add the attribute data-role="popupwindow" to a <div> element inside
50  * a page. Alternatively, call popupwindow()
51  * on an element, eg :
52  *
53  *     $("#mypopupwindowContent").popupwindow();
54  * where the html might be :
55  *     <div id="mypopupwindowContent"></div>
56  *
57  * To trigger the popupwindow to appear, it is necessary to make a call to its
58  * 'open()' method. This is typically done by binding a function to an event
59  * emitted by an input element, such as a the clicked event emitted by a button
60  * element. The open() method takes two arguments, specifying the x and y
61  * screen coordinates of the center of the popup window.
62
63  * You can associate a button with a popup window like this:
64  *      <div id="mypopupContent" style="display: table;" data-role="popupwindow">
65  *          <table>
66  *              <tr> <td>Eenie</td>   <td>Meenie</td>  <td>Mynie</td>   <td>Mo</td>  </tr>
67  *              <tr> <td>Catch-a</td> <td>Tiger</td>   <td>By-the</td>  <td>Toe</td> </tr>
68  *              <tr> <td>If-he</td>   <td>Hollers</td> <td>Let-him</td> <td>Go</td>  </tr>
69  *              <tr> <td>Eenie</td>   <td>Meenie</td>  <td>Mynie</td>   <td>Mo</td>  </tr>
70  *          </table>
71  *      </div>
72  * <a href="#myPopupContent" data-rel="popupwindow" data-role="button">Show popup</a>
73  *
74  * Options:
75  *
76  *     theme: String; the theme for the popupwindow contents
77  *                   Default: null
78  *
79  *     overlayTheme: String; the theme for the popupwindow
80  *                   Default: null
81  *
82  *     shadow: Boolean; display a shadow around the popupwindow
83  *             Default: true
84  *
85  *     corners: Boolean; display a shadow around the popupwindow
86  *             Default: true
87  *
88  *     fade: Boolean; fades the opening and closing of the popupwindow
89  *
90  *     transition: String; the transition to use when opening or closing
91  *                 a popupwindow
92  *                 Default: $.mobile.defaultDialogTransition
93  *
94  * Events:
95  *      popupbeforeposition: triggered after a popup has completed preparations for opening, but has not yet opened
96  *      popupafteropen: triggered after a popup has completely opened
97  *      popupafterclose triggered when a popup has completely closed
98 */
99
100 /**
101         class Popupwindow
102         The pop-up widget shows a list of items in a pop-up window in the middle of the screen. It automatically optimizes the pop-up window size within the screen.
103         To add a pop-up widget to the application, use the following code:
104
105                 // Basic pop-up
106                 <div id="center_info" data-role="popup" data-style="center_info">
107                         <div data-role="text">
108                                 <p>
109                                 Pop-up dialog box, a child window that blocks user interaction in the parent window
110                                 </p>
111                         </div>
112                 </div>
113                 // Pop-up with a title and button
114                 <div id="center_title_1btn" data-role="popup" data-style="center_title_1btn">
115                         <p data-role="title">
116                                 Pop-up title
117                         </p>
118                         <p data-role="text">
119                                 Pop-up dialog box
120                         </p>
121                 <div data-role="button-bg">
122                         <input type="button" value="Text Button" />
123                 </div>
124                 </div>
125
126         The pop-up can define callbacks for events as described in the jQueryMobile documentation for pop-up events. <br/>You can use methods with the pop-up as described in the jQueryMobile documentation for pop-up methods.
127
128         @deprecated 2.0 verisons
129 */
130
131 /**
132         @property {String} data-style
133         Defines the pop-up window style.
134         The following styles are available:
135
136         center_info: basic pop-up message
137         center_title: pop-up message with a title
138         center_basic_1btn: pop-up message with 1 button
139         center_basic_2btn: pop-up message with 2 horizontal buttons
140         center_title_1btn: pop-up message with a title and 1 button
141         center_title_2btn: pop-up message with a title and 2 horizontal buttons
142         center_title_3btn: pop-up message with a title and 3 horizontal buttons
143         center_button_vertical: pop-up message with vertical buttons
144         center_checkbox: pop-up message with a check box
145         center_liststyle_1btn>: pop-up message with a list and 1 button
146         center_liststyle_2btn: pop-up message with a list and 2 horizontal buttons
147         center_liststyle_3btn: pop-up message with a list and 3 horizontal buttons
148 */
149
150 (function ( $, undefined ) {
151         $.widget( "tizen.popupwindow", $.tizen.widgetex, {
152                 options: {
153                         theme: null,
154                         overlayTheme: "s",
155                         style: "custom",
156                         disabled: false,
157                         shadow: true,
158                         corners: true,
159                         fade: false,
160                         opacity: 0.7,
161                         widthRatio: 0.8612,
162                         transition: $.mobile.defaultDialogTransition,
163                         initSelector: ":jqmData(role='popupwindow')"
164                 },
165
166                 _htmlProto: {
167                         ui: {
168                                 screen: "#popupwindow-screen",
169                                 container: "#popupwindow-container"
170                         }
171                 },
172
173                 _setStyle: function () {
174                         var popup = this.element,
175                                 style = popup.attr( 'data-style' );
176
177                         if ( style ) {
178                                 this.options.style = style;
179                         }
180
181                         popup.addClass( this.options.style );
182                         popup.find( ":jqmData(role='title')" )
183                                         .wrapAll( "<div class='popup-title'></div>" );
184                         popup.find( ":jqmData(role='text')" )
185                                         .wrapAll( "<div class='popup-text'></div>" );
186                         popup.find( ":jqmData(role='button-bg')" )
187                                         .wrapAll( "<div class='popup-button-bg'></div>" );
188                         popup.find( ":jqmData(role='check-bg')" )
189                                         .wrapAll( "<div class='popup-check-bg'></div>" );
190                         popup.find( ":jqmData(role='scroller-bg')" )
191                                         .addClass( "popup-scroller-bg" );
192                         popup.find( ":jqmData(role='text-bottom-bg')" )
193                                         .wrapAll( "<div class='popup-text-bottom-bg'></div>" );
194                         popup.find( ":jqmData(role='text-left')" )
195                                         .wrapAll( "<div class='popup-text-left'></div>" );
196                         popup.find( ":jqmData(role='text-right')" )
197                                         .wrapAll( "<div class='popup-text-right'></div>" );
198                         popup.find( ":jqmData(role='progress-bg')" )
199                                         .wrapAll( "<div class='popup-progress-bg'></div>" );
200                 },
201
202                 _create: function () {
203                         console.warn("popupwindow() was deprecated. use popup() instead.");
204                         var thisPage = this.element.closest(":jqmData(role='page')"),
205                                 self = this;
206
207                         if ( thisPage.length === 0 ) {
208                                 thisPage = $("body");
209                         }
210
211                         this._ui.placeholder =
212                                         $( "<div><!-- placeholder for " + this.element.attr("id") + " --></div>" )
213                                         .css("display", "none")
214                                         .insertBefore( this.element );
215
216                         thisPage.append( this._ui.screen );
217                         this._ui.container.insertAfter( this._ui.screen );
218                         this._ui.container.append( this.element );
219
220                         this._setStyle();
221
222                         this._isOpen = false;
223
224                         this._ui.screen.bind( "vclick", function ( e ) {
225                                 self.close();
226                                 return false;
227                         } );
228
229                         this.element.bind( "vclick", function ( e ) {
230                                 if ( $( e.target ).is("ui-btn-ctxpopup-close") ) {
231                                         self.close();
232                                 }
233                         } );
234                 },
235
236                 destroy: function () {
237                         this.element.insertBefore( this._ui.placeholder );
238
239                         this._ui.placeholder.remove();
240                         this._ui.container.remove();
241                         this._ui.screen.remove();
242                         this.element.triggerHandler("destroyed");
243                         $.Widget.prototype.destroy.call( this );
244                 },
245
246                 _placementCoords: function ( x, y, cw, ch ) {
247                         var screenHeight = $( window ).height(),
248                                 screenWidth = $( window ).width(),
249                                 halfheight = ch / 2,
250                                 maxwidth = parseFloat( this._ui.container.css( "max-width" ) ),
251                                 roomtop = y,
252                                 roombot = screenHeight - y,
253                                 newtop,
254                                 newleft;
255
256                         if ( roomtop > ch / 2 && roombot > ch / 2 ) {
257                                 newtop = y - halfheight;
258                         } else {
259                                 newtop = roomtop > roombot ? screenHeight - ch - 30 : 30;
260                         }
261
262                         if ( cw < maxwidth ) {
263                                 newleft = ( screenWidth - cw ) / 2;
264                         } else {
265                                 newleft = x - cw / 2;
266
267                                 if ( newleft < 10 ) {
268                                         newleft = 10;
269                                 } else if ( ( newleft + cw ) > screenWidth ) {
270                                         newleft = screenWidth - cw - 10;
271                                 }
272                         }
273
274                         return { x : newleft, y : newtop };
275                 },
276
277                 _setPosition: function ( x_where, y_where ) {
278                         var x = ( undefined === x_where ? $( window ).width()  / 2 : x_where ),
279                                 y = ( undefined === y_where ? $( window ).height() / 2 : y_where ),
280                                 coords,
281                                 ctxpopup = this.element.data("ctxpopup"),
282                                 popupWidth,
283                                 menuHeight,
284                                 menuWidth,
285                                 screenHeight,
286                                 screenWidth,
287                                 roomtop,
288                                 roombot,
289                                 halfheight,
290                                 maxwidth,
291                                 newtop,
292                                 newleft;
293
294                         if ( !ctxpopup ) {
295                                 popupWidth = $( window ).width() * this.options.widthRatio;
296                                 this._ui.container.css( "width", popupWidth );
297
298                                 if ( this._ui.container.outerWidth() > $( window ).width() ) {
299                                         this._ui.container.css( {"max-width" : $( window ).width() - 30} );
300                                 }
301                         }
302
303                         coords = this._placementCoords( x, y,
304                                         this._ui.container.outerWidth(),
305                                         this._ui.container.outerHeight() );
306
307                         menuHeight = this._ui.container.innerHeight();
308                         menuWidth = this._ui.container.innerWidth();
309                         screenHeight = $( window ).height();
310                         screenWidth = $( window ).width();
311                         roomtop = y;
312                         roombot = screenHeight - y;
313                         halfheight = menuHeight / 2;
314                         maxwidth = parseFloat( this._ui.container.css( "max-width" ) );
315                         newtop = ( screenHeight - menuHeight ) / 2;
316
317                         if ( !maxwidth || menuWidth < maxwidth ) {
318                                 newleft = ( screenWidth - menuWidth ) / 2;
319                         } else {
320                                 newleft = x - menuWidth / 2;
321
322                                 if ( newleft < 30 ) {
323                                         newleft = 30;
324                                 } else if ( ( newleft + menuWidth ) > screenWidth ) {
325                                         newleft = screenWidth - menuWidth - 30;
326                                 }
327                         }
328
329                         if ( ctxpopup ) {
330                                 newtop = coords.y;
331                                 newleft = coords.x;
332                         }
333
334                         this._ui.container.css({
335                                 top: newtop,
336                                 left: newleft
337                         });
338
339                         this._ui.screen.css( "height", screenHeight );
340                 },
341                 open: function ( x_where, y_where, backgroundclose ) {
342                         var self = this,
343                                 zIndexMax = 0;
344
345                         if ( this._isOpen || this.options.disabled ) {
346                                 return;
347                         }
348
349                         $( document ).find("*").each( function () {
350                                 var el = $( this ),
351                                         zIndex = parseInt( el.css("z-index"), 10 );
352
353                                 if ( !( el.is( self._ui.container ) ||
354                                                 el.is( self._ui.screen ) ||
355                                                 isNaN( zIndex ))) {
356                                         zIndexMax = Math.max( zIndexMax, zIndex );
357                                 }
358                         } );
359
360                         this._ui.screen.css( "height", $( window ).height() );
361
362                         if ( backgroundclose ) {
363                                 this._ui.screen.css( "opacity", 0 )
364                                                 .removeClass("ui-screen-hidden");
365                         } else {
366                                 this._ui.removeClass("ui-screen-hidden");
367
368                                 if ( this.options.fade ) {
369                                         this._ui.screen.animate( {opacity: this.options.opacity}, "fast" );
370                                 } else {
371                                         this._ui.screen.css( {opacity: this.options.opacity} );
372                                 }
373                         }
374
375                         this._setPosition( x_where, y_where );
376
377                         this.element.trigger("popupbeforeposition");
378
379                         this._ui.container
380                                 .removeClass("ui-selectmenu-hidden")
381                                 .addClass("in")
382                                 .animationComplete( function () {
383                                         self.element.trigger("popupafteropen");
384                                 } );
385
386                         this._isOpen = true;
387
388                         if ( !this._reflow ) {
389                                 this._reflow = function () {
390                                         if ( !self._isOpen ) {
391                                                 return;
392                                         }
393
394                                         self._setPosition( x_where, y_where );
395                                 };
396
397                                 $( window ).bind( "resize", this._reflow );
398                         }
399                 },
400
401                 close: function () {
402                         if ( !this._isOpen ) {
403                                 return;
404                         }
405
406                         if ( this._reflow ) {
407                                 $( window ).unbind( "resize", this._reflow );
408                                 this._reflow = null;
409                         }
410
411                         var self = this,
412                                 hideScreen = function () {
413                                         self._ui.screen.addClass("ui-screen-hidden");
414                                         self._isOpen = false;
415                                 };
416
417                         this._ui.container.removeClass("in").addClass("reverse out");
418
419                         if ( this.options.transition === "none" ) {
420                                 this._ui.container
421                                         .addClass("ui-selectmenu-hidden")
422                                         .removeAttr("style");
423                                 this.element.trigger("popupafterclose");
424                         } else {
425                                 this._ui.container.animationComplete( function () {
426                                         self._ui.container
427                                                 .removeClass("reverse out")
428                                                 .addClass("ui-selectmenu-hidden")
429                                                 .removeAttr("style");
430                                         self.element.trigger("popupafterclose");
431                                 } );
432                         }
433
434                         if ( this.options.fade ) {
435                                 this._ui.screen.animate( {opacity: 0}, "fast", hideScreen );
436                         } else {
437                                 hideScreen();
438                         }
439                 },
440
441                 _realSetTheme: function ( dst, theme ) {
442                         var classes = ( dst.attr("class") || "" ).split(" "),
443                                 alreadyAdded = true,
444                                 currentTheme = null,
445                                 matches;
446
447                         while ( classes.length > 0 ) {
448                                 currentTheme = classes.pop();
449                                 matches = currentTheme.match(/^ui-body-([a-z])$/);
450
451                                 if ( matches && matches.length > 1 ) {
452                                         currentTheme = matches[1];
453                                         break;
454                                 } else {
455                                         currentTheme = null;
456                                 }
457                         }
458
459                         dst.removeClass( "ui-body-" + currentTheme );
460                         if ( ( theme || "" ).match(/[a-z]/) ) {
461                                 dst.addClass( "ui-body-" + theme );
462                         }
463                 },
464
465                 _setTheme: function ( value ) {
466                         this._realSetTheme( this.element, value );
467                         this.options.theme = value;
468                         this.element.attr( "data-" + ( $.mobile.ns || "" ) + "theme", value );
469                 },
470
471                 _setOverlayTheme: function ( value ) {
472                         this._realSetTheme( this._ui.container, value );
473                         this.options.overlayTheme = value;
474                         this.element.attr( "data-" + ( $.mobile.ns || "" ) + "overlay-theme", value );
475                 },
476
477                 _setShadow: function ( value ) {
478                         this.options.shadow = value;
479                         this.element.attr( "data-" + ( $.mobile.ns || "" ) + "shadow", value );
480                         this._ui.container[value ? "addClass" : "removeClass"]("ui-overlay-shadow");
481                 },
482
483                 _setCorners: function ( value ) {
484                         this.options.corners = value;
485                         this.element.attr( "data-" + ( $.mobile.ns || "" ) + "corners", value );
486                         this._ui.container[value ? "addClass" : "removeClass"]("ui-corner-all");
487                 },
488
489                 _setFade: function ( value ) {
490                         this.options.fade = value;
491                         this.element.attr( "data-" + ( $.mobile.ns || "" ) + "fade", value );
492                 },
493
494                 _setTransition: function ( value ) {
495                         this._ui.container
496                                 .removeClass( this.options.transition || "" )
497                                 .addClass( value );
498                         this.options.transition = value;
499                         this.element.attr( "data-" + ( $.mobile.ns || "" ) + "transition", value );
500                 },
501
502                 _setDisabled: function ( value ) {
503                         $.Widget.prototype._setOption.call( this, "disabled", value );
504                         if ( value ) {
505                                 this.close();
506                         }
507                 }
508         });
509
510         $.tizen.popupwindow.bindPopupToButton = function ( btn, popup ) {
511                 if ( btn.length === 0 || popup.length === 0 ) {
512                         return;
513                 }
514
515                 var btnVClickHandler = function ( e ) {
516                         if ( !popup.jqmData("overlay-theme-set") ) {
517                                 popup.popupwindow( "option", "overlayTheme", btn.jqmData("theme") );
518                         }
519
520                         popup.popupwindow( "open",
521                                 btn.offset().left + btn.outerWidth()  / 2,
522                                 btn.offset().top  + btn.outerHeight() / 2 );
523
524                         return false;
525                 };
526
527                 if ( ( popup.popupwindow("option", "overlayTheme") || "" ).match(/[a-z]/) ) {
528                         popup.jqmData( "overlay-theme-set", true );
529                 }
530
531                 btn
532                         .attr({
533                                 "aria-haspopup": true,
534                                 "aria-owns": btn.attr("href")
535                         })
536                         .removeAttr("href")
537                         .bind( "vclick", btnVClickHandler );
538
539                 popup.bind( "destroyed", function () {
540                         btn.unbind( "vclick", btnVClickHandler );
541                 } );
542         };
543
544         $( document ).bind( "pagecreate create", function ( e ) {
545                 $( $.tizen.popupwindow.prototype.options.initSelector, e.target )
546                         .not(":jqmData(role='none'), :jqmData(role='nojs')")
547                         .popupwindow();
548
549                 $( "a[href^='#']:jqmData(rel='popupwindow')", e.target ).each( function () {
550                         $.tizen.popupwindow.bindPopupToButton( $( this ), $( $( this ).attr("href") ) );
551                 });
552         });
553 }( jQuery ));
554
555 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
556 } );
557 //>>excludeEnd("jqmBuildExclude");