diff --git a/README.md b/README.md index 244a2a3..c44515c 100755 --- a/README.md +++ b/README.md @@ -217,9 +217,9 @@ The call diagram: + pre + pre + + post + post + Action event handler: o-------x o-------x v ^ -Actions o-------x o-------x +Actions: o-------x o-------x v ^ -Root Action o---|---x +Root Action: o---|---x ``` @@ -255,19 +255,19 @@ Root Action o---|---x **Action (event) handler** -When `action_set` object is inherited from a `ActionSet` object or +When `actionSet` object is inherited from a `ActionSet` object or from `MetaActions`: ```javascript -action_set.on('action_name', function(){ +actionSet.on('action_name', function(){ // post code... }) -action_set.on('action_name.post', function(){ +actionSet.on('action_name.post', function(){ // post code... }) -action_set.on('action_name.pre', function(){ +actionSet.on('action_name.pre', function(){ // pre code... }) ``` @@ -288,14 +288,11 @@ action_set.on('action_name.pre', function(){ **Alias** ```javascript - // ... - fullAlias: ['Alias to .full(..) action...', - 'This alias will call the .full(..) action and pass it a couple of arguments', + `This alias will call the .full(..) action and pass it a couple of + arguments`, // the alias code... 'full: "argument" 1'], - - // ... ``` - an action created by `Alias(..)`, @@ -318,178 +315,211 @@ from an instance of `ActionSet`. In general this includes all `ActionSet / object` level methods while anything accessible from the _action_ is build-in. -1. Documentation generation and introspection (`MetaActions`) +#### 1. Documentation generation and introspection (`MetaActions`) - ``` - .toString() - -> code of original action function +``` +.toString() + -> code of original action function - .getDoc() - .getDoc([, ..]) - -> dict of action-name, doc +.getDoc() +.getDoc([, ..]) + -> dict of action-name, doc - .getHandlerDocStr() - -> formated string of action handlers +.getHandlerDocStr() + -> formated string of action handlers - .actions - -> list of action names - ``` +.actions + -> list of action names +``` -2. Event-like callbacks for actions (`MetaActions`, `Action`) +#### 2. Event-like callbacks for actions (`MetaActions`, `Action`) - ``` - .on('action', function(){ ... }) - .on('action.post', function(){ ... }) +``` +.on('action', function(){ ... }) +.on('action.post', function(){ ... }) - .on('action.pre', function(){ ... }) - ``` +.on('action.pre', function(){ ... }) +``` -3. A mechanism to define and extend already defined actions - This replaces / complements the standard JavaScript overloading - mechanisms (`Action`, `Actions`) +#### 3. A mechanism to define and extend already defined actions - ```javascript - // Actions... - var X = Actions({ - m: [function(){ console.log('m') }] - }) - var O = Actions(X, { - m: [function(){ - console.log('pre') - return function(res){ - console.log('post') - } - }] - }) - ``` +This replaces / complements the standard JavaScript overloading +mechanisms (`Action`, `Actions`) - **Notes:** - - what is done here is similar to calling `O.__proto__.m.call(..)` - but is implicit, and not dependant on the original containing - object name/reference (`O`), thus enabling an action to be - referenced and called from any object and still chain correctly. +```javascript +// Actions... +var X = Actions({ + m: [function(){ console.log('m') }] +}) +var O = Actions(X, { + m: [function(){ + console.log('pre') + return function(res){ + console.log('post') + } + }] +}) +``` + +**Notes:** +- what is done here is similar to calling `O.__proto__.m.call(..)` + but is implicit, and not dependant on the original containing + object name/reference (`O`), thus enabling an action to be + referenced and called from any object and still chain correctly. ### Secondary action protocols: -1. A mechanism to manually call the pre/post stages of an action +#### 1. A mechanism to manually call the pre/post stages of an action - Pre phase... - ``` - .pre() - .pre(, [, ..]) - -> - ``` +Pre phase... +``` +.pre() +.pre(, [, ..]) + -> +``` - Post phase... - ``` - .post(, ) - -> - ``` +Post phase... +``` +.post(, ) + -> +``` - This is internally used to implement the action call as well as the - chaining callbacks (see below). +This is internally used to implement the action call as well as the +chaining callbacks (see below). - All action protocol details apply. +All action protocol details apply. - **Notes:** - - there is no reliable way to call the post phase without first - calling the pre phase due to how the pre phase is defined (i.e. - pre phase functions can return post phase functions). +**Notes:** +- there is no reliable way to call the post phase without first + calling the pre phase due to how the pre phase is defined (i.e. + pre phase functions can return post phase functions). -2. A mechanism to chain/wrap actions or an action and a function. - This enables us to call a callback or another action (inner) between - the root action's (outer) pre and post stages. +#### 2. A mechanism to chain/wrap actions or an action and a function. +This enables us to call a callback or another action (inner) between +the root action's (outer) pre and post stages. - ``` - Outer action o-------x o-------x - v ^ - Inner action/callback o---|---x - ``` +``` +Outer action o-------x o-------x + v ^ +Inner action/callback o---|---x +``` - A trivial example: +A trivial example: - ```javascript - actionSet.someAction.chainApply(actionsSet, - function(){ - // this gets run between someAction's pre and post - // stages... - }, - args) - ``` +```javascript +actionSet.someAction.chainApply(actionsSet, + function(){ + // this gets run between someAction's pre and post + // stages... + }, + args) +``` - This is intended to implement protocols where a single action is - intended to act as a hook point (outer) and multiple different - implementations (inner) within a single action set can be used as - entry points. +This is intended to implement protocols where a single action is +intended to act as a hook point (outer) and multiple different +implementations (inner) within a single action set can be used as +entry points. - ```javascript - // Protocol root action (outer) definition... - protocolAction: [function(){}], +```javascript + // Protocol root action (outer) definition... + protocolAction: [function(){}], - // Implementation actions (inner)... - implementationAction1: [function(){ - return this.protocolAction.chainApply(this, function(){ - // ... - }, ..) - }] + // Implementation actions (inner)... + implementationAction1: [function(){ + return this.protocolAction.chainApply(this, function(){ + ... + }, ..) + }], - implementationAction2: [function(){ - return this.protocolAction.chainApply(this, function(){ - // ... - }, ..) - }] - ``` + implementationAction2: [function(){ + return this.protocolAction.chainApply(this, function(){ + ... + }, ..) + }], +``` - Now calling any of the 'implementation' actions will execute code - in the following order: - 1. pre phase of protocol action (outer) - 2. implementation action (inner) - 3. post phase of protocol action (outer) +Now calling any of the 'implementation' actions will execute code +in the following order: +1. pre phase of protocol action (outer) +2. implementation action (inner) +3. post phase of protocol action (outer) - **Notes:** - - this will not affect to protocol/signature of the outer action - in any way. - - both the inner and outer actions will get passed the same - arguments. - - another use-case is testing/debugging actions. - - this is effectively the inside-out of normal action overloading. - - there is intentionally no shorthand for this feature, to avoid - confusion and to discourage the use of this feature unless - really necessary. +**Notes:** +- this will not affect to protocol/signature of the outer action + in any way. +- both the inner and outer actions will get passed the same + arguments. +- another use-case is testing/debugging actions. +- this is effectively the inside-out of normal action overloading. +- there is intentionally no shorthand for this feature, to avoid + confusion and to discourage the use of this feature unless + really necessary. -3. `.__call__` action / handler +#### 3. `.__call__` action / handler - This action if defined is called for every action called. It behaves - like any other action but with a fixed signature, it always receives - the action name as first argument and a list of action arguments as - the second arguments, and as normal a result on the post phase. +This action if defined is called for every action called. It behaves +like any other action but with a fixed signature, it always receives +the action name as first argument and a list of action arguments as +the second arguments, and as normal a result on the post phase. - **Notes:** - - it is not necessary to define the actual action, binding to a - handler will also work. - - one should not call actions directly from within a __call__ - handler as that will result in infinite recursion. - - one should use this with extreme care as this will introduce - an overhead on all the actions if not done carefully. +**Notes:** +- it is not necessary to define the actual action, binding to a + handler will also work. +- one should not call actions directly from within a __call__ + handler as that will result in infinite recursion. +- one should use this with extreme care as this will introduce + an overhead on all the actions if not done carefully. -4. Action attributes +#### 4. Action attributes - XXX +XXX - ``` - .getActionAttr('action', 'attr') - -> +``` +.getActionAttr('action', 'attr') + -> - .getRootActionAttr('action', 'attr') - -> - ``` +.getRootActionAttr('action', 'attr') + -> +``` + +#### 5. Scheduling a call after the running action + +This enables the action code to schedule a call after the current +action level or the root action is done. + +``` +.afterAction(func) +.afterAction('top', func) + -> this + +.afterAction('local', func) + -> this +``` + +Example: +```javascript + someAction: [ + function(){ + ... + + // the function passed will get called after the root action + // and all it's handlers are done. + this.afterAction(function(){ ... }) + + ... + }], +``` + +**Notes:** +- The functions are executed in order of registration. +- This is pointless outside of an action call, this an exception will be thrown. ### Alias protocols: diff --git a/actions.js b/actions.js index 1b86279..90f611d 100755 --- a/actions.js +++ b/actions.js @@ -903,14 +903,16 @@ Action.prototype.post = function(context, data){ .forEach(function(func){ func.call(context) }) // top calls... - if(context.__action_after_running[0] == null){ - ;(context.__action_after_running[1] || []) - .forEach(function(func){ - func.call(context) }) - delete context.__action_after_running - // back to prev level... - } else { - context.__action_after_running = context.__action_after_running[0] + if(context.__action_after_running){ + if(context.__action_after_running[0] == null){ + ;(context.__action_after_running[1] || []) + .forEach(function(func){ + func.call(context) }) + delete context.__action_after_running + // back to prev level... + } else { + context.__action_after_running = context.__action_after_running[0] + } } return res diff --git a/package.json b/package.json index d4d051e..a05f30e 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-actions", - "version": "3.22.0", + "version": "3.22.2", "description": "", "main": "actions.js", "scripts": {