      1 // ==========================================================================
      2 // Project:   The M-Project - Mobile HTML5 Application Framework
      3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
      4 // Creator:   Sebastian
      5 // Date:      02.11.2010
      6 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
      7 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
      8 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
      9 // ==========================================================================
     10
     11 /**
     12  * @class
     13  *
     14  * M.PageView is the prototype of any page. It is the seconds 'highest' view, right after
     15  * M.Application. A page is the container view for all other views.
     16  *
     17  * @extends M.View
     18  */
     19 M.PageView = M.View.extend(
     20 /** @scope M.PageView.prototype */ {
     21
     22     /**
     23      * The type of this object.
     24      *
     25      * @type String
     26      */
     27     type: 'M.PageView',
     28
     29     /**
     30      * States whether a page is loaded the first time or not. It is automatically set to NO
     31      * once the page was first loaded.
     32      *
     33      * @type Boolean
     34      */
     35     isFirstLoad: YES,
     36
     37     /**
     38      * This property can be used to set the page's beforeLoad action.
     39      *
     40      * @type Object
     41      */
     42     beforeLoad: null,
     43
     44     /**
     45      * This property can be used to set the page's onLoad action.
     46      *
     47      * @type Object
     48      */
     49     onLoad: null,
     50
     51     /**
     52      * This property can be used to set the page's beforeHide action.
     53      *
     54      * @type Object
     55      */
     56     beforeHide: null,
     57
     58     /**
     59      * This property can be used to set the page's onHide action.
     60      *
     61      * @type Object
     62      */
     63     onHide: null,
     64
     65     /**
     66      * Indicates whether the page has a tab bar or not.
     67      *
     68      * @type Boolean
     69      */
     70     hasTabBarView: NO,
     71
     72     /**
     73      * The page's tab bar.
     74      *
     75      * @type M.TabBarView
     76      */
     77     tabBarView: null,
     78
     79     /**
     80      * Renders in three steps:
     81      * 1. Rendering Opening div tag with corresponding data-role
     82      * 2. Triggering render process of child views
     83      * 3. Rendering closing tag
     84      *
     85      * @private
     86      * @returns {String} The page view's html representation.
     87      */
     88     render: function() {
     89         this.html += '<div id="' + this.id + '" data-role="page"' + this.style() + '>';
     90
     91         this.renderChildViews();
     92
     93         this.html += '</div>';
     94
     95         this.writeToDOM();
     96         this.theme();
     97     },
     98
     99     /**
    100      * This method writes the view's html string into the DOM. M.Page is the only view that does
    101      * that. All other views just deliver their html representation to a page view.
    102      */
    103     writeToDOM: function() {
    104         document.write(this.html);
    105     },
    106
    107     /**
    108      * This method is called right before the page is loaded. If a beforeLoad-action is defined
    109      * for the page, it is now called.
    110      */
    111     pageWillLoad: function() {
    112         if(this.beforeLoad) {
    113             this.beforeLoad.target[this.beforeLoad.action](this.isFirstLoad);
    114         }
    115     },
    116
    117     /**
    118      * This method is called right after the page was loaded. If a onLoad-action is defined
    119      * for the page, it is now called.
    120      */
    121     pageDidLoad: function() {
    122         if(this.onLoad) {
    123             this.onLoad.target[this.onLoad.action](this.isFirstLoad);
    124         }
    125
    126         /* if there is a list on the page, reset it: deactivate possible active list items */
    127         $('#' + this.id).find('.ui-btn-active').each(function() {
    128             if(M.ViewManager.getViewById($(this).attr('id')) && M.ViewManager.getViewById($(this).attr('id')).type === 'M.ListItemView') {
    129                 var listItem = M.ViewManager.getViewById($(this).attr('id'));
    130                 listItem.removeCssClass('ui-btn-active');
    131             }
    132         });
    133
    134         /* WORKAROUND for being able to use more than two tab items within a tab bar */
    135         /* TODO: Get rid of this workaround with a future version of jquery mobile */
    136         if(this.isFirstLoad && this.childViews) {
    137             var childViews = $.trim(this.childViews).split(' ');
    138             for(var i in childViews) {
    139                 var view = this[childViews[i]];
    140                 if(view.type === 'M.TabBarView' && view.anchorLocation === M.BOTTOM) {
    141                     $('[data-id="' + view.name + '"]:not(:last-child)').each(function() {
    142                         if(!$(this).hasClass('ui-footer-duplicate')) {
    143                             /* first empty the tabbar and then hide it, since jQuery's remove() doesn't work */
    144                             $(this).empty();
    145                             $(this).hide();
    146                         }
    147                     });
    148                 }
    149             }
    150         }
    151
    152         this.isFirstLoad = NO;
    153     },
    154
    155     /**
    156      * This method is called right before the page is hidden. If a beforeHide-action is defined
    157      * for the page, it is now called.
    158      */
    159     pageWillHide: function() {
    160         if(this.beforeHide) {
    161             this.beforeHide.target[this.beforeHide.action]();
    162         }
    163     },
    164
    165     /**
    166      * This method is called right after the page was hidden. If a onHide-action is defined
    167      * for the page, it is now called.
    168      */
    169     pageDidHide: function() {
    170         if(this.onHide) {
    171             this.onHide.target[this.onHide.action]();
    172         }
    173     },
    174
    175     /**
    176      * This method is called if the device's orientation changed.
    177      */
    178     orientationDidChange: function(orientation) {
    179         if(this.onOrientationChange) {
    180             this.onOrientationChange.target[this.onOrientationChange.action](orientation);
    181         }
    182     },
    183
    184     /**
    185      * Triggers the rendering engine, jQuery mobile, to style the page and call the theme() of
    186      * its child views.
    187      *
    188      * @private
    189      */
    190     theme: function() {
    191         $('#' + this.id).page();
    192         this.themeChildViews();
    193     },
    194
    195     /**
    196      * Applies some style-attributes to the page.
    197      *
    198      * @private
    199      * @returns {String} The page's styling as html representation.
    200      */
    201     style: function() {
    202         var html = '';
    203         if(this.cssClass) {
    204             if(!html) {
    205                 html += ' class="';
    206             }
    207             html += this.cssClass;
    208         }
    209         if(html) {
    210             html += '"';
    211         }
    212         return html;
    213     }
    214
    215 });