1 | /* |
---|
2 | * Envjs event.1.3.pre03 |
---|
3 | * Pure JavaScript Browser Environment |
---|
4 | * By John Resig <http://ejohn.org/> and the Envjs Team |
---|
5 | * Copyright 2008-2010 John Resig, under the MIT License |
---|
6 | * |
---|
7 | * This file simply provides the global definitions we need to |
---|
8 | * be able to correctly implement to core browser DOM Event interfaces. |
---|
9 | |
---|
10 | - leaked globally - |
---|
11 | |
---|
12 | var Event, |
---|
13 | MouseEvent, |
---|
14 | UIEvent, |
---|
15 | KeyboardEvent, |
---|
16 | MutationEvent, |
---|
17 | DocumentEvent, |
---|
18 | EventTarget, |
---|
19 | EventException; |
---|
20 | |
---|
21 | */ |
---|
22 | |
---|
23 | var Envjs = Envjs || require('./platform/core').Envjs, |
---|
24 | After = After || require('./platform/core').After, |
---|
25 | Document = Document || require('./dom').Document; |
---|
26 | /* |
---|
27 | * Envjs event.1.3.pre03 |
---|
28 | * Pure JavaScript Browser Environment |
---|
29 | * By John Resig <http://ejohn.org/> and the Envjs Team |
---|
30 | * Copyright 2008-2010 John Resig, under the MIT License |
---|
31 | */ |
---|
32 | |
---|
33 | //CLOSURE_START |
---|
34 | (function(){ |
---|
35 | |
---|
36 | |
---|
37 | |
---|
38 | |
---|
39 | |
---|
40 | /** |
---|
41 | * @author john resig |
---|
42 | */ |
---|
43 | // Helper method for extending one object with another. |
---|
44 | function __extend__(a,b) { |
---|
45 | for ( var i in b ) { |
---|
46 | if(b.hasOwnProperty(i)){ |
---|
47 | var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); |
---|
48 | if ( g || s ) { |
---|
49 | if ( g ) { a.__defineGetter__(i, g); } |
---|
50 | if ( s ) { a.__defineSetter__(i, s); } |
---|
51 | } else { |
---|
52 | a[i] = b[i]; |
---|
53 | } |
---|
54 | } |
---|
55 | } |
---|
56 | return a; |
---|
57 | } |
---|
58 | |
---|
59 | /** |
---|
60 | * @author john resig |
---|
61 | */ |
---|
62 | //from jQuery |
---|
63 | function __setArray__( target, array ) { |
---|
64 | // Resetting the length to 0, then using the native Array push |
---|
65 | // is a super-fast way to populate an object with array-like properties |
---|
66 | target.length = 0; |
---|
67 | Array.prototype.push.apply( target, array ); |
---|
68 | } |
---|
69 | var __addEventListener__, |
---|
70 | __removeEventListener__, |
---|
71 | __dispatchEvent__, |
---|
72 | __captureEvent__, |
---|
73 | __bubbleEvent__; |
---|
74 | |
---|
75 | (function(){ |
---|
76 | |
---|
77 | var log = Envjs.logger(); |
---|
78 | |
---|
79 | Envjs.once('tick', function(){ |
---|
80 | log = Envjs.logger('Envjs.DOM.EventTarget').debug('available'); |
---|
81 | }); |
---|
82 | |
---|
83 | /** |
---|
84 | * @name EventTarget |
---|
85 | * @w3c:domlevel 2 |
---|
86 | * @uri -//TODO: paste dom event level 2 w3c spc uri here |
---|
87 | */ |
---|
88 | exports.EventTarget = EventTarget = function(){}; |
---|
89 | EventTarget.prototype.addEventListener = function(type, fn, phase){ |
---|
90 | __addEventListener__(this, type, fn, phase); |
---|
91 | }; |
---|
92 | EventTarget.prototype.removeEventListener = function(type, fn, phase){ |
---|
93 | __removeEventListener__(this, type, fn, phase); |
---|
94 | }; |
---|
95 | EventTarget.prototype.dispatchEvent = function(event, bubbles){ |
---|
96 | __dispatchEvent__(this, event, bubbles); |
---|
97 | }; |
---|
98 | |
---|
99 | __extend__(Node.prototype, EventTarget.prototype); |
---|
100 | |
---|
101 | var $events = [{}]; |
---|
102 | |
---|
103 | __addEventListener__ = function(target, type, fn, phase){ |
---|
104 | phase = !!phase?"CAPTURING":"BUBBLING"; |
---|
105 | if ( !target.uuid ) { |
---|
106 | target.uuid = $events.length+''; |
---|
107 | log.debug('add event uuid for %s %s', target, target.uuid); |
---|
108 | } |
---|
109 | if ( !$events[target.uuid] ) { |
---|
110 | log.debug('creating listener for target: %s %s', target, target.uuid); |
---|
111 | $events[target.uuid] = {}; |
---|
112 | } |
---|
113 | if ( !$events[target.uuid][type] ){ |
---|
114 | log.debug('creating listener for type: %s %s %s', target, target.uuid, type); |
---|
115 | $events[target.uuid][type] = { |
---|
116 | CAPTURING:[], |
---|
117 | BUBBLING:[] |
---|
118 | }; |
---|
119 | } |
---|
120 | if ( $events[target.uuid][type][phase].indexOf( fn ) < 0 ){ |
---|
121 | log.debug( 'adding event listener %s %s %s %s', target, target.uuid, type, phase); |
---|
122 | $events[target.uuid][type][phase].push( fn ); |
---|
123 | } |
---|
124 | log.debug('registered event listeners %s', $events.length); |
---|
125 | }; |
---|
126 | |
---|
127 | __removeEventListener__ = function(target, type, fn, phase){ |
---|
128 | phase = !!phase?"CAPTURING":"BUBBLING"; |
---|
129 | if ( !target.uuid ) { |
---|
130 | log.debug('target has never had registered events %s', target); |
---|
131 | return; |
---|
132 | } |
---|
133 | if ( !$events[target.uuid] ) { |
---|
134 | log.debug('target has no registered events to remove %s %s', target, target.uuid); |
---|
135 | return; |
---|
136 | } |
---|
137 | if(type == '*'){ |
---|
138 | //used to clean all event listeners for a given node |
---|
139 | log.debug('cleaning all event listeners for node %s %s',target, target.uuid); |
---|
140 | delete $events[target.uuid]; |
---|
141 | return; |
---|
142 | }else if ( !$events[target.uuid][type] ){ |
---|
143 | log.debug('target has no registered events of type %s to remove %s %s', type, target, target.uuid); |
---|
144 | return; |
---|
145 | } |
---|
146 | $events[target.uuid][type][phase] = |
---|
147 | $events[target.uuid][type][phase].filter(function(f){ |
---|
148 | log.debug('removing event listener %s %s %s %s', target, type, phase ); |
---|
149 | return f != fn; |
---|
150 | }); |
---|
151 | }; |
---|
152 | |
---|
153 | var __eventuuid__ = 0; |
---|
154 | |
---|
155 | __dispatchEvent__ = function(target, event, bubbles){ |
---|
156 | |
---|
157 | if (!event.uuid) { |
---|
158 | event.uuid = __eventuuid__++; |
---|
159 | } |
---|
160 | //the window scope defines the $event object, for IE(^^^) compatibility; |
---|
161 | //$event = event; |
---|
162 | |
---|
163 | if (bubbles === undefined || bubbles === null) { |
---|
164 | bubbles = true; |
---|
165 | } |
---|
166 | |
---|
167 | if (!event.target) { |
---|
168 | event.target = target; |
---|
169 | } |
---|
170 | |
---|
171 | log.debug('dispatching %s %s %s %s', event.uuid, target, event.type, bubbles); |
---|
172 | if ( event.type && (target.nodeType || target === window )) { |
---|
173 | |
---|
174 | __captureEvent__(target, event); |
---|
175 | |
---|
176 | event.eventPhase = Event.AT_TARGET; |
---|
177 | if ( target.uuid && $events[target.uuid] && $events[target.uuid][event.type] ) { |
---|
178 | event.currentTarget = target; |
---|
179 | |
---|
180 | log.debug('begin dispatching capturing phase %s %s', target, event.type); |
---|
181 | $events[target.uuid][event.type].CAPTURING.forEach(function(fn){ |
---|
182 | log.debug('capturing event %s', target); |
---|
183 | var returnValue = fn.apply(target, [event]); |
---|
184 | if(returnValue === false){ |
---|
185 | event.stopPropagation(); |
---|
186 | } |
---|
187 | }); |
---|
188 | |
---|
189 | log.debug('begin dispatching bubbling phase %s %s', target, event.type); |
---|
190 | $events[target.uuid][event.type].BUBBLING.forEach(function(fn){ |
---|
191 | log.debug('bubbling event %s', target); |
---|
192 | var returnValue = fn.apply(target, [event] ); |
---|
193 | if(returnValue === false){ |
---|
194 | event.stopPropagation(); |
---|
195 | } |
---|
196 | }); |
---|
197 | } |
---|
198 | if (target["on" + event.type]) { |
---|
199 | target["on" + event.type](event); |
---|
200 | } |
---|
201 | if (bubbles && !event.cancelled){ |
---|
202 | __bubbleEvent__(target, event); |
---|
203 | } |
---|
204 | if(!event._preventDefault){ |
---|
205 | //At this point I'm guessing that just HTMLEvents are concerned |
---|
206 | //with default behavior being executed in a browser but I could be |
---|
207 | //wrong as usual. The goal is much more to filter at this point |
---|
208 | //what events have no need to be handled |
---|
209 | //console.log('triggering default behavior for %s', event.type); |
---|
210 | if(event.type in Envjs.defaultEventBehaviors){ |
---|
211 | Envjs.defaultEventBehaviors[event.type](event); |
---|
212 | } |
---|
213 | } |
---|
214 | log.debug('deleting event %s', event.uuid); |
---|
215 | event.target = null; |
---|
216 | event = null; |
---|
217 | }else{ |
---|
218 | throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR); |
---|
219 | } |
---|
220 | }; |
---|
221 | |
---|
222 | __captureEvent__ = function(target, event){ |
---|
223 | var ancestorStack = [], |
---|
224 | parent = target.parentNode, |
---|
225 | stopevent = function(fn){ |
---|
226 | var returnValue = fn( event ); |
---|
227 | if(returnValue === false){ |
---|
228 | event.stopPropagation(); |
---|
229 | } |
---|
230 | }; |
---|
231 | |
---|
232 | event.eventPhase = Event.CAPTURING_PHASE; |
---|
233 | while(parent){ |
---|
234 | if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type]){ |
---|
235 | ancestorStack.push(parent); |
---|
236 | } |
---|
237 | parent = parent.parentNode; |
---|
238 | } |
---|
239 | while(ancestorStack.length && !event.cancelled){ |
---|
240 | event.currentTarget = ancestorStack.pop(); |
---|
241 | if($events[event.currentTarget.uuid] && $events[event.currentTarget.uuid][event.type]){ |
---|
242 | $events[event.currentTarget.uuid][event.type].CAPTURING.forEach(stopevent); |
---|
243 | } |
---|
244 | } |
---|
245 | }; |
---|
246 | |
---|
247 | __bubbleEvent__ = function(target, event){ |
---|
248 | var parent = target.parentNode, |
---|
249 | stopevent = function(fn){ |
---|
250 | var returnValue = fn( event ); |
---|
251 | if(returnValue === false){ |
---|
252 | event.stopPropagation(); |
---|
253 | } |
---|
254 | }; |
---|
255 | event.eventPhase = Event.BUBBLING_PHASE; |
---|
256 | while(parent){ |
---|
257 | if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type] ){ |
---|
258 | event.currentTarget = parent; |
---|
259 | $events[event.currentTarget.uuid][event.type].BUBBLING.forEach(stopevent); |
---|
260 | } |
---|
261 | parent = parent.parentNode; |
---|
262 | } |
---|
263 | }; |
---|
264 | |
---|
265 | }(/*Envjs.DOM2.EventTarget*/)); |
---|
266 | |
---|
267 | |
---|
268 | |
---|
269 | |
---|
270 | (function(){ |
---|
271 | |
---|
272 | var log = Envjs.logger(); |
---|
273 | |
---|
274 | Envjs.once('tick', function(){ |
---|
275 | log = Envjs.logger('Envjs.DOM.Event').debug('available'); |
---|
276 | }); |
---|
277 | |
---|
278 | /** |
---|
279 | * @class Event |
---|
280 | */ |
---|
281 | exports.Event = Event = function(options){ |
---|
282 | // event state is kept read-only by forcing |
---|
283 | // a new object for each event. This may not |
---|
284 | // be appropriate in the long run and we'll |
---|
285 | // have to decide if we simply dont adhere to |
---|
286 | // the read-only restriction of the specification |
---|
287 | this._bubbles = true; |
---|
288 | this._cancelable = true; |
---|
289 | this._cancelled = false; |
---|
290 | this._currentTarget = null; |
---|
291 | this._target = null; |
---|
292 | this._eventPhase = Event.AT_TARGET; |
---|
293 | this._timeStamp = new Date().getTime(); |
---|
294 | this._preventDefault = false; |
---|
295 | this._stopPropogation = false; |
---|
296 | }; |
---|
297 | |
---|
298 | __extend__(Event.prototype,{ |
---|
299 | get bubbles(){return this._bubbles;}, |
---|
300 | get cancelable(){return this._cancelable;}, |
---|
301 | get currentTarget(){return this._currentTarget;}, |
---|
302 | set currentTarget(currentTarget){ this._currentTarget = currentTarget; }, |
---|
303 | get eventPhase(){return this._eventPhase;}, |
---|
304 | set eventPhase(eventPhase){this._eventPhase = eventPhase;}, |
---|
305 | get target(){return this._target;}, |
---|
306 | set target(target){ this._target = target;}, |
---|
307 | get timeStamp(){return this._timeStamp;}, |
---|
308 | get type(){return this._type;}, |
---|
309 | initEvent: function(type, bubbles, cancelable){ |
---|
310 | this._type=type?type:''; |
---|
311 | this._bubbles=!!bubbles; |
---|
312 | this._cancelable=!!cancelable; |
---|
313 | }, |
---|
314 | preventDefault: function(){ |
---|
315 | this._preventDefault = true; |
---|
316 | }, |
---|
317 | stopPropagation: function(){ |
---|
318 | if(this._cancelable){ |
---|
319 | this._cancelled = true; |
---|
320 | this._bubbles = false; |
---|
321 | } |
---|
322 | }, |
---|
323 | get cancelled(){ |
---|
324 | return this._cancelled; |
---|
325 | }, |
---|
326 | toString: function(){ |
---|
327 | return '[object Event]'; |
---|
328 | } |
---|
329 | }); |
---|
330 | |
---|
331 | __extend__(Event,{ |
---|
332 | CAPTURING_PHASE : 1, |
---|
333 | AT_TARGET : 2, |
---|
334 | BUBBLING_PHASE : 3 |
---|
335 | }); |
---|
336 | |
---|
337 | }(/*Envjs.DOM.Event*/)); |
---|
338 | |
---|
339 | |
---|
340 | |
---|
341 | (function(){ |
---|
342 | |
---|
343 | var log = Envjs.logger(); |
---|
344 | |
---|
345 | Envjs.once('tick', function(){ |
---|
346 | log = Envjs.logger('Envjs.DOM.UIEvent').debug('available'); |
---|
347 | }); |
---|
348 | |
---|
349 | /** |
---|
350 | * @name UIEvent |
---|
351 | * @param {Object} options |
---|
352 | */ |
---|
353 | exports.UIEvent = UIEvent = function(options) { |
---|
354 | this._view = null; |
---|
355 | this._detail = 0; |
---|
356 | }; |
---|
357 | |
---|
358 | UIEvent.prototype = new Event(); |
---|
359 | __extend__(UIEvent.prototype,{ |
---|
360 | get view(){ |
---|
361 | return this._view; |
---|
362 | }, |
---|
363 | get detail(){ |
---|
364 | return this._detail; |
---|
365 | }, |
---|
366 | initUIEvent: function(type, bubbles, cancelable, windowObject, detail){ |
---|
367 | this.initEvent(type, bubbles, cancelable); |
---|
368 | this._detail = 0; |
---|
369 | this._view = windowObject; |
---|
370 | } |
---|
371 | }); |
---|
372 | |
---|
373 | }(/*Envjs.DOM.UIEvent*/)); |
---|
374 | |
---|
375 | (function(){ |
---|
376 | |
---|
377 | var log = Envjs.logger(); |
---|
378 | |
---|
379 | Envjs.once('tick', function(){ |
---|
380 | log = Envjs.logger('Envjs.DOM.MouseEvent').debug('available'); |
---|
381 | }); |
---|
382 | |
---|
383 | /** |
---|
384 | * @name MouseEvent |
---|
385 | * @w3c:domlevel 2 |
---|
386 | * @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html |
---|
387 | */ |
---|
388 | exports.MouseEvent = MouseEvent = function(options) { |
---|
389 | this._screenX= 0; |
---|
390 | this._screenY= 0; |
---|
391 | this._clientX= 0; |
---|
392 | this._clientY= 0; |
---|
393 | this._ctrlKey= false; |
---|
394 | this._metaKey= false; |
---|
395 | this._altKey= false; |
---|
396 | this._button= null; |
---|
397 | this._relatedTarget= null; |
---|
398 | }; |
---|
399 | MouseEvent.prototype = new UIEvent(); |
---|
400 | __extend__(MouseEvent.prototype,{ |
---|
401 | get screenX(){ |
---|
402 | return this._screenX; |
---|
403 | }, |
---|
404 | get screenY(){ |
---|
405 | return this._screenY; |
---|
406 | }, |
---|
407 | get clientX(){ |
---|
408 | return this._clientX; |
---|
409 | }, |
---|
410 | get clientY(){ |
---|
411 | return this._clientY; |
---|
412 | }, |
---|
413 | get ctrlKey(){ |
---|
414 | return this._ctrlKey; |
---|
415 | }, |
---|
416 | get altKey(){ |
---|
417 | return this._altKey; |
---|
418 | }, |
---|
419 | get shiftKey(){ |
---|
420 | return this._shiftKey; |
---|
421 | }, |
---|
422 | get metaKey(){ |
---|
423 | return this._metaKey; |
---|
424 | }, |
---|
425 | get button(){ |
---|
426 | return this._button; |
---|
427 | }, |
---|
428 | get relatedTarget(){ |
---|
429 | return this._relatedTarget; |
---|
430 | }, |
---|
431 | initMouseEvent: function(type, bubbles, cancelable, windowObject, detail, |
---|
432 | screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, |
---|
433 | metaKey, button, relatedTarget){ |
---|
434 | this.initUIEvent(type, bubbles, cancelable, windowObject, detail); |
---|
435 | this._screenX = screenX; |
---|
436 | this._screenY = screenY; |
---|
437 | this._clientX = clientX; |
---|
438 | this._clientY = clientY; |
---|
439 | this._ctrlKey = ctrlKey; |
---|
440 | this._altKey = altKey; |
---|
441 | this._shiftKey = shiftKey; |
---|
442 | this._metaKey = metaKey; |
---|
443 | this._button = button; |
---|
444 | this._relatedTarget = relatedTarget; |
---|
445 | } |
---|
446 | }); |
---|
447 | |
---|
448 | }(/*Envjs.DOM2.MouseEvent*/)); |
---|
449 | |
---|
450 | (function(){ |
---|
451 | |
---|
452 | var log = Envjs.logger(); |
---|
453 | |
---|
454 | Envjs.once('tick', function(){ |
---|
455 | log = Envjs.logger('Envjs.DOM.KeyboardEvent'). |
---|
456 | debug('KeyboardEvent available'); |
---|
457 | }); |
---|
458 | |
---|
459 | /** |
---|
460 | * Interface KeyboardEvent (introduced in DOM Level 3) |
---|
461 | */ |
---|
462 | exports.KeyboardEvent = KeyboardEvent = function(options) { |
---|
463 | this._keyIdentifier = 0; |
---|
464 | this._keyLocation = 0; |
---|
465 | this._ctrlKey = false; |
---|
466 | this._metaKey = false; |
---|
467 | this._altKey = false; |
---|
468 | this._metaKey = false; |
---|
469 | }; |
---|
470 | KeyboardEvent.prototype = new UIEvent(); |
---|
471 | |
---|
472 | __extend__(KeyboardEvent.prototype,{ |
---|
473 | |
---|
474 | get ctrlKey(){ |
---|
475 | return this._ctrlKey; |
---|
476 | }, |
---|
477 | get altKey(){ |
---|
478 | return this._altKey; |
---|
479 | }, |
---|
480 | get shiftKey(){ |
---|
481 | return this._shiftKey; |
---|
482 | }, |
---|
483 | get metaKey(){ |
---|
484 | return this._metaKey; |
---|
485 | }, |
---|
486 | get button(){ |
---|
487 | return this._button; |
---|
488 | }, |
---|
489 | get relatedTarget(){ |
---|
490 | return this._relatedTarget; |
---|
491 | }, |
---|
492 | getModifiersState: function(keyIdentifier){ |
---|
493 | |
---|
494 | }, |
---|
495 | initMouseEvent: function(type, bubbles, cancelable, windowObject, |
---|
496 | keyIdentifier, keyLocation, modifiersList, repeat){ |
---|
497 | this.initUIEvent(type, bubbles, cancelable, windowObject, 0); |
---|
498 | this._keyIdentifier = keyIdentifier; |
---|
499 | this._keyLocation = keyLocation; |
---|
500 | this._modifiersList = modifiersList; |
---|
501 | this._repeat = repeat; |
---|
502 | } |
---|
503 | }); |
---|
504 | |
---|
505 | KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0; |
---|
506 | KeyboardEvent.DOM_KEY_LOCATION_LEFT = 1; |
---|
507 | KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 2; |
---|
508 | KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 3; |
---|
509 | KeyboardEvent.DOM_KEY_LOCATION_MOBILE = 4; |
---|
510 | KeyboardEvent.DOM_KEY_LOCATION_JOYSTICK = 5; |
---|
511 | |
---|
512 | }(/*Envjs.DOM3.KeyboardEvent*/)); |
---|
513 | |
---|
514 | |
---|
515 | //We dont fire mutation events until someone has registered for them |
---|
516 | var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/; |
---|
517 | |
---|
518 | var __fireMutationEvents__ = Aspect.before({ |
---|
519 | target: EventTarget, |
---|
520 | method: 'addEventListener' |
---|
521 | }, function(target, type){ |
---|
522 | if(type && type.match(__supportedMutations__)){ |
---|
523 | //unweaving removes the __addEventListener__ aspect |
---|
524 | __fireMutationEvents__.unweave(); |
---|
525 | // These two methods are enough to cover all dom 2 manipulations |
---|
526 | Aspect.around({ |
---|
527 | target: Node, |
---|
528 | method:"removeChild" |
---|
529 | }, function(invocation){ |
---|
530 | var event, |
---|
531 | node = invocation['arguments'][0]; |
---|
532 | event = node.ownerDocument.createEvent('MutationEvents'); |
---|
533 | event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null); |
---|
534 | node.dispatchEvent(event, false); |
---|
535 | return invocation.proceed(); |
---|
536 | |
---|
537 | }); |
---|
538 | Aspect.around({ |
---|
539 | target: Node, |
---|
540 | method:"appendChild" |
---|
541 | }, function(invocation) { |
---|
542 | var event, |
---|
543 | node = invocation.proceed(); |
---|
544 | event = node.ownerDocument.createEvent('MutationEvents'); |
---|
545 | event.initEvent('DOMNodeInserted', true, false, node.parentNode, null, null, null, null); |
---|
546 | node.dispatchEvent(event, false); |
---|
547 | return node; |
---|
548 | }); |
---|
549 | } |
---|
550 | }); |
---|
551 | |
---|
552 | (function(){ |
---|
553 | |
---|
554 | var log = Envjs.logger(); |
---|
555 | |
---|
556 | Envjs.once('tick', function(){ |
---|
557 | log = Envjs.logger('Envjs.DOM.MutationEvent').debug('available'); |
---|
558 | }); |
---|
559 | |
---|
560 | /** |
---|
561 | * @name MutationEvent |
---|
562 | * @param {Object} options |
---|
563 | */ |
---|
564 | exports.MutationEvent = MutationEvent = function(options) { |
---|
565 | this._cancelable = false; |
---|
566 | this._timeStamp = 0; |
---|
567 | }; |
---|
568 | |
---|
569 | MutationEvent.prototype = new Event(); |
---|
570 | __extend__(MutationEvent.prototype,{ |
---|
571 | get relatedNode(){ |
---|
572 | return this._relatedNode; |
---|
573 | }, |
---|
574 | get prevValue(){ |
---|
575 | return this._prevValue; |
---|
576 | }, |
---|
577 | get newValue(){ |
---|
578 | return this._newValue; |
---|
579 | }, |
---|
580 | get attrName(){ |
---|
581 | return this._attrName; |
---|
582 | }, |
---|
583 | get attrChange(){ |
---|
584 | return this._attrChange; |
---|
585 | }, |
---|
586 | initMutationEvent: function( type, bubbles, cancelable, |
---|
587 | relatedNode, prevValue, newValue, attrName, attrChange ){ |
---|
588 | this._relatedNode = relatedNode; |
---|
589 | this._prevValue = prevValue; |
---|
590 | this._newValue = newValue; |
---|
591 | this._attrName = attrName; |
---|
592 | this._attrChange = attrChange; |
---|
593 | switch(type){ |
---|
594 | case "DOMSubtreeModified": |
---|
595 | this.initEvent(type, true, false); |
---|
596 | break; |
---|
597 | case "DOMNodeInserted": |
---|
598 | this.initEvent(type, true, false); |
---|
599 | break; |
---|
600 | case "DOMNodeRemoved": |
---|
601 | this.initEvent(type, true, false); |
---|
602 | break; |
---|
603 | case "DOMNodeRemovedFromDocument": |
---|
604 | this.initEvent(type, false, false); |
---|
605 | break; |
---|
606 | case "DOMNodeInsertedIntoDocument": |
---|
607 | this.initEvent(type, false, false); |
---|
608 | break; |
---|
609 | case "DOMAttrModified": |
---|
610 | this.initEvent(type, true, false); |
---|
611 | break; |
---|
612 | case "DOMCharacterDataModified": |
---|
613 | this.initEvent(type, true, false); |
---|
614 | break; |
---|
615 | default: |
---|
616 | this.initEvent(type, bubbles, cancelable); |
---|
617 | } |
---|
618 | } |
---|
619 | }); |
---|
620 | |
---|
621 | // constants |
---|
622 | MutationEvent.ADDITION = 0; |
---|
623 | MutationEvent.MODIFICATION = 1; |
---|
624 | MutationEvent.REMOVAL = 2; |
---|
625 | |
---|
626 | }(/*Envjs.DOM.MutationEvent*/)); |
---|
627 | |
---|
628 | |
---|
629 | (function(){ |
---|
630 | |
---|
631 | var log = Envjs.logger(); |
---|
632 | |
---|
633 | Envjs.once('tick', function(){ |
---|
634 | log = Envjs.logger('Envjs.DOM.EventException').debug('available'); |
---|
635 | }); |
---|
636 | |
---|
637 | /** |
---|
638 | * @name EventException |
---|
639 | */ |
---|
640 | exports.EventException = EventException = function(code) { |
---|
641 | this.code = code; |
---|
642 | }; |
---|
643 | EventException.UNSPECIFIED_EVENT_TYPE_ERR = 0; |
---|
644 | |
---|
645 | }(/*Envjs.DOM2.EventException*/)); |
---|
646 | /** |
---|
647 | * |
---|
648 | * DOM Level 2: http://www.w3.org/TR/DOM-Level-2-Events/events.html |
---|
649 | * DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Events/ |
---|
650 | * |
---|
651 | * interface DocumentEvent { |
---|
652 | * Event createEvent (in DOMString eventType) |
---|
653 | * raises (DOMException); |
---|
654 | * }; |
---|
655 | * |
---|
656 | * Firefox (3.6) exposes DocumentEvent |
---|
657 | * Safari (4) does NOT. |
---|
658 | */ |
---|
659 | |
---|
660 | (function(){ |
---|
661 | |
---|
662 | var log = Envjs.logger(); |
---|
663 | |
---|
664 | Envjs.once('tick', function(){ |
---|
665 | log = Envjs.logger('Envjs.DOM.DocumentEvent').debug('available'); |
---|
666 | }); |
---|
667 | |
---|
668 | /** |
---|
669 | * TODO: Not sure we need a full prototype. We not just an regular object? |
---|
670 | */ |
---|
671 | exports.DocumentEvent = DocumentEvent = function(){}; |
---|
672 | DocumentEvent.prototype.__EventMap__ = { |
---|
673 | // Safari4: singular and plural forms accepted |
---|
674 | // Firefox3.6: singular and plural forms accepted |
---|
675 | 'Event' : Event, |
---|
676 | 'Events' : Event, |
---|
677 | 'UIEvent' : UIEvent, |
---|
678 | 'UIEvents' : UIEvent, |
---|
679 | 'MouseEvent' : MouseEvent, |
---|
680 | 'MouseEvents' : MouseEvent, |
---|
681 | 'MutationEvent' : MutationEvent, |
---|
682 | 'MutationEvents' : MutationEvent, |
---|
683 | |
---|
684 | // Safari4: accepts HTMLEvents, but not HTMLEvent |
---|
685 | // Firefox3.6: accepts HTMLEvents, but not HTMLEvent |
---|
686 | 'HTMLEvent' : Event, |
---|
687 | 'HTMLEvents' : Event, |
---|
688 | |
---|
689 | // Safari4: both not accepted |
---|
690 | // Firefox3.6, only KeyEvents is accepted |
---|
691 | 'KeyEvent' : KeyboardEvent, |
---|
692 | 'KeyEvents' : KeyboardEvent, |
---|
693 | |
---|
694 | // Safari4: both accepted |
---|
695 | // Firefox3.6: none accepted |
---|
696 | 'KeyboardEvent' : KeyboardEvent, |
---|
697 | 'KeyboardEvents' : KeyboardEvent |
---|
698 | }; |
---|
699 | |
---|
700 | DocumentEvent.prototype.createEvent = function(eventType) { |
---|
701 | var Clazz = this.__EventMap__[eventType]; |
---|
702 | if (Clazz) { |
---|
703 | return new Clazz(); |
---|
704 | } |
---|
705 | throw(new DOMException(DOMException.NOT_SUPPORTED_ERR)); |
---|
706 | }; |
---|
707 | |
---|
708 | __extend__(Document.prototype, DocumentEvent.prototype); |
---|
709 | |
---|
710 | |
---|
711 | }(/*Envjs.DOM.DocumentEvent*/)); |
---|
712 | |
---|
713 | /** |
---|
714 | * @author john resig & the envjs team |
---|
715 | * @uri http://www.envjs.com/ |
---|
716 | * @copyright 2008-2010 |
---|
717 | * @license MIT |
---|
718 | */ |
---|
719 | //CLOSURE_END |
---|
720 | }()); |
---|