[mochikit] Re: connectEach shortcut
On Tue, Dec 16, 2008 at 3:47 PM, Eoghan eoghanomur...@gmail.com wrote: 2. Modify the lookup by id convention to lookup by selector + map: connect('#my-ul li', 'onclick', func); Yes, changing these lookups would break the current API. But it wouldn't be impossible to create a migration path with decent backwards compatibility if we really want to. The more important issues with this, I think, is that we would have to: * Change every MochiKit.DOM, Style, Signal, Visual... function that accepts the current shortcut to work properly on node lists (not just individual nodes). * Add the MochiKit.Selector module as a dependency for the DOM module (actually a circular dependency). I'm not very convinced that this is the right direction, but on the other side I hardly ever use the current shortcut either. My own use cases all rely on keeping object maps with direct references to my DOM nodes. 4. Map if passed an array-like connect($$('#my-ul li'), 'onclick', func); This looks like the fastest way forward right now. But instead of connecting signal handlers all over, I'd personally do the following instead: var func = function (evt) { var li = evt.target(); if (li.tagName == null || li.tagName.toUpperCase() != LI) { li = getFirstParentByTagAndClassName(evt.target(), LI); } ... whatever you wanted to do ... } connect('my-ul', 'onclick', func); Agreed that using getFirstParentByTagAndClassName() gets a bit messy, since it doesn't check the specified node for a match (just the parents). 5. More powerful partial: forEach($$('#my-ul li'), partial(connect, __, 'onclick', func)); We probably need the more powerful partial or bind, but I'm not so sure about this API. Cheers, /Per --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
On Tue, Dec 16, 2008 at 14:47, Eoghan eoghanomur...@gmail.com wrote: 4. Map if passed an array-like connect($$('#my-ul li'), 'onclick', func); This one gets my vote. cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
So I guess there's a few options. Taking the connect/onclick example: 0. Existing: forEach($$('#my-ul li'), function(el){ connect(el, 'onclick', func); }); 1. JQuery like: Query('#my-ul li').click(func); 2. Modify the lookup by id convention to lookup by selector + map: connect('#my-ul li', 'onclick', func); 3. As above but double the namespace '-) connectAll('#my-ul li', 'onclick', func); 4. Map if passed an array-like connect($$('#my-ul li'), 'onclick', func); 5. More powerful partial: forEach($$('#my-ul li'), partial(connect, __, 'onclick', func)); --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
I think it is an interesting idea to be able to bind any argument position. Think I mentioned it earlier in the 1.5 API discussion that we now have quite a few variants of bind-like functions -- bind, bindLate, bindMethods, forwardCall, partial, method, methodCaller... Too many for my taste, so I think it is time to revisit these API:s. Perhaps something more generic than the current bind() might be a good idea? Or perhaps it would have an API that is too complex? Don't know really. I'll look into the code posted by Arnar later on (no much time right now) and comment on the specifics then. Cheers, /Per On Sun, Dec 14, 2008 at 1:53 AM, Arnar Birgisson arna...@gmail.com wrote: On Sat, Dec 13, 2008 at 23:26, Eoghan eoghanomur...@gmail.com wrote: May I suggest MochiKit.Base.__ as the name of the placeholder variable. If Bob or Per want to include this, I'd like to change it to make it compatible with the current partial (namely, any extra parameters passed on the call itself will just be tacked on the end). MochiKit.Base.__ sounds good to me. Just _ is more likely to step on someone's toes. I can't imagine needing the permuting version myself. Actually, 95% of the cases I've wanted this I just wanted flip (reverse the order of two parameters). At the very least I'd like to see function flip(f) { return function (x,y) { return f(y,x); }; } included. In other cases, I have definitely had use for the generic permuting version. cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
Look at the MochiKit.Query module of the MochiKit Extensions (http:// launchpad.net/mochikit-ext). It provides jQuery style signal functions... MochiKit.Query('#my-ul li').click(function(evt){ // handle events here }); or MochiKit.Query('#my-ul li').click(some_callback); then you can signal to matched elements by simply calling... MochiKit.Query('#my-ul li').click(); Regards -- Amit On Dec 12, 9:45 pm, Eoghan eoghanomur...@gmail.com wrote: I often use the following utility function: function connectEach(iterable, signal, dest, func){ forEach(iterable, function(el){ connect(el, signal, dest, func); }); } It might be used as follows: connectEach($$('#my-ul li'), 'onclick', function(e){ // do sumn' }); rather than slightly more unwieldy: forEach($$('#my-ul li'), function(el){ connect(el, 'onclick', function(e){ // do sumn' }); }); Is it a good candidate to include in the Signal api? Eoghan --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
On Dec 13, 12:45 am, Bob Ippolito b...@redivi.com wrote: Personally I think it's useful, but I would rather have the connect take a selector as a string instead of a list. Makes it much easier to track down when the lookup happens in-connect. connectAll(#my-ul li, onclick, ...); (not sold on the name) We could even have the existing API do this if passed a list, but perhaps that's a bit too magical. connect([#my-ul li], onclick, ...); The other problem is that the return signature has to change for disconnect, or we have to allow for a different kind of disconnect. -bob What I like in MochiKit is that you can pass an id to be looked up by getElement anywhere a DOM node is expected. Some functions, such as connect, could adapt naturally to receiving a list instead of a node (others, such as swapDOM, do not). This might be a crazy suggestion, but if the goal here is to integrate selectors throughout MochiKit, a nice way to do it might be to use findDocElements instead of getElement when a string is passed instead of a node. Implemented along the lines of the following (thanks Arnar): connect(src, sig, objOrFunc, funcOrStr) { // removed:src = MochiKit.DOM.getElement(src); if (typeof(src) == 'string') { return map(function (el) { return connect(el, sig, objOrFunc, funcOrStr);}, MochiKit.Selector.findDocElements(src)); } else { // current connect code for a single element } } This would be backwards incompatible as current code such as: connect('my-id', 'onclick', ) Would have to be rewritten as: connect('#my-id', 'onclick', ) IMO think this would give MochiKit a lot of the ease of use of JQuery, where selectors are pervasive. Is this a bridge too far? Eoghan --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
Hi, On Sat, Dec 13, 2008 at 12:14, Eoghan eoghanomur...@gmail.com wrote: This would be backwards incompatible as current code such as: connect('my-id', 'onclick', ) Would have to be rewritten as: connect('#my-id', 'onclick', ) IMO think this would give MochiKit a lot of the ease of use of JQuery, where selectors are pervasive. Is this a bridge too far? The backwards incompatibility thing is a bit too much I think. One workaround would be to make selector automagically interpret a string like bla as #bla -- but I don't think I'd vote for such as suggestion though :) cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
Hi, On Fri, Dec 12, 2008 at 21:46, Eoghan eoghanomur...@gmail.com wrote: After consideration of generalisation, maybe what I'm looking for is a version of `partial` that can take out of order arguments, something along the following lines: forEach($$('#my-ul li'), partial(connect, MochiKit.Base.placeholder, 'onclick', function(e){ // do sumn' })); Although I'm not sure what the implementation of partial would look like in order to support out of order placeholder arguments... Ah, yes - I have *often* felt the need for this. Here is one possible implementation: function p() { var args = Array.prototype.slice.call(arguments); appendChildNodes('logpane', DIV(null, args.join(', '))); } var _ = new Object(); var invalidNumberOfArgs = new Error(Number of given arguments does not match number of unknown arguments.); function partial() { var args = Array.prototype.slice.call(arguments); var f = args.shift(); var unknowns = filter(MochiKit.Base.partial(operator.seq, _), args).length; return function() { if (arguments.length != unknowns) { throw invaldNumberOfArgs; } var passed = Array.prototype.slice.call(arguments); var filled = map(function (a) { if (a === _) { return passed.shift(); } else { return a; } }, args); return f.apply(this, filled); } } function test() { p('start'); var x = partial(p, one, _, three); x('two'); x = partial(p, _, _, three, _); x('one', 'two', 'four'); p('done'); } addLoadEvent(test); As for permuting arguments, I have some ideas.. let me think about them a bit. cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
Hi again all, On Sat, Dec 13, 2008 at 14:34, Arnar Birgisson arna...@gmail.com wrote: As for permuting arguments, I have some ideas.. let me think about them a bit. Here is an implementation of partial that does out-of-order arguments, both via unnumbered placeholders and numbered ones (see the function test() for examples): // I'm also attaching an html file that you can load in your browser to see it in action. function p() { var args = Array.prototype.slice.call(arguments); appendChildNodes('logpane', DIV(null, args.join(', '))); } function _(n) { return {'__argument_index': n}; } var invalidNumberOfArgs = new Error(Number of given arguments does not match number of unknown arguments.); var mixingNumberedWithUnnumbered = new Error(Cannot mix numbered argument placeholders with numbered ones.); var invalidNumberedPlaceholders = new Error(Numbered placeholders must be sequential (i.e. no gaps) starting from 0 or 1.); function partial() { var args = Array.prototype.slice.call(arguments); var f = args.shift(); var unnumbered = filter(MochiKit.Base.partial(operator.seq, _), args).length; var indexes = map(itemgetter('__argument_index'), filter(function (a) { return typeof a == 'object' '__argument_index' in a; }, args)); if (unnumbered 0 indexes.length 0) { throw mixingNumberedWithUnnumbered; } if (indexes.length == 0) { return function() { if (arguments.length != unnumbered) { throw invalidNumberOfArgs; } var passed = Array.prototype.slice.call(arguments); var filled = map(function (a) { if (a === _) { return passed.shift(); } else { return a; } }, args); return f.apply(this, filled); } } else { // some sanity checks var sorted = indexes.slice(0); sorted.sort(); if (sorted[0] == 1) { indexes = map(function (x) {return x-1;}, indexes); sorted = map(function (x) {return x-1;}, sorted); } else if (sorted[0] != 0) { throw invalidNumberedPlaceholders; // must start with 0 or 1 } // make sure there are no gaps if (!every(izip(count(), sorted), function (pair) { return pair[0] == pair[1]})) { throw invalidNumberedPlaceholders; // can't have gaps } return function() { if (arguments.length != indexes.length) { throw invalidNumberOfArgs; } var passed = Array.prototype.slice.call(arguments); var i = 0; var filled = map(function (a) { if (typeof a == 'object' '__argument_index' in a) { return passed[indexes.shift()]; } else { return a; } }, args); return f.apply(this, filled); } } } function test() { p('start'); var x = partial(p, one, _, three); x('two'); x = partial(p, _, _, three, _); x('one', 'two', 'four'); x = partial(p, _); x('one'); x = partial(p, 'one'); x(); x = partial(p, _(2), _(1)); x('two', 'one'); // for convenience: function flip(f) { return partial(f, _(2), _(1)); } x = flip(p); x('two', 'one'); // can also be zero based x = partial(p, _(1), _(0)); x('two', 'one'); x = partial(p, 'one', _(3), 'three', _(1), 'five', _(2)); x('four', 'six', 'two'); p('done'); } addLoadEvent(test); cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~--- Title: untitled
[mochikit] Re: connectEach shortcut
On Dec 13, 2:34 pm, Arnar Birgisson arna...@gmail.com wrote: Hi, On Fri, Dec 12, 2008 at 21:46, Eoghan eoghanomur...@gmail.com wrote: After consideration of generalisation, maybe what I'm looking for is a version of `partial` that can take out of order arguments, something along the following lines: forEach($$('#my-ul li'), partial(connect, MochiKit.Base.placeholder, 'onclick', function(e){ // do sumn' })); Although I'm not sure what the implementation of partial would look like in order to support out of order placeholder arguments... Ah, yes - I have *often* felt the need for this. Here is one possible implementation: function p() { var args = Array.prototype.slice.call(arguments); appendChildNodes('logpane', DIV(null, args.join(', '))); } var _ = new Object(); var invalidNumberOfArgs = new Error(Number of given arguments does not match number of unknown arguments.); function partial() { var args = Array.prototype.slice.call(arguments); var f = args.shift(); var unknowns = filter(MochiKit.Base.partial(operator.seq, _), args).length; return function() { if (arguments.length != unknowns) { throw invaldNumberOfArgs; } var passed = Array.prototype.slice.call(arguments); var filled = map(function (a) { if (a === _) { return passed.shift(); } else { return a; } }, args); return f.apply(this, filled); } } function test() { p('start'); var x = partial(p, one, _, three); x('two'); x = partial(p, _, _, three, _); x('one', 'two', 'four'); p('done'); } addLoadEvent(test); As for permuting arguments, I have some ideas.. let me think about them a bit. cheers, Arnar Very nice, I thought to implement this myself but baulked. May I suggest MochiKit.Base.__ as the name of the placeholder variable. I can't imagine needing the permuting version myself. Eoghan --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
On Sat, Dec 13, 2008 at 23:26, Eoghan eoghanomur...@gmail.com wrote: May I suggest MochiKit.Base.__ as the name of the placeholder variable. If Bob or Per want to include this, I'd like to change it to make it compatible with the current partial (namely, any extra parameters passed on the call itself will just be tacked on the end). MochiKit.Base.__ sounds good to me. Just _ is more likely to step on someone's toes. I can't imagine needing the permuting version myself. Actually, 95% of the cases I've wanted this I just wanted flip (reverse the order of two parameters). At the very least I'd like to see function flip(f) { return function (x,y) { return f(y,x); }; } included. In other cases, I have definitely had use for the generic permuting version. cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
Hi On 12.12.2008, at 16:45, Eoghan eoghanomur...@gmail.com wrote: connectEach($$('#my-ul li'), 'onclick', function(e){ // do sumn' }); rather than slightly more unwieldy: forEach($$('#my-ul li'), function(el){ connect(el, 'onclick', function(e){ // do sumn' }); }); Is it a good candidate to include in the signal api? I can definitely see the use case, but IMO this is one of the cases where I'd not want to add since forEach is not that much typing. In my mind this the whole point of having a functional, composable API such as the iter module. Just my 2000 ISK cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
On Dec 12, 7:20 pm, Arnar Birgisson arna...@gmail.com wrote: Hi On 12.12.2008, at 16:45, Eoghan eoghanomur...@gmail.com wrote: connectEach($$('#my-ul li'), 'onclick', function(e){ // do sumn' }); rather than slightly more unwieldy: forEach($$('#my-ul li'), function(el){ connect(el, 'onclick', function(e){ // do sumn' }); }); Is it a good candidate to include in the signal api? I can definitely see the use case, but IMO this is one of the cases where I'd not want to add since forEach is not that much typing. In my mind this the whole point of having a functional, composable API such as the iter module. Just my 2000 ISK cheers, Arnar I agree. After consideration of generalisation, maybe what I'm looking for is a version of `partial` that can take out of order arguments, something along the following lines: forEach($$('#my-ul li'), partial(connect, MochiKit.Base.placeholder, 'onclick', function(e){ // do sumn' })); Although I'm not sure what the implementation of partial would look like in order to support out of order placeholder arguments... Eoghan --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
On Fri, Dec 12, 2008 at 11:20 AM, Arnar Birgisson arna...@gmail.com wrote: Hi On 12.12.2008, at 16:45, Eoghan eoghanomur...@gmail.com wrote: connectEach($$('#my-ul li'), 'onclick', function(e){ // do sumn' }); rather than slightly more unwieldy: forEach($$('#my-ul li'), function(el){ connect(el, 'onclick', function(e){ // do sumn' }); }); Is it a good candidate to include in the signal api? I can definitely see the use case, but IMO this is one of the cases where I'd not want to add since forEach is not that much typing. In my mind this the whole point of having a functional, composable API such as the iter module. Just my 2000 ISK Personally I think it's useful, but I would rather have the connect take a selector as a string instead of a list. Makes it much easier to track down when the lookup happens in-connect. connectAll(#my-ul li, onclick, ...); (not sold on the name) We could even have the existing API do this if passed a list, but perhaps that's a bit too magical. connect([#my-ul li], onclick, ...); The other problem is that the return signature has to change for disconnect, or we have to allow for a different kind of disconnect. -bob --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---
[mochikit] Re: connectEach shortcut
Hi, On Sat, Dec 13, 2008 at 00:45, Bob Ippolito b...@redivi.com wrote: connect([#my-ul li], onclick, ...); I agree this looks a little bit too magical. Perhaps more expected would be to allow the first argument to be a list, but in that case a list of elements (or strings passed to getElement). The selector case is then simply: connect($$(#my-ul li), onclick, ...); As for the return, this would return a list. I.e. connect(elements, event, handler) { if (isIterable(elements)) { return map(function (el) {connect(el, event, handler);}, elements); } else { // current connect code for a single element } } cheers, Arnar --~--~-~--~~~---~--~~ 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 mochikit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~--~~~~--~~--~--~---