UNPKG

page-app

Version:

Builder for rich single-page js apps (frontend)

236 lines (187 loc) 5.19 kB
/* global Module,Sandbox */ (function (window, $) { var App = function () { this.init(); }; App.prototype.init = function () { var data = { basePath: window.location.pathname.replace(/\/[^\/]*?$/,''), indexPath: window.location.pathname.replace(/^.*\/([^\/]*)$/,'$1') }; if (window.IsDev) { data.development = true; } this.$ = $; this.sandboxes = []; this.modules = {}; this.pages = []; this.set = function (param, value) { var newData; if (typeof (param) === 'object') { newData = param; } else { newData = {}; newData[param] = value; } data = extend(data, newData); }; this.get = function (param) { return data[param]; }; }; /** * Создание потомка класса Модуль */ App.prototype.createModule = function (params, onready) { if (typeof(params) === 'string') { params = { name: params }; } function emptyReady () {} this.modules[params.name] = function () { var param; Module.apply(this, arguments); for (param in params) { if (params.hasOwnProperty(param)) { this[param] = params[param]; } } }; this.modules[params.name].prototype = Object.create(Module.prototype); this.modules[params.name].prototype.name = params.name; if (typeof(onready) === 'function') { this.modules[params.name].prototype.ready = onready; } else if (onready === null) { this.modules[params.name].prototype.ready = emptyReady; } return this.modules[params.name]; }; App.prototype.create = function (moduleType, data, callback, parentModule) { var module, sandbox, CurrentModule = this.modules[moduleType]; if (CurrentModule) { module = new CurrentModule(); module.set(data); sandbox = new Sandbox(this, module.name, parentModule); this.sandboxes.push(sandbox); module.start(sandbox).done(function (module) { callback(module, sandbox); }); } else { throw 'Module "' + moduleType + '" not found!'; //callback(); } }; App.prototype.renderModules = function (node, container, parentModule, callback) { if (typeof(container) === 'function') { callback = container; container = undefined; } if (typeof(parentModule) === 'function') { callback = parentModule; parentModule = undefined; } var app = this, wrapper = $('<div></div>'); wrapper.append(node); this.initModules(wrapper, function () { if (!container) { container = app.container; app.node = app.container; } container.empty(); container.append(wrapper.contents()); app.trigger('append'); app.trigger('resize'); if (callback) { callback(); } }, parentModule); }; App.prototype.initModules = function (container, callback, parentModule) { var app = this, loaders = [], modules; modules = container.find('[data-module]').addBack('[data-module]').not('[data-module] [data-module]'); modules.each(function () { var loader = $.Deferred(); loaders.push(loader); app.initModule(this, function () { loader.resolve(); }, parentModule); }); function initDone() { //remove uninited modules from template modules.remove(); callback(); } if (callback) { if (loaders.length) { $.when.apply($, loaders).done(initDone); } else { initDone(); } } }; App.prototype.initModule = function (moduleNode, callback, parentModule) { var app = this, $this = $(moduleNode), name = $this.data('module'); if (name) { app.create(name, {dom: $this}, function (module, sandbox) { if (module && module.node) { app.initModules(module.node, callback, sandbox); } else { callback(); } }, parentModule); } else { callback(); } }; App.prototype.start = function (name, data, container, callback) { var app = this; this.name = name; this.set('name', this.name); function start() { var page, pageRx = /^page\/(.*)$/, templates = app.getTemplates(); for (page in templates) { if (templates.hasOwnProperty(page) && pageRx.test(page)) { app.pages.push(page.replace(pageRx, '$1')); } } app.container = $(container) || $('body'); callback = callback || function () { app.trigger('hide.loader', 'start'); }; app.render(app.name, data, function (err, html) { app.node = $('<div></div>'); app.node.html(html); if (err) { throw err; } app.renderModules(app.node, callback); }); $(window).resize(function (e) { app.trigger('resize', e); }).scroll(function (e) { app.trigger('scroll', e); }); } $(start); }; App.prototype.pushState = function (data, title, url) { window.history.pushState(data, title, url); }; App.prototype.replaceState = function (data, title, url) { window.history.replaceState(data, title, url); }; /* exported App */ window.App = App; /* exported app */ window.app = new App(); } (window, jQuery));