UNPKG

mmir-lib

Version:

MMIR (Mobile Multimodal Interaction and Relay) library

251 lines (221 loc) 7.96 kB
/** * Stub for view/rendering engine: * * mocks the function calls and invokes the hooks on the controllers without actually rendering anything. * * * @example * mmir.present.render('theController', 'theView'); * * @class * @name StubViewEngine * @memberOf mmir.env.view * @static * @hideconstructor * * @depends document (DOM object) * @depends HTMLElement.parentElement * @depends HTMLElement.removeChild * */ define(['mmirf/logger', 'mmirf/util/deferred', 'module'],function(Logger, Deferred, module){ var log = Logger.create(module); var promise = new Deferred(); //property names for passing the respected objects from doRenderView() to doRemoveElementsAfterViewLoad() var FIELD_NAME_RESOLVE = '__renderResolve'; var FIELD_NAME_VIEW = '__view'; var FIELD_NAME_DATA = '__renderData'; var FIELD_NAME_CONTROLLER = '__ctrl'; var FIELD_NAME_MANAGER = '__present'; //function for removing "old" content from DOM (-> remove old, un-used page content) var doRemoveElementsAfterViewLoad = function(_event, data){ var presentMgr = data[FIELD_NAME_MANAGER]; var ctrl = data[FIELD_NAME_CONTROLLER]; var view = data[FIELD_NAME_VIEW]; var renderData = data[FIELD_NAME_DATA]; var defer = data[FIELD_NAME_RESOLVE]; //FIX handle missing ctrl/view parameter gracefully // this may occur when doRemoveElementsAfterViewLoad is // triggered NOT through doRenderView but by some automatic // mechanism, e.g. BACK history event that was not handled // by the framework (which ideally should not happen ...) var viewName; if(view){ viewName = view.getName(); } if(!ctrl){ log.e('PresentationManager[stubViewEngine].__doRemoveElementsAfterViewLoad: missing controller (and view)!',data.options); return; } log.d('on_page_load::'+viewName, renderData); //trigger "after page loading" hooks on controller: // the hook for all views of the controller MUST be present/implemented: presentMgr._fireRenderEvent(ctrl, 'on_page_load', renderData, viewName, renderData); //... the hook for single/specific view MAY be present/implemented: if(view){ presentMgr._fireRenderEvent(ctrl, 'on_page_load_'+viewName, renderData); } defer.resolve(); }; /** * Actually renders the View.<br> * Fetches the layout for the controller, then fills the * layout-template with the view content, while incorporating * partials and contents that helper methods have provided. Then * Dialogs are created and the pageContainer id is updated. At last * all the content is localized using * {@link mmir.LanguageManager#translateHTML}, and appended to * the HTML document of the application, while the old one is * removed.<br> * At the end the <b>on_page_load</b> action is performed. * * @function doRenderView * * @param {String} * _ctrlName Name of the controller * @param {String} * viewName Name of the view to render * @param {Object} * view View object that is to be rendered * @param {Object} * ctrl Controller object of the view to render * @param {Object} * [data] optional data for the view. * @returns {Promise} * a Promise that gets resolved when rendering is finished * * @memberOf mmir.env.view.StubViewEngine# */ var doRenderView = function(_ctrlName, viewName, view, ctrl, data){ //if set to FALSE by one of the hooks (ie. before_page_prepare / before_page_load) // will prevent rendering of the view! var isContinue; log.d('before_page_prepare::'+viewName, data); //trigger "before page preparing" hooks on controller, if present/implemented: isContinue = this._fireRenderEvent(ctrl, 'before_page_prepare', data, viewName, data); if(isContinue === false){ return;/////////////////////// EARLY EXIT //////////////////////// } isContinue = this._fireRenderEvent(ctrl, 'before_page_prepare_'+viewName, data); if(isContinue === false){ return;/////////////////////// EARLY EXIT //////////////////////// } // var layout = this.getLayout(ctrlName, true); var renderResolve = new Deferred(); var presentMgr = this; var renderFunc = function(){ //provide "change" data for before_page_load calls: var pageEvtData = { name: viewName }; log.d('before_page_load::'+viewName, pageEvtData); //trigger "before page loading" hooks on controller, if present/implemented: isContinue = presentMgr._fireRenderEvent(ctrl, 'before_page_load', data, pageEvtData);//<- this is triggered for every view in the corresponding controller if(isContinue === false){ return;/////////////////////// EARLY EXIT //////////////////////// } isContinue = presentMgr._fireRenderEvent(ctrl, 'before_page_load_'+viewName, data, pageEvtData); if(isContinue === false){ return;/////////////////////// EARLY EXIT //////////////////////// } //pass controller- and view-instance to "after page change" handler var changeOptions = {}; changeOptions[FIELD_NAME_RESOLVE] = renderResolve; changeOptions[FIELD_NAME_VIEW] = view; changeOptions[FIELD_NAME_DATA] = data; changeOptions[FIELD_NAME_CONTROLLER] = ctrl; changeOptions[FIELD_NAME_MANAGER] = presentMgr; doRemoveElementsAfterViewLoad.call(null,{},changeOptions); }; renderFunc(); return renderResolve; }; promise.resolve({ /** * @copydoc mmir.env.view.StubViewEngine#doRenderView * @function render * @public * * @memberOf mmir.env.view.StubViewEngine.prototype * @see mmir.PresentationManager#render */ render: doRenderView, /** * Closes a modal window / dialog.<br> * * * @function hideCurrentDialog * @public * * @memberOf mmir.env.view.StubViewEngine.prototype * @see mmir.PresentationManager#hideCurrentDialog */ hideCurrentDialog : function() { //stub: do nothing log.i('hideCurrentDialog'); }, /** * Opens the requested dialog.<br> * * @function showDialog * @param {String} * _ctrlName Name of the controller * @param {String} * _dialogId Id of the dialog * @param {Object} * _data Optionally data - not used * * @returns {Object} the instance of the current dialog that was opened * * @public * * @memberOf mmir.env.view.StubViewEngine.prototype * @see mmir.PresentationManager#showDialog */ showDialog : function(_ctrlName, _dialogId, _data) { //stub: do nothing log.i('showDialog'); }, /** * Shows a "wait" dialog, i.e. "work in progress" notification. * * @function showWaitDialog * * @param {String} [_text] OPTIONAL * the text that should be displayed. * If omitted the language setting for <code>loadingText</code> * will be used instead (from dictionary.json) * @param {String} [_theme] OPTIONAL * set the jQuery Mobile theme to be used for the wait-dialog * (e.g. "a" or "b"). * NOTE: if this argument is used, then the <code>text</code> * must also be supplied. * * @public * * @see #hideWaitDialog * * @memberOf mmir.env.view.StubViewEngine.prototype * @see mmir.PresentationManager#showWaitDialog */ showWaitDialog : function(_text, _theme) { //stub: do nothing log.i('showWaitDialog'); }, /** * Hides / closes the "wait" dialog. * * @function hideWaitDialog * @public * * @see #showWaitDialog * * @memberOf mmir.env.view.StubViewEngine.prototype * @see mmir.PresentationManager#hideWaitDialog */ hideWaitDialog : function() { //stub: do nothing log.i('hideWaitDialog'); }, }); return promise; });