2016-09-26 09:28:47 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
var Object = require('./object');
|
2016-09-26 09:28:47 +00:00
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
/**
|
2015-03-06 23:33:54 +00:00
|
|
|
* Creates a object from a XML specification.
|
2022-05-24 10:18:44 +00:00
|
|
|
*/
|
|
|
|
module.exports = new Class({
|
2016-09-26 09:28:47 +00:00
|
|
|
Extends: Object
|
2015-11-09 17:11:51 +00:00
|
|
|
,_addedMap: {}
|
|
|
|
,_contexts: null
|
2015-10-14 11:51:43 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,add: function(id, object) {
|
2015-11-09 17:11:51 +00:00
|
|
|
this._addedMap[id] = object;
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,setParent: function(parentResult) {
|
2015-11-09 17:11:51 +00:00
|
|
|
this._parentResult = parentResult;
|
|
|
|
|
|
|
|
if (parentResult && !this.signalData)
|
|
|
|
this.signalData = parentResult.builder.signalData;
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,getMain: function(result) {
|
2015-11-09 17:11:51 +00:00
|
|
|
return result.objects[this._mainContext];
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,getById: function(result, objectId) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var index = this._contextMap[objectId];
|
|
|
|
|
|
|
|
if (index !== undefined)
|
|
|
|
return result.objects[index];
|
2016-10-04 15:27:49 +00:00
|
|
|
|
|
|
|
var object = this._addedMap[objectId];
|
|
|
|
|
|
|
|
if (object !== undefined)
|
|
|
|
return object;
|
|
|
|
|
|
|
|
if (this._parentResult)
|
2022-05-24 10:18:44 +00:00
|
|
|
return this._parentResult.getById(objectId);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
return null;
|
2015-11-09 08:14:33 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,getByTagName: function(result, tagName) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var tags = this._tags[tagName];
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (tags) {
|
|
|
|
var arr = new Array(tags.length);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
for (var i = 0; i < tags.length; i++)
|
|
|
|
arr[i] = result.objects[tags[i]];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2015-11-17 10:34:33 +00:00
|
|
|
/**
|
|
|
|
* Compiles an XML file.
|
|
|
|
*
|
|
|
|
* @path String The XML path
|
|
|
|
* @dstDocument Document The document used to create the nodes
|
|
|
|
* @return %true on success, %false othersise
|
2022-05-24 10:18:44 +00:00
|
|
|
*/
|
|
|
|
,loadXml: function(path, dstDocument) {
|
2016-09-26 09:28:47 +00:00
|
|
|
this._path = path;
|
2022-05-24 10:18:44 +00:00
|
|
|
return this.loadFromXmlDoc(Vn.getXml(path), dstDocument);
|
2016-09-26 09:28:47 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,loadFromString: function(xmlString, dstDocument) {
|
|
|
|
var parser = new DOMParser();
|
|
|
|
var xmlDoc = parser.parseFromString(xmlString, 'text/xml');
|
|
|
|
return this.loadFromXmlDoc(xmlDoc, dstDocument);
|
2016-09-26 09:28:47 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,loadFromXmlDoc: function(xmlDoc, dstDocument, scope) {
|
2015-03-06 23:33:54 +00:00
|
|
|
if (!xmlDoc)
|
|
|
|
return false;
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
this._compileInit(dstDocument, scope);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2015-03-06 23:33:54 +00:00
|
|
|
var docElement = xmlDoc.documentElement;
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (docElement.tagName !== 'vn') {
|
|
|
|
this._showError('Malformed XML');
|
2015-11-09 17:11:51 +00:00
|
|
|
this._contexts = null;
|
2015-03-06 23:33:54 +00:00
|
|
|
return false;
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-03-06 23:33:54 +00:00
|
|
|
var childs = docElement.childNodes;
|
|
|
|
|
|
|
|
if (childs)
|
|
|
|
for (var i = 0; i < childs.length; i++)
|
2022-05-24 10:18:44 +00:00
|
|
|
this._compileNode(childs[i]);
|
2015-03-06 23:33:54 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
this._compileEnd();
|
2015-03-06 23:33:54 +00:00
|
|
|
return true;
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-03-09 08:36:54 +00:00
|
|
|
|
2015-11-17 10:34:33 +00:00
|
|
|
/**
|
|
|
|
* Compiles a single DOM node.
|
|
|
|
*
|
|
|
|
* @path Node The DOM node
|
|
|
|
* @dstDocument Document The document used to create the nodes
|
|
|
|
* @return %true on success, %false othersise
|
2022-05-24 10:18:44 +00:00
|
|
|
*/
|
|
|
|
,loadXmlFromNode: function(node, dstDocument, scope) {
|
|
|
|
this._compileInit(dstDocument, scope);
|
|
|
|
this._mainContext = this._compileNode(node).id;
|
|
|
|
this._compileEnd();
|
2015-11-17 10:34:33 +00:00
|
|
|
return true;
|
2015-03-09 08:36:54 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,load: function() {
|
2015-11-09 17:11:51 +00:00
|
|
|
if (this._contexts === null)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var contexts = this._contexts;
|
|
|
|
var len = contexts.length;
|
2022-05-24 10:18:44 +00:00
|
|
|
var objects = new Array(len);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = 0; i < len; i++) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var context = contexts[i];
|
|
|
|
|
|
|
|
if (context.tagName)
|
2022-05-24 10:18:44 +00:00
|
|
|
objects[i] = this.elementInstantiate(context);
|
2015-11-09 17:11:51 +00:00
|
|
|
else if (context.klass)
|
2022-05-24 10:18:44 +00:00
|
|
|
objects[i] = this.objectInstantiate(context);
|
2015-11-09 17:11:51 +00:00
|
|
|
else
|
2022-05-24 10:18:44 +00:00
|
|
|
objects[i] = this.textInstantiate(context);
|
2015-03-06 23:33:54 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
return new BuilderResult(this, objects);
|
2015-11-17 10:34:33 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,link: function(result, self, scope) {
|
2015-11-17 10:34:33 +00:00
|
|
|
var objects = result.objects;
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = this._links.length - 1; i >= 0; i--) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var l = this._links[i];
|
|
|
|
var addedObject = this._addedMap[l.objectId];
|
2016-10-04 15:27:49 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (addedObject) {
|
2015-11-09 17:11:51 +00:00
|
|
|
if (l.prop)
|
|
|
|
objects[l.context.id][l.prop] = addedObject;
|
|
|
|
else
|
2022-05-24 10:18:44 +00:00
|
|
|
objects[l.context.id].appendChild(addedObject);
|
|
|
|
} else
|
|
|
|
this._showError('Referenced unexistent object with id \'%s\'',
|
2015-11-09 17:11:51 +00:00
|
|
|
l.objectId);
|
2015-03-06 23:33:54 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
this.linkExpr(result, self, scope);
|
|
|
|
|
2015-11-17 10:34:33 +00:00
|
|
|
var contexts = this._contexts;
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = 0; i < contexts.length; i++) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var context = contexts[i];
|
|
|
|
var object = objects[i];
|
|
|
|
|
|
|
|
if (context.tagName)
|
2022-05-24 10:18:44 +00:00
|
|
|
this.elementLink(context, object, objects, result);
|
2015-11-09 17:11:51 +00:00
|
|
|
else if (context.klass)
|
2022-05-24 10:18:44 +00:00
|
|
|
this.objectLink(context, object, objects, result);
|
2015-03-19 19:36:11 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
2022-05-24 10:18:44 +00:00
|
|
|
|
|
|
|
,fnExpr(expr) {
|
|
|
|
return new Function(this._scopeArgs,
|
|
|
|
'"use strict"; return ' + expr + ';'
|
|
|
|
);
|
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,matchExpr(value) {
|
|
|
|
const match = /^{{(.*)}}$/.exec(value);
|
|
|
|
if (!match) return null;
|
|
|
|
return this.fnExpr(match[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
,linkExpr(result, self, scope) {
|
|
|
|
const contexts = this._contexts;
|
|
|
|
const objects = result.objects;
|
|
|
|
let args = [_]
|
|
|
|
|
|
|
|
if (scope) args = args.concat(scope);
|
|
|
|
|
|
|
|
for (let i = 0; i < contexts.length; i++) {
|
|
|
|
const context = contexts[i];
|
|
|
|
const object = objects[i];
|
|
|
|
|
|
|
|
if (context.exprs) {
|
|
|
|
const values = [];
|
|
|
|
for (expr of context.exprs) {
|
|
|
|
let value = undefined;
|
|
|
|
try {
|
|
|
|
value = expr.apply(self, args);
|
|
|
|
} catch (e) {
|
|
|
|
console.warn('Expression error:', e.message);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
values.push(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
let k = 0;
|
|
|
|
const text = context.text.replace(/{{\d+}}/g, function() {
|
|
|
|
return values[k++];
|
|
|
|
});
|
|
|
|
object.textContent = text;
|
|
|
|
} else {
|
|
|
|
const dynProps = context.dynProps;
|
|
|
|
|
|
|
|
for (const prop in dynProps) {
|
|
|
|
let value = undefined;
|
|
|
|
try {
|
|
|
|
value = dynProps[prop].apply(self, args);
|
|
|
|
} catch (e) {
|
|
|
|
console.warn('Expression error:', e.message);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (context.tagName)
|
|
|
|
object.setAttribute(prop, value);
|
|
|
|
else
|
|
|
|
object[prop] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
,_compileInit: function(dstDocument, scope) {
|
2015-11-09 17:11:51 +00:00
|
|
|
this._path = null;
|
|
|
|
this._tags = {};
|
|
|
|
this._contexts = [];
|
|
|
|
this._contextMap = {};
|
|
|
|
this._links = [];
|
|
|
|
this._mainContext = null;
|
2016-10-16 14:16:08 +00:00
|
|
|
this._doc = dstDocument ? dstDocument : document;
|
2022-05-24 10:18:44 +00:00
|
|
|
|
|
|
|
this._scope = ['_'];
|
|
|
|
if (scope)
|
|
|
|
this._scope = this._scope.concat(scope);
|
|
|
|
this._scopeArgs = this._scope.join(',');
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_compileEnd: function() {
|
|
|
|
for (var i = this._links.length - 1; i >= 0; i--) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var l = this._links[i];
|
2016-10-04 15:27:49 +00:00
|
|
|
var contextId = this._contextMap[l.objectId];
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (contextId != undefined) {
|
2015-11-09 17:11:51 +00:00
|
|
|
if (l.prop)
|
|
|
|
l.context.objectProps[l.prop] = contextId;
|
2015-03-27 19:10:49 +00:00
|
|
|
else
|
2022-05-24 10:18:44 +00:00
|
|
|
l.context.childs.push(contextId);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
this._links.splice(i, 1);
|
|
|
|
} else {
|
2015-11-17 10:34:33 +00:00
|
|
|
var object = this._addedMap[l.objectId];
|
|
|
|
|
|
|
|
if (!object && this._parentResult)
|
2022-05-24 10:18:44 +00:00
|
|
|
object = this._parentResult.getById(l.objectId);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (object) {
|
2015-11-17 10:34:33 +00:00
|
|
|
l.context.props[l.prop] = object;
|
2022-05-24 10:18:44 +00:00
|
|
|
this._links.splice(i, 1);
|
2015-11-17 10:34:33 +00:00
|
|
|
}
|
2015-03-06 23:33:54 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_compileNode: function(node) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var context = null;
|
|
|
|
var tagName = null;
|
2015-11-09 08:14:33 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
if (node.nodeType === Node.ELEMENT_NODE)
|
2022-05-24 10:18:44 +00:00
|
|
|
tagName = node.tagName.toLowerCase();
|
2015-11-09 17:11:51 +00:00
|
|
|
else if (node.nodeType !== Node.TEXT_NODE
|
2022-05-24 10:18:44 +00:00
|
|
|
|| /^[\n\r\t]*$/.test(node.textContent))
|
2015-03-19 19:36:11 +00:00
|
|
|
return null;
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
var context =
|
2022-05-24 10:18:44 +00:00
|
|
|
this.textCompile(node, tagName)
|
|
|
|
|| this.objectCompile(node, tagName)
|
|
|
|
|| this.elementCompile(node, tagName);
|
2015-03-19 19:36:11 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
context.id = this._contexts.length;
|
2015-03-19 19:36:11 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (tagName) {
|
|
|
|
var nodeId = node.getAttribute('id');
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
if (nodeId)
|
|
|
|
this._contextMap[nodeId] = context.id;
|
2015-11-09 08:14:33 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
var tags = this._tags[tagName];
|
|
|
|
|
|
|
|
if (!tags)
|
|
|
|
this._tags[tagName] = tags = [];
|
2015-03-19 19:36:11 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
tags.push(context.id);
|
2015-11-09 08:14:33 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
this._contexts.push(context);
|
2015-11-09 17:11:51 +00:00
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a text node context.
|
2022-05-24 10:18:44 +00:00
|
|
|
*/
|
|
|
|
,textCompile: function(node, tagName) {
|
|
|
|
if (!tagName) {
|
|
|
|
let text = node.textContent;
|
|
|
|
|
|
|
|
if (/{{.*}}/.test(text)) {
|
|
|
|
let i = 0;
|
|
|
|
const self = this;
|
|
|
|
const exprs = [];
|
|
|
|
text = text.replace(/{{((?:(?!}}).)*)}}/g, function(match, capture) {
|
|
|
|
exprs.push(self.fnExpr(capture));
|
|
|
|
return `{{${i++}}}`;
|
|
|
|
});
|
|
|
|
|
|
|
|
return {text, exprs};
|
|
|
|
} else
|
|
|
|
return {text};
|
|
|
|
} else if (tagName === 't')
|
|
|
|
return {text: _(node.firstChild.textContent)};
|
2015-11-09 17:11:51 +00:00
|
|
|
else
|
|
|
|
return null;
|
2015-03-19 19:36:11 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,textInstantiate: function(context) {
|
|
|
|
return this._doc.createTextNode(context.exprs ? '' : context.text);
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a object context.
|
2022-05-24 10:18:44 +00:00
|
|
|
*/
|
|
|
|
,objectCompile: function(node, tagName) {
|
2016-09-26 09:28:47 +00:00
|
|
|
var klass = vnCustomTags[tagName];
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
if (!klass)
|
|
|
|
return null;
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
var props = {};
|
2022-05-24 10:18:44 +00:00
|
|
|
var dynProps = {};
|
2015-11-09 17:11:51 +00:00
|
|
|
var objectProps = {};
|
|
|
|
var childs = [];
|
|
|
|
var events = {};
|
|
|
|
|
|
|
|
var context = {
|
|
|
|
klass: klass,
|
|
|
|
props: props,
|
2022-05-24 10:18:44 +00:00
|
|
|
dynProps: dynProps,
|
2015-11-09 17:11:51 +00:00
|
|
|
objectProps: objectProps,
|
|
|
|
childs: childs,
|
|
|
|
events: events,
|
|
|
|
custom: null
|
|
|
|
};
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
var a = node.attributes;
|
2015-11-09 08:14:33 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = 0; i < a.length; i++) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var attribute = a[i].nodeName;
|
|
|
|
var value = a[i].nodeValue;
|
2015-11-09 08:14:33 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (this._isEvent(attribute)) {
|
|
|
|
var handler = this._getMethod(value)
|
2015-11-19 13:57:23 +00:00
|
|
|
|
|
|
|
if (handler)
|
2022-05-24 10:18:44 +00:00
|
|
|
events[attribute.substr(3)] = handler;
|
|
|
|
} else if (!/^(id|property)$/.test(attribute)) {
|
|
|
|
this.propCompile(context, klass, props, dynProps,
|
2015-11-09 17:11:51 +00:00
|
|
|
node, attribute, value);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
var childNodes = node.childNodes;
|
|
|
|
|
|
|
|
if (childNodes)
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = 0; i < childNodes.length; i++) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var child = childNodes[i];
|
2018-03-26 16:35:02 +00:00
|
|
|
var isElement = child.nodeType === Node.ELEMENT_NODE;
|
2022-05-24 10:18:44 +00:00
|
|
|
var childTagName = isElement ? child.tagName.toLowerCase() : null;
|
2015-11-09 17:11:51 +00:00
|
|
|
var childContext;
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (childTagName === 'pointer') {
|
|
|
|
this._addLink(context, null, child.getAttribute('object'));
|
|
|
|
} else if (childTagName === 'custom') {
|
2015-11-09 17:11:51 +00:00
|
|
|
context.custom = child;
|
2022-05-24 10:18:44 +00:00
|
|
|
} else if (childContext = this._compileNode(child)) {
|
|
|
|
var prop = isElement ? child.getAttribute('property') : null;
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (prop) {
|
|
|
|
prop = prop.replace(/-./g, this._replaceFunc);
|
2015-11-09 17:11:51 +00:00
|
|
|
objectProps[prop] = childContext.id;
|
2022-05-24 10:18:44 +00:00
|
|
|
} else
|
|
|
|
childs.push(childContext.id);
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
2015-07-07 15:27:47 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
return context;
|
2015-07-07 15:27:47 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,propCompile: function(context, klass, props, dynProps, node, attribute, value) {
|
2015-12-02 17:26:58 +00:00
|
|
|
var isLink = false;
|
2015-11-09 17:11:51 +00:00
|
|
|
var newValue = null;
|
2022-05-24 10:18:44 +00:00
|
|
|
var propName = attribute.replace(/-./g, this._replaceFunc);
|
2015-11-09 17:11:51 +00:00
|
|
|
var propInfo = klass.Properties[propName];
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
if (!propInfo) {
|
|
|
|
this._showError('Attribute \'%s\' not valid for tag \'%s\'',
|
2015-11-09 17:11:51 +00:00
|
|
|
attribute, node.tagName);
|
2015-07-03 05:49:45 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-05-24 10:18:44 +00:00
|
|
|
if (!value) {
|
|
|
|
this._showError('Attribute \'%s\' empty on tag \'%s\'',
|
2015-11-09 17:11:51 +00:00
|
|
|
attribute, node.tagName);
|
2015-01-23 13:09:30 +00:00
|
|
|
return;
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
const expr = this.matchExpr(value);
|
|
|
|
|
|
|
|
if (expr) {
|
|
|
|
dynProps[propName] = expr;
|
|
|
|
} else {
|
|
|
|
switch (propInfo.type) {
|
2015-01-23 13:09:30 +00:00
|
|
|
case Boolean:
|
2022-05-24 10:18:44 +00:00
|
|
|
newValue = (/^(true|1)$/i).test(value);
|
2015-01-23 13:09:30 +00:00
|
|
|
break;
|
|
|
|
case Number:
|
2022-05-24 10:18:44 +00:00
|
|
|
newValue = 0 + new Number(value);
|
2015-01-23 13:09:30 +00:00
|
|
|
break;
|
|
|
|
case String:
|
2022-05-24 10:18:44 +00:00
|
|
|
newValue = this._translateValue(value);
|
2015-03-06 23:33:54 +00:00
|
|
|
break;
|
2015-01-23 13:09:30 +00:00
|
|
|
case Function:
|
2022-05-24 10:18:44 +00:00
|
|
|
var method = this._getMethod(value);
|
|
|
|
newValue = method ? method.bind(this.signalData) : null;
|
2015-01-23 13:09:30 +00:00
|
|
|
break;
|
|
|
|
default:
|
2015-11-09 17:11:51 +00:00
|
|
|
if (propInfo.enumType)
|
|
|
|
newValue = propInfo.enumType[value];
|
2015-12-02 17:26:58 +00:00
|
|
|
else if (propInfo.type instanceof Function)
|
|
|
|
isLink = true;
|
2022-05-24 10:18:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isLink)
|
|
|
|
this._addLink(context, propName, value);
|
|
|
|
else if (newValue !== null && newValue !== undefined)
|
|
|
|
props[propName] = newValue;
|
|
|
|
else
|
|
|
|
this._showError('Attribute \'%s\' invalid for tag \'%s\'',
|
|
|
|
attribute, node.tagName);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,objectInstantiate: function(context) {
|
|
|
|
return new context.klass();
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,objectLink: function(context, object, objects, res) {
|
|
|
|
object.setProperties(context.props);
|
2015-11-17 10:34:33 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
var objectProps = context.objectProps;
|
|
|
|
for (var prop in objectProps)
|
|
|
|
object[prop] = objects[objectProps[prop]];
|
|
|
|
|
|
|
|
var childs = context.childs;
|
|
|
|
for (var i = 0; i < childs.length; i++)
|
2022-05-24 10:18:44 +00:00
|
|
|
object.appendChild(objects[childs[i]]);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
var events = context.events;
|
|
|
|
for (var event in events)
|
2022-05-24 10:18:44 +00:00
|
|
|
object.on(event, events[event], this.signalData);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
if (context.custom)
|
2022-05-24 10:18:44 +00:00
|
|
|
object.loadXml(res, context.custom);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a HTML node context.
|
2022-05-24 10:18:44 +00:00
|
|
|
*/
|
|
|
|
,elementCompile: function(node, tagName) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var attributes = {};
|
2022-05-24 10:18:44 +00:00
|
|
|
var dynProps = {};
|
2015-11-09 17:11:51 +00:00
|
|
|
var childs = [];
|
|
|
|
var events = {};
|
|
|
|
var handler;
|
|
|
|
|
|
|
|
var a = node.attributes;
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = 0; i < a.length; i++) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var attribute = a[i].nodeName;
|
|
|
|
var value = a[i].nodeValue;
|
2022-05-24 10:18:44 +00:00
|
|
|
const expr = this.matchExpr(value);
|
|
|
|
|
|
|
|
if (expr) {
|
|
|
|
dynProps[attribute] = expr;
|
|
|
|
} else if (this._isEvent(attribute)) {
|
|
|
|
var handler = this._getMethod(value);
|
2015-11-19 13:57:23 +00:00
|
|
|
|
|
|
|
if (handler)
|
2022-05-24 10:18:44 +00:00
|
|
|
events[attribute.substr(3)] = handler;
|
|
|
|
} else if (attribute !== 'id')
|
|
|
|
attributes[attribute] = this._translateValue(value);
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
2015-10-14 11:51:43 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
var childContext;
|
|
|
|
var childNodes = node.childNodes;
|
|
|
|
|
|
|
|
if (childNodes)
|
|
|
|
for (var i = 0; i < childNodes.length; i++)
|
2022-05-24 10:18:44 +00:00
|
|
|
if (childContext = this._compileNode(childNodes[i]))
|
|
|
|
childs.push(childContext.id);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
|
|
|
return {
|
2022-05-24 10:18:44 +00:00
|
|
|
tagName,
|
|
|
|
attributes,
|
|
|
|
dynProps,
|
|
|
|
childs,
|
|
|
|
events
|
2015-11-09 17:11:51 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,elementInstantiate: function(context) {
|
|
|
|
return this._doc.createElement(context.tagName);
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,elementLink: function(context, object, objects) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var attributes = context.attributes;
|
|
|
|
for (var attribute in attributes)
|
2022-05-24 10:18:44 +00:00
|
|
|
object.setAttribute(attribute, attributes[attribute]);
|
2015-10-14 11:51:43 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
var childs = context.childs;
|
2022-05-24 10:18:44 +00:00
|
|
|
for (var i = 0; i < childs.length; i++) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var child = objects[childs[i]];
|
|
|
|
|
|
|
|
if (child instanceof Htk.Widget)
|
2016-10-16 14:16:08 +00:00
|
|
|
child = child.node;
|
2015-11-17 10:34:33 +00:00
|
|
|
if (child instanceof Node)
|
2022-05-24 10:18:44 +00:00
|
|
|
object.appendChild(child);
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var events = context.events;
|
|
|
|
for (var event in events)
|
2022-05-24 10:18:44 +00:00
|
|
|
object.addEventListener(event,
|
|
|
|
events[event].bind(this.signalData));
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_showError: function(error) {
|
2015-11-09 17:11:51 +00:00
|
|
|
var path = this._path ? this._path : 'Node';
|
|
|
|
var logArgs = ['Vn.Builder: %s: '+ error, path];
|
|
|
|
|
|
|
|
for (var i = 1; i < arguments.length; i++)
|
2022-05-24 10:18:44 +00:00
|
|
|
logArgs.push(arguments[i]);
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
console.warn.apply(null, logArgs);
|
2015-11-09 17:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_addLink: function(context, prop, objectId) {
|
|
|
|
this._links.push({
|
2015-11-09 17:11:51 +00:00
|
|
|
context: context
|
|
|
|
,prop: prop
|
|
|
|
,objectId: objectId
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_translateValue: function(value) {
|
|
|
|
var chr = value.charAt(0);
|
2015-10-14 11:51:43 +00:00
|
|
|
|
2015-11-09 17:11:51 +00:00
|
|
|
if (chr === '_')
|
2022-05-24 10:18:44 +00:00
|
|
|
return _(value.substr(1));
|
|
|
|
else if (chr === '\\' && value.charAt(1) === '_')
|
|
|
|
return value.substr(1);
|
2015-10-14 11:51:43 +00:00
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_getMethod: function(value) {
|
2015-10-14 11:51:43 +00:00
|
|
|
if (this.signalData)
|
2016-08-22 10:41:05 +00:00
|
|
|
var method = this.signalData[value];
|
2015-10-14 11:51:43 +00:00
|
|
|
else
|
2016-08-22 10:41:05 +00:00
|
|
|
var method = window[value];
|
2015-10-14 11:51:43 +00:00
|
|
|
|
2015-11-19 13:57:23 +00:00
|
|
|
if (method === undefined)
|
2022-05-24 10:18:44 +00:00
|
|
|
this._showError('Function \'%s\' not found', value);
|
2015-10-14 11:51:43 +00:00
|
|
|
|
|
|
|
return method;
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_isEvent: function(attribute) {
|
|
|
|
return /^on-\w+/.test(attribute);
|
2015-10-14 11:51:43 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_replaceFunc: function(token) {
|
|
|
|
return token.charAt(1).toUpperCase();
|
2015-10-14 11:51:43 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
});
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
var BuilderResult = new Class({
|
2016-09-26 09:28:47 +00:00
|
|
|
Extends: Object
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,initialize: function(builder, objects) {
|
2015-11-09 17:11:51 +00:00
|
|
|
this.builder = builder;
|
|
|
|
this.objects = objects;
|
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,getMain: function() {
|
|
|
|
return this.builder.getMain(this);
|
2015-03-27 19:10:49 +00:00
|
|
|
}
|
2015-07-03 05:49:45 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,$: function(objectId) {
|
|
|
|
return this.builder.getById(this, objectId);
|
2015-07-03 05:49:45 +00:00
|
|
|
}
|
2015-11-09 17:11:51 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,getById: function(objectId) {
|
|
|
|
return this.builder.getById(this, objectId);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,getByTagName: function(tagName) {
|
|
|
|
return this.builder.getByTagName(this, tagName);
|
2015-11-17 10:34:33 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,link: function(self, scope) {
|
|
|
|
this.builder.link(this, self, scope);
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
2015-07-28 19:14:26 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
,_destroy: function() {
|
2015-11-09 17:11:51 +00:00
|
|
|
var objects = this.objects;
|
|
|
|
|
|
|
|
for (var i = 0; i < objects.length; i++)
|
2016-09-26 09:28:47 +00:00
|
|
|
if (objects[i] instanceof Object)
|
2022-05-24 10:18:44 +00:00
|
|
|
objects[i].unref();
|
2015-08-17 18:02:14 +00:00
|
|
|
|
2022-05-24 10:18:44 +00:00
|
|
|
this.parent();
|
2015-07-28 19:14:26 +00:00
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
});
|
|
|
|
|