0eecaced309711cf67cedc5b42cc28fa1198f625
[Plinn.git] / skins / ajax_scripts / javascript_events_api.js
1 // (c) Benoît PIN 2006-2009
2 // http://plinn.org
3 // Licence GPL
4 // $Id: javascript_events_api.js 1532 2009-08-13 14:18:16Z pin $
5 // $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/skins/ajax_scripts/javascript_events_api.js $
6 // Meta functions for events management.
7
8 var addListener; /* (ob, eventName, listenerFunction, group) add event listener eventName without "on" prefix.
9 * optionally, listeners can be grouped to make removing convenient.
10 */
11 var removeListener; // (ob, eventName, listenerFunction, group) remove event listener.
12 var removeGroupListeners; // (group) remove all listeners in group.
13 var raiseMouseEvent; // (ob, eventName) raise mouse event (without "on" prefix) on object.
14
15 var getTargetedObject; // (event) retrieves the object that fired the event. Event parameter is optional.
16 var getEventObject; // (event) return the event object. Event parameter is optional.
17 var disableDefault; // (event) disable default event's action. Event parameter is optional.
18 var disablePropagation; // (event) disable event propagation or bubbling.
19
20 // etc utils
21 var getWindowWidth; // returns browser's window width
22 var getWindowHeight; // returns browser's window height
23 var clearSelection; // clear current selection (useful on drag and drop)
24 var getCopyOfNode; /* (node) returns a clone of the given node.
25 * Useful when :
26 * the node came from a foreign document (eg. XmlHttpRequest xml reponse)
27 * to inject HMTL code inside tags where innerHtml is read only (IE)
28 */
29
30 (function(){
31
32 function buildMetaFunctions() {
33 addListener = _build_addListener();
34 removeListener = _build_removeListener();
35 raiseMouseEvent = _build_raiseMouseEvent();
36
37 getTargetedObject = _build_getTargetedObject();
38 getEventObject = _build_getEventObject();
39 disableDefault = _build_disableDefault();
40 disablePropagation = _build_disablePropagation();
41 getWindowWidth = _build_getWindowWidth();
42 getWindowHeight = _build_getWindowHeight();
43 clearSelection = _build_clearSelection();
44 }
45
46 __groupListeners = {};
47
48 function _build_addListener() {
49 var _browserSpecific;
50 if (browser.isIE55 || browser.isIE6up) {
51 _browserSpecific = function(ob, eventName, listenerFunction) {
52 eventName = "on" + eventName;
53 ob.attachEvent(eventName, listenerFunction);
54 };
55 }
56 else if (browser.isDOM2Event) {
57 _browserSpecific = function(ob, eventName, listenerFunction) {
58 ob.addEventListener(eventName, listenerFunction, false); // only bubbling events :-(
59 };
60 }
61 var common = function(ob, eventName, listenerFunction, group) {
62 _browserSpecific(ob, eventName, listenerFunction);
63 if (group) {
64 if(!__groupListeners[group])
65 __groupListeners[group] = new Array();
66 __groupListeners[group].push([ob, eventName, listenerFunction]);
67 }
68 }
69 return common;
70 }
71
72 function _build_removeListener() {
73 if (browser.isIE55 || browser.isIE6up) {
74 var _ie_removeListener = function(ob, eventName, listenerFunction) {
75 eventName = "on" + eventName;
76 ob.detachEvent(eventName, listenerFunction);
77 }
78 return _ie_removeListener;
79 }
80 else if (browser.isDOM2Event) {
81 var _dom2_removeListener = function(ob, eventName, listenerFunction) {
82 ob.removeEventListener(eventName, listenerFunction, false); // only bubbling events :-(
83 }
84 return _dom2_removeListener;
85 }
86 }
87
88 removeGroupListeners = function(group) {
89 var listeners = __groupListeners[group];
90 var l;
91 for (var i=0 ; i<listeners.length ; i++){
92 l = listeners[i];
93 removeListener(l[0], l[1], l[2])
94 }
95 __groupListeners[group] = null;
96
97 }
98
99 function _build_raiseMouseEvent() {
100 if (browser.isIE55 || browser.isIE6up) {
101 var _ie_raiseMouseEvent = function(ob, eventName) {
102 ob.fireEvent("on" + eventName);
103 }
104 return _ie_raiseMouseEvent;
105 }
106 else if (browser.isDOM2Event) {
107 var _dom2_raiseMouseEvent = function(ob, eventName) {
108 var event = document.createEvent("MouseEvents");
109 event.initEvent(eventName, true, true);
110 ob.dispatchEvent(event);
111 }
112 return _dom2_raiseMouseEvent;
113 }
114 }
115
116 function _build_getTargetedObject(){
117 if (browser.isIE55 || browser.isIE6up) {
118 var _ie_getTargetedObject = function() {
119 return window.event.srcElement;
120 }
121 return _ie_getTargetedObject;
122 }
123 else if (browser.isDOM2Event) {
124 var _appleWebKit_getTargetedeObject = function(evt) {
125 var target = evt.target;
126 // is it really safe ?...
127 return (target.nodeType == 3) ? target.parentNode : target;
128 }
129 var _dom2_getTargetedObject = function(evt) {
130 return evt.target
131 }
132 return (browser.isAppleWebKit) ? _appleWebKit_getTargetedeObject : _dom2_getTargetedObject;
133 }
134 }
135
136 function _build_getEventObject(){
137 if (browser.isIE) {
138 var _ie_getEventObject = function() {
139 return window.event;
140 }
141 return _ie_getEventObject;
142 }
143 else if (browser.isDOM2Event) {
144 var _dom2_getEventObject = function(evt) {
145 return evt;
146 }
147 return _dom2_getEventObject;
148 }
149 }
150
151
152 function _build_disableDefault(){
153 if (browser.isIE55 || browser.isIE6up) {
154 var _ie_disableDefault = function() {
155 window.event.returnValue = false;
156 }
157 return _ie_disableDefault;
158 }
159 else if (browser.isDOM2Event) {
160 var _dom2_disableDefault = function(evt) {
161 evt.preventDefault();
162 }
163 return _dom2_disableDefault;
164 }
165 }
166
167 function _build_disablePropagation() {
168 if (browser.isIE55 || browser.isIE6up) {
169 var _ie_disablePropagation = function() {
170 window.event.cancelBubble = true;
171 }
172 return _ie_disablePropagation;
173 }
174 else if (browser.isDOM2Event) {
175 var _dom2_disablePropagation = function(evt) {
176 evt.stopPropagation();
177 }
178 return _dom2_disablePropagation;
179 }
180 }
181
182 function _build_getWindowWidth() {
183 if (window.innerWidth != undefined){
184 return function(){
185 return window.innerWidth;
186 };
187 }
188 else {
189 return function(){
190 return document.documentElement.clientWidth;
191 };
192 }
193 }
194
195 function _build_getWindowHeight() {
196 if (window.innerHeight != undefined) {
197 return function(){
198 return window.innerHeight;
199 };
200 }
201 else {
202 return function(){
203 return document.documentElement.clientHeight;
204 };
205 }
206 }
207
208 function _build_clearSelection() {
209 if (document.selection) {
210 return function() {
211 document.selection.clear();
212 };
213 }
214 else {
215 return function() {
216 window.getSelection().removeAllRanges();
217 }
218 }
219 }
220
221
222 buildMetaFunctions();
223
224 var ELEMENT_NODE = 1;
225 var TEXT_NODE = 3;
226 var _setAttribute;
227 getCopyOfNode = function(node) {
228
229 switch(node.nodeType) {
230 case ELEMENT_NODE:
231 var attributes = node.attributes;
232 var childs = node.childNodes;
233
234 var e = document.createElement(node.nodeName);
235
236 var attribute;
237 for(var i=0 ; i<attributes.length ; i++) {
238 attribute = attributes[i];
239 _setAttribute(e, attribute.name, attribute.value);
240 }
241
242 for(var i=0 ; i<childs.length ; i++)
243 e.appendChild(getCopyOfNode(childs[i]));
244
245 return e;
246 break;
247 case TEXT_NODE:
248 return document.createTextNode(node.nodeValue);
249 break;
250 }
251 }
252
253 if (browser.isIE) {
254 _setAttribute = function(e, name, value) {
255 // workarround IE lack of dom implementation.
256 switch(name.toLowerCase()) {
257 case 'colspan' :
258 e.colSpan = value;
259 break;
260 case 'class' :
261 e.className = value;
262 break;
263 case 'style' :
264 var cssText = value;
265 loadCssText(e, value);
266 break;
267 default:
268 if (name.slice(0,2) == 'on') // event handler
269 e[name] = function(){eval(value);};
270 else
271 e.setAttribute(name, value);
272 }
273 };
274 var reCompoundPropName = /^\s*([^\-]+)\-([a-z])([a-z]+)\s*$/;
275 function _capitalizeCssPropName(s, g1, g2, g3) { // gN args match above regexp groups
276 if(g2)
277 return g1 + g2.toUpperCase() + g3;
278 else
279 return s;
280 }
281
282 function loadCssText(e, cssText) {
283 var pairs = cssText.split(';');
284 var pair, name, value;
285 var style = e.style;
286 for (var i= 0; i < pairs.length; i++) {
287 pair = pairs[i].split(':');
288 if (pair.length != 2)
289 continue;
290 name = _capitalizeCssPropName(pair[0]);
291 value = pair[1];
292 style[name] = value;
293 }
294 }
295 }
296 else {
297 _setAttribute = function(e, name, value) {e.setAttribute(name, value);};
298 }
299
300 })();