123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858 |
- /***
- MochiKit.Signal 1.4
- See <http://mochikit.com/> for documentation, downloads, license, etc.
- (c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved.
- ***/
- if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Signal');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
- dojo.require('MochiKit.Style');
- }
- if (typeof(JSAN) != 'undefined') {
- JSAN.use('MochiKit.Base', []);
- JSAN.use('MochiKit.DOM', []);
- JSAN.use('MochiKit.Style', []);
- }
- try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw '';
- }
- } catch (e) {
- throw 'MochiKit.Signal depends on MochiKit.Base!';
- }
- try {
- if (typeof(MochiKit.DOM) == 'undefined') {
- throw '';
- }
- } catch (e) {
- throw 'MochiKit.Signal depends on MochiKit.DOM!';
- }
- try {
- if (typeof(MochiKit.Style) == 'undefined') {
- throw '';
- }
- } catch (e) {
- throw 'MochiKit.Signal depends on MochiKit.Style!';
- }
- if (typeof(MochiKit.Signal) == 'undefined') {
- MochiKit.Signal = {};
- }
- MochiKit.Signal.NAME = 'MochiKit.Signal';
- MochiKit.Signal.VERSION = '1.4';
- MochiKit.Signal._observers = [];
- /** @id MochiKit.Signal.Event */
- MochiKit.Signal.Event = function (src, e) {
- this._event = e || window.event;
- this._src = src;
- };
- MochiKit.Base.update(MochiKit.Signal.Event.prototype, {
- __repr__: function () {
- var repr = MochiKit.Base.repr;
- var str = '{event(): ' + repr(this.event()) +
- ', src(): ' + repr(this.src()) +
- ', type(): ' + repr(this.type()) +
- ', target(): ' + repr(this.target()) +
- ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) +
- ', ctrl: ' + repr(this.modifier().ctrl) +
- ', meta: ' + repr(this.modifier().meta) +
- ', shift: ' + repr(this.modifier().shift) +
- ', any: ' + repr(this.modifier().any) + '}';
- if (this.type() && this.type().indexOf('key') === 0) {
- str += ', key(): {code: ' + repr(this.key().code) +
- ', string: ' + repr(this.key().string) + '}';
- }
- if (this.type() && (
- this.type().indexOf('mouse') === 0 ||
- this.type().indexOf('click') != -1 ||
- this.type() == 'contextmenu')) {
- str += ', mouse(): {page: ' + repr(this.mouse().page) +
- ', client: ' + repr(this.mouse().client);
- if (this.type() != 'mousemove') {
- str += ', button: {left: ' + repr(this.mouse().button.left) +
- ', middle: ' + repr(this.mouse().button.middle) +
- ', right: ' + repr(this.mouse().button.right) + '}}';
- } else {
- str += '}';
- }
- }
- if (this.type() == 'mouseover' || this.type() == 'mouseout') {
- str += ', relatedTarget(): ' + repr(this.relatedTarget());
- }
- str += '}';
- return str;
- },
- /** @id MochiKit.Signal.Event.prototype.toString */
- toString: function () {
- return this.__repr__();
- },
- /** @id MochiKit.Signal.Event.prototype.src */
- src: function () {
- return this._src;
- },
- /** @id MochiKit.Signal.Event.prototype.event */
- event: function () {
- return this._event;
- },
- /** @id MochiKit.Signal.Event.prototype.type */
- type: function () {
- return this._event.type || undefined;
- },
- /** @id MochiKit.Signal.Event.prototype.target */
- target: function () {
- return this._event.target || this._event.srcElement;
- },
- _relatedTarget: null,
- /** @id MochiKit.Signal.Event.prototype.relatedTarget */
- relatedTarget: function () {
- if (this._relatedTarget !== null) {
- return this._relatedTarget;
- }
- var elem = null;
- if (this.type() == 'mouseover') {
- elem = (this._event.relatedTarget ||
- this._event.fromElement);
- } else if (this.type() == 'mouseout') {
- elem = (this._event.relatedTarget ||
- this._event.toElement);
- }
- if (elem !== null) {
- this._relatedTarget = elem;
- return elem;
- }
- return undefined;
- },
- _modifier: null,
- /** @id MochiKit.Signal.Event.prototype.modifier */
- modifier: function () {
- if (this._modifier !== null) {
- return this._modifier;
- }
- var m = {};
- m.alt = this._event.altKey;
- m.ctrl = this._event.ctrlKey;
- m.meta = this._event.metaKey || false; // IE and Opera punt here
- m.shift = this._event.shiftKey;
- m.any = m.alt || m.ctrl || m.shift || m.meta;
- this._modifier = m;
- return m;
- },
- _key: null,
- /** @id MochiKit.Signal.Event.prototype.key */
- key: function () {
- if (this._key !== null) {
- return this._key;
- }
- var k = {};
- if (this.type() && this.type().indexOf('key') === 0) {
- /*
- If you're looking for a special key, look for it in keydown or
- keyup, but never keypress. If you're looking for a Unicode
- chracter, look for it with keypress, but never keyup or
- keydown.
- Notes:
- FF key event behavior:
- key event charCode keyCode
- DOWN ku,kd 0 40
- DOWN kp 0 40
- ESC ku,kd 0 27
- ESC kp 0 27
- a ku,kd 0 65
- a kp 97 0
- shift+a ku,kd 0 65
- shift+a kp 65 0
- 1 ku,kd 0 49
- 1 kp 49 0
- shift+1 ku,kd 0 0
- shift+1 kp 33 0
- IE key event behavior:
- (IE doesn't fire keypress events for special keys.)
- key event keyCode
- DOWN ku,kd 40
- DOWN kp undefined
- ESC ku,kd 27
- ESC kp 27
- a ku,kd 65
- a kp 97
- shift+a ku,kd 65
- shift+a kp 65
- 1 ku,kd 49
- 1 kp 49
- shift+1 ku,kd 49
- shift+1 kp 33
- Safari key event behavior:
- (Safari sets charCode and keyCode to something crazy for
- special keys.)
- key event charCode keyCode
- DOWN ku,kd 63233 40
- DOWN kp 63233 63233
- ESC ku,kd 27 27
- ESC kp 27 27
- a ku,kd 97 65
- a kp 97 97
- shift+a ku,kd 65 65
- shift+a kp 65 65
- 1 ku,kd 49 49
- 1 kp 49 49
- shift+1 ku,kd 33 49
- shift+1 kp 33 33
- */
- /* look for special keys here */
- if (this.type() == 'keydown' || this.type() == 'keyup') {
- k.code = this._event.keyCode;
- k.string = (MochiKit.Signal._specialKeys[k.code] ||
- 'KEY_UNKNOWN');
- this._key = k;
- return k;
- /* look for characters here */
- } else if (this.type() == 'keypress') {
- /*
- Special key behavior:
- IE: does not fire keypress events for special keys
- FF: sets charCode to 0, and sets the correct keyCode
- Safari: sets keyCode and charCode to something stupid
- */
- k.code = 0;
- k.string = '';
- if (typeof(this._event.charCode) != 'undefined' &&
- this._event.charCode !== 0 &&
- !MochiKit.Signal._specialMacKeys[this._event.charCode]) {
- k.code = this._event.charCode;
- k.string = String.fromCharCode(k.code);
- } else if (this._event.keyCode &&
- typeof(this._event.charCode) == 'undefined') { // IE
- k.code = this._event.keyCode;
- k.string = String.fromCharCode(k.code);
- }
- this._key = k;
- return k;
- }
- }
- return undefined;
- },
- _mouse: null,
- /** @id MochiKit.Signal.Event.prototype.mouse */
- mouse: function () {
- if (this._mouse !== null) {
- return this._mouse;
- }
- var m = {};
- var e = this._event;
- if (this.type() && (
- this.type().indexOf('mouse') === 0 ||
- this.type().indexOf('click') != -1 ||
- this.type() == 'contextmenu')) {
- m.client = new MochiKit.Style.Coordinates(0, 0);
- if (e.clientX || e.clientY) {
- m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX;
- m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY;
- }
- m.page = new MochiKit.Style.Coordinates(0, 0);
- if (e.pageX || e.pageY) {
- m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
- m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
- } else {
- /*
- The IE shortcut can be off by two. We fix it. See:
- http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
- This is similar to the method used in
- MochiKit.Style.getElementPosition().
- */
- var de = MochiKit.DOM._document.documentElement;
- var b = MochiKit.DOM._document.body;
- m.page.x = e.clientX +
- (de.scrollLeft || b.scrollLeft) -
- (de.clientLeft || 0);
- m.page.y = e.clientY +
- (de.scrollTop || b.scrollTop) -
- (de.clientTop || 0);
- }
- if (this.type() != 'mousemove') {
- m.button = {};
- m.button.left = false;
- m.button.right = false;
- m.button.middle = false;
- /* we could check e.button, but which is more consistent */
- if (e.which) {
- m.button.left = (e.which == 1);
- m.button.middle = (e.which == 2);
- m.button.right = (e.which == 3);
- /*
- Mac browsers and right click:
- - Safari doesn't fire any click events on a right
- click:
- http://bugzilla.opendarwin.org/show_bug.cgi?id=6595
- - Firefox fires the event, and sets ctrlKey = true
- - Opera fires the event, and sets metaKey = true
- oncontextmenu is fired on right clicks between
- browsers and across platforms.
- */
- } else {
- m.button.left = !!(e.button & 1);
- m.button.right = !!(e.button & 2);
- m.button.middle = !!(e.button & 4);
- }
- }
- this._mouse = m;
- return m;
- }
- return undefined;
- },
- /** @id MochiKit.Signal.Event.prototype.stop */
- stop: function () {
- this.stopPropagation();
- this.preventDefault();
- },
- /** @id MochiKit.Signal.Event.prototype.stopPropagation */
- stopPropagation: function () {
- if (this._event.stopPropagation) {
- this._event.stopPropagation();
- } else {
- this._event.cancelBubble = true;
- }
- },
- /** @id MochiKit.Signal.Event.prototype.preventDefault */
- preventDefault: function () {
- if (this._event.preventDefault) {
- this._event.preventDefault();
- } else if (this._confirmUnload === null) {
- this._event.returnValue = false;
- }
- },
- _confirmUnload: null,
- /** @id MochiKit.Signal.Event.prototype.confirmUnload */
- confirmUnload: function (msg) {
- if (this.type() == 'beforeunload') {
- this._confirmUnload = msg;
- this._event.returnValue = msg;
- }
- }
- });
- /* Safari sets keyCode to these special values onkeypress. */
- MochiKit.Signal._specialMacKeys = {
- 3: 'KEY_ENTER',
- 63289: 'KEY_NUM_PAD_CLEAR',
- 63276: 'KEY_PAGE_UP',
- 63277: 'KEY_PAGE_DOWN',
- 63275: 'KEY_END',
- 63273: 'KEY_HOME',
- 63234: 'KEY_ARROW_LEFT',
- 63232: 'KEY_ARROW_UP',
- 63235: 'KEY_ARROW_RIGHT',
- 63233: 'KEY_ARROW_DOWN',
- 63302: 'KEY_INSERT',
- 63272: 'KEY_DELETE'
- };
- /* for KEY_F1 - KEY_F12 */
- (function () {
- var _specialMacKeys = MochiKit.Signal._specialMacKeys;
- for (i = 63236; i <= 63242; i++) {
- // no F0
- _specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1);
- }
- })();
- /* Standard keyboard key codes. */
- MochiKit.Signal._specialKeys = {
- 8: 'KEY_BACKSPACE',
- 9: 'KEY_TAB',
- 12: 'KEY_NUM_PAD_CLEAR', // weird, for Safari and Mac FF only
- 13: 'KEY_ENTER',
- 16: 'KEY_SHIFT',
- 17: 'KEY_CTRL',
- 18: 'KEY_ALT',
- 19: 'KEY_PAUSE',
- 20: 'KEY_CAPS_LOCK',
- 27: 'KEY_ESCAPE',
- 32: 'KEY_SPACEBAR',
- 33: 'KEY_PAGE_UP',
- 34: 'KEY_PAGE_DOWN',
- 35: 'KEY_END',
- 36: 'KEY_HOME',
- 37: 'KEY_ARROW_LEFT',
- 38: 'KEY_ARROW_UP',
- 39: 'KEY_ARROW_RIGHT',
- 40: 'KEY_ARROW_DOWN',
- 44: 'KEY_PRINT_SCREEN',
- 45: 'KEY_INSERT',
- 46: 'KEY_DELETE',
- 59: 'KEY_SEMICOLON', // weird, for Safari and IE only
- 91: 'KEY_WINDOWS_LEFT',
- 92: 'KEY_WINDOWS_RIGHT',
- 93: 'KEY_SELECT',
- 106: 'KEY_NUM_PAD_ASTERISK',
- 107: 'KEY_NUM_PAD_PLUS_SIGN',
- 109: 'KEY_NUM_PAD_HYPHEN-MINUS',
- 110: 'KEY_NUM_PAD_FULL_STOP',
- 111: 'KEY_NUM_PAD_SOLIDUS',
- 144: 'KEY_NUM_LOCK',
- 145: 'KEY_SCROLL_LOCK',
- 186: 'KEY_SEMICOLON',
- 187: 'KEY_EQUALS_SIGN',
- 188: 'KEY_COMMA',
- 189: 'KEY_HYPHEN-MINUS',
- 190: 'KEY_FULL_STOP',
- 191: 'KEY_SOLIDUS',
- 192: 'KEY_GRAVE_ACCENT',
- 219: 'KEY_LEFT_SQUARE_BRACKET',
- 220: 'KEY_REVERSE_SOLIDUS',
- 221: 'KEY_RIGHT_SQUARE_BRACKET',
- 222: 'KEY_APOSTROPHE'
- // undefined: 'KEY_UNKNOWN'
- };
- (function () {
- /* for KEY_0 - KEY_9 */
- var _specialKeys = MochiKit.Signal._specialKeys;
- for (var i = 48; i <= 57; i++) {
- _specialKeys[i] = 'KEY_' + (i - 48);
- }
- /* for KEY_A - KEY_Z */
- for (i = 65; i <= 90; i++) {
- _specialKeys[i] = 'KEY_' + String.fromCharCode(i);
- }
- /* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
- for (i = 96; i <= 105; i++) {
- _specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
- }
- /* for KEY_F1 - KEY_F12 */
- for (i = 112; i <= 123; i++) {
- // no F0
- _specialKeys[i] = 'KEY_F' + (i - 112 + 1);
- }
- })();
- MochiKit.Base.update(MochiKit.Signal, {
- __repr__: function () {
- return '[' + this.NAME + ' ' + this.VERSION + ']';
- },
- toString: function () {
- return this.__repr__();
- },
- _unloadCache: function () {
- var self = MochiKit.Signal;
- var observers = self._observers;
- for (var i = 0; i < observers.length; i++) {
- self._disconnect(observers[i]);
- }
- delete self._observers;
- try {
- window.onload = undefined;
- } catch(e) {
- // pass
- }
- try {
- window.onunload = undefined;
- } catch(e) {
- // pass
- }
- },
- _listener: function (src, func, obj, isDOM) {
- var self = MochiKit.Signal;
- var E = self.Event;
- if (!isDOM) {
- return MochiKit.Base.bind(func, obj);
- }
- obj = obj || src;
- if (typeof(func) == "string") {
- return function (nativeEvent) {
- obj[func].apply(obj, [new E(src, nativeEvent)]);
- };
- } else {
- return function (nativeEvent) {
- func.apply(obj, [new E(src, nativeEvent)]);
- };
- }
- },
- _browserAlreadyHasMouseEnterAndLeave: function () {
- return /MSIE/.test(navigator.userAgent);
- },
- _mouseEnterListener: function (src, sig, func, obj) {
- var E = MochiKit.Signal.Event;
- return function (nativeEvent) {
- var e = new E(src, nativeEvent);
- try {
- e.relatedTarget().nodeName;
- } catch (err) {
- /* probably hit a permission denied error; possibly one of
- * firefox's screwy anonymous DIVs inside an input element.
- * Allow this event to propogate up.
- */
- return;
- }
- e.stop();
- if (MochiKit.DOM.isChildNode(e.relatedTarget(), src)) {
- /* We've moved between our node and a child. Ignore. */
- return;
- }
- e.type = function () { return sig; };
- if (typeof(func) == "string") {
- return obj[func].apply(obj, [e]);
- } else {
- return func.apply(obj, [e]);
- }
- };
- },
- _getDestPair: function (objOrFunc, funcOrStr) {
- var obj = null;
- var func = null;
- if (typeof(funcOrStr) != 'undefined') {
- obj = objOrFunc;
- func = funcOrStr;
- if (typeof(funcOrStr) == 'string') {
- if (typeof(objOrFunc[funcOrStr]) != "function") {
- throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
- }
- } else if (typeof(funcOrStr) != 'function') {
- throw new Error("'funcOrStr' must be a function or string");
- }
- } else if (typeof(objOrFunc) != "function") {
- throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
- } else {
- func = objOrFunc;
- }
- return [obj, func];
- },
- /** @id MochiKit.Signal.connect */
- connect: function (src, sig, objOrFunc/* optional */, funcOrStr) {
- src = MochiKit.DOM.getElement(src);
- var self = MochiKit.Signal;
- if (typeof(sig) != 'string') {
- throw new Error("'sig' must be a string");
- }
- var destPair = self._getDestPair(objOrFunc, funcOrStr);
- var obj = destPair[0];
- var func = destPair[1];
- if (typeof(obj) == 'undefined' || obj === null) {
- obj = src;
- }
- var isDOM = !!(src.addEventListener || src.attachEvent);
- if (isDOM && (sig === "onmouseenter" || sig === "onmouseleave")
- && !self._browserAlreadyHasMouseEnterAndLeave()) {
- var listener = self._mouseEnterListener(src, sig.substr(2), func, obj);
- if (sig === "onmouseenter") {
- sig = "onmouseover";
- } else {
- sig = "onmouseout";
- }
- } else {
- var listener = self._listener(src, func, obj, isDOM);
- }
- if (src.addEventListener) {
- src.addEventListener(sig.substr(2), listener, false);
- } else if (src.attachEvent) {
- src.attachEvent(sig, listener); // useCapture unsupported
- }
- var ident = [src, sig, listener, isDOM, objOrFunc, funcOrStr, true];
- self._observers.push(ident);
- if (!isDOM && typeof(src.__connect__) == 'function') {
- var args = MochiKit.Base.extend([ident], arguments, 1);
- src.__connect__.apply(src, args);
- }
- return ident;
- },
- _disconnect: function (ident) {
- // already disconnected
- if (!ident[6]) { return; }
- ident[6] = false;
- // check isDOM
- if (!ident[3]) { return; }
- var src = ident[0];
- var sig = ident[1];
- var listener = ident[2];
- if (src.removeEventListener) {
- src.removeEventListener(sig.substr(2), listener, false);
- } else if (src.detachEvent) {
- src.detachEvent(sig, listener); // useCapture unsupported
- } else {
- throw new Error("'src' must be a DOM element");
- }
- },
- /** @id MochiKit.Signal.disconnect */
- disconnect: function (ident) {
- var self = MochiKit.Signal;
- var observers = self._observers;
- var m = MochiKit.Base;
- if (arguments.length > 1) {
- // compatibility API
- var src = MochiKit.DOM.getElement(arguments[0]);
- var sig = arguments[1];
- var obj = arguments[2];
- var func = arguments[3];
- for (var i = observers.length - 1; i >= 0; i--) {
- var o = observers[i];
- if (o[0] === src && o[1] === sig && o[4] === obj && o[5] === func) {
- self._disconnect(o);
- if (!self._lock) {
- observers.splice(i, 1);
- } else {
- self._dirty = true;
- }
- return true;
- }
- }
- } else {
- var idx = m.findIdentical(observers, ident);
- if (idx >= 0) {
- self._disconnect(ident);
- if (!self._lock) {
- observers.splice(idx, 1);
- } else {
- self._dirty = true;
- }
- return true;
- }
- }
- return false;
- },
- /** @id MochiKit.Signal.disconnectAllTo */
- disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) {
- var self = MochiKit.Signal;
- var observers = self._observers;
- var disconnect = self._disconnect;
- var locked = self._lock;
- var dirty = self._dirty;
- if (typeof(funcOrStr) === 'undefined') {
- funcOrStr = null;
- }
- for (var i = observers.length - 1; i >= 0; i--) {
- var ident = observers[i];
- if (ident[4] === objOrFunc &&
- (funcOrStr === null || ident[5] === funcOrStr)) {
- disconnect(ident);
- if (locked) {
- dirty = true;
- } else {
- observers.splice(i, 1);
- }
- }
- }
- self._dirty = dirty;
- },
- /** @id MochiKit.Signal.disconnectAll */
- disconnectAll: function (src/* optional */, sig) {
- src = MochiKit.DOM.getElement(src);
- var m = MochiKit.Base;
- var signals = m.flattenArguments(m.extend(null, arguments, 1));
- var self = MochiKit.Signal;
- var disconnect = self._disconnect;
- var observers = self._observers;
- var i, ident;
- var locked = self._lock;
- var dirty = self._dirty;
- if (signals.length === 0) {
- // disconnect all
- for (i = observers.length - 1; i >= 0; i--) {
- ident = observers[i];
- if (ident[0] === src) {
- disconnect(ident);
- if (!locked) {
- observers.splice(i, 1);
- } else {
- dirty = true;
- }
- }
- }
- } else {
- var sigs = {};
- for (i = 0; i < signals.length; i++) {
- sigs[signals[i]] = true;
- }
- for (i = observers.length - 1; i >= 0; i--) {
- ident = observers[i];
- if (ident[0] === src && ident[1] in sigs) {
- disconnect(ident);
- if (!locked) {
- observers.splice(i, 1);
- } else {
- dirty = true;
- }
- }
- }
- }
- self._dirty = dirty;
- },
- /** @id MochiKit.Signal.signal */
- signal: function (src, sig) {
- var self = MochiKit.Signal;
- var observers = self._observers;
- src = MochiKit.DOM.getElement(src);
- var args = MochiKit.Base.extend(null, arguments, 2);
- var errors = [];
- self._lock = true;
- for (var i = 0; i < observers.length; i++) {
- var ident = observers[i];
- if (ident[0] === src && ident[1] === sig) {
- try {
- ident[2].apply(src, args);
- } catch (e) {
- errors.push(e);
- }
- }
- }
- self._lock = false;
- if (self._dirty) {
- self._dirty = false;
- for (var i = observers.length - 1; i >= 0; i--) {
- if (!observers[i][6]) {
- observers.splice(i, 1);
- }
- }
- }
- if (errors.length == 1) {
- throw errors[0];
- } else if (errors.length > 1) {
- var e = new Error("Multiple errors thrown in handling 'sig', see errors property");
- e.errors = errors;
- throw e;
- }
- }
- });
- MochiKit.Signal.EXPORT_OK = [];
- MochiKit.Signal.EXPORT = [
- 'connect',
- 'disconnect',
- 'signal',
- 'disconnectAll',
- 'disconnectAllTo'
- ];
- MochiKit.Signal.__new__ = function (win) {
- var m = MochiKit.Base;
- this._document = document;
- this._window = win;
- this._lock = false;
- this._dirty = false;
- try {
- this.connect(window, 'onunload', this._unloadCache);
- } catch (e) {
- // pass: might not be a browser
- }
- this.EXPORT_TAGS = {
- ':common': this.EXPORT,
- ':all': m.concat(this.EXPORT, this.EXPORT_OK)
- };
- m.nameFunctions(this);
- };
- MochiKit.Signal.__new__(this);
- //
- // XXX: Internet Explorer blows
- //
- if (MochiKit.__export__) {
- connect = MochiKit.Signal.connect;
- disconnect = MochiKit.Signal.disconnect;
- disconnectAll = MochiKit.Signal.disconnectAll;
- signal = MochiKit.Signal.signal;
- }
- MochiKit.Base._exportSymbols(this, MochiKit.Signal);
|