/* RENVOIE UN WRAPPER POUR UTILISER LES REFERENCES */ function references(data){ return { $: data }; } /* CONSTRUCTEUR -> INITIALISE UNE L'INSTANCE A PARTIR D'UNE DEFINITION * * @object Attributs de l'élément (selon une définition) * @definitions 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; }; /************************************************/ /* ____ _____ _ _____ ___ ____ */ /* / ___|_ _|/ \|_ _|_ _/ ___| */ /* \___ \ | | / _ \ | | | | | */ /* ___) || |/ ___ \| | | | |___ */ /* |____/ |_/_/ \_\_| |___\____| */ /************************************************/