Diffstat (limited to 'frontend/gamma/js/MochiKit/Signal.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/MochiKit/Signal.js | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/frontend/gamma/js/MochiKit/Signal.js b/frontend/gamma/js/MochiKit/Signal.js index 7df5619..11590c1 100644 --- a/frontend/gamma/js/MochiKit/Signal.js +++ b/frontend/gamma/js/MochiKit/Signal.js | |||
@@ -1,43 +1,43 @@ | |||
1 | /*** | 1 | /*** |
2 | 2 | ||
3 | MochiKit.Signal 1.5 | 3 | MochiKit.Signal 1.5 |
4 | 4 | ||
5 | See <http://mochikit.com/> for documentation, downloads, license, etc. | 5 | See <http://mochikit.com/> for documentation, downloads, license, etc. |
6 | 6 | ||
7 | (c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved. | 7 | (c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved. |
8 | 8 | ||
9 | ***/ | 9 | ***/ |
10 | 10 | ||
11 | MochiKit.Base._module('Signal', '1.5', ['Base', 'DOM', 'Style']); | 11 | MochiKit.Base.module(MochiKit, 'Signal', '1.5', ['Base', 'DOM']); |
12 | 12 | ||
13 | MochiKit.Signal._observers = []; | 13 | MochiKit.Signal._observers = []; |
14 | 14 | ||
15 | /** @id MochiKit.Signal.Event */ | 15 | /** @id MochiKit.Signal.Event */ |
16 | MochiKit.Signal.Event = function (src, e) { | 16 | MochiKit.Signal.Event = function (src, e) { |
17 | this._event = e || window.event; | 17 | this._event = e || window.event; |
18 | this._src = src; | 18 | this._src = src; |
19 | }; | 19 | }; |
20 | MochiKit.Signal.Event.__export__ = false; | 20 | MochiKit.Signal.Event.__export__ = false; |
21 | 21 | ||
22 | MochiKit.Base.update(MochiKit.Signal.Event.prototype, { | 22 | MochiKit.Base.update(MochiKit.Signal.Event.prototype, { |
23 | 23 | ||
24 | __repr__: function () { | 24 | __repr__: function () { |
25 | var repr = MochiKit.Base.repr; | 25 | var repr = MochiKit.Base.repr; |
26 | var str = '{event(): ' + repr(this.event()) + | 26 | var str = '{event(): ' + repr(this.event()) + |
27 | ', src(): ' + repr(this.src()) + | 27 | ', src(): ' + repr(this.src()) + |
28 | ', type(): ' + repr(this.type()) + | 28 | ', type(): ' + repr(this.type()) + |
29 | ', target(): ' + repr(this.target()); | 29 | ', target(): ' + repr(this.target()); |
30 | 30 | ||
31 | if (this.type() && | 31 | if (this.type() && |
32 | this.type().indexOf('key') === 0 || | 32 | this.type().indexOf('key') === 0 || |
33 | this.type().indexOf('mouse') === 0 || | 33 | this.type().indexOf('mouse') === 0 || |
34 | this.type().indexOf('click') != -1 || | 34 | this.type().indexOf('click') != -1 || |
35 | this.type() == 'contextmenu') { | 35 | this.type() == 'contextmenu') { |
36 | str += ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) + | 36 | str += ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) + |
37 | ', ctrl: ' + repr(this.modifier().ctrl) + | 37 | ', ctrl: ' + repr(this.modifier().ctrl) + |
38 | ', meta: ' + repr(this.modifier().meta) + | 38 | ', meta: ' + repr(this.modifier().meta) + |
39 | ', shift: ' + repr(this.modifier().shift) + | 39 | ', shift: ' + repr(this.modifier().shift) + |
40 | ', any: ' + repr(this.modifier().any) + '}'; | 40 | ', any: ' + repr(this.modifier().any) + '}'; |
41 | } | 41 | } |
42 | 42 | ||
43 | if (this.type() && this.type().indexOf('key') === 0) { | 43 | if (this.type() && this.type().indexOf('key') === 0) { |
@@ -237,136 +237,137 @@ MochiKit.Base.update(MochiKit.Signal.Event.prototype, { | |||
237 | k.string = ''; | 237 | k.string = ''; |
238 | 238 | ||
239 | if (typeof(this._event.charCode) != 'undefined' && | 239 | if (typeof(this._event.charCode) != 'undefined' && |
240 | this._event.charCode !== 0 && | 240 | this._event.charCode !== 0 && |
241 | !MochiKit.Signal._specialMacKeys[this._event.charCode]) { | 241 | !MochiKit.Signal._specialMacKeys[this._event.charCode]) { |
242 | k.code = this._event.charCode; | 242 | k.code = this._event.charCode; |
243 | k.string = String.fromCharCode(k.code); | 243 | k.string = String.fromCharCode(k.code); |
244 | } else if (this._event.keyCode && | 244 | } else if (this._event.keyCode && |
245 | typeof(this._event.charCode) == 'undefined') { // IE | 245 | typeof(this._event.charCode) == 'undefined') { // IE |
246 | k.code = this._event.keyCode; | 246 | k.code = this._event.keyCode; |
247 | k.string = String.fromCharCode(k.code); | 247 | k.string = String.fromCharCode(k.code); |
248 | } | 248 | } |
249 | 249 | ||
250 | this._key = k; | 250 | this._key = k; |
251 | return k; | 251 | return k; |
252 | } | 252 | } |
253 | } | 253 | } |
254 | return undefined; | 254 | return undefined; |
255 | }, | 255 | }, |
256 | 256 | ||
257 | _mouse: null, | 257 | _mouse: null, |
258 | /** @id MochiKit.Signal.Event.prototype.mouse */ | 258 | /** @id MochiKit.Signal.Event.prototype.mouse */ |
259 | mouse: function () { | 259 | mouse: function () { |
260 | if (this._mouse !== null) { | 260 | if (this._mouse !== null) { |
261 | return this._mouse; | 261 | return this._mouse; |
262 | } | 262 | } |
263 | 263 | ||
264 | var m = {}; | 264 | var m = {}; |
265 | var e = this._event; | 265 | var e = this._event; |
266 | 266 | ||
267 | if (this.type() && ( | 267 | if (this.type() && ( |
268 | this.type().indexOf('mouse') === 0 || | 268 | this.type().indexOf('mouse') === 0 || |
269 | this.type().indexOf('drag') === 0 || | ||
269 | this.type().indexOf('click') != -1 || | 270 | this.type().indexOf('click') != -1 || |
270 | this.type() == 'contextmenu')) { | 271 | this.type() == 'contextmenu')) { |
271 | 272 | ||
272 | m.client = new MochiKit.Style.Coordinates(0, 0); | 273 | m.client = { x: 0, y: 0 }; |
273 | if (e.clientX || e.clientY) { | 274 | if (e.clientX || e.clientY) { |
274 | m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX; | 275 | m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX; |
275 | m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY; | 276 | m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY; |
276 | } | 277 | } |
277 | 278 | ||
278 | m.page = new MochiKit.Style.Coordinates(0, 0); | 279 | m.page = { x: 0, y: 0 }; |
279 | if (e.pageX || e.pageY) { | 280 | if (e.pageX || e.pageY) { |
280 | m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX; | 281 | m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX; |
281 | m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY; | 282 | m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY; |
282 | } else { | 283 | } else { |
283 | /* | 284 | /* |
284 | 285 | ||
285 | The IE shortcut can be off by two. We fix it. See: | 286 | The IE shortcut can be off by two. We fix it. See: |
286 | http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp | 287 | http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp |
287 | 288 | ||
288 | This is similar to the method used in | 289 | This is similar to the method used in |
289 | MochiKit.Style.getElementPosition(). | 290 | MochiKit.Style.getElementPosition(). |
290 | 291 | ||
291 | */ | 292 | */ |
292 | var de = MochiKit.DOM._document.documentElement; | 293 | var de = MochiKit.DOM._document.documentElement; |
293 | var b = MochiKit.DOM._document.body; | 294 | var b = MochiKit.DOM._document.body; |
294 | 295 | ||
295 | m.page.x = e.clientX + | 296 | m.page.x = e.clientX + |
296 | (de.scrollLeft || b.scrollLeft) - | 297 | (de.scrollLeft || b.scrollLeft) - |
297 | (de.clientLeft || 0); | 298 | (de.clientLeft || 0); |
298 | 299 | ||
299 | m.page.y = e.clientY + | 300 | m.page.y = e.clientY + |
300 | (de.scrollTop || b.scrollTop) - | 301 | (de.scrollTop || b.scrollTop) - |
301 | (de.clientTop || 0); | 302 | (de.clientTop || 0); |
302 | 303 | ||
303 | } | 304 | } |
304 | if (this.type() != 'mousemove' && this.type() != 'mousewheel') { | 305 | if (this.type() != 'mousemove' && this.type() != 'mousewheel') { |
305 | m.button = {}; | 306 | m.button = {}; |
306 | m.button.left = false; | 307 | m.button.left = false; |
307 | m.button.right = false; | 308 | m.button.right = false; |
308 | m.button.middle = false; | 309 | m.button.middle = false; |
309 | 310 | ||
310 | /* we could check e.button, but which is more consistent */ | 311 | /* we could check e.button, but which is more consistent */ |
311 | if (e.which) { | 312 | if (e.which) { |
312 | m.button.left = (e.which == 1); | 313 | m.button.left = (e.which == 1); |
313 | m.button.middle = (e.which == 2); | 314 | m.button.middle = (e.which == 2); |
314 | m.button.right = (e.which == 3); | 315 | m.button.right = (e.which == 3); |
315 | 316 | ||
316 | /* | 317 | /* |
317 | 318 | ||
318 | Mac browsers and right click: | 319 | Mac browsers and right click: |
319 | 320 | ||
320 | - Safari doesn't fire any click events on a right | 321 | - Safari doesn't fire any click events on a right |
321 | click: | 322 | click: |
322 | http://bugs.webkit.org/show_bug.cgi?id=6595 | 323 | http://bugs.webkit.org/show_bug.cgi?id=6595 |
323 | 324 | ||
324 | - Firefox fires the event, and sets ctrlKey = true | 325 | - Firefox fires the event, and sets ctrlKey = true |
325 | 326 | ||
326 | - Opera fires the event, and sets metaKey = true | 327 | - Opera fires the event, and sets metaKey = true |
327 | 328 | ||
328 | oncontextmenu is fired on right clicks between | 329 | oncontextmenu is fired on right clicks between |
329 | browsers and across platforms. | 330 | browsers and across platforms. |
330 | 331 | ||
331 | */ | 332 | */ |
332 | 333 | ||
333 | } else { | 334 | } else { |
334 | m.button.left = !!(e.button & 1); | 335 | m.button.left = !!(e.button & 1); |
335 | m.button.right = !!(e.button & 2); | 336 | m.button.right = !!(e.button & 2); |
336 | m.button.middle = !!(e.button & 4); | 337 | m.button.middle = !!(e.button & 4); |
337 | } | 338 | } |
338 | } | 339 | } |
339 | if (this.type() == 'mousewheel') { | 340 | if (this.type() == 'mousewheel') { |
340 | m.wheel = new MochiKit.Style.Coordinates(0, 0); | 341 | m.wheel = { x: 0, y: 0 }; |
341 | if (e.wheelDeltaX || e.wheelDeltaY) { | 342 | if (e.wheelDeltaX || e.wheelDeltaY) { |
342 | m.wheel.x = e.wheelDeltaX / -40 || 0; | 343 | m.wheel.x = e.wheelDeltaX / -40 || 0; |
343 | m.wheel.y = e.wheelDeltaY / -40 || 0; | 344 | m.wheel.y = e.wheelDeltaY / -40 || 0; |
344 | } else if (e.wheelDelta) { | 345 | } else if (e.wheelDelta) { |
345 | m.wheel.y = e.wheelDelta / -40; | 346 | m.wheel.y = e.wheelDelta / -40; |
346 | } else { | 347 | } else { |
347 | m.wheel.y = e.detail || 0; | 348 | m.wheel.y = e.detail || 0; |
348 | } | 349 | } |
349 | } | 350 | } |
350 | this._mouse = m; | 351 | this._mouse = m; |
351 | return m; | 352 | return m; |
352 | } | 353 | } |
353 | return undefined; | 354 | return undefined; |
354 | }, | 355 | }, |
355 | 356 | ||
356 | /** @id MochiKit.Signal.Event.prototype.stop */ | 357 | /** @id MochiKit.Signal.Event.prototype.stop */ |
357 | stop: function () { | 358 | stop: function () { |
358 | this.stopPropagation(); | 359 | this.stopPropagation(); |
359 | this.preventDefault(); | 360 | this.preventDefault(); |
360 | }, | 361 | }, |
361 | 362 | ||
362 | /** @id MochiKit.Signal.Event.prototype.stopPropagation */ | 363 | /** @id MochiKit.Signal.Event.prototype.stopPropagation */ |
363 | stopPropagation: function () { | 364 | stopPropagation: function () { |
364 | if (this._event.stopPropagation) { | 365 | if (this._event.stopPropagation) { |
365 | this._event.stopPropagation(); | 366 | this._event.stopPropagation(); |
366 | } else { | 367 | } else { |
367 | this._event.cancelBubble = true; | 368 | this._event.cancelBubble = true; |
368 | } | 369 | } |
369 | }, | 370 | }, |
370 | 371 | ||
371 | /** @id MochiKit.Signal.Event.prototype.preventDefault */ | 372 | /** @id MochiKit.Signal.Event.prototype.preventDefault */ |
372 | preventDefault: function () { | 373 | preventDefault: function () { |
@@ -643,246 +644,258 @@ MochiKit.Base.update(MochiKit.Signal, { | |||
643 | } else if (isDOM && sig == "onmousewheel" && self._browserLacksMouseWheelEvent()) { | 644 | } else if (isDOM && sig == "onmousewheel" && self._browserLacksMouseWheelEvent()) { |
644 | var listener = self._listener(src, sig, func, obj, isDOM); | 645 | var listener = self._listener(src, sig, func, obj, isDOM); |
645 | sig = "onDOMMouseScroll"; | 646 | sig = "onDOMMouseScroll"; |
646 | } else { | 647 | } else { |
647 | var listener = self._listener(src, sig, func, obj, isDOM); | 648 | var listener = self._listener(src, sig, func, obj, isDOM); |
648 | } | 649 | } |
649 | 650 | ||
650 | if (src.addEventListener) { | 651 | if (src.addEventListener) { |
651 | src.addEventListener(sig.substr(2), listener, false); | 652 | src.addEventListener(sig.substr(2), listener, false); |
652 | } else if (src.attachEvent) { | 653 | } else if (src.attachEvent) { |
653 | src.attachEvent(sig, listener); // useCapture unsupported | 654 | src.attachEvent(sig, listener); // useCapture unsupported |
654 | } | 655 | } |
655 | 656 | ||
656 | var ident = new MochiKit.Signal.Ident({ | 657 | var ident = new MochiKit.Signal.Ident({ |
657 | source: src, | 658 | source: src, |
658 | signal: sig, | 659 | signal: sig, |
659 | listener: listener, | 660 | listener: listener, |
660 | isDOM: isDOM, | 661 | isDOM: isDOM, |
661 | objOrFunc: objOrFunc, | 662 | objOrFunc: objOrFunc, |
662 | funcOrStr: funcOrStr, | 663 | funcOrStr: funcOrStr, |
663 | connected: true | 664 | connected: true |
664 | }); | 665 | }); |
665 | self._observers.push(ident); | 666 | self._observers.push(ident); |
666 | 667 | ||
667 | if (!isDOM && typeof(src.__connect__) == 'function') { | 668 | if (!isDOM && typeof(src.__connect__) == 'function') { |
668 | var args = MochiKit.Base.extend([ident], arguments, 1); | 669 | var args = MochiKit.Base.extend([ident], arguments, 1); |
669 | src.__connect__.apply(src, args); | 670 | src.__connect__.apply(src, args); |
670 | } | 671 | } |
671 | 672 | ||
672 | return ident; | 673 | return ident; |
673 | }, | 674 | }, |
674 | 675 | ||
676 | /** @id MochiKit.Signal.connectOnce */ | ||
677 | connectOnce: function (src, sig, objOrFunc/* optional */, funcOrStr) { | ||
678 | var self = MochiKit.Signal; | ||
679 | var ident1 = self.connect(src, sig, objOrFunc, funcOrStr); | ||
680 | var ident2; | ||
681 | ident2 = self.connect(src, sig, function() { | ||
682 | self.disconnect(ident1); | ||
683 | self.disconnect(ident2); | ||
684 | }); | ||
685 | return ident1; | ||
686 | }, | ||
687 | |||
675 | _disconnect: function (ident) { | 688 | _disconnect: function (ident) { |
676 | // already disconnected | 689 | // already disconnected |
677 | if (!ident.connected) { | 690 | if (!ident.connected) { |
678 | return; | 691 | return; |
679 | } | 692 | } |
680 | ident.connected = false; | 693 | ident.connected = false; |
681 | var src = ident.source; | 694 | var src = ident.source; |
682 | var sig = ident.signal; | 695 | var sig = ident.signal; |
683 | var listener = ident.listener; | 696 | var listener = ident.listener; |
684 | // check isDOM | 697 | // check isDOM |
685 | if (!ident.isDOM) { | 698 | if (!ident.isDOM) { |
686 | if (typeof(src.__disconnect__) == 'function') { | 699 | if (typeof(src.__disconnect__) == 'function') { |
687 | src.__disconnect__(ident, sig, ident.objOrFunc, ident.funcOrStr); | 700 | src.__disconnect__(ident, sig, ident.objOrFunc, ident.funcOrStr); |
688 | } | 701 | } |
689 | return; | 702 | return; |
690 | } | 703 | } |
691 | if (src.removeEventListener) { | 704 | if (src.removeEventListener) { |
692 | src.removeEventListener(sig.substr(2), listener, false); | 705 | src.removeEventListener(sig.substr(2), listener, false); |
693 | } else if (src.detachEvent) { | 706 | } else if (src.detachEvent) { |
694 | src.detachEvent(sig, listener); // useCapture unsupported | 707 | src.detachEvent(sig, listener); // useCapture unsupported |
695 | } else { | 708 | } else { |
696 | throw new Error("'src' must be a DOM element"); | 709 | throw new Error("'src' must be a DOM element"); |
697 | } | 710 | } |
698 | }, | 711 | }, |
699 | 712 | ||
700 | /** @id MochiKit.Signal.disconnect */ | 713 | /** @id MochiKit.Signal.disconnect */ |
701 | disconnect: function (ident) { | 714 | disconnect: function (ident) { |
702 | var self = MochiKit.Signal; | 715 | var self = MochiKit.Signal; |
703 | var observers = self._observers; | 716 | var observers = self._observers; |
704 | var m = MochiKit.Base; | 717 | var m = MochiKit.Base; |
705 | if (arguments.length > 1) { | 718 | if (arguments.length > 1) { |
706 | // compatibility API | 719 | // compatibility API |
707 | var src = arguments[0]; | 720 | var src = arguments[0]; |
708 | if (typeof(src) == "string") { | 721 | if (typeof(src) == "string") { |
709 | src = MochiKit.DOM.getElement(src); | 722 | src = MochiKit.DOM.getElement(src); |
710 | } | 723 | } |
711 | var sig = arguments[1]; | 724 | var sig = arguments[1]; |
712 | var obj = arguments[2]; | 725 | var obj = arguments[2]; |
713 | var func = arguments[3]; | 726 | var func = arguments[3]; |
714 | for (var i = observers.length - 1; i >= 0; i--) { | 727 | for (var i = observers.length - 1; i >= 0; i--) { |
715 | var o = observers[i]; | 728 | var o = observers[i]; |
716 | if (o.source === src && o.signal === sig && o.objOrFunc === obj && o.funcOrStr === func) { | 729 | if (o.source === src && o.signal === sig && o.objOrFunc === obj && o.funcOrStr === func) { |
717 | self._disconnect(o); | 730 | self._disconnect(o); |
718 | if (!self._lock) { | 731 | if (self._lock === 0) { |
719 | observers.splice(i, 1); | 732 | observers.splice(i, 1); |
720 | } else { | 733 | } else { |
721 | self._dirty = true; | 734 | self._dirty = true; |
722 | } | 735 | } |
723 | return true; | 736 | return true; |
724 | } | 737 | } |
725 | } | 738 | } |
726 | } else { | 739 | } else { |
727 | var idx = m.findIdentical(observers, ident); | 740 | var idx = m.findIdentical(observers, ident); |
728 | if (idx >= 0) { | 741 | if (idx >= 0) { |
729 | self._disconnect(ident); | 742 | self._disconnect(ident); |
730 | if (!self._lock) { | 743 | if (self._lock === 0) { |
731 | observers.splice(idx, 1); | 744 | observers.splice(idx, 1); |
732 | } else { | 745 | } else { |
733 | self._dirty = true; | 746 | self._dirty = true; |
734 | } | 747 | } |
735 | return true; | 748 | return true; |
736 | } | 749 | } |
737 | } | 750 | } |
738 | return false; | 751 | return false; |
739 | }, | 752 | }, |
740 | 753 | ||
741 | /** @id MochiKit.Signal.disconnectAllTo */ | 754 | /** @id MochiKit.Signal.disconnectAllTo */ |
742 | disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) { | 755 | disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) { |
743 | var self = MochiKit.Signal; | 756 | var self = MochiKit.Signal; |
744 | var observers = self._observers; | 757 | var observers = self._observers; |
745 | var disconnect = self._disconnect; | 758 | var disconnect = self._disconnect; |
746 | var locked = self._lock; | 759 | var lock = self._lock; |
747 | var dirty = self._dirty; | 760 | var dirty = self._dirty; |
748 | if (typeof(funcOrStr) === 'undefined') { | 761 | if (typeof(funcOrStr) === 'undefined') { |
749 | funcOrStr = null; | 762 | funcOrStr = null; |
750 | } | 763 | } |
751 | for (var i = observers.length - 1; i >= 0; i--) { | 764 | for (var i = observers.length - 1; i >= 0; i--) { |
752 | var ident = observers[i]; | 765 | var ident = observers[i]; |
753 | if (ident.objOrFunc === objOrFunc && | 766 | if (ident.objOrFunc === objOrFunc && |
754 | (funcOrStr === null || ident.funcOrStr === funcOrStr)) { | 767 | (funcOrStr === null || ident.funcOrStr === funcOrStr)) { |
755 | disconnect(ident); | 768 | disconnect(ident); |
756 | if (locked) { | 769 | if (lock === 0) { |
757 | dirty = true; | ||
758 | } else { | ||
759 | observers.splice(i, 1); | 770 | observers.splice(i, 1); |
771 | } else { | ||
772 | dirty = true; | ||
760 | } | 773 | } |
761 | } | 774 | } |
762 | } | 775 | } |
763 | self._dirty = dirty; | 776 | self._dirty = dirty; |
764 | }, | 777 | }, |
765 | 778 | ||
766 | /** @id MochiKit.Signal.disconnectAll */ | 779 | /** @id MochiKit.Signal.disconnectAll */ |
767 | disconnectAll: function (src/* optional */, sig) { | 780 | disconnectAll: function (src/* optional */, sig) { |
768 | if (typeof(src) == "string") { | 781 | if (typeof(src) == "string") { |
769 | src = MochiKit.DOM.getElement(src); | 782 | src = MochiKit.DOM.getElement(src); |
770 | } | 783 | } |
771 | var m = MochiKit.Base; | 784 | var m = MochiKit.Base; |
772 | var signals = m.flattenArguments(m.extend(null, arguments, 1)); | 785 | var signals = m.flattenArguments(m.extend(null, arguments, 1)); |
773 | var self = MochiKit.Signal; | 786 | var self = MochiKit.Signal; |
774 | var disconnect = self._disconnect; | 787 | var disconnect = self._disconnect; |
775 | var observers = self._observers; | 788 | var observers = self._observers; |
776 | var i, ident; | 789 | var i, ident; |
777 | var locked = self._lock; | 790 | var lock = self._lock; |
778 | var dirty = self._dirty; | 791 | var dirty = self._dirty; |
779 | if (signals.length === 0) { | 792 | if (signals.length === 0) { |
780 | // disconnect all | 793 | // disconnect all |
781 | for (i = observers.length - 1; i >= 0; i--) { | 794 | for (i = observers.length - 1; i >= 0; i--) { |
782 | ident = observers[i]; | 795 | ident = observers[i]; |
783 | if (ident.source === src) { | 796 | if (ident.source === src) { |
784 | disconnect(ident); | 797 | disconnect(ident); |
785 | if (!locked) { | 798 | if (lock === 0) { |
786 | observers.splice(i, 1); | 799 | observers.splice(i, 1); |
787 | } else { | 800 | } else { |
788 | dirty = true; | 801 | dirty = true; |
789 | } | 802 | } |
790 | } | 803 | } |
791 | } | 804 | } |
792 | } else { | 805 | } else { |
793 | var sigs = {}; | 806 | var sigs = {}; |
794 | for (i = 0; i < signals.length; i++) { | 807 | for (i = 0; i < signals.length; i++) { |
795 | sigs[signals[i]] = true; | 808 | sigs[signals[i]] = true; |
796 | } | 809 | } |
797 | for (i = observers.length - 1; i >= 0; i--) { | 810 | for (i = observers.length - 1; i >= 0; i--) { |
798 | ident = observers[i]; | 811 | ident = observers[i]; |
799 | if (ident.source === src && ident.signal in sigs) { | 812 | if (ident.source === src && ident.signal in sigs) { |
800 | disconnect(ident); | 813 | disconnect(ident); |
801 | if (!locked) { | 814 | if (lock === 0) { |
802 | observers.splice(i, 1); | 815 | observers.splice(i, 1); |
803 | } else { | 816 | } else { |
804 | dirty = true; | 817 | dirty = true; |
805 | } | 818 | } |
806 | } | 819 | } |
807 | } | 820 | } |
808 | } | 821 | } |
809 | self._dirty = dirty; | 822 | self._dirty = dirty; |
810 | }, | 823 | }, |
811 | 824 | ||
812 | /** @id MochiKit.Signal.signal */ | 825 | /** @id MochiKit.Signal.signal */ |
813 | signal: function (src, sig) { | 826 | signal: function (src, sig) { |
814 | var self = MochiKit.Signal; | 827 | var self = MochiKit.Signal; |
815 | var observers = self._observers; | 828 | var observers = self._observers; |
816 | if (typeof(src) == "string") { | 829 | if (typeof(src) == "string") { |
817 | src = MochiKit.DOM.getElement(src); | 830 | src = MochiKit.DOM.getElement(src); |
818 | } | 831 | } |
819 | var args = MochiKit.Base.extend(null, arguments, 2); | 832 | var args = MochiKit.Base.extend(null, arguments, 2); |
820 | var errors = []; | 833 | var errors = []; |
821 | self._lock = true; | 834 | self._lock++; |
822 | for (var i = 0; i < observers.length; i++) { | 835 | for (var i = 0; i < observers.length; i++) { |
823 | var ident = observers[i]; | 836 | var ident = observers[i]; |
824 | if (ident.source === src && ident.signal === sig && | 837 | if (ident.source === src && ident.signal === sig && |
825 | ident.connected) { | 838 | ident.connected) { |
826 | try { | 839 | try { |
827 | if (ident.isDOM && ident.funcOrStr != null) { | 840 | if (ident.isDOM && ident.funcOrStr != null) { |
828 | var obj = ident.objOrFunc; | 841 | var obj = ident.objOrFunc; |
829 | obj[ident.funcOrStr].apply(obj, args); | 842 | obj[ident.funcOrStr].apply(obj, args); |
830 | } else if (ident.isDOM) { | 843 | } else if (ident.isDOM) { |
831 | ident.objOrFunc.apply(src, args); | 844 | ident.objOrFunc.apply(src, args); |
832 | } else { | 845 | } else { |
833 | ident.listener.apply(src, args); | 846 | ident.listener.apply(src, args); |
834 | } | 847 | } |
835 | } catch (e) { | 848 | } catch (e) { |
836 | errors.push(e); | 849 | errors.push(e); |
837 | } | 850 | } |
838 | } | 851 | } |
839 | } | 852 | } |
840 | self._lock = false; | 853 | self._lock--; |
841 | if (self._dirty) { | 854 | if (self._lock === 0 && self._dirty) { |
842 | self._dirty = false; | 855 | self._dirty = false; |
843 | for (var i = observers.length - 1; i >= 0; i--) { | 856 | for (var i = observers.length - 1; i >= 0; i--) { |
844 | if (!observers[i].connected) { | 857 | if (!observers[i].connected) { |
845 | observers.splice(i, 1); | 858 | observers.splice(i, 1); |
846 | } | 859 | } |
847 | } | 860 | } |
848 | } | 861 | } |
849 | if (errors.length == 1) { | 862 | if (errors.length == 1) { |
850 | throw errors[0]; | 863 | throw errors[0]; |
851 | } else if (errors.length > 1) { | 864 | } else if (errors.length > 1) { |
852 | var e = new Error("Multiple errors thrown in handling 'sig', see errors property"); | 865 | var e = new Error("Multiple errors thrown in handling 'sig', see errors property"); |
853 | e.errors = errors; | 866 | e.errors = errors; |
854 | throw e; | 867 | throw e; |
855 | } | 868 | } |
856 | } | 869 | } |
857 | 870 | ||
858 | }); | 871 | }); |
859 | 872 | ||
860 | MochiKit.Signal.__new__ = function (win) { | 873 | MochiKit.Signal.__new__ = function (win) { |
861 | var m = MochiKit.Base; | 874 | var m = MochiKit.Base; |
862 | this._document = document; | 875 | this._document = document; |
863 | this._window = win; | 876 | this._window = win; |
864 | this._lock = false; | 877 | this._lock = 0; |
865 | this._dirty = false; | 878 | this._dirty = false; |
866 | 879 | ||
867 | try { | 880 | try { |
868 | this.connect(window, 'onunload', this._unloadCache); | 881 | this.connect(window, 'onunload', this._unloadCache); |
869 | } catch (e) { | 882 | } catch (e) { |
870 | // pass: might not be a browser | 883 | // pass: might not be a browser |
871 | } | 884 | } |
872 | 885 | ||
873 | m.nameFunctions(this); | 886 | m.nameFunctions(this); |
874 | }; | 887 | }; |
875 | 888 | ||
876 | MochiKit.Signal.__new__(this); | 889 | MochiKit.Signal.__new__(this); |
877 | 890 | ||
878 | // | 891 | // |
879 | // XXX: Internet Explorer blows | 892 | // XXX: Internet Explorer blows |
880 | // | 893 | // |
881 | if (MochiKit.__export__) { | 894 | if (MochiKit.__export__) { |
882 | connect = MochiKit.Signal.connect; | 895 | connect = MochiKit.Signal.connect; |
883 | disconnect = MochiKit.Signal.disconnect; | 896 | disconnect = MochiKit.Signal.disconnect; |
884 | disconnectAll = MochiKit.Signal.disconnectAll; | 897 | disconnectAll = MochiKit.Signal.disconnectAll; |
885 | signal = MochiKit.Signal.signal; | 898 | signal = MochiKit.Signal.signal; |
886 | } | 899 | } |
887 | 900 | ||
888 | MochiKit.Base._exportSymbols(this, MochiKit.Signal); | 901 | MochiKit.Base._exportSymbols(this, MochiKit.Signal); |