222 lines
7.3 KiB
JavaScript
Executable File
222 lines
7.3 KiB
JavaScript
Executable File
/* RENVOIE UN WRAPPER POUR UTILISER LES REFERENCES */
|
|
function references(data){ return { $: data }; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* CONSTRUCTEUR -> INITIALISE UNE L'INSTANCE A PARTIR D'UNE DEFINITION
|
|
*
|
|
* @object<Object> Attributs de l'élément (selon une définition)
|
|
* @definitions<Object> Définition des éléments
|
|
*
|
|
*/
|
|
var ElementObject = function(object, definitions){
|
|
/* [0] Initialisation
|
|
=========================================================*/
|
|
/* (1) Si on a pas un objet, on quitte */
|
|
if( !(object instanceof Object) )
|
|
return;
|
|
|
|
/* (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;
|
|
|
|
};
|
|
|
|
|
|
/************************************************************************/
|
|
/* _ _____ _____ ____ ___ ____ _ _ _____ _____ ____ */
|
|
/* / \|_ _|_ _| _ \|_ _| __ )| | | |_ _| ____/ ___| */
|
|
/* / _ \ | | | | | |_) || || _ \| | | | | | | _| \___ \ */
|
|
/* / ___ \| | | | | _ < | || |_) | |_| | | | | |___ ___) | */
|
|
/* /_/ \_\_| |_| |_| \_\___|____/ \___/ |_| |_____|____/ */
|
|
/************************************************************************/
|
|
|
|
/* DEFINITION DES ATTRIBUTS
|
|
*
|
|
*/
|
|
ElementObject.prototype = {
|
|
node: this.node, /* Type de noeud (à lier à sa définition) */
|
|
node_type: null, /* Type de noeud (html tag) */
|
|
prev_nodes: [], /* List des éléments précédents */
|
|
next_nodes: [], /* Liste des éléments suivants */
|
|
children: [], /* Liste des éléments enfants */
|
|
attributes: {}, /* Liste des attributs */
|
|
text: null, /* contenu HTML (innerHTML) */
|
|
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éé */
|
|
};
|
|
|
|
/* 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
|
|
};
|
|
|
|
/************************************************************/
|
|
/* __ __ _____ _____ _ _ ___ ____ ____ */
|
|
/* | \/ | ____|_ _| | | |/ _ \| _ \/ ___| */
|
|
/* | |\/| | _| | | | |_| | | | | | | \___ \ */
|
|
/* | | | | |___ | | | _ | |_| | |_| |___) | */
|
|
/* |_| |_|_____| |_| |_| |_|\___/|____/|____/ */
|
|
/************************************************************/
|
|
|
|
/* 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;
|
|
};
|
|
|
|
/************************************************/
|
|
/* ____ _____ _ _____ ___ ____ */
|
|
/* / ___|_ _|/ \|_ _|_ _/ ___| */
|
|
/* \___ \ | | / _ \ | | | | | */
|
|
/* ___) || |/ ___ \| | | | |___ */
|
|
/* |____/ |_/_/ \_\_| |___\____| */
|
|
/************************************************/
|