src/app/app.js
'use strict'
import { HistoryRouter, HashRouter } from '../app/router.js'
/**
* Application.
*
* @memberOf flatout
*/
class App {
/* Do not call */
constructor() {}
/**
* Activate application
*
* @param {Class<View>} rootViewClass - root view class.
* @param {Object} routeMap - routing map.
* @param {Object} [opts] - options.
* @param {Object} [opts.mode] - HISTORY or HASH
* @param {Object} [opts.rootPath] - history root path.
* @param {Object} [opts.pathHead] - hash path prefix.
*/
activate(rootViewClass, routeMap, opts = {}) {
/**
* Root area.
* @type {View}
*/
this._rootArea = new rootViewClass();
/**
* Page area replaced if path changed.
* @type {Page}
*/
this._curPage = null;
const onMove = ({ view, ctx }) => { this.replace(view, ctx) };
this._router = opts.mode === 'HISTORY'
? new HistoryRouter(routeMap, onMove, opts.rootPath)
: new HashRouter(routeMap, onMove, opts.pathHead);
const loadCb = e => { this._router.depart() }
if (document.readyState !== 'loading') loadCb()
else document.addEventListener('DOMContentLoaded', loadCb, false)
}
/**
* Go a page.
*
* @param {string} path - URL path
* @param {Object} ctx - context
* @return {boolean} always false.
*/
go(path, ctx) {
this._preCtx = ctx;
this._router.go(path);
return false;
}
/**
* Back page.
*
* @return {boolean} - always false.
*/
back() {
window.history.back();
return false;
}
/**
* Replace page.
*
* @param {Class<Page>} page - Page class
* @param {*} ctx - context
*/
replace(page, ctx = {}) {
if (this._preCtx) {
// Merge ctx by go to layer.ctx that contains idMap
ctx = { ...ctx, ...this._preCtx };
this._preCtx = null;
}
this._replaceContent(page, ctx);
this._updateTitle();
}
/**
* Replace layer.
*
* @param {Class<Page>} page - new page class.
* @param {Object} ctx - passing context.
*/
_replaceContent(page, ctx) {
const ra = this._rootArea, oldPage = this._curPage;
let data = null;
if (oldPage) {
oldPage.destroy()
} else {
data = window.initPageData || {};
delete window.initPageData;
}
const params = Object.assign({
parent: ra,
context: { ...ra.context, ...ctx }
}, data ? { data, hasInitData: true } : {});
this._curPage = new page(params)
}
/**
* Update page title of browser
*/
_updateTitle() {
let ttl = '';
if (this._curPage) {
ttl = this._curPage.title()
}
document.title = this._rootArea.title(ttl);
}
}
export default new App();