simpleitjs
Version:
Simple light frontend framework
165 lines (143 loc) • 4.9 kB
text/typescript
/// <reference path="./module.ts" />
/// <reference path="./ajax.ts" />
/// <reference path="./module-scope.ts" />
let ModuleScopeParent: typeof ModuleScope;
if (typeof window === "undefined") {
ModuleScopeParent = require('./module-scope');
} else {
const win: any = window;
ModuleScopeParent = win.ModuleScope;
}
class RouterLoaderAttributes {
public basePath?: string = "";
public rootElemSelector?: string = "";
}
class Router extends ModuleScopeParent {
private Ajax!: Ajax;
public configs: any = [];
public basePath = '';
public rootElemSelector = '.router-main';
/**
* Loads state by state object
* @param {Object} state State object to load.
* @param {boolean} updateURL Optional, should update URL after loading the state. Default false
*/
public loadState(state: any, updateURL: boolean) {
var exeResolvers = function () {
if (state.resolvers && state.resolvers.length) {
Promise.all(state.resolvers).then(function () {
// $('a.nav-item').removeClass('active');
// $('a[href="' + state.path.replace('/', '') + '"]').addClass('active');
state.module.invoke.apply(window, arguments);
return arguments;
});
} else {
// $('a.nav-item').removeClass('active');
// $('a[href="' + state.path.replace('/', '') + '"]').addClass('active');
state.module.invoke();
}
};
var authUser = function (out: boolean) {
if (typeof out == 'boolean' && out) {
exeResolvers();
} else if (typeof out == 'boolean' && out == false) {
state.onAuthFail();
}
};
if (updateURL) {
var url = location.protocol + '//' + location.host + this.basePath + state.path;
window.history.pushState(JSON.parse(JSON.stringify(state)), state.title, url);
}
this.Ajax.get(state.template, (templateHTML: string) => {
const elem = document.querySelector(this.rootElemSelector);
if (elem != null) {
elem.innerHTML = templateHTML;
}
if (state.authGaurds && state.authGaurds.length && typeof state.authGaurdCb == 'function') {
Promise.all(state.authGaurds).then(function () {
var out = state.authGaurdCb.apply(window, arguments);
authUser(out);
if (typeof out == 'object' && out.then) {
out.then(authUser);
}
return arguments;
});
}
});
}
public loadProperState() {
var currState = this.getCurrentState();
if (currState) {
this.loadState(currState, false);
} else {
var defState = this.getDefaultState();
if (defState) {
this.loadState(defState, true);
}
}
}
public getCurrentState() {
for (var i = 0; i < this.configs.length; i++) {
var currConfig = this.configs[i];
var path = location.protocol + '//' + location.host + this.basePath + currConfig.path;
if (path == location.href) {
return currConfig;
}
}
}
/**
* Loads configs and starts routing.
*/
public load(config: any, attr: RouterLoaderAttributes) {
if (attr == void 0) { attr = {}; }
if (attr.basePath == void 0) { attr.basePath = ''; }
if (attr.rootElemSelector == void 0) { attr.rootElemSelector = '.router-main'; }
window.addEventListener('popstate', (event) => {
this.loadProperState();
});
window.addEventListener('pushstate', (event) => {
this.loadProperState();
});
this.configs = config;
this.basePath = attr.basePath;
this.rootElemSelector = attr.rootElemSelector;
this.loadProperState();
}
public getDefaultState() {
for (var i = 0; i < this.configs.length; i++) {
var currConfig = this.configs[i];
if (currConfig.isDefault) {
return currConfig;
}
}
}
/**
* Loads given state.
* @param {string} stateName Name of state to load.
* @param {boolean} updateURL Optional, should update URL after loading the state. Default false
*/
public goTo(stateName: string, updateURL: boolean) {
for (var i = 0; i < this.configs.length; i++) {
var currConfig = this.configs[i];
if (currConfig.stateName == stateName) {
return this.loadState(currConfig, updateURL);
}
}
}
public static invoke(model: Router, Ajax: Ajax): Router {
model.Ajax = Ajax;
return model;
}
}
declare var require: (...args: any[]) => any;
(function () {
let ModuleClass: typeof Module;
if (typeof window === "undefined") {
ModuleClass = require('./module');
} else {
var win: any = window;
win.SimpleJS = win.SimpleJS || {};
ModuleClass = win.SimpleJS.Module;
}
new ModuleClass('Router', 'Ajax', Router);
})();