NxTIC/public_html/js/lib/element-object.js

222 lines
7.3 KiB
JavaScript

/* 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;
};
/************************************************/
/* ____ _____ _ _____ ___ ____ */
/* / ___|_ _|/ \|_ _|_ _/ ___| */
/* \___ \ | | / _ \ | | | | | */
/* ___) || |/ ___ \| | | | |___ */
/* |____/ |_/_/ \_\_| |___\____| */
/************************************************/