[wp-trac] [WordPress Trac] #21170: JavaScript actions and filters
WordPress Trac
wp-trac at lists.automattic.com
Sun Jul 15 12:05:18 UTC 2012
#21170: JavaScript actions and filters
----------------------------+--------------------------
Reporter: koopersmith | Owner: koopersmith
Type: task (blessed) | Status: new
Priority: normal | Milestone: 3.5
Component: General | Version: 3.4
Severity: normal | Resolution:
Keywords: |
----------------------------+--------------------------
Comment (by carldanley):
Replying to [comment:31 azaozz]:
> The .namespace/identifier bit would only be used to identify the
callback, so each "leaf" on the "branch" would have a name and we would be
able to easily remove anonymous "leaves" by branch name + leaf name
So, as an example, when we use the action identifier
'actionname.namespace.other.third', I was thinking that there were several
identifiers for this particular action. The action being 'actionname' and
then several tiers of identifiers: 'actionname.namespace',
'actionname.namespace.other', 'actionname.namespace.other.third'. Each
unique identifier tier would simply be it's own key in a flat array.
Essentially, the callback passed lives in the
'actionname.namespace.other.third' array key. However, the problem I see
with this is as follows:[[br]][[br]]
{{{
addAction( 'foo.bar', callback1 );
//Actions:
//ACTIONS[ 'foo.bar' ] = [ callback1 ];
addAction( 'foo.bar.test', callback2 );
//Actions:
//ACTIONS[ 'foo.bar' ] = [ callback1 ];
//ACTIONS[ 'foo.bar.test' ] = [ callback2 ];
addAction( 'foo.bar.test.foo', callback3 );
//Actions:
//ACTIONS[ 'foo.bar' ] = [ callback1 ];
//ACTIONS[ 'foo.bar.test' ] = [ callback2 ];
//ACTIONS[ 'foo.bar.test.foo' ] = [ callback3 ];
}}}
So when we doAction( 'foo.bar' ), we'd have to loop through each key in
the flat array finding keys prefixed with 'foo.bar' and execute them. To
me, this could get very heavy ( especially since we'd have to use for( var
k in arr ) ) in different areas of a site with a lot of plugins installed.
To combat this, I created the tree for easier access in calling the
'children' identifiers. Meaning, if we called 'foo.bar' in this example,
we would know that 'foo.bar' would have an array of callbacks that needed
execution and to find the children, we know the object had a property
called children where 'foo.bar.test' and 'foo.bar.test.foo' lived in the
same manner that their ancestor, 'foo.bar', was created ( as an object
with properties like 'callbacks' and 'children' ). I really like the flat
array approach, I was just hesitant because of look-up speed for doing
anything. You could also make the value of each unique array key an object
with 2 properties ('callbacks' and 'siblings' where 'siblings' would store
an array of values that could be used to find siblings when looking up for
deletion/execution)[[br]][[br]]
> If we create the nodes as instances of a small class, or even as simple
objects, we can store the nodeType in each.
Consider the following:
{{{
var appendHookToArray = function( arr, hookIdentifier, data ){
var identifiers = hookIdentifier.split( '.' );
var levels = [], identifier;
for( var i = 1, len = identifiers.length; i <= len; i++ ){
identifier = identifiers.slice( 0, i ).join( '.' );
if( arr[ identifier ] === undefined ){
arr[ identifier ] = [];
if( i === len ){
//just push it since we know it's a new
identifier
arr[ identifier ].push( data );
}
}
else if( i === len ){
//insert the callback now
arr[ identifier ] = insertHookByPriority( arr[
identifier ], data );
}
}
return arr;
};
}}}
So then, when addAction is called all it does is this:
{{{
SELF.addAction = function( action, callback, priority ){
if( typeof callback !== 'function' ){
return SELF;
}
ACTIONS = appendHookToArray( ACTIONS, action, {
'callback' : callback,
'priority' : ( priority || 10 )
} );
return SELF;
};
}}}
With 'ACTIONS' being a private class property ( 'FILTERS' would also exist
as something separately. ) ACTIONS/FILTERS will def. need to be kept
separate but I think that adding a 'nodeType' property to the object
created is a little bit of an unnecessary waste, if i'm understanding
correctly, meaning: I don't think it's necessary to specify nodeType of
'action' for 100+ different actions, as an example. We already know that
it's an action because we have to access the 'ACTIONS' variable and, for
this example, storing a 'nodeType' for each ACTION of value 'action' would
mean making the array 600+ bytes heavier at run-time. I would use the same
new 'object' class for both actions and filters. Thoughts?
> Yeah, chaining is definitely handy. The question is whether it's better
to support chaining or to return true/false on success/failure when adding
or removing actions and filter.
You're also making me sway on chaining vs. true/false. It would
interesting to hear other opinions as well.
> Perhaps if we get it right, it can also be released as a stand-alone JS
class.
That's what I'm shooting for! :)
--
Ticket URL: <http://core.trac.wordpress.org/ticket/21170#comment:32>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list