[TemporaryStorage] add files required for SDK build
[samples/web/TemporaryStorage.git] / tizen-web-ui-fw / latest / js / src / widgets / jquery.mobile.tizen.pagelayout.js
1
2 /* ***************************************************************************
3  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  * ***************************************************************************
23  *
24  *      Author: Jinhyuk Jun <jinhyuk.jun@samsung.com>
25  */
26
27 (function ( $, undefined ) {
28
29         $.widget( "mobile.pagelayout", $.mobile.widget, {
30                 options: {
31                         visibleOnPageShow: true,
32                         disablePageZoom: true,
33                         transition: "slide", //can be none, fade, slide (slide maps to slideup or slidedown)
34                         fullscreen: false,
35                         tapToggle: true,
36                         tapToggleBlacklist: "a, input, select, textarea, .ui-header-fixed, .ui-footer-fixed",
37                         hideDuringFocus: "input, textarea, select",
38                         updatePagePadding: true,
39                         // Browser detection! Weeee, here we go...
40                         // Unfortunately, position:fixed is costly, not to mention probably impossible, to feature-detect accurately.
41                         // Some tests exist, but they currently return false results in critical devices and browsers, which could lead to a broken experience.
42                         // Testing fixed positioning is also pretty obtrusive to page load, requiring injected elements and scrolling the window
43                         // The following function serves to rule out some popular browsers with known fixed-positioning issues
44                         // This is a plugin option like any other, so feel free to improve or overwrite it
45                         supportBlacklist: function () {
46                                 var w = window,
47                                         ua = navigator.userAgent,
48                                         platform = navigator.platform,
49                                         // Rendering engine is Webkit, and capture major version
50                                         wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ ),
51                                         wkversion = !!wkmatch && wkmatch[ 1 ],
52                                         ffmatch = ua.match( /Fennec\/([0-9]+)/ ),
53                                         ffversion = !!ffmatch && ffmatch[ 1 ],
54                                         operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ ),
55                                         omversion = !!operammobilematch && operammobilematch[ 1 ];
56
57                                 if (
58                                         // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
59                                         ( ( platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1  || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534 ) ||
60                                                 // Opera Mini
61                                                 ( w.operamini && ({}).toString.call( w.operamini ) === "[object OperaMini]" ) ||
62                                                 ( operammobilematch && omversion < 7458 ) ||
63                                                 //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
64                                                 ( ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533 ) ||
65                                                 // Firefox Mobile before 6.0 -
66                                                 ( ffversion && ffversion < 6 ) ||
67                                                 // WebOS less than 3
68                                                 ( window.palmGetResource !== undefined && wkversion && wkversion < 534 ) ||
69                                                 // MeeGo
70                                                 ( ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1 )
71                                 ) {
72                                         return true;
73                                 }
74
75                                 return false;
76                         },
77                         initSelector: ":jqmData(role='content')"
78                 },
79
80                 _create: function () {
81
82                         var self = this,
83                                 o = self.options,
84                                 $el = self.element;
85
86                         // Feature detecting support for
87                         if ( o.supportBlacklist() ) {
88                                 self.destroy();
89                                 return;
90                         }
91
92                         self._addFixedClass();
93                         self._addTransitionClass();
94                         self._bindPageEvents();
95
96                         // only content
97                         self._bindContentControlEvents();
98
99                         // Store back-button, to show again
100                         self._backBtnQueue = [];
101                 },
102
103                 /* add minimum fixed css style to bar(header/footer) and content
104                 *  it need to update when core source modified(jquery.mobile.page.section.js)
105                 *  modified from core source cuz initSelector different */
106                 _addFixedClass: function () {
107                         var self = this,
108                                 o = self.options,
109                                 $el = self.element,
110                                 $elHeader = $el.siblings( ":jqmData(role='header')" ),
111                                 $elFooter = $el.siblings( ":jqmData(role='footer')" ),
112                                 $elPage = $el.closest(".ui-page");
113
114                         $elHeader.addClass( "ui-header-fixed" );
115                         $elFooter.addClass( "ui-footer-fixed" );
116
117                         // "fullscreen" overlay positioning
118                         if ( o.fullscreen ) {
119                                 $elHeader.addClass( "ui-header-fullscreen" );
120                                 $elFooter.addClass( "ui-footer-fullscreen" );
121                                 $elPage
122                                         .addClass( "ui-page-header-fullscreen" )
123                                         .addClass( "ui-page-footer-fullscreen" );
124                         } else {
125                         // If not fullscreen, add class to page to set top or bottom padding
126                                 $elPage.addClass( "ui-page-header-fixed" )
127                                         .addClass( "ui-page-footer-fixed" );
128                         }
129                 },
130
131                 /* original core source(jquery.mobile.fixedToolbar.js)
132                 * never changed */
133                 _addTransitionClass: function () {
134                         var tclass = this.options.transition;
135
136                         if ( tclass && tclass !== "none" ) {
137                                 // use appropriate slide for header or footer
138                                 if ( tclass === "slide" ) {
139                                         tclass = this.element.is( ".ui-header" ) ? "slidedown" : "slideup";
140                                 }
141
142                                 this.element.addClass( tclass );
143                         }
144                 },
145
146
147                 /* Set default page positon
148                 * 1. add title style to header
149                 * 2. Set default header/footer position */
150                 setHeaderFooter: function ( thisPage ) {
151                         var $elPage = $( thisPage ),
152                                 $elHeader = $elPage.find( ":jqmData(role='header')" ).length ? $elPage.find( ":jqmData(role='header')") : $elPage.siblings( ":jqmData(role='header')"),
153                                 $elContent = $elPage.find( ".ui-content" ),
154                                 $elFooter = $elPage.find( ":jqmData(role='footer')" ),
155                                 $elFooterGroup = $elFooter.find( ":jqmData(role='fieldcontain')" ),
156                                 $elFooterControlGroup = $elFooter.find( ".ui-controlgroup" );
157
158                         // divide content mode scrollview and non-scrollview
159                         if ( !$elPage.is( ".ui-dialog" ) ) {
160                                 if ( $elHeader.jqmData("position") == "fixed" || ( $.support.scrollview && $.tizen.frameworkData.theme.match(/tizen/) ) ) {
161                                         $elHeader
162                                                 .css( "position", "fixed" )
163                                                 .css( "top", "0px" );
164                                 } else if ( !$.support.scrollview && $elHeader.jqmData("position") != "fixed" ) {
165                                         $elHeader.css( "position", "relative" );
166                                 }
167                         }
168
169                         /* set Title style */
170                         if ( $elHeader.find("span.ui-title-text-sub").length ) {
171                                 $elHeader.addClass( "ui-title-multiline");
172                         }
173
174                         if ( $elFooterGroup.find( "div" ).is( ".ui-controlgroup-label" ) ) {
175                                 $elFooterGroup.find( "div.ui-controlgroup-label" ).remove();
176                         }
177
178                         if ( $elFooterControlGroup.length ) {
179                                 var anchorPer = 100 / $elFooterControlGroup.find( "a" ).length;
180                                 $elFooterControlGroup.find( "a" ).each( function ( i ) {
181                                         $elFooterControlGroup.find( "a" ).eq( i ).width( anchorPer + "%" );
182                                 });
183                         }
184                 },
185
186                 _bindPageEvents: function () {
187                         var self = this,
188                                 o = self.options,
189                                 $el = self.element,
190                                 $elCurrentFooter;
191
192                         //page event bindings
193                         // Fixed toolbars require page zoom to be disabled, otherwise usability issues crop up
194                         // This method is meant to disable zoom while a fixed-positioned toolbar page is visible
195                         $el.closest( ".ui-page" )
196                                 .bind( "pagebeforeshow", function ( event ) {
197                                         var thisPage = this;
198                                         if ( o.disablePageZoom ) {
199                                                 $.mobile.zoom.disable( true );
200                                         }
201                                         if ( !o.visibleOnPageShow ) {
202                                                 self.hide( true );
203                                         }
204                                         self.setHeaderFooter( thisPage );
205                                         self._setContentMinHeight( thisPage );
206                                 } )
207                                 .bind( "webkitAnimationStart animationstart updatelayout", function ( e, data ) {
208                                         var thisPage = this;
209                                         if ( o.updatePagePadding ) {
210                                                 self.updatePagePadding(thisPage);
211                                                 self.updatePageLayout( thisPage, data);
212                                         }
213                                 })
214
215                                 .bind( "pageshow", function ( event ) {
216                                         var thisPage = this;
217                                         self._setContentMinHeight( thisPage );
218                                         self.updatePagePadding( thisPage );
219                                         self._updateHeaderArea( thisPage );
220                                         if ( o.updatePagePadding ) {
221                                                 $( window ).bind( "throttledresize." + self.widgetName, function () {
222                                                         self.updatePagePadding(thisPage);
223
224                                                         self.updatePageLayout( thisPage, false);
225                                                         self._updateHeaderArea( thisPage );
226                                                         self._setContentMinHeight( thisPage );
227                                                 });
228                                         }
229                                 })
230
231                                 .bind( "pagebeforehide", function ( e, ui ) {
232                                         if ( o.disablePageZoom ) {
233                                                 $.mobile.zoom.enable( true );
234                                         }
235                                         if ( o.updatePagePadding ) {
236                                                 $( window ).unbind( "throttledresize." + self.widgetName );
237                                         }
238                                 });
239
240                         window.addEventListener( "softkeyboardchange", function ( e ) {
241                                 var $elDownBtn = $( "<div class='ui-btn-footer-down'></div>" ),
242                                         $elPage = $( ".ui-page-active" ),
243                                         backBtn,
244                                         backBtnPosition = "footer";
245
246                                 if ( $elPage.data( "addBackBtn" ) ) {
247                                         $elPage.data( "addBackBtn" ) == "header" ? backBtnPosition = "header" : backBtnPosition = "footer";
248
249                                         if ( e.state == "on" ) {
250                                                 if ( !$elPage.find( ".ui-" + backBtnPosition + " .ui-btn-footer-down" ).length ) {
251                                                         $elDownBtn.buttonMarkup( { icon: "down" } ).appendTo( $elPage.find( ".ui-" + backBtnPosition ) );
252                                                 }
253
254                                                 // N_SE-32900: If an app moves a page when the pop is shown, the .ui-page-active page
255                                                 //             is changed.
256                                                 //             In this case, the '.ui-page-active .ui-btn-back' selector indicates a
257                                                 //             new page's one, and the old page's .ui-btn-back button is still hidden.
258                                                 //             So, the current back button is remembered to be shown at the
259                                                 //             softkeyboardchange.off event.
260                                                 backBtn = $( ".ui-page-active .ui-btn-back" );
261                                                 backBtn.hide();
262                                                 self._backBtnQueue.push( backBtn );     // Store hidden backBtn
263                                         } else if ( e.state == "off" ) {
264                                                 self._backBtnQueue.forEach( function ( b ) {
265                                                         b.show();       // Show each backBtn,
266                                                 } );
267                                                 self._backBtnQueue.length = 0;  // and clear queue.
268
269                                                 $( ".ui-btn-footer-down" ).remove();
270                                         }
271                                 }
272
273                         });
274                 },
275
276                 _bindContentControlEvents: function () {
277                         var self = this,
278                                 o = self.options,
279                                 $el = self.element;
280
281                         $el.closest( ".ui-page" )
282                                 .bind( "pagebeforeshow", function ( event ) {
283
284                                 });
285                 },
286
287                 _setContentMinHeight : function ( thisPage ) {
288                         var $elPage = $( thisPage ),
289                                 $elHeader = $elPage.find( ":jqmData(role='header')" ),
290                                 $elFooter = $elPage.find( ":jqmData(role='footer')" ),
291                                 $elContent = $elPage.find( ":jqmData(role='content')" ),
292                                 resultMinHeight,
293                                 dpr = 1,
294                                 layoutInnerHeight = window.innerHeight;
295
296                         if ( !$.support.scrollview || ($.support.scrollview && $elContent.jqmData("scroll") === "none") ) {
297                                 dpr = window.outerWidth / window.innerWidth;
298                                 layoutInnerHeight = Math.floor( window.outerHeight / dpr );
299                         } else {
300                                 layoutInnerHeight = window.innerHeight;
301                         }
302
303                         resultMinHeight = layoutInnerHeight - $elHeader.height() - $elFooter.height();
304
305                         if ( $.support.scrollview && $elContent.jqmData("scroll") !== "none" ) {
306                                 $elContent.css( "min-height", resultMinHeight - parseFloat( $elContent.css("padding-top") ) - parseFloat( $elContent.css("padding-bottom") ) + "px" );
307                                 $elContent.children( ".ui-scrollview-view" ).css( "min-height", $elContent.css( "min-height" ) );
308                         }
309                 },
310
311                 _updateHeaderArea : function ( thisPage ) {
312                         var $elPage = $( thisPage ),
313                                 $elHeader = $elPage.find( ":jqmData(role='header')" ).length ? $elPage.find( ":jqmData(role='header')") : $elPage.siblings( ":jqmData(role='header')"),
314                                 headerBtnNum = $elHeader.children("a").length,
315                                 headerSrcNum = $elHeader.children("img").length;
316
317                         if ( !$elPage.is( ".ui-dialog" ) ) {
318                                 $elHeader.find( "h1" ).css( "width", window.innerWidth - parseInt( $elHeader.find( "h1" ).css( "margin-left" ), 10 ) * 2 - $elHeader.children( "a" ).width() * headerBtnNum - $elHeader.children( "a" ).width() / 4 - $elHeader.children( "img" ).width() * headerSrcNum * 4 );
319                         }
320                         /* add half width for default space between text and button, and img tag area is too narrow, so multiply three for img width*/
321                 },
322
323                 _visible: true,
324
325                 // This will set the content element's top or bottom padding equal to the toolbar's height
326                 updatePagePadding: function ( tbPage ) {
327                         var $el = this.element,
328                                 header = $el.siblings( ".ui-header" ).length,
329                                 footer = $el.siblings( ".ui-footer" ).length;
330
331                         // This behavior only applies to "fixed", not "fullscreen"
332                         if ( this.options.fullscreen ) {
333                                 return;
334                         }
335
336                         tbPage = tbPage || $el.closest( ".ui-page" );
337
338                         if ( $el.siblings( ".ui-header" ).jqmData("position") == "fixed" || ($.support.scrollview && $el.jqmData("scroll") !== "none" )) {
339                                 $( tbPage ).css( "padding-top", ( header ? $el.siblings( ".ui-header" ).outerHeight() : 0 ) );
340                         }
341                         $( tbPage ).css( "padding-bottom", ( footer ? $el.siblings( ".ui-footer" ).outerHeight() : 0 ) );
342                 },
343
344                 /* 1. Calculate and update content height   */
345                 updatePageLayout: function ( thisPage, receiveType ) {
346                         var $elFooter,
347                                 $elPage = $( thisPage ),
348                                 $elHeader = $elPage.find( ":jqmData(role='header')" ),
349                                 $elContent = $elPage.find( ":jqmData(role='content')" ),
350                                 resultContentHeight = 0,
351                                 resultFooterHeight = 0,
352                                 resultHeaderHeight = 0,
353                                 layoutInnerHeight = window.innerHeight,
354                                 dpr = 1;
355
356                         if ( $elPage.length ) {
357                                 $elFooter = $elPage.find( ":jqmData(role='footer')" );
358                         } else {
359                                 $elFooter = $( document ).find( ":jqmData(role='footer')" ).eq( 0 );
360                         }
361
362                         // calculate footer height
363                         resultFooterHeight = ( $elFooter.css( "display" ) == "none" || $elFooter.length == 0 ) ? 0 : $elFooter.height();
364                         resultHeaderHeight = ( $elHeader.css( "display" ) == "none" || $elHeader.length == 0 ) ? 0 : $elHeader.height();
365
366                         if (resultFooterHeight != 0 ) {
367                                 $elFooter.css( "bottom", 0 );
368                         }
369
370                         if ( !$.support.scrollview || ($.support.scrollview && $elContent.jqmData("scroll") === "none") ) {
371                                 dpr = window.outerWidth / window.innerWidth;
372                                 layoutInnerHeight = Math.floor( window.outerHeight / dpr );
373                         } else {
374                                 layoutInnerHeight = window.innerHeight;
375                         }
376
377                         resultContentHeight = layoutInnerHeight - resultFooterHeight - resultHeaderHeight;
378
379                         if ( $.support.scrollview && $elContent.jqmData("scroll") !== "none" ) {
380                                 $elContent.height( resultContentHeight -
381                                                 parseFloat( $elContent.css("padding-top") ) -
382                                                 parseFloat( $elContent.css("padding-bottom") ) );
383                         }
384
385                         // External call page( "refresh") - in case title changed
386                         if ( receiveType ) {
387                                 $elPage
388                                         .css( "min-height", resultContentHeight )
389                                         .css( "padding-top", resultHeaderHeight )
390                                         .css( "padding-bottom", resultFooterHeight );
391                         }
392                 },
393
394                 show: function ( notransition ) {
395                         /* blank function: deprecated */
396                 },
397
398                 hide: function ( notransition ) {
399                         /* blank function: deprecated */
400                 },
401
402                 toggle: function () {
403                         this[ this._visible ? "hide" : "show" ]();
404                 },
405
406                 destroy: function () {
407                         this.element.removeClass( "ui-header-fixed ui-footer-fixed ui-header-fullscreen ui-footer-fullscreen in out fade slidedown slideup ui-fixed-hidden" );
408                         this.element.closest( ".ui-page" ).removeClass( "ui-page-header-fixed ui-page-footer-fixed ui-page-header-fullscreen ui-page-footer-fullscreen" );
409                 },
410
411                 refresh: function () {
412                         var $elPage = $( ".ui-page-active" );
413                         this.setHeaderFooter( $elPage );
414                         this._updateHeaderArea( $elPage );
415                 }
416         });
417
418         //auto self-init widgets
419         $( document )
420                 .bind( "pagecreate create", function ( e ) {
421                         // DEPRECATED in 1.1: support for data-fullscreen=true|false on the page element.
422                         // This line ensures it still works, but we recommend moving the attribute to the toolbars themselves.
423                         if ( $( e.target ).jqmData( "fullscreen" ) ) {
424                                 $( $.mobile.pagelayout.prototype.options.initSelector, e.target ).not( ":jqmData(fullscreen)" ).jqmData( "fullscreen", true );
425                         }
426                         $.mobile.pagelayout.prototype.enhanceWithin( e.target );
427                 });
428
429 }( jQuery ));
430