unclean SPARC
This commit is contained in:
Executable
+173
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* @category Core
|
||||
* @subcategory Application
|
||||
*/
|
||||
class Controller {
|
||||
|
||||
static _template = null;
|
||||
static _contents = [];
|
||||
static _currentContent = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor() { }
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
destructor() {}
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @param {*} name
|
||||
* @param {*} args
|
||||
* @param {*} data
|
||||
* @returns {View}
|
||||
*/
|
||||
loadView(name, args, data) {
|
||||
args = args || {};
|
||||
args.name = name+'.html';
|
||||
args.className = name.split('/').pop();
|
||||
args.onContentLoaded = args.onContentLoaded || this.appendHTML;
|
||||
args.path = app.config.router.viewsPath;
|
||||
|
||||
let request = app.Assets.loadHtml(args);
|
||||
|
||||
return request.then(args.onContentLoaded.bind(this, args, data));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} args
|
||||
* @param {*} data
|
||||
* @param {*} html
|
||||
* @returns {View}
|
||||
*/
|
||||
appendHTML(args,data, html) {
|
||||
|
||||
if(!args.target) {
|
||||
args.target = document.body;
|
||||
} else {
|
||||
if(typeof args.target == 'string') {
|
||||
let selector = null;
|
||||
let content = document.body;
|
||||
|
||||
let crumbs = args.target.split('@')
|
||||
|
||||
if(crumbs.length > 1) {
|
||||
let targetId = crumbs.pop()
|
||||
content = Controller._contents.find(o => o.view._sparcId == targetId).view.el;
|
||||
}
|
||||
|
||||
selector = crumbs.join('@');
|
||||
args.target = content.querySelector(selector);
|
||||
}
|
||||
}
|
||||
|
||||
let container = document.createElement('div');
|
||||
|
||||
container.innerHTML = Controller.processTemplate(args.name, html, data);
|
||||
|
||||
let parent = args.target;
|
||||
|
||||
parent.innerHTML = '';
|
||||
|
||||
while(container.children.length > 0) {
|
||||
parent.appendChild(container.children[0]);
|
||||
}
|
||||
|
||||
let view = new app.LoadedClasses[args.className]();
|
||||
view._className = args.name.replace('.html', '');
|
||||
|
||||
Controller._currentContent = view;
|
||||
Controller._contents.push({view: view, dom: parent, type: 'nested'});
|
||||
view.el = parent;
|
||||
view.el.setAttribute('sparc-id', view._sparcId);
|
||||
view._controller = this;
|
||||
|
||||
//view.DOMContentLoaded(data);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} content
|
||||
*/
|
||||
unloadView(content) {
|
||||
app.events.clear(content.view._sparcId);
|
||||
Controller._contents = Controller._contents.filter(o => o.view._sparcId != content.view._sparcId);
|
||||
content.view.DOMContentRemoved();
|
||||
content.view.el.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} name
|
||||
* @param {*} args
|
||||
*/
|
||||
loadModel(name, args) { }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} id
|
||||
* @returns {View}
|
||||
*/
|
||||
static getContentById(id) { return Controller._contents.find(o => o.view._sparcId == id); }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} name
|
||||
* @param {*} html
|
||||
* @param {*} templateData
|
||||
* @returns {string}
|
||||
*/
|
||||
static processTemplate(name, html, templateData) {
|
||||
|
||||
// Define a function inside of which templateData keys will become local variables
|
||||
// AND where templateData values will become thos variable values ;-)
|
||||
// Drawback is that complex epression
|
||||
function evalaluateTemplate(tpl, params) {
|
||||
var interpretor = Function(...Object.keys(params), 'return('+tpl+');' );
|
||||
return interpretor(...Object.values(params));
|
||||
}
|
||||
|
||||
// Define a function inside of which a string of a variable name becomes that variable
|
||||
// and where we check tht the corresponding (evaluable) expression in templateData is defined
|
||||
function checkExpression(varname, params) {
|
||||
var code = ' try{var t=typeof('+varname+');} catch(e){ t="badexpr"; } return(t)';
|
||||
var interpretor = Function(...Object.keys(params), code );
|
||||
return interpretor(...Object.values(params));
|
||||
}
|
||||
|
||||
// Preflight check to avoid template crashes on undefined expressions
|
||||
const rgxp = /\$\{(.*?)\}/gm;
|
||||
let m = null;
|
||||
|
||||
templateData = templateData || {};
|
||||
|
||||
while ((m = rgxp.exec(html)) !== null) {
|
||||
let safeType = checkExpression(m[1],templateData);
|
||||
|
||||
if(safeType == 'undefined') {
|
||||
// variable undefined in templateData: add an empty one
|
||||
console.warn(`In template ${name}, ${m[1]} is not defined !`);
|
||||
templateData[m[1]]='';
|
||||
} else if(safeType == 'badexpr') {
|
||||
// unevaluable expression : remove it from template
|
||||
console.warn(`In template ${name}, Bad expression: ${m[1]}`);
|
||||
var escsearch = m[1].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
var replrexp = new RegExp('\\$\\{'+escsearch+'\\}','gm')
|
||||
html = html.replace(replrexp,'');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Now that all remaining expressions are OK, evaluate the template via backtits !
|
||||
return(evalaluateTemplate('`' + html + '`', templateData));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass("Controller", Controller);
|
||||
Reference in New Issue
Block a user