diff --git a/js/lib/element-object-min.js b/js/lib/element-object-min.js index dcee2a4..f5ba1b8 100644 --- a/js/lib/element-object-min.js +++ b/js/lib/element-object-min.js @@ -1 +1,5 @@ -var references=function(a){return{$:a}},ElementObject=function(a){this.node="undefined"==typeof a?null:a};ElementObject.prototype={node:this.node,node_type:null,prev_nodes:[],next_nodes:[],children:[],attributes:{},text:null,repeat:1,parent:null,node_def:null,element:null}; +function references(a){return{$:a}} +var ElementObject=function(a,c){if(a instanceof Object){c=c instanceof Object?c:{};var b,d;!a.hasOwnProperty("repeat")||isNaN(a.repeat)&&ElementObject.regex.arr_out_set.test(a.repeat);b=(b=a.hasOwnProperty("node"))&&"string"==typeof a.node;d=(d=a.hasOwnProperty("node_type"))&&"string"==typeof a.node_type;a.hasOwnProperty("prev_nodes");a.hasOwnProperty("next_nodes");a.hasOwnProperty("children");a.hasOwnProperty("attributes");a.hasOwnProperty("text");a.hasOwnProperty("listeners");a.hasOwnProperty("scope"); +if(d)this.element=document.createElement(node_type);else if(b){if(!this.fetchDefinition(c))return null;scope=this.scope;return new ElementObject}a&&(this.node="undefined"==typeof node?null:node)}};ElementObject.prototype={node:this.node,node_type:null,prev_nodes:[],next_nodes:[],children:[],attributes:{},text:null,listeners:[],repeat:1,scope:{},parent:null,node_def:null,element:null}; +ElementObject.regex={reg_in_key:/^\/\^(.+)\$\/$/,reg_out_val:/\{(\$[1-9])\}/,pri_out_val:/\{([a-z-]+)\}/g,pri_in_key:/^\$([a-z-]+)$/,arr_out_set:/^\{\{([a-z-]+)\}\}$/,arr_out_val:/\{([a-z-]+)\.([a-z-]+)\}/g,arr_in_key:/^\$\$([a-z-]+)$/}; +ElementObject.prototype.fetchDefinition=function(a){var c,b;r=ElementObject.regex.reg_in_key;if(a.hasOwnProperty(this.node))return this.node_def=a[this.node],!0;for(c in a)if(r.test(c)&&(b=new RegExp(c.slice(1,-1)),b.test(this.node))){for(b=1;bb;b++)this.scope["$"+b]=RegExp["$"+b];this.node_def=a[c];return!0}return!1}; diff --git a/js/lib/element-object.js b/js/lib/element-object.js index 208519d..26a8137 100644 --- a/js/lib/element-object.js +++ b/js/lib/element-object.js @@ -1,5 +1,5 @@ /* RENVOIE UN WRAPPER POUR UTILISER LES REFERENCES */ -var references = function(data){ return { $: data }; }; +function references(data){ return { $: data }; } @@ -10,14 +10,97 @@ var references = function(data){ return { $: data }; }; -/* CONSTRUCTEUR -> INITIALISE UNE L'INSTANCE +/* CONSTRUCTEUR -> INITIALISE UNE L'INSTANCE A PARTIR D'UNE DEFINITION * -* @node [OPT] Identifiant d'un élément (selon une définition) +* @object Attributs de l'élément (selon une définition) +* @definitions Définition des éléments * */ -var ElementObject = function(node){ +var ElementObject = function(object, definitions){ + /* [0] Initialisation + =========================================================*/ + /* (1) Si on a pas un objet, on quitte */ + if( !(object instanceof Object) ) + return; - /* Gestion du paramètre @node */ + /* (2) Si pas de définition, on met au bon format */ + definitions = definitions instanceof Object ? definitions : {}; + + /* (2) Initialisation des variables */ + var i; + + + /* [1] Vérifiaction des attributs + =========================================================*/ + var attr_check = {}; + + /* (1) repeat */ + attr_check.repeat = object.hasOwnProperty('repeat'); + attr_check.repeat = attr_check.repeat && ( !isNaN(object.repeat) || ElementObject.regex.arr_out_set.test(object.repeat) ); + + /* (2) node */ + attr_check.node = object.hasOwnProperty('node'); + attr_check.node = attr_check.node && typeof object.node == 'string'; + + /* (3) node_type */ + attr_check.node_type = object.hasOwnProperty('node_type'); + attr_check.node_type = attr_check.node_type && typeof object.node_type == 'string'; + + /* (4) prev_nodes */ + attr_check.prev_nodes = object.hasOwnProperty('prev_nodes'); + attr_check.prev_nodes = attr_check.prev_nodes && object.prev_nodes instanceof Array; + + /* (5) next_nodes */ + attr_check.next_nodes = object.hasOwnProperty('next_nodes'); + attr_check.next_nodes = attr_check.next_nodes && object.next_nodes instanceof Array; + + /* (6) children */ + attr_check.children = object.hasOwnProperty('children'); + attr_check.children = attr_check.children && object.children instanceof Array; + + /* (7) attributes */ + attr_check.attributes = object.hasOwnProperty('attributes'); + attr_check.attributes = attr_check.attributes && object.attributes instanceof Object; + + /* (8) text */ + attr_check.text = object.hasOwnProperty('text'); + attr_check.text = attr_check.text && typeof object.text == 'string'; + + /* (9) listeners */ + attr_check.listeners = object.hasOwnProperty('listeners'); + attr_check.listeners = attr_check.listeners && object.listeners instanceof Array; + + /* (10) scope */ + attr_check.scope = object.hasOwnProperty('scope'); + attr_check.scope = attr_check.scope && object.scope instanceof Object; + + + /* [2] Attribution des attributs et traitement + =========================================================*/ + + /* (2.1) Création de l'élément + ---------------------------------------------------------*/ + /* (1) Création avec @node_type s'il est donné*/ + if( attr_check.node_type ) + this.element = document.createElement(node_type); + + /* (2) Sinon on crée en chargeant la définition */ + else if( attr_check.node ){ + + // si on ne trouve pas de definition + if( !this.fetchDefinition(definitions) ) + return null; + + // sinon on construit un nouvel element + scope = this.scope + return new ElementObject() + + } + + + /* (2) Section Title */ + + if( object ) this.node = typeof node == 'undefined' ? null : node; }; @@ -45,10 +128,26 @@ ElementObject.prototype = { listeners: [], /* Liste des listeners (event) */ repeat: 1, /* Nombre de fois qu'il faut répéter l'élément */ + scope: {}, /* Variables du scope actuel */ + parent: null, /* Element parent */ node_def: null, /* Définition de l'élément (en fonction de @node) */ - element: null, /* Contiendra l'élément quand il sera créé */ + element: null /* Contiendra l'élément quand il sera créé */ +}; + +/* DEFINITION DES ATTRIBUTS STATIQUES +* +*/ +ElementObject.regex = { + reg_in_key: /^\/\^(.+)\$\/$/, // Regex associée à une "regex" incluse dans une clé + reg_out_val: /\{(\$[1-9])\}/, // Regex associée à la valeur du dernier match de "regex" + + pri_out_val: /\{([a-z-]+)\}/g, // Regex associée à une variable primitif à remplacer + pri_in_key: /^\$([a-z-]+)$/, // Regex associée à la clé d'une variable primitive + arr_out_set: /^\{\{([a-z-]+)\}\}$/, // Regex associée à un tableau à remplacer + arr_out_val: /\{([a-z-]+)\.([a-z-]+)\}/g, // Regex associée à une valeur de tableau à remplacer (primitif) + arr_in_key: /^\$\$([a-z-]+)$/ // Regex associée à la clé d'un tableau }; /************************************************************/ @@ -59,6 +158,60 @@ ElementObject.prototype = { /* |_| |_|_____| |_| |_| |_|\___/|____/|____/ */ /************************************************************/ +/* CHERCHE UNE DEFINITION CORRESPONDANT A L'ATTRIBUT 'node' +* +*/ +ElementObject.prototype.fetchDefinition = function(definitions){ + /* [0] Initialisation + =========================================================*/ + var m = null, key, i, regex; + r = ElementObject.regex.reg_in_key; + + + /* [1] Si la définition existe, on la retourne + =========================================================*/ + if( definitions.hasOwnProperty(this.node) ){ + + this.node_def = definitions[this.node]; + return true; + + + /* [2] Sinon, on cherche une REGEX + =========================================================*/ + }else{ + + // Pour chaque définition + for( key in definitions ){ + + /* (2.1) On regarde s'il n'y a pas de REGEX dans la clé + ---------------------------------------------------------*/ + if( r.test(key) ){ + + // On construit la regex + regex = new RegExp( key.slice(1, -1) ); + + /* (1) Si la regex match */ + if( (m=regex.test(this.node)) ){ + + /* (2) On récupère les 'match' */ + for( i = 1 ; i < RegExp.length && i < 10 ; i++ ) + this.scope['$'+i] = RegExp['$'+i]; + + /* (3) On renvoie le lien + le scope */ + this.node_def = definitions[key]; + return true; + + } + + } + + } + + } + + return false; +}; + /************************************************/ /* ____ _____ _ _____ ___ ____ */ /* / ___|_ _|/ \|_ _|_ _/ ___| */ diff --git a/js/lib/form-builder-min.js b/js/lib/form-builder-min.js index 3155afe..ac8950b 100644 --- a/js/lib/form-builder-min.js +++ b/js/lib/form-builder-min.js @@ -1,8 +1,9 @@ -var FormBuilder=function(a,d){this.parent_element=a;this.form_object=d};FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:this.parent_element,built_form:null};FormBuilder.regex={regex_input_key:/^\/\^(.+)\$\/$/,regex_ouput_value:/\{(\$[1-9])\}/,primitive_ouput_value:/\{([a-z-]+)\}/g,primitive_input_key:/^\$([a-z-]+)$/,array_output_set:/^\{\{([a-z-]+)\}\}$/,array_output_value:/\{([a-z-]+)\.([a-z-]+)\}/g,array_input_key:/^\$\$([a-z-]+)$/}; -FormBuilder.spread_attr=["children","next_nodes","prev_nodes","attributes"];FormBuilder.allowed_attr="node node_type next_nodes prev_nodes attributes children text repeat".split(" ");FormBuilder.no_recursion=["parent","scope","received"];FormBuilder.prototype.add_definition=function(a){for(var d in a)this.defs_object[d]=a[d]}; +var FormBuilder=function(a,d){this.parent_element=a;this.form_object=d};FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:this.parent_element,built_form:null};FormBuilder.regex={reg_in_key:/^\/\^(.+)\$\/$/,reg_out_val:/\{(\$[1-9])\}/,pri_out_val:/\{([a-z-]+)\}/g,pri_in_key:/^\$([a-z-]+)$/,arr_out_set:/^\{\{([a-z-]+)\}\}$/,arr_out_val:/\{([a-z-]+)\.([a-z-]+)\}/g,arr_in_key:/^\$\$([a-z-]+)$/}; +FormBuilder.spread_attr=["children","next_nodes","prev_nodes","attributes","node_link"];FormBuilder.allowed_attr="node node_type next_nodes prev_nodes attributes children text repeat".split(" ");FormBuilder.no_recursion=["parent","scope","received"];FormBuilder.prototype.add_definition=function(a){for(var d in a)this.defs_object[d]=a[d]}; FormBuilder.prototype.build=function(a){a=null==a?{}:a;this.built_form=FormBuilder.formatFormObject(this.form_object,this.defs_object);this.built_form=FormBuilder.replaceStatements(this.form_object,a)}; FormBuilder.formatFormObject=function(a,d){if(a.hasOwnProperty("node")&&"string"==typeof a.node){var b=FormBuilder.fetchNodeDefinition(a.node,d);null!==b&&(a.node_link=b.def,b.hasOwnProperty("scope")&&(a.scope=b.scope))}if(a.hasOwnProperty("children"))for(var f in a.children)a.children[f].parent=a,FormBuilder.formatFormObject(a.children[f],d);return a}; -FormBuilder.fetchNodeDefinition=function(a,d){var b,f;r=FormBuilder.regex.regex_input_key;if(null!=d&&d.hasOwnProperty(a))return{def:d.node,scope:null};for(b in d)if(r.test(b)&&(f=new RegExp(b.slice(1,-1)),f.test(a))){matches={};for(f=1;ff;f++)matches["$"+f]=RegExp["$"+f];return{def:d[b],scope:matches}}return null}; -FormBuilder.replaceStatements=function(a,d){a=a instanceof Object?a:{};d=d instanceof Object?d:{};var b,f,c,g={};for(b in a)if("string"==typeof a[b]){f=FormBuilder.regex.array_output_set;var e=[];(c=f.exec(a[b]))&&e.push(c[1]);for(c in e)d.hasOwnProperty(e[c])||(d[e[c]]=[]),a[b]=d[e[c]];if(!(0=f.lastIndex);)lasti=f.lastIndex,e.push(c[1]);for(c in e)d.hasOwnProperty(e[c])||(d[e[c]]=""),f=new RegExp("{\\$"+e[c][1]+"}","g"),a[b]=a[b].replace(f,d[e[c]]);if(!(0f;f++)matches["$"+f]=RegExp["$"+f];return{def:d[b],scope:matches}}return null}; +FormBuilder.replaceStatements=function(a,d){a=a instanceof Object?a:{};d=d instanceof Object?d:{};var b,f,c,g={};if(a.hasOwnProperty("scope")&&a.scope instanceof Object)for(b in a.scope)g[b]=a.scope[b];for(b in a)if("string"==typeof a[b]){f=FormBuilder.regex.arr_out_set;var e=[];(c=f.exec(a[b]))&&e.push(c[1]);for(c in e)d.hasOwnProperty(e[c])||(d[e[c]]=[]),a[b]=d[e[c]];if(!(0=f.lastIndex);)lasti=f.lastIndex,e.push(c[1]);for(c in e)d.hasOwnProperty(e[c])||(d[e[c]]=""),f=new RegExp("{\\$"+e[c][1]+"}","g"),a[b]=a[b].replace(f,d[e[c]]);if(!(0 -1 ){ + console.log('spreads to', key); /* (1) on envoie aussi le scope actuel (le tout cloné) */ var tmp = [ @@ -442,7 +442,7 @@ FormBuilder.replaceStatements = function(object, scope){ if( tmp[0].length > 2 && tmp[1].length > 2 ) tmp[1] = ',' + tmp[1]; - next_scope = JSON.parse( tmp[0] +''+ tmp[1] ); + next_scope = JSON.parse( tmp[0] + tmp[1] ); /* (3) Si c'est un tableau, on lance récursivement pour chaque item */ if( object[key] instanceof Array ) diff --git a/js/lib/form-builder/main.js b/js/lib/form-builder/main.js index 40e4eae..cd187a7 100644 --- a/js/lib/form-builder/main.js +++ b/js/lib/form-builder/main.js @@ -53,16 +53,16 @@ var form = { node: 'h4', attributes: { 'data-icon': 'o', 'class': 'new-contact color2' }, children: [ - { node: 'input:hidden', $name: 'uid', $value: '{uid}' }, - { node: 'input:hidden', $name: 'call', $value: '{call}' }, - { node: 'input:hidden', $name: 'sms', $value: '{sms}' }, - { node: 'input:hidden', $name: 'countcall', $value: '{countcall}' }, - { node: 'input:hidden', $name: 'countsms', $value: '{countsms}' }, - { node: 'input:hidden', $name: 'total', $value: '{countcall} calls + {countsms} sms to {number}' }, + { node: 'input:hidden', $name: 'uid', $value: '{uid}' }, + { node: 'input:hidden', $name: 'call', $value: '{call}' }, + { node: 'input:hidden', $name: 'sms', $value: '{sms}' }, + { node: 'input:hidden', $name: 'countcall', $value: '{countcall}' }, + { node: 'input:hidden', $name: 'countsms', $value: '{countsms}' }, + { node: 'input:hidden', $name: 'total', $value: '{countcall} calls + {countsms} sms to {number}' }, - { node: 'input:text', $name: 'number', $value: '{number}' }, + { node: 'input:text', $name: 'number', $value: '{number}' }, - { node: 'custom-select', $name: 'existing', $$options: '{{options}}' } + { node: 'custom-select', $name: 'existing', $$options: '{{options}}' } ] }; diff --git a/view.php b/view.php index 25f9f1f..a3a547b 100755 --- a/view.php +++ b/view.php @@ -36,7 +36,6 @@ -