require(["core/app"],function(App){ var global = App.globals[item_global]; if( global ){ var item = global.get(item_id); if( item ){ show_single( item ); }else{ Utils.log('Router single route : item with id "'+ item_id +'" not found in global "'+ item_global +'".'); App.loadRouteItemFromRemote( item_id, item_global, 'posts-list', { success: function( item ) { show_single( item ); }, error: function() { App.router.default_route(); } } ); } }else{ Utils.log('Error : router single route : global "'+ item_global +'" not found.'); App.router.default_route(); } });
var default_template_failed = function( error ) { if( _this.fallback_template_name != '' ){ Utils.log('View template "'+ _this.template_name +'.html" not found in theme : load fallback template "'+ _this.fallback_template_name +'"'); require(['text!theme/'+ _this.fallback_template_name +'.html'], function(tpl){ if( tpl.length ) { _this.template = _.template(tpl); cb_ok(); } else { //On mobile devices (but not in browsers) the require(['text!template']) //is successful even if the template is not there... //So we solve the problem by checking if tpl is empty, and //if it is we consider that the template was not found : fallback_template_failed(); } }, function( fallback_error){ fallback_template_failed( fallback_error ); } ); }else{ Utils.log('Error : view template "'+ _this.template_name +'.html" not found in theme'); if( cb_error ){ cb_error(); } } };
require(["core/app"],function(App){ var global = App.globals[item_global]; if( global ){ var item = global.get(item_id); if( item ){ var item_json = item.toJSON(); var item_data = item_global == 'posts' ? {post:item_json} : {item:item_json}; if( check_route('single/'+ item_global +'/'+ item_id) ){ RegionManager.show( 'single', {item:item,global:item_global}, {screen_type:'single',component_id:'',item_id:parseInt(item_id),global:item_global,data:item_data,label:item_json.title} ); } }else{ Utils.log('Error : router single route : item with id "'+ item_id +'" not found in global "'+ item_global +'".'); App.router.default_route(); } }else{ Utils.log('Error : router single route : global "'+ item_global +'" not found.'); App.router.default_route(); } });
var openView = function (view) { var first_static_opening = false; var custom_rendering = App.getParam('custom-screen-rendering'); if( !view.is_static || !$(view.el).html().length ){ if( view.is_static != undefined && view.is_static ){ first_static_opening = true; Utils.log('Open static view',{screen_data:App.getCurrentScreenData(),view:view}); }else{ Utils.log('Open view',{screen_data:App.getCurrentScreenData(),view:view}); } view.render(); } else { Utils.log('Re-open existing static view',{view:view}); } var $elContent = $(elContent); if( custom_rendering ){ /** * 'screen-transition' action: allows to implement your own screen transitions using JS/CSS. * * @param $wrapper: jQuery Object corresponding to div#app-content-wrapper, which is the element wrapping $current and $next screens. * @param $current: jQuery Object corresponding to the screen (div.app-screen) that we're leaving, to display $next instead. * @param $next: jQuery Object corresponding to the new screen (div.app-screen) that we want to display (by replacing $current). * @param current_screen: JSON Object: screen object containing information about the screen we're leaving. * @param next_screen: JSON Object: screen object containing information (screen type, screen item id, etc) about the new screen we want to display (see getCurrentScreen() for details about screen objects) . * @param $deferred: jQuery deferred object that must be resolved at the end of the transition animation to tell app core that the new screen has finished rendering. */ Hooks.doActions( 'screen-transition', [$elContent,$('div:first-child',$elContent),$(view.el),App.getPreviousScreenMemoryData(),App.getCurrentScreenData()] ).done(function(){ renderSubRegions(); vent.trigger('screen:showed',App.getCurrentScreenData(),currentView,first_static_opening); }).fail(function(){ //Note : Hooks.doActions doesn't handle a fail case for now, //but it may in the future! renderSubRegions(); vent.trigger('screen:showed:failed',App.getCurrentScreenData(),currentView,first_static_opening); }); }else{ $elContent.empty().append(view.el); renderSubRegions(); vent.trigger('screen:showed',App.getCurrentScreenData(),currentView,first_static_opening); } if(view.onShow) { view.onShow(); } };
wpak_note.canLaunch = function(){ if( app_dynamic_data.email_not_satisfied === '' ){ Utils.log('WPAK Note error : please set an email for not satisfied users'); } if( app_dynamic_data.app_url_in_app_store === '' ){ Utils.log('WPAK Note error : please set the app store\'s app url'); } return parseInt(app_dynamic_data.campaign_on) === 1 && app_dynamic_data.email_not_satisfied !== '' && app_dynamic_data.app_url_in_app_store !== '' && ( get_count_open() == get_trigger_count() || Flags.isUp('wpak_note_go') ); };
_.each( app.favorites.toJSON(), function( item, index ) { if( undefined === globals_keys.get( item.global ) ) { // Favorite type doesn't exist into globals keys Utils.log( 'Favorite type doesn\'t exist into globals keys', { type: item.global, globals_keys: globals_keys } ); globals_keys.add( { id: item.global } ); app.globals[item.global] = new Items.Items( { global: item.global } ); } if( null === app.getGlobalItem( item.global, item.id ) ) { // Favorite item doesn't exist into global items Utils.log( 'Favorite item doesn\'t exist into global items', { item: item, globals: app.globals } ); app.globals[item.global].add( item ); } });
single: function ( item_global, item_id ) { route_asked = 'single/'+ item_global +'/'+ item_id; this.default_route_redirect( route_asked ); var _this = this; var show_single = function() { var route_data = _this.getRouteData( 'single', { item_global: item_global, item_id: item_id } ); if ( route_data.error.length === 0 ) { if ( check_route( 'single/'+ item_global +'/'+ item_id ) ) { RegionManager.show( route_data.view_type, route_data.view_data, route_data.screen_data ); } } else { Utils.log( route_data.error ); App.router.default_route(); } }; var global = App.globals[item_global]; if( global ){ var item = global.get(item_id); if( item ){ show_single(); }else{ Utils.log('Router single route : item with id "'+ item_id +'" not found in global "'+ item_global +'".'); App.loadRouteItemFromRemote( item_id, item_global, 'posts-list', { success: function( item ) { show_single(); }, error: function() { App.router.default_route(); } } ); } }else{ Utils.log('Error : router single route : global "'+ item_global +'" not found.'); App.router.default_route(); } },
app.resetDefaultRoute = function(){ var default_route = ''; if( app.navigation.length > 0 ){ var first_nav_component_id = app.navigation.first().get('component_id'); default_route = '#component-'+ first_nav_component_id; }else{ //No navigation item : set default route to first component found: if( app.components.length ){ var first_component = app.components.first(); default_route = '#component-'+ first_component.id; }else{ Utils.log('No navigation, no component found. Could not set default route.'); } } /** * Hook : filter 'default-route' : use this to define your own default route */ default_route = Hooks.applyFilter('default-route',default_route,[Stats.get_count_open(),Stats.get_last_open_date()]); if( default_route != '' ){ app.router.setDefaultRoute(default_route); } };
var success = function( data ) { if ( data.hasOwnProperty( 'result' ) && data.result.hasOwnProperty( 'status' ) ) { if ( data.result.status == 1 ) { if ( data.public_key && data.public_key.length && data.control ) { if ( checkHMAC( data.public_key + user, web_service_params.control_key, data.control ) ) { //Set public key to Local Storage : authenticationData.set( 'public_key', data.public_key ); authenticationData.save(); Utils.log( 'Public key retrieved successfully' ); cb_ok( data.public_key ); } else { cb_error( 'wrong-hmac' ); } } else if ( data.hasOwnProperty( 'auth_error' ) ) { cb_error( data.auth_error ); } else { cb_error( 'no-auth-error' ); } } else { cb_error( 'web-service-error', data.result.message ); } } else { cb_error( 'no-result' ); } };
var show_page = function( page_component_id ) { //To allow page route with no component (#page/[page_id]): if ( page_component_id === 'wpak-page-component-placeholder' ) { //If the page was loaded dynamically, it has no corresponding component, //so we pass true to getPageComponentByPageId() so that the first page component //found is used in that case: var page_component = App.getPageComponentByPageId( item.get('id'), true ); if ( page_component ) { page_component_id = page_component.id; } } var route_data = _this.getRouteData( 'page', { component_id: page_component_id, page_id: page_id } ); if ( route_data.error.length === 0 ) { //This is still component_id to check the route and not page_component_id, to handle the case //where the page was not in the app and was retrieved from remote: in that case the page's fragment //includes component_id but it really displays the page linked to page_component_id //(TODO: see if we could redirect to real page fragment here). if( check_route('page/'+ component_id +'/'+ page_id) ) { RegionManager.show( route_data.view_type, route_data.view_data, route_data.screen_data ); } } else { Utils.log( route_data.error ); App.router.default_route(); } };
app.resetDefaultRoute = function(is_app_launch){ var default_route = ''; var is_app_launch = is_app_launch !== undefined && is_app_launch === true; if( app.navigation.length > 0 ){ var first_nav_component_id = app.navigation.first().get('component_id'); default_route = '#component-'+ first_nav_component_id; }else{ //No navigation item : set default route to first component found: if( app.components.length ){ var first_component = app.components.first(); default_route = '#component-'+ first_component.id; }else{ Utils.log('No navigation, no component found. Could not set default route.'); } } /** * Hook : filter 'default-route' : use this to define your own default route */ default_route = Hooks.applyFilter('default-route',default_route,[Stats.getStats(),is_app_launch]); if( default_route != '' ){ app.router.setDefaultRoute(default_route); } return default_route; };
_.each( Config.options, function( value, key, list ) { // Don't override an existing option if( undefined === app.options.get( key ) ) { Utils.log( 'Option not existing: adding to collection', { key: key, value: value } ); app.options.add( { id: key, value: value } ); } });
wpak_note.launch = function(){ if( Phonegap.getNetworkState() === 'online' ){ wpak_note.setState('first-box'); actions_callbacks.display_first_box(); }else{ Utils.log('WP AppKit Note : did not display first box because the app is offline! Will retry later'); } };
app.triggerError = function(error_id,error_data,error_callback){ vent.trigger('error:'+ error_id,error_data); Utils.log('app.js error ('+ error_id +') : '+ error_data.message, error_data); if( error_callback != undefined ){ error_data = _.extend({event: 'error:'+ error_id}, error_data); error_callback(error_data); } };
'success': function( appFavorites, response, options ) { Utils.log( 'Favorites retrieved from local storage.', { favorites: appFavorites } ); if( components.length == 0 || force ){ syncWebService(cb_ok,cb_error); }else{ Utils.log('Components retrieved from local storage.',{components:components}); app.navigation.fetch({'success': function(navigation, response_nav, options_nav){ if( navigation.length == 0 ){ syncWebService(cb_ok,cb_error); }else{ Utils.log('Navigation retrieved from local storage.',{navigation:navigation}); globals_keys.fetch({'success': function(global_keys, response_global_keys, options_global_keys){ if( global_keys.length == 0 ){ syncWebService(cb_ok,cb_error); }else{ var fetch = function(_items,_key){ return _items.fetch({'success': function(fetched_items, response_items, options_items){ app.globals[_key] = fetched_items; //Backbone's fetch returns jQuery ajax deferred object > works with $.when }}); }; var fetches = []; global_keys.each(function(value, key, list){ var global_id = value.get('id'); var items = new Items.Items({global:global_id}); fetches.push(fetch(items,global_id)); }); $.when.apply($, fetches).done(function () { if( app.globals.length == 0 ){ syncWebService(cb_ok,cb_error); }else{ Utils.log('Global items retrieved from local storage.',{globals:app.globals}); // @TODO: find a better way to do this? addFavoritesToGlobals(); cb_ok(); } }); } }}); } }}); } },
$.when.apply($, fetches).done(function () { if( app.globals.length == 0 ){ syncWebService(cb_ok,cb_error); }else{ Utils.log('Global items retrieved from local storage.',{globals:app.globals}); cb_ok(); } });
var openView = function (view) { if( !view.isStatic || !$(view.el).html().length ){ if( view.isStatic != undefined && view.isStatic ){ Utils.log('Open static view',{screen_data:App.getCurrentScreenData(),view:view}); }else{ Utils.log('Open view',{screen_data:App.getCurrentScreenData(),view:view}); } view.render(); var $el = $(el); vent.trigger('screen:before-transition',App.getCurrentScreenData(),currentView); var custom_rendering = App.getParam('custom-screen-rendering'); if( custom_rendering ){ Hooks.doActions( 'screen-transition', [$el,$('div:first-child',$el),$(view.el),App.getCurrentScreenData(),App.getPreviousScreenMemoryData()] ).done(function(){ renderSubRegions(); vent.trigger('screen:showed',App.getCurrentScreenData(),currentView); }).fail(function(){ //Note : Hooks.doActions doesn't handle a fail case for now, //but it may in the future! renderSubRegions(); vent.trigger('screen:showed:failed',App.getCurrentScreenData(),currentView); }); }else{ $el.empty().append(view.el); renderSubRegions(); vent.trigger('screen:showed',App.getCurrentScreenData(),currentView); } if(view.onShow) { view.onShow(); } }else{ //TODO : we should apply custom rendering logic here too... Utils.log('Re-open existing static view',{view:view}); $(el).empty().append(view.el); renderSubRegions(); vent.trigger('screen:showed',App.getCurrentScreenData(),currentView); } };
var cb_ok = function( data ) { var user = authentication.getCurrentUser(); Utils.log( 'User authentication remote check ok : user "'+ user.login +'" connected', user ); if ( cb_auth_ok !== undefined ) { cb_auth_ok( data ); } };
var renderSubRegions = function(){ if( headerView && headerView.templateExists() && layoutView.containsHeader() ){ headerView.render(); Utils.log('Render header',{header_view:headerView}); if( headerView.containsMenu() ){ showMenu(true); } vent.trigger('header:render',App.getCurrentScreenData(),headerView); } };
$.when.apply($, fetches).done(function () { if( app.globals.length == 0 ){ syncWebService(cb_ok,cb_error); }else{ Utils.log('Global items retrieved from local storage.',{globals:app.globals}); // @TODO: find a better way to do this? addFavoritesToGlobals(); cb_ok(); } });
component: function ( component_id ) { route_asked = 'component-'+ component_id; this.default_route_redirect( route_asked ); var route_data = this.getRouteData( 'component', { component_id: component_id } ); if ( route_data.error.length === 0 ) { if ( check_route( 'component-'+ component_id ) ) { switch( route_data.screen_data.component_type ) { case 'posts-list': RegionManager.show( route_data.view_type, route_data.view_data, route_data.screen_data ); break; case 'page': //Directly redirect to "page" route : //Note : when displaying a page component, it is better to directly use the //page fragment (/page/:component_id/:page_id) rather than the component //fragment, because the following redirection makes the native browser's back button //fail. To be sure to handle that correctly, just use App.getScreenFragment( 'component', ... ) //that will build the correct fragment for you for any component type. this.navigate( App.getScreenFragment( 'page', { component_id: component_id, item_id: route_data.screen_data.data.root_id } ), {trigger: true} ); break; case 'hooks-list': case 'hooks-no-global': RegionManager.show( route_data.view_type, route_data.view_data, route_data.screen_data ); break; default: if( route_data.view_type !== '' ) { RegionManager.show( route_data.view_type, route_data.view_data, route_data.screen_data ); } break; } } } else { Utils.log( route_data.error ); App.router.default_route(); } },
var addTemplateArgs = function( template_args ) { // Add query string parameters to template args, so that template can acces them if( Object.keys( query_string ).length > 0 ) { Utils.log( 'Adding query string parameters to template args', query_string ); template_args.query_string = query_string; } // Remove filter as these parameters need to be added only once, for the first page launched Hooks.removeFilter( 'template-args', addTemplateArgs ); return template_args; };
var ajaxQuery = function( web_service_params, success, error ) { /** * Filter 'web-service-params' : use this to send custom key/value formated * data along with the web service. Those params are passed to the server * (via $_GET) when calling the web service. * * Filtered data : web_service_params : JSON object where you can add your custom web service params * Filter arguments : * - web_service_name : string : name of the current web service ('synchronization' here). */ web_service_params = Hooks.applyFilters( 'web-service-params', web_service_params, [ 'authentication' ] ); //Build the ajax query : var ajax_args = { timeout: 40000, data: web_service_params }; /** * Filter 'ajax-args' : allows to customize the web service jQuery ajax call. * Any jQuery.ajax() arg can be passed here except for : 'url', 'type', 'dataType', * 'success' and 'error' that are reserved by app core. * * Filtered data : ajax_args : JSON object containing jQuery.ajax() arguments. * Filter arguments : * - web_service_name : string : name of the current web service ('synchronization' here). */ ajax_args = Hooks.applyFilters( 'ajax-args', ajax_args, [ 'authentication' ] ); ajax_args.url = Config.wp_ws_url + ws_url; ajax_args.type = 'GET'; ajax_args.dataType = 'json'; ajax_args.success = success; ajax_args.error = function( jqXHR, textStatus, errorThrown ) { var error_id = 'ajax-failed'; error_id += ( ':' + Utils.getAjaxErrorType( jqXHR, textStatus, errorThrown ) ); error( error_id, { jqXHR: jqXHR, textStatus: textStatus, errorThrown: errorThrown } ); }; Utils.log( 'Sending authentication query', ( web_service_params.hasOwnProperty( 'auth_action' ) ? '"' + web_service_params.auth_action + '"' : '' ), ( web_service_params.hasOwnProperty( 'user' ) ? 'for user ' + web_service_params.user : '' ) ); $.ajax( ajax_args ); };
function(error){ if( _this.fallback_template_name != '' ){ Utils.log('View template "'+ _this.template_name +'.html" not found in theme : load fallback template "'+ _this.fallback_template_name +'"'); require(['text!theme/'+ _this.fallback_template_name +'.html'], function(tpl){ _this.template = _.template(tpl); cb_ok(); }, function(error){ Utils.log('Error : view templates "'+ _this.template_name +'.html" and "'+ _this.fallback_template_name +'.html" not found in theme'); if( cb_error ){ cb_error(); } } ); }else{ Utils.log('Error : view template "'+ _this.template_name +'.html" not found in theme'); if( cb_error ){ cb_error(); } } }
require(["core/app"],function(App){ var item_global = 'pages'; var global = App.globals[item_global]; if( global ){ var item = global.get(page_id); if( item ){ var component = App.getComponentData(component_id); if( component ){ var item_data = { post:item.toJSON(), is_tree_page:component.data.is_tree, is_tree_root:(page_id == component.data.root_id), root_id:component.data.root_id, root_depth:component.data.root_depth }; if( check_route('page/'+ component_id +'/'+ page_id) ){ RegionManager.show( 'page', {item:item,global:item_global}, {screen_type:'page',component_id:component_id,item_id:parseInt(page_id),global:item_global,data:item_data,label:item_data.post.title} ); } }else{ Utils.log('Error : router : page route : component with id "'+ component_id +'" not found'); App.router.default_route(); } }else{ Utils.log('Error : router : page route : item with id "'+ page_id +'" not found in global "'+ item_global +'".'); App.router.default_route(); } }else{ Utils.log('Error : router : screen route : global "'+ item_global +'" not found.'); App.router.default_route(); } });
var showMenu = function(force_reload){ if( menuView ){ if( $(elMenu).length && (!$(elMenu).html().length || (force_reload!=undefined && force_reload) ) ){ menuView.render(); vent.trigger('menu:refresh',App.getCurrentScreenData(),menuView); Utils.log('Render navigation',{menu_view:menuView,force_reload:force_reload}); } }else{ if( $(elMenu).html().length ){ $(elMenu).empty(); } } };
success: function(answer) { if( answer.result && answer.result.status == 1 ){ if( answer.component.slug == component_id ){ var global = answer.component.global; if( app.globals.hasOwnProperty(global) ){ var new_ids = _.difference(answer.component.data.ids,component_data.ids); component_data.ids = _.union(component_data.ids,answer.component.data.ids); //merge ids component.set('data',component_data); var current_items = app.globals[global]; _.each(answer.globals[global],function(item, id){ current_items.add(_.extend({id:id},item)); //auto merges if "id" already in items }); var new_items = []; _.each(new_ids,function(item_id){ new_items.push(current_items.get(item_id)); }); var nb_left = component_data.total - component_data.ids.length; var is_last = !_.isEmpty(answer.component.data.query.is_last_page) ? true : nb_left <= 0; Utils.log('More content retrieved for component',{component_id:component_id,new_ids:new_ids,new_items:new_items,component:component}); cb_ok(new_items,is_last,{nb_left:nb_left,new_ids:new_ids,global:global,component:component}); }else{ app.triggerError( 'getmore:global-not-found', {type:'not-found',where:'app::getMoreOfComponent',message:'Global not found : '+ global}, cb_error ); } }else{ app.triggerError( 'getmore:wrong-component-id', {type:'not-found',where:'app::getMoreOfComponent',message:'Wrong component id : '+ component_id}, cb_error ); } }else{ app.triggerError( 'getmore:ws-return-error', {type:'web-service',where:'app::getMoreOfComponent',message:'Web service "component" returned an error : ['+ answer.result.message +']'}, cb_error ); } },
var success = function( data ) { if ( data.hasOwnProperty( 'result' ) && data.result.hasOwnProperty( 'status' ) && data.result.hasOwnProperty( 'message' ) ) { if ( data.result.status == 1 ) { if ( data.hasOwnProperty( 'authenticated' ) ) { if ( data.authenticated === 1 ) { if ( data.hasOwnProperty( 'permissions' ) ) { //Check control hmac : if ( checkHMAC( 'authenticated' + user, user_secret, data.control ) ) { //Memorize current user login and secret : authenticationData.set( 'user_login', user ); authenticationData.set( 'secret', user_secret ); authenticationData.set( 'is_authenticated', true ); //Memorize returned user permissions authenticationData.set( 'permissions', data.permissions ); //Save all this to local storage authenticationData.save(); Utils.log( 'User "' + user + '" logged in successfully', authentication.getCurrentUser() ); cb_ok( { user: user, permissions: data.permissions } ); } else { cb_error( 'wrong-hmac' ); } } else { cb_error( 'no-permissions' ); } } else if ( data.hasOwnProperty( 'auth_error' ) ) { cb_error( data.auth_error ); } else { cb_error( 'no-auth-error' ); } } else { cb_error( 'wrong-auth-data' ); } } else { cb_error( 'web-service-error', data.result.message ); } }else { cb_error( 'wrong-result-data' ); } };
execute_route_silently: function( route ) { var fragment = Backbone.history.getFragment( route ); var route_handler = _.find( Backbone.history.handlers, function( handler ) { return handler.route.test( fragment ); }); if ( route_handler !== undefined ) { this.execute( route_handler.callback, [fragment], '' ); } else { Utils.log( 'Router.js error: execute_route_silently: route not found.' ); } }
var show_single = function() { var route_data = _this.getRouteData( 'single', { item_global: item_global, item_id: item_id } ); if ( route_data.error.length === 0 ) { if ( check_route( 'single/'+ item_global +'/'+ item_id ) ) { RegionManager.show( route_data.view_type, route_data.view_data, route_data.screen_data ); } } else { Utils.log( route_data.error ); App.router.default_route(); } };