Sorry, I was probably unclear in my previous post. In this comment: >1. connect(src, signal, dst, func) uses late binding to dst[func] for >DOM signals, but uses early binding in other cases (with >MochiKit.Base.bind). I think we should use late binding at all times >instead.
I was not referring to your suggested patch. Rather that MochiKit sometimes does the dst[func] --> <function object> lookup when calling connect(), and sometimes only when the actual signals happen (late binding). I think late binding is better, since then it will be possible to redefine functions, etc. In either way, I think the behavior should be consistent. Actually, thinking about this I registered a new Trac ticket: http://trac.mochikit.com/ticket/307 Anyway, my main point was that MochiKit.Signal.signal(...) doesn't do what the documentation says. So I think it should be corrected, as the documented behavior seems reasonable to me. Think that is another Trac ticket... :-) Cheers, /Per On Wed, May 14, 2008 at 9:03 AM, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > > Hi Per, > > Thanks for the feedback. > > I am unsure how making it late bound helps, doesn't that just shift > the problem? How would that behave in the following two cases; > > 1. A request to connect "onclick" occurs. > > Does the listener early bind a function to the native event onclick > which then calls the clients function late bound? If so what > advantage does this have? > > 2. A request to connect(someDomElement, "my-custom-signal", > myHandler); occurs. > > When signal(someDomElement, "my-custom-signal", "param1", "param2") > occurs how does the late binding know whether to try and wrap a > native event to pass to myHandler or whether to pass the arguments > passed to signal? Wont signal() still need to look at the signal > name to determine if it is a DOM event handler or not? > > My original point about the documentation was not so much that I > thought the contract wasn't being fullfilled but rather that in order > to implement cross browser DOM event handling MochiKit had already > decided to always expect the "on" prefix and to remove it for those > browsers that don't want it. (MochiKit could have gone the other way > and never accepted the "on" when registering events but then it would > have to add it for those browsers that do want it). > > So seeing as MochiKit has already made the decision that all DOM Event > signals must start with "on" then we could take advantage of this > documented expectation to allow handling for custom signals on DOM > Elements without breaking any backwards compatibility. > > On a side note, I am currently working on a patch for handling mouse > scroll events in a uniform way. Different browsers use completely > different names for these events I was planning on early binding > browser specific handlers that normalise the values, etc so I am keen > to solve this problem so that my next patch wont conflict. > > Regards, Simon. > > On May 6, 6:00 pm, "Per Cederberg" <[EMAIL PROTECTED]> wrote: >> I've also been bitten by this same issue, but didn't dig deeper into >> it before. Great analysis and nice with a patched solution! >> >> Looking at the code in MochiKit.Signal, I have two comments: >> >> 1. connect(src, signal, dst, func) uses late binding to dst[func] for >> DOM signals, but uses early binding in other cases (with >> MochiKit.Base.bind). I think we should use late binding at all times >> instead. >> >> 2. I don't agree with the solution to the issue that signal() doesn't >> fulfill its contract (as per the documentation). Rather, I think a >> better solution would be to modify signal() to call ident.objOrFunc >> and ident.objOrFunc directly instead of using ident.listener. Then it >> would be fully up to the caller of signal() which arguments are to be >> specified and in which order. Using the "on" prefix seems a bit like >> an ad-hoc work-around to me. >> >> Cheers, >> >> /Per >> >> On Mon, May 5, 2008 at 7:44 AM, [EMAIL PROTECTED] >> >> <[EMAIL PROTECTED]> wrote: >> >> > Hi all, >> >> > I have found it very handy while building widgets to be able to >> > connect custom signals on DOM elements to arbitrary handlers. >> > Unfortunately "signal( elem, signalName, param1, param2, ...)" didn't >> > work as expected. >> >> > I traced this down to the isDOM check in the connect function. >> >> > Signal.connect is assuming that if the src object has an >> > addEventListener or an attachEvent attribute then the handler wants to >> > be passed the MochiKit.Event object. For my handlers bound to custom >> > signals this is not the case, it wouldn't really matter except that I >> > also like to pass arguments via MochiKit.signal to these handlers. >> >> > My fix is based on the documented assumption that MochiKit assumes an >> > `on' prefix for all DOM event signals. I assume that MochiKit's goal >> > here is to homogonise the different events between browsers. For >> > example, MochiKit assumes `on...' and then removes it for browsers >> > that want to have `click' connected instead of 'onclick', etc. >> >> > Thus if in Signal.connect the isDOM calculation is strengthened to >> > make this assumption explicit then we get the ability to connect >> > custom signals to DOM elements and have Signal.signal pass any extra >> > parameters correctly. Eg; >> >> > var isDOM = (src.addEventListener || src.attachEvent) && >> > (sig.substr(0,2) === 'on'); >> >> > The only caveat is that custom signals cannot start with 'on' which I >> > think is acceptable as that is already a documented assumption by >> > MochiKit. >> >> > This allows for the following code to work; >> >> > var myHandler = function( one, two, three ) { log( one, two, >> > three ); }; >> > connect( 'my-div', 'my-custom-event', myHandler ); >> > signal ( 'my-div', 'my-custom-event', 1, 2, 3 ); >> >> > this will log "1 2 3". >> >> > Below is a diff against SVN Revision 1368 including changes to the >> > test suite. >> >> > I have tested against FF2 and IE7 which is all I have access to, I >> > would appreciate it if others with access to other browsers could run >> > the test too. >> >> > Regards, Simon Cusack. >> >> > diff -r ae903235ba94 MochiKit/Signal.js >> > --- a/MochiKit/Signal.js Mon May 05 13:37:27 2008 +1000 >> > +++ b/MochiKit/Signal.js Mon May 05 15:39:44 2008 +1000 >> > @@ -63,7 +63,7 @@ >> > str += '}'; >> > } >> > } >> > - if (this.type() == 'mouseover' || this.type() == 'mouseout' >> > || >> > + if (this.type() == 'mouseover' || this.type() == 'mouseout' >> > || >> > this.type() == 'mouseenter' || this.type() == >> > 'mouseleave') { >> > str += ', relatedTarget(): ' + >> > repr(this.relatedTarget()); >> > } >> > @@ -516,10 +516,10 @@ >> > if (sig === 'onload' || sig === 'onunload') { >> > return function (nativeEvent) { >> > obj[func].apply(obj, [new E(src, nativeEvent)]); >> > - >> > + >> > var ident = new MochiKit.Signal.Ident({ >> > source: src, signal: sig, objOrFunc: obj, >> > funcOrStr: func}); >> > - >> > + >> > MochiKit.Signal._disconnect(ident); >> > }; >> > } else { >> > @@ -531,10 +531,10 @@ >> > if (sig === 'onload' || sig === 'onunload') { >> > return function (nativeEvent) { >> > func.apply(obj, [new E(src, nativeEvent)]); >> > - >> > + >> > var ident = new MochiKit.Signal.Ident({ >> > source: src, signal: sig, objOrFunc: func}); >> > - >> > + >> > MochiKit.Signal._disconnect(ident); >> > }; >> > } else { >> > @@ -613,7 +613,13 @@ >> > obj = src; >> > } >> >> > - var isDOM = !!(src.addEventListener || src.attachEvent); >> > + // The documentation states that DOM signals all start with >> > + // 'on', so make this an explicit check, which has the bonus >> > + // of allowing us to connect custom signals to elements and >> > + // have our handler get called with the params passed to >> > + // signal instead of the wrapped native Event object. >> > + var isDOM = (src.addEventListener || src.attachEvent) && >> > (sig.substr(0,2) === 'on'); >> > + >> > if (isDOM && (sig === "onmouseenter" || sig === >> > "onmouseleave") >> > && !self._browserAlreadyHasMouseEnterAndLeave()) { >> > var listener = self._mouseEnterListener(src, >> > sig.substr(2), func, obj); >> > @@ -626,19 +632,20 @@ >> > var listener = self._listener(src, sig, func, obj, >> > isDOM); >> > } >> >> > - if (src.addEventListener) { >> > - src.addEventListener(sig.substr(2), listener, false); >> > - } else if (src.attachEvent) { >> > - src.attachEvent(sig, listener); // useCapture unsupported >> > + if (isDOM) { >> > + if (src.addEventListener) { >> > + src.addEventListener(sig.substr(2), listener, false); >> > + } else if (src.attachEvent) { >> > + src.attachEvent(sig, listener); // useCapture >> > unsupported >> > + } >> > } >> > - >> > var ident = new MochiKit.Signal.Ident({ >> > - source: src, >> > - signal: sig, >> > - listener: listener, >> > - isDOM: isDOM, >> > - objOrFunc: objOrFunc, >> > - funcOrStr: funcOrStr, >> > + source: src, >> > + signal: sig, >> > + listener: listener, >> > + isDOM: isDOM, >> > + objOrFunc: objOrFunc, >> > + funcOrStr: funcOrStr, >> > connected: true >> > }); >> > self._observers.push(ident); >> > diff -r ae903235ba94 tests/test_MochiKit-Signal.html >> > --- a/tests/test_MochiKit-Signal.html Mon May 05 13:37:27 2008 +1000 >> > +++ b/tests/test_MochiKit-Signal.html Mon May 05 15:39:44 2008 +1000 >> > @@ -4,26 +4,29 @@ >> > <script type="text/javascript" src="../MochiKit/Iter.js"></ >> > script> >> > <script type="text/javascript" src="../MochiKit/DOM.js"></script> >> > <script type="text/javascript" src="../MochiKit/Style.js"></ >> > script> >> > - <script type="text/javascript" src="../MochiKit/Signal.js"></ >> > script> >> > - <script type="text/javascript" src="../MochiKit/Logging.js"></ >> > script> >> > - <script type="text/javascript" src="SimpleTest/SimpleTest.js"></ >> > script> >> > + <script type="text/javascript" src="../MochiKit/Signal.js"></ >> > script> >> > + <script type="text/javascript" src="../MochiKit/Logging.js"></ >> > script> >> > + <script type="text/javascript" src="SimpleTest/SimpleTest.js"></ >> > script> >> > <link rel="stylesheet" type="text/css" href="SimpleTest/ >> > test.css"> >> >> > </head> >> > <body> >> >> > Please ignore this button: <input type="submit" id="submit" /><br /> >> > +Please ignore this div: <br /> >> > +<div id="custom-signal-test" /> >> > +<br /> >> >> > <pre id="test"> >> > <script type="text/javascript" src="test_Signal.js"></script> >> > <script type="text/javascript"> >> > try { >> > - >> > + >> > tests.test_Signal({ok:ok, is:is}); >> > ok(true, "test suite finished!"); >> > - >> > + >> > } catch (err) { >> > - >> > + >> > var s = "test suite failure!\n"; >> > var o = {}; >> > var k = null; >> > diff -r ae903235ba94 tests/test_Signal.js >> > --- a/tests/test_Signal.js Mon May 05 13:37:27 2008 +1000 >> > +++ b/tests/test_Signal.js Mon May 05 15:39:44 2008 +1000 >> > @@ -3,7 +3,7 @@ >> > if (typeof(tests) == 'undefined') { tests = {}; } >> >> > tests.test_Signal = function (t) { >> > - >> > + >> > var submit = MochiKit.DOM.getElement('submit'); >> > var ident = null; >> > var i = 0; >> > @@ -14,7 +14,7 @@ >> > i += this.someVar; >> > } >> > }; >> > - >> > + >> > var aObject = {}; >> > aObject.aMethod = function() { >> > t.ok(this === aObject, "aMethod should have 'this' as >> > aObject"); >> > @@ -37,19 +37,19 @@ >> >> > disconnect(ident); >> > submit.click(); >> > - t.is(i, 2, '...and then disconnected'); >> > - >> > - if (MochiKit.DOM.getElement('submit').fireEvent || >> > - (document.createEvent && >> > + t.is(i, 2, '...and then disconnected'); >> > + >> > + if (MochiKit.DOM.getElement('submit').fireEvent || >> > + (document.createEvent && >> > typeof(document.createEvent('MouseEvents').initMouseEvent) == >> > 'function')) { >> > - >> > - /* >> > - >> > - Adapted from: >> > + >> > + /* >> > + >> > + Adapted from: >> > >> > http://www.devdaily.com/java/jwarehouse/jforum/tests/selenium/javascr... >> > License: Apache >> > Copyright: Copyright 2004 ThoughtWorks, Inc >> > - >> > + >> > */ >> > var triggerMouseEvent = function(element, eventType, >> > canBubble) { >> > element = MochiKit.DOM.getElement(element); >> > @@ -98,7 +98,7 @@ >> > t.ok((typeof(e.key()) === 'undefined'), 'checking that >> > key() is undefined'); >> > }; >> >> > - >> > + >> > ident = connect('submit', 'onmousedown', eventTest); >> > triggerMouseEvent('submit', 'mousedown', false); >> > t.is(i, 3, 'Connecting an event to an HTML object and firing >> >> ... >> >> read more ยป > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "MochiKit" group. To post to this group, send email to mochikit@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~----------~----~----~----~------~----~------~--~---