toolkit/javascript/nco/relations.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 function Relations() {
       
     2 	this.items = {};
       
     3 }
       
     4 
       
     5 Relations.prototype = {
       
     6 	constructor: Relations,
       
     7 	
       
     8 	/**
       
     9 	 * Add an element to the dictionnary under the given name.
       
    10 	 * 
       
    11 	 * @param {String} id: identifier for the item
       
    12 	 * @param {Object} element: item to register
       
    13 	 * 
       
    14 	 * @returns {Connector}: inserted element wrapped with a Connector
       
    15 	 */
       
    16 	add: function(id, element) {
       
    17 		return this.items[id] = new Connector(element, id, this);
       
    18 	},
       
    19 	
       
    20 	remove: function(id) {
       
    21 		
       
    22 	},
       
    23 	
       
    24 	/**
       
    25 	 * Gets the wanted item
       
    26 	 * 
       
    27 	 * @param {String} id: item name
       
    28 	 * 
       
    29 	 * @returns {Connector}: the wanted item, wrapped in a selector
       
    30 	 */
       
    31 	get: function(id) {
       
    32 		return this.items[id];
       
    33 	},
       
    34 	
       
    35 	/**
       
    36 	 * Executes all the registered actions for a given element and a given event.
       
    37 	 * 
       
    38 	 * First, if the required item is frozen, nothing is executed.
       
    39 	 * Then, it checks every observer to see if they are locked, otherwise, their 
       
    40 	 * action is performed.
       
    41 	 *  
       
    42 	 * @param {String} id: id of the element activated
       
    43 	 * @param {String} event: name of the event activated
       
    44 	 * @param eventParameters: parameters passed by the event raised
       
    45 	 * 
       
    46 	 * @returns: null
       
    47 	 */
       
    48 	execute: function(id, event, eventParameters) {
       
    49 		var item = this.get(id);
       
    50 		if (!item.isFrozen()) {
       
    51 			var functions = item.listenedEvents[event];
       
    52 			for(var i =0; i<functions.length; ++i) {
       
    53 				var observer = this.get(functions[i][0]);
       
    54 				if (!observer.isLocked()) {
       
    55 					functions[i][1](observer.element, eventParameters);
       
    56 				}
       
    57 			}
       
    58 		}
       
    59 	},
       
    60 	
       
    61 	/**
       
    62 	 * Executes an action on each selected item
       
    63 	 * 
       
    64 	 * The selection is made through an selector string or directly a regular
       
    65 	 * expression. Then, on each selected item, the given action is performed
       
    66 	 * passed the item as this in the action.
       
    67 	 * 
       
    68 	 * @param {String/RegExp} selector: selection test to get items
       
    69 	 * @param {Function} action: action to perform
       
    70 	 * @param {Boolean} getDetails: retrieve all information captured 
       
    71 	 * 	by special expressions
       
    72 	 * 
       
    73 	 * @returns: {Integer} nombre d'éléments trouvés par la recherche
       
    74 	 */
       
    75 	each: function(selector, action, getDetails) {
       
    76 		if (undefined==getDetails) {
       
    77 			getDetails = false;
       
    78 		}
       
    79 		
       
    80 		var expr = this.buildExpression(selector, getDetails);
       
    81 		var compteur = 0;
       
    82 		if (false==getDetails) {
       
    83 			for (var itemName in this.items) {
       
    84 				if (expr.test(itemName)) {
       
    85 					action.call(this.items[itemName], this.items[itemName].element);
       
    86 					++compteur;
       
    87 				}
       
    88 			}
       
    89 		}
       
    90 		else {
       
    91 			var details = null;
       
    92 			for (var itemName in this.items) {
       
    93 				details = itemName.match(expr);
       
    94 				if (null!=details) {
       
    95 					action.call(this.items[itemName], this.items[itemName].element, details);
       
    96 					++compteur;
       
    97 				}
       
    98 			}
       
    99 		}
       
   100 		
       
   101 		return compteur;
       
   102 	},
       
   103 	
       
   104 	/**
       
   105 	 * Build a selector from a string
       
   106 	 * 
       
   107 	 * If a string is passed, it is turned as a RegExp.
       
   108 	 * If an RegExp instance is passed, it is returned directly.
       
   109 	 * 
       
   110 	 * @param string selector: string to turn as selector
       
   111 	 * @param RegExp selector: regular expression to use
       
   112 	 * 
       
   113 	 * @returns {RegExp}: selector
       
   114 	 */
       
   115 	buildExpression: function(selector, getDetails) {
       
   116 		if (RegExp==selector) {
       
   117 			return selector;
       
   118 		}
       
   119 		
       
   120 		var expression = selector;
       
   121 		expression = expression.replace(/(\(|\))/g, "\\$1");
       
   122 		
       
   123 		if (false==getDetails) {
       
   124 			expression = expression.replace(/\[\[digit\]\]/g, "[0-9]+");
       
   125 			expression = expression.replace(/\[\[letter\]\]/g, "[a-zA-Z]+");
       
   126 			expression = expression.replace(/\./g, "\\.");
       
   127 			expression = expression.replace(/\?/g, ".");
       
   128 			expression = expression.replace(/\*/g, ".+");
       
   129 		}
       
   130 		else {
       
   131 			expression = expression.replace(/\[\[digit\]\]/g, "([0-9]+)");
       
   132 			expression = expression.replace(/\[\[letter\]\]/g, "([a-zA-Z]+)");
       
   133 			expression = expression.replace(/\./g, "\\.");
       
   134 			expression = expression.replace(/\?/g, "(.)");
       
   135 			expression = expression.replace(/\*/g, "(.+)");
       
   136 		}
       
   137 		
       
   138 		return RegExp("^" + expression + "$");
       
   139 	}
       
   140 };
       
   141 
       
   142 function Connector(object, id, manager) {
       
   143 	this.manager = manager;
       
   144 	this.element = object;
       
   145 	this.id = id;
       
   146 	this.listenedEvents = {};
       
   147 	this.locked = false;
       
   148 	this.frozen = false;
       
   149 }
       
   150 
       
   151 Connector.prototype = {
       
   152 	constructor: Connector,
       
   153 	
       
   154 	object: function() { return this.element; },
       
   155 	
       
   156 	bind: function(event, id, action) {
       
   157 		if (undefined==action) {
       
   158 			this.bind(event, this.id, id);
       
   159 		}
       
   160 		else {
       
   161 			if (undefined!=this.listenedEvents[event]) {
       
   162 				this.listenedEvents[event].push([id, action]);
       
   163 			}
       
   164 			else {
       
   165 				var object = this;
       
   166 				this.listenedEvents[event] = [[id, action]];
       
   167 				this.element.on(event, function() {
       
   168 					object.manager.execute(object.id, event, arguments);
       
   169 				}) ;
       
   170 			}
       
   171 		}
       
   172 		
       
   173 		return this;
       
   174 	},
       
   175 	
       
   176 	bindTo: function(event, id, action) {
       
   177 		this.manager.get(id).bind(event, this.id, action);
       
   178 		
       
   179 		return this;
       
   180 	},
       
   181 	
       
   182 	unbind: function(id, event) {
       
   183 		return this;
       
   184 	},
       
   185 	
       
   186 	click: function(id, action) {
       
   187 		return this.bind("click", id, action);
       
   188 	},
       
   189 	
       
   190 	dblclick: function(id, action) {
       
   191 		return this.bind("dblclick", id, action);
       
   192 	},
       
   193 	
       
   194 	mouseover: function(id, action) {
       
   195 		return this.bind("mouseover", id, action);
       
   196 	},
       
   197 	
       
   198 	mouseout: function(id, action) {
       
   199 		return this.bind("mouseout", id, action);
       
   200 	},
       
   201 	
       
   202 	lock: function() {	this.locked = true;	},
       
   203 	
       
   204 	unlock: function() {	this.locked = false;	},
       
   205 	
       
   206 	isLocked: function() {	return true==this.locked; },
       
   207 	
       
   208 	freeze: function() {	this.frozen = true;	},
       
   209 	
       
   210 	unfreeze: function() {	this.frozen = false;	},
       
   211 	
       
   212 	isFrozen: function() {	return true==this.frozen; }
       
   213 };