Remplacement par référence fonctionnel [FCT] reste à faire des 'getters' et 'setters' de références

This commit is contained in:
xdrm-brackets 2016-09-19 10:09:10 +02:00
parent 1ce1788801
commit 1f0155e109
3 changed files with 174 additions and 104 deletions

View File

@ -1,11 +1,12 @@
var ref=function(a,b){for(var d=null;null==d||a.hasOwnProperty(d);)d="$"+(1048576+Math.floor(15728639*Math.random())).toString(16)+"$";a[d]=b;return d},FormBuilder=function(a){this.form_object=a};FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:null,built_form:null,root_element:null,ref_table:{}};
var ref=function(a,c){for(var e=null;null==e||a.hasOwnProperty(e);)e="$"+(1048576+Math.floor(15728639*Math.random())).toString(16)+"$";a[e]=c;return e},FormBuilder=function(a){this.form_object=a};FormBuilder.prototype={form_object:this.form_object,defs_object:{},parent_element:null,built_form:null,root_element:null,ref_table:{}};
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-]+)$/,ref_pri:/^\$[a-f0-9]{6}\$$/};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.prototype.add_definition=function(a){for(var b in a)this.defs_object[b]=a[b]};FormBuilder.prototype.build=function(a){a=null==a?{}:a;for(var b in a)a[b]=ref(this.ref_table,a[b]);this.built_form=JSON.parse(JSON.stringify(this.form_object));this.built_form=FormBuilder.formatFormObject(this.built_form,this.defs_object);this.built_form=FormBuilder.replaceStatements(this.built_form,a,this.defs_object,this.ref_table)};
FormBuilder.prototype.attach=function(a){if(!(a instanceof Element)&&null==this.parent_element)return!1;this.parent_element=a instanceof Element?a:this.parent_element};FormBuilder.formatFormObject=function(a,b){if(a.hasOwnProperty("children"))for(var d in a.children)a.children[d].parent=a,FormBuilder.formatFormObject(a.children[d],b);return a};
FormBuilder.fetchNodeDefinition=function(a,b){var d,f;r=FormBuilder.regex.reg_in_key;if("undefined"!=typeof b&&b.hasOwnProperty(a))return{def:b[a]};for(d in b)if(r.test(d)&&(f=new RegExp(d.slice(1,-1)),f.test(a))){matches={};for(f=1;f<RegExp.length&&10>f;f++)matches["$"+f]=RegExp["$"+f];return{def:b[d],scope:matches}}return{}};
FormBuilder.replaceStatements=function(a,b,d,f){a=a instanceof Object?a:{};b=b instanceof Object?JSON.parse(JSON.stringify(b)):{};var c,h,e,g,k,l,n;if(a.hasOwnProperty("scope")&&a.scope instanceof Object)for(c in a.scope)b[c]=a.scope[c];if(a.hasOwnProperty("node")&&"string"==typeof a.node&&(e=FormBuilder.fetchNodeDefinition(a.node,d),e.hasOwnProperty("def")&&(a.node_link=JSON.parse(JSON.stringify(e.def)),e.hasOwnProperty("scope"))))for(c in e.scope)b[c]=e.scope[c];for(c in a)if("string"==typeof a[c])if(a[c]=
[a[c]],e=FormBuilder.replaceStatementsArray(a[c][0],b),!1!==e)a[c][0]=e;else{h=FormBuilder.regex.reg_out_val;g=-1;for(l=[];null!==(e=h.exec(a[c][0]))&&!(g>=h.lastIndex);)g=h.lastIndex,l.push(e[1]);for(e in l)b.hasOwnProperty(l[e])||(b[l[e]]=""),h=new RegExp("{\\$"+l[e][1]+"}","g"),a[c][0]=a[c][0].replace(h,b[l[e]]);if(!(0<l.length))for(k in a[c]=FormBuilder.replaceStatementsPrimary(a[c],b),h=FormBuilder.regex.arr_out_val,a[c])if(null!=a[c][k]){for(n=[];null!==(e=h.exec(a[c][k]));)n.push(e);g=0;l=
[];for(e in n)(0<g||0<n[e].index)&&l.push(a[c][k].substr(g,n[e].index)),b.hasOwnProperty(n[e][1])||(b[n[e][1]]=""),l.push(b[n[e][1]]),g=n[e].index+n[e][0].length;g<a[c][k].length&&l.push(a[c][k].substr(g,a[c][k].length));0<n.length&&(a[c]=a[c].slice(0,k).concat(l).concat(a[c].slice(k+1)))}}for(c in a)FormBuilder.regex.pri_in_key.test(c)?b[c.substring(1)]=ref(f,a[c]):FormBuilder.regex.arr_in_key.test(c)&&(b[c.substring(2)]=ref(f,a[c]));b=JSON.parse(JSON.stringify(b));for(c in a)if(-1<FormBuilder.spread_attr.indexOf(c))if(a[c]instanceof
Array)for(var p in a[c])FormBuilder.replaceStatements(a[c][p],b,d,f);else a[c]instanceof Object&&FormBuilder.replaceStatements(a[c],b,d,f);return a};FormBuilder.replaceStatementsArray=function(a,b){var d=null,d=FormBuilder.regex.arr_out_set.exec(a);if(null===d)return!1;b.hasOwnProperty(d[1])||(b[d[1]]=[]);return b[d[1]]};
FormBuilder.replaceStatementsPrimary=function(a,b){var d=FormBuilder.regex.pri_out_val,f=null,c=[],h,e,g,k;for(g=0;g<a.length;g++){m=null;c=[];h=0;for(e=[];null!==(f=d.exec(a[g]));)c.push(f);for(f=0;f<c.length;f++)k=c[f][1],(0<h||0<c[f].index)&&e.push(a[g].substr(h,c[f].index-h)),b.hasOwnProperty(k)||(b[k]=""),e.push(b[k]),h=c[f].index+c[f][0].length;h<a[g].length&&e.push(a[g].substr(h,a[g].length));a=a.slice(0,g).concat(e).concat(a.slice(g+1))}return a};
FormBuilder.buildString=function(a,b){var d,f="";if("string"==typeof b&&FormBuilder.regex.ref_pri.test(b))return a[b];for(d in b)f=FormBuilder.regex.ref_pri.test(b[d])&&a.hasOwnProperty(b[d])?a[b[d]]instanceof Array?f+(""+FormBuilder.buildString(a,a[b[d]])):f+(""+a[b[d]]):f+(""+b[d].toString());return f};
FormBuilder.prototype.add_definition=function(a){for(var c in a)this.defs_object[c]=a[c]};FormBuilder.prototype.build=function(a){a=null==a?{}:a;for(var c in a)a[c]=ref(this.ref_table,a[c]);this.built_form=JSON.parse(JSON.stringify(this.form_object));this.built_form=FormBuilder.formatFormObject(this.built_form,this.defs_object);this.built_form=FormBuilder.replaceStatements(this.built_form,a,this.defs_object,this.ref_table)};
FormBuilder.prototype.attach=function(a){if(!(a instanceof Element)&&null==this.parent_element)return!1;this.parent_element=a instanceof Element?a:this.parent_element};FormBuilder.formatFormObject=function(a,c){if(a.hasOwnProperty("children"))for(var e in a.children)a.children[e].parent=a,FormBuilder.formatFormObject(a.children[e],c);return a};
FormBuilder.fetchNodeDefinition=function(a,c){var e,d;r=FormBuilder.regex.reg_in_key;if("undefined"!=typeof c&&c.hasOwnProperty(a))return{def:c[a]};for(e in c)if(r.test(e)&&(d=new RegExp(e.slice(1,-1)),d.test(a))){matches={};for(d=1;d<RegExp.length&&10>d;d++)matches["$"+d]=RegExp["$"+d];return{def:c[e],scope:matches}}return{}};
FormBuilder.replaceStatements=function(a,c,e,d){a=a instanceof Object?a:{};c=c instanceof Object?JSON.parse(JSON.stringify(c)):{};var b,f;if(a.hasOwnProperty("scope")&&a.scope instanceof Object)for(b in a.scope)c[b]=a.scope[b];if(a.hasOwnProperty("node")&&"string"==typeof a.node&&(f=FormBuilder.fetchNodeDefinition(a.node,e),f.hasOwnProperty("def")&&(a.node_link=JSON.parse(JSON.stringify(f.def)),f.hasOwnProperty("scope"))))for(b in f.scope)c[b]=f.scope[b];for(b in a)"string"==typeof a[b]&&(a[b]=[a[b]],
f=FormBuilder.replaceStatementsArray(a[b][0],c),!1!==f?a[b]=f:(a[b]=FormBuilder.replaceStatementsRegex(a[b],c),a[b]=FormBuilder.replaceStatementsPrimary(a[b],c),a[b]=FormBuilder.replaceStatementsArrayValue(a[b],c)));for(b in a)FormBuilder.regex.pri_in_key.test(b)?c[b.substring(1)]=ref(d,a[b]):FormBuilder.regex.arr_in_key.test(b)&&(c[b.substring(2)]=ref(d,a[b]));c=JSON.parse(JSON.stringify(c));for(b in a)if(-1<FormBuilder.spread_attr.indexOf(b))if(a[b]instanceof Array)for(var h in a[b])FormBuilder.replaceStatements(a[b][h],
c,e,d);else a[b]instanceof Object&&FormBuilder.replaceStatements(a[b],c,e,d);return a};FormBuilder.replaceStatementsArray=function(a,c){var e=null,e=FormBuilder.regex.arr_out_set.exec(a);if(null===e)return!1;c.hasOwnProperty(e[1])||(c[e[1]]=[]);return c[e[1]]};
FormBuilder.replaceStatementsRegex=function(a,c){var e=FormBuilder.regex.reg_out_val,d=null,b=[],f,h,g,k;for(g=0;g<a.length;g++){m=null;b=[];f=-1;for(h=[];null!==(d=e.exec(a[g]))&&!(f>=e.lastIndex);)f=e.lastIndex,b.push(d);for(d=f=0;d<b.length;d++)k=b[d][1],(0<f||0<b[d].index)&&h.push(a[g].substr(f,b[d].index-f)),c.hasOwnProperty(k)||(c[k]=""),h.push(c[k]),f=b[d].index+b[d][0].length;f<a[g].length&&h.push(a[g].substr(f,a[g].length));a=a.slice(0,g).concat(h).concat(a.slice(g+1))}return a};
FormBuilder.replaceStatementsPrimary=function(a,c){var e=FormBuilder.regex.pri_out_val,d=null,b=[],f,h,g,k;for(g=0;g<a.length;g++){m=null;b=[];f=0;for(h=[];null!==(d=e.exec(a[g]));)b.push(d);for(d=0;d<b.length;d++)k=b[d][1],(0<f||0<b[d].index)&&h.push(a[g].substr(f,b[d].index-f)),c.hasOwnProperty(k)||(c[k]=""),h.push(c[k]),f=b[d].index+b[d][0].length;f<a[g].length&&h.push(a[g].substr(f,a[g].length));a=a.slice(0,g).concat(h).concat(a.slice(g+1))}return a};
FormBuilder.replaceStatementsArrayValue=function(a,c){var e=FormBuilder.regex.arr_out_val,d=null,b=[],f,h,g,k;for(g=0;g<a.length;g++){m=null;b=[];f=0;for(h=[];null!==(d=e.exec(a[g]));)b.push(d);for(d=0;d<b.length;d++)k=b[d][1],(0<f||0<b[d].index)&&h.push(a[g].substr(f,b[d].index-f)),c.hasOwnProperty(k)||(c[k]=""),h.push(c[k]),f=b[d].index+b[d][0].length;f<a[g].length&&h.push(a[g].substr(f,a[g].length));a=a.slice(0,g).concat(h).concat(a.slice(g+1))}return a};
FormBuilder.buildString=function(a,c){var e,d="";if("string"==typeof c&&FormBuilder.regex.ref_pri.test(c))return a[c];for(e in c)d=FormBuilder.regex.ref_pri.test(c[e])&&a.hasOwnProperty(c[e])?a[c[e]]instanceof Array?d+(""+FormBuilder.buildString(a,a[c[e]])):d+(""+a[c[e]]):d+(""+c[e].toString());return d};

View File

@ -209,9 +209,7 @@ FormBuilder.prototype.attach = function(parent){
*/
FormBuilder.formatFormObject = function(object, defs){
/* [1] Pour chaque enfant, s'il y a
==================================================================*/
/* Pour chaque enfant, s'il y a */
if( object.hasOwnProperty('children') ){
for( var child in object.children ){
@ -360,110 +358,30 @@ FormBuilder.replaceStatements = function(object, scope, definitions, ref_table){
/* (1) On récupère le remplacement */
m_arr = FormBuilder.replaceStatementsArray(object[key][0], scope);
/* (2) Si on a remplacé, on remplace, et on passe à la clé suivante */
/* (2) Si on un remplacement, on remplace, et on passe à la clé suivante */
if( m_arr !== false ){
object[key][0] = m_arr;
object[key] = m_arr;
continue;
}
/* (2.2) On cherche toutes les variables REGEX à remplacer
/* (2.2) On cherche toutes les match de REGEX à remplacer
---------------------------------------------------------*/
/* (1.1) On récupère les remplacements REGEX */
m = null, r = FormBuilder.regex.reg_out_val,
lasti = -1;
m_reg = [];
/* (1.2) Tant que ça match */
var max = 10;
while( (m=r.exec(object[key][0])) !== null && max > 0 ){
// si on boucle, on sort
if( lasti >= r.lastIndex ) break;
lasti = r.lastIndex;
m_reg.push( m[1] );
}
/* (1.3) Pour chaque match */
for( m in m_reg ){
// {1} Si la var n'est pas dans le scope //
if( !scope.hasOwnProperty(m_reg[m]) )
scope[m_reg[m]] = ''; // on met une chaine vide
// {2} on remplace toutes les occurences par la valeur //
tmp = new RegExp( "{\\$"+m_reg[m][1]+"}", 'g' );
object[key][0] = object[key][0].replace(tmp, scope[m_reg[m]]);
}
/* (1.4) Si on a trouvé qqch, on passe à la clé suivante */
if( m_reg.length > 0 )
continue;
/* (1) On récupère les remplacements */
object[key] = FormBuilder.replaceStatementsRegex(object[key], scope);
/* (2.3) On cherche toutes les variables PRIMITIVES à remplacer
/* (2.3) On cherche toutes les variables primitives à remplacer
---------------------------------------------------------*/
/* (1) On récupère les remplacements */
object[key] = FormBuilder.replaceStatementsPrimary(object[key], scope);
/* (2.4) On cherche toutes les valeurs de TABLEAUX à remplacer
/* (2.4) On cherche toutes les valeurs de tableaux à remplacer
---------------------------------------------------------*/
/* (1.1) On récupère les remplacements de valeurs de TABLEAUX */
r = FormBuilder.regex.arr_out_val;
/* (1.2) Pour chaque partie de la chaine */
for( s in object[key] ){
// bugfix
if( object[key][s] == null )
continue;
m = null,
m_aval = [];
/* (1.3) Tant que ça match */
while( (m=r.exec(object[key][s])) !== null )
m_aval.push( m );
/* (1.4) Pour chaque match */
lasti = 0;
parts = [];
for( m in m_aval ){
// {1} On met la chaine d'avant le match //
if( lasti > 0 || m_aval[m].index > 0 )
parts.push( object[key][s].substr(lasti, m_aval[m].index) );
// {2} Si la var n'est pas dans le scope //
if( !scope.hasOwnProperty(m_aval[m][1]) )
scope[m_aval[m][1]] = ''; // on met une chaine vide
// {3} On met le match //
parts.push( scope[m_aval[m][1]] );
// {4} On met à jour l'index de fin pour la suite //
lasti = m_aval[m].index + m_aval[m][0].length;
// // {2} [OLD]on remplace toutes les occurences par la valeur //
// tmp = new RegExp( "{"+m_pri[m]+"}", 'g' );
// object[key][s] = object[key][s].replace(tmp, scope[m_pri[m]]);
}
// {5} On ajoute la partie après le match //
if( lasti < object[key][s].length )
parts.push( object[key][s].substr(lasti, object[key][s].length) );
/* (1.5) Si on l'attribue */
if( m_aval.length > 0 )
object[key] = object[key].slice(0, s).concat(parts).concat(object[key].slice(s+1));
}
/* (1) On récupère les remplacements */
object[key] = FormBuilder.replaceStatementsArrayValue(object[key], scope);
}
@ -552,6 +470,84 @@ FormBuilder.replaceStatementsArray = function(statement, scope){
};
/* REMPLACE LES VALEURS DE MATCH DE REGEX SOUS LA FORME "{$matchNumber}" par leur référence
*
* @statements<Array> Tableau contenant les parties de la chaine
* @scope<Object> Objet contenant le scope
*
* @return splitVal<Array> Tableau contenant les parties de la chaine (références + chaine)
*
*/
FormBuilder.replaceStatementsRegex = function(statements, scope){
/* [1] Initialisation
=========================================================*/
var regex = FormBuilder.regex.reg_out_val;
var match = null;
var matches = [];
var lasti, parts, p, i, key;
/* [2] Pour chaque partie de la chaine
=========================================================*/
for( p = 0 ; p < statements.length ; p++ ){
/* (1) Initialisation */
m = null;
matches = [];
lasti = -1;
parts = [];
/* (2) Tant que ça match, on récupère les infos du match */
while( (match=regex.exec(statements[p])) !== null ){
// si on boucle, on sort
if( lasti >= regex.lastIndex ) break;
lasti = regex.lastIndex;
matches.push( match );
}
lasti = 0;
/* [3] Pour chaque match
=========================================================*/
for( i = 0 ; i < matches.length ; i++ ){
key = matches[i][1];
/* (1) On met la chaine d'avant le match (si existe) */
if( lasti > 0 || matches[i].index > 0 )
parts.push( statements[p].substr(lasti, matches[i].index-lasti) );
/* (2) Si la var n'est pas dans le scope, on l'initialise vide */
if( !scope.hasOwnProperty(key) )
scope[key] = ''; // on met une chaine vide
/* (3) On insère la valeur du scope */
parts.push( scope[key] );
/* (4) On met à jour l'index de fin pour la suite */
lasti = matches[i].index + matches[i][0].length;
}
/* (5) On ajoute la partie après le match */
if( lasti < statements[p].length )
parts.push( statements[p].substr(lasti, statements[p].length) );
/* [4] on remplace statements[p] par sa décomposition
=========================================================*/
statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1));
}
/* [5] On retourne la chaine modifiée (ou non)
=========================================================*/
return statements;
};
/* REMPLACE LES VARIABLE SOUS LA FORME "{varName}" par leur référence
*
* @statements<Array> Tableau contenant les parties de la chaine
@ -613,7 +609,7 @@ FormBuilder.replaceStatementsPrimary = function(statements, scope){
/* [4] on remplace statements[p] par sa décomposition
=========================================================*/
statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1));
statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1));
}
@ -623,6 +619,79 @@ FormBuilder.replaceStatementsPrimary = function(statements, scope){
return statements;
};
/* REMPLACE LES VARIABLE SOUS LA FORME "{arrName.itemValName}" par leur référence
*
* @statements<Array> Tableau contenant les parties de la chaine
* @scope<Object> Objet contenant le scope
*
* @return splitVal<Array> Tableau contenant les parties de la chaine (références + chaine)
*
*/
FormBuilder.replaceStatementsArrayValue = function(statements, scope){
/* [1] Initialisation
=========================================================*/
var regex = FormBuilder.regex.arr_out_val;
var match = null;
var matches = [];
var lasti, parts, p, i, key;
/* [2] Pour chaque partie de la chaine
=========================================================*/
for( p = 0 ; p < statements.length ; p++ ){
/* (1) Initialisation */
m = null;
matches = [];
lasti = 0;
parts = [];
/* (2) Tant que ça match, on récupère les infos du match */
while( (match=regex.exec(statements[p])) !== null )
matches.push( match );
/* [3] Pour chaque match
=========================================================*/
for( i = 0 ; i < matches.length ; i++ ){
key = matches[i][1];
/* (1) On met la chaine d'avant le match (si existe) */
if( lasti > 0 || matches[i].index > 0 )
parts.push( statements[p].substr(lasti, matches[i].index-lasti) );
/* (2) Si la var n'est pas dans le scope, on l'initialise vide */
if( !scope.hasOwnProperty(key) )
scope[key] = ''; // on met une chaine vide
/* (3) On insère la valeur du scope */
parts.push( scope[key] );
/* (4) On met à jour l'index de fin pour la suite */
lasti = matches[i].index + matches[i][0].length;
}
/* (5) On ajoute la partie après le match */
if( lasti < statements[p].length )
parts.push( statements[p].substr(lasti, statements[p].length) );
/* [4] on remplace statements[p] par sa décomposition
=========================================================*/
statements = statements.slice(0, p).concat(parts).concat(statements.slice(p+1));
}
/* [5] On retourne la chaine modifiée (ou non)
=========================================================*/
return statements;
};
/* CONSTRUIT UNE CHAINE A PARTIR DE SES PARTIES (VARIABLES OU TEXTE BRUT)
*
* @ref_table<Object> Objet contenant les références

View File

@ -1,4 +1,4 @@
document.body.innerHTML="";"use strict";
var default_definition={input:{node_type:"input"},"/^h([1-6])$/":{node_type:"h{$1}"},br:{node_type:"br"},option:{node_type:"option"},select:{node_type:"select"},span:{node_type:"span"}},custom_definition={"/^input.([a-z]+)$/":{node:"input",attributes:{type:"{$1}","data-name":"{name}",value:"{value}",placeholder:"{placeholder}"},next_nodes:[{node:"br"}]},"custom-select":{node:"span",attributes:{"class":"select-container nobold"},children:[{node:"select",attributes:{"data-name":"{name}"},children:[{node:"option",
var default_definition={input:{node_type:"input"},"/^h([1-6])$/":{node_type:"h{$1}"},br:{node_type:"br"},option:{node_type:"option"},select:{node_type:"select"},span:{node_type:"span"}},custom_definition={"/^input.([a-z]+)$/":{node:"input",attributes:{type:"{$1}","data-name":"{name}",value:"{value}",placeholder:":{placeholder}:"},next_nodes:[{node:"br"}]},"custom-select":{node:"span",attributes:{"class":"select-container nobold"},children:[{node:"select",attributes:{"data-name":"{name}"},children:[{node:"option",
attribute:{value:"{options.value}"},text:"{options.value}",repeat:"{{options}}"}]}],next_nodes:[{node:"br"}]}},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:"xx{countcall} calls + {countsms} sms to {number}xx"},
{node:"input.text",$name:"number",$value:"{number}"},{node:"custom-select",$name:"existing",$$options:"{{options}}"}]},fb=new FormBuilder(form);fb.add_definition(default_definition);fb.add_definition(custom_definition);fb.build({uid:1,call:2,sms:3,countcall:4,countsms:5,number:"01 02 03 04 05",options:["a","b","c","d"]});console.log(fb.built_form);var str=function(a){return FormBuilder.buildString(fb.ref_table,a)};