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 });