Module: capsula

Capsula.js is the core module of Capsula library. The base concept of Capsula library is the Capsule class, a class similar to an OO class with different encapsulation model and many new and powerful concepts like operations, hooks, loops, and many more.

To create new Capsule class, use defCapsule method.

Since:
  • 0.1.0
Source:

Requires

Classes

Capsule
Data
ElementRef
Hook
Input
Loop
Operation
Output

Namespaces

Errors
ServiceType

Members

(static, constant) STOP

Constant to return from operation's filter function or to use as an argument in operation's setFilter to stop propagation of operation call (read more on filters in setFilter, getFilter, and operation's documentation).
Since:
  • 0.1.0
Source:

Methods

(static) contextualize(f) → {function}

Creates and returns new contextualized function that "remembers" the context in which this function (contextualize) is called. When called, the returned function executes the function being an argument of contextualize within that "remembered" context.
Parameters:
Name Type Description
f function function to be executed by the returned contextualized function in the context in which contextualize is called
Since:
  • 0.1.0
Source:
Throws:
Type
Error
Returns:
contextualized function that executes the given function in the context in which contextualize is called
Type
function

(static) defCapsule(def) → {function}

Creates and returns a capsule constructor function based on the given capsule (class) definition object.
Parameters:
Name Type Description
def Object capsule (class) definition object
Since:
  • 0.1.0
Source:
Throws:
Type
Error
Returns:
capsule constructor function
Type
function
Examples

The simplest possible capsule (class)

let TheSimplest = sol.defCapsule({}); // creates capsule class
let capsule = new TheSimplest();      // creates capsule object

Simple capsule (class) with two operations, hook, and loop

let Simple = sol.defCapsule({
    '> in': null,  // an input operation named in
    '< out': null, // an output operation named out
    hooks: 'h',    // a hook named h
    loops: 'l'     // a loop named l
});

Full-featured capsule (class)

var FullFeatured = sol.defCapsule({
    isAbstract: false, // or true (to prevent creation of direct instances)
    base: TheSimplest, // inherit from TheSimplest
    init: function(){  // the constructor function
        // ...
    },
    handle: function(error){ // error handler function, for all errors thrown inside this capsule
        // ...
    },

    // hooks and loops
    hooks: ['h1', 'h2'], // an array of hooks, or a single string in case of a single hook
    loops: 'l1',         // an array of loops, or a single string in case of a single loop

    // input declarations

    '> in1': null,       // declaration of an input operation
    '> in2': function(){ // input operation wired to a protected method with the same name
        return 'Hi';
    },
    '> in3': 'this.out1',            // input operation wired to an existing output operation
    '> in4': ['this.out1', 'p1.in'], // input operation wired to several existing output operations

    // output declarations

    '< out1': null,                   // declaration of an output operation
    '< out2': function(arg1, arg2){}, // operation parameters declaratively listed, the body does not count

    // filters

    'f this.in1': function(){ // operation filter returning an array of filtered values
        return [...];
    },
    'f this.in2': function(){ // operation filter preventing propagation of operation calls
        return sol.STOP;
    },

    // public and protected methods

    '+ publicMethod': function(){ // declaration of public method
        return 'Hi';
    },
    privateMethod: function(){    // declaration of protected method
        return 'Hello world';
    },

    // part declarations
    p1: Part,             // no arguments
    p2: {                 // the same as above
        capsule: Part
    },
    p3: {                 // fixed arguments
        capsule: Part,
        args: 'Hi world'  // args or arguments (can be used interchangeably)
    },
    p4: {                 // the same arguments used for instantiation of this (FullFeatured) capsule
        capsule: Part,
        args: 'this.args'
    },
    p5: {                 // the FullFeatured capsule instance (this) given as an argument
        capsule: Part,
        args: 'this'
    },
    p6: {                 // arguments created "on spot" using function
        capsule: Part,
        deferredArgs: function(){
            return {message: 'Hello world'};
        }
    },

    // wires

    'this.in1': ['this.out1', 'p1.in'],
    'this.in2': 'this.out2',
    'p2.out': 'this.out1',
    'p3.out': ['this.out2', 'p4.in'],

    // ties

    'this.l1': 'p1.l',
    'p1.h': ['p2.l', 'p3.l', 'this.h1'],

    // data

    sharedInitialValue: {...}, // all instances share the same value (object, array, or whatever), but the reference is not static, it is just initialized with the same value for each FullFeatured capsule

    myObject: '*{}',        // each capsule gets its own Object in myObject
    myArray: '*[]',         // each capsule gets its own Array in myArray
    myMap: '*Map',          // each capsule gets its own Map in myMap
    mySet: '*Set',          // each capsule gets its own Set in mySet
    myWeakMap: '*WeakMap',  // each capsule gets its own WeakMap in myWeakMap
    myWeakSet: '*WeakSet',  // each capsule gets its own WeakSet in myWeakSet

    myData: {               // general case for data
        call: function(){   // "call" can be replaced with "new" if the function is to be called using the "new" operator
            return ...;     // myData becomes what is returned here
        },
        args: ...           // (arguments / deferredArgs) arguments for the function above it; the same as with parts (see above)
    },
});

(static) extend(Sub, Base)

Not meant to be used by regular users; only by those who work on the framework itself.

Declares that the derived class Sub (i.e. its constructor function) inherits the base class Base. Sets the prototype chain so that instanceof operator and constructor property work correctly. Also, provides the access to the base class constructor via super$ property of the Sub constructor.

Parameters:
Name Type Description
Sub function function that acts as a sub-class constructor
Base function function constructor that acts as a base class constructor
Since:
  • 0.1.0
Source:

(static) isCapsule(obj) → {boolean}

Checks whether the given object is (instance of) capsule or not.
Parameters:
Name Type Description
obj Object object to be checked
Since:
  • 0.1.0
Source:
Returns:
whether the given object is (instance of) capsule or not
Type
boolean

(static) isCapsuleConstructor(func) → {boolean}

Checks whether the given function is capsule constructor (i.e. created using defCapsule) or not.
Parameters:
Name Type Description
func function function to be checked
Since:
  • 0.1.0
Source:
Returns:
whether the given function is capsule constructor or not
Type
boolean

(static) isData(obj) → {boolean}

Checks whether the given object is data or not.
Parameters:
Name Type Description
obj Object object to be checked
Since:
  • 0.2.0
Source:
Returns:
whether the given object is data or not
Type
boolean

(static) isHook(obj) → {boolean}

Checks whether the given object is hook or not.
Parameters:
Name Type Description
obj Object object to be checked
Since:
  • 0.1.0
Source:
Returns:
whether the given object is hook or not
Type
boolean

(static) isLoop(obj) → {boolean}

Checks whether the given object is loop or not.
Parameters:
Name Type Description
obj Object object to be checked
Since:
  • 0.1.0
Source:
Returns:
whether the given object is loop or not
Type
boolean

(static) isOperation(obj) → {boolean}

Checks whether the given object is operation or not.
Parameters:
Name Type Description
obj Object object to be checked
Since:
  • 0.1.0
Source:
Returns:
whether the given object is operation or not
Type
boolean

(static) setDefaultElementHandlers(onHook, offHook, setClasses)

This function gives the (domain-specific) meaning to connecting hooks and loops. Before reading this, one should be familiar with information on hooks and loops.

Function setDefaultElementHandlers injects onHook, offHook, and setClasses functions into the framework, later to be called by the framework when certain events occur. Events that trigger calls to onHook, offHook, and setClasses functions are related to paths of hooks and loops.

onHook, offHook, and setClasses functions are therefore always called with respect to a path that changed: when a path of hooks and loops gets completed onHook function is called; when completed path of hooks and loops gets broken (fragmented) offHook is called; when setClass is called on a hook that sits on a complete path of hooks and loops setClasses is called. In each of the cases the function may be called more than once, depending on a number of affected elements.

onHook and offHook functions should actually modify the hierarchy of (external) elements. onHook function should create a parent-child relationship between two elements. offHook function should break a parent-child relationship between two elements.

onHook function is called by the framework with the following arguments:
- hookElement - parent element in the parent-child relationship to be created by the onHook function; this element is represented by the connector hook of the path that just got completed
- loopElement - child element in the parent-child relationship to be created by the onHook function; this element is represented by the connector loop of the path that just got completed
- afterElement - the element before which the loopElement should be placed in a collection of child elements of the hookElement
- classes - a collection of classes to add to the loopElement (interpretation of classes is left undefined and depends on the domain); (see hook's setClass method)

offHook function is called by the framework with the following arguments:
- hookElement - parent element in the parent-child relationship to be broken by the offHook function; this element is represented by the connector hook of the path that just got broken
- loopElement - child element in the parent-child relationship to be broken by the offHook function; this element is represented by the connector loop of the path that just got broken
- classes - a collection of classes to remove from the loopElement

setClasses function should apply the list of classes to an element.

setClasses function is called by the framework with the following arguments:
- loopElement - this element is represented by the connector loop of the complete path in which any of the hooks got its class modified (by setClass)
- classes - a collection of classes to set to the loopElement

The example bellow shows how to implement onHook, offHook, and setClasses functions for DOM elements. This example is exactly how html.js module injects these functions into the framework to handle hierarchy of HTML (DOM) elements.

Parameters:
Name Type Description
onHook function function that creates a parent-child relationship between two (external) elements
offHook function function that breaks a parent-child relationship between two (external) elements
setClasses function function that updates classes of an element
Since:
  • 0.1.0
Source:
Throws:
Type
Error
Example

Example of setting onHook and offHook functions when elements are assumed to be the DOM elements

capsula.setDefaultElementHandlers(
    function onHook(hookElement, loopElement, afterElement, classes) {
        if (afterElement)
            hookElement.insertBefore(loopElement, afterElement); // DOM's insertBefore
        else
            hookElement.appendChild(loopElement); // DOM's appendChild
        for (var i = 0; i < classes.length; i++)
            loopElement.classList.add(classes[i]); // DOM's classList and add
    },
    function offHook(hookElement, loopElement, classes) {
        if (loopElement.parentElement === hookElement)
            hookElement.removeChild(loopElement); // DOM's removeChild
        for (var i = 0; i < classes.length; i++)
            loopElement.classList.remove(classes[i]); // DOM's classList and remove
    },
    function setClasses(loopElement, classes){
        var classList = loopElement.classList;
        while (classList.length > 0)
            classList.remove(classList.item(0));
        classList.add.apply(classList, classes);
    }
);

(static) signOffForPostProcessing(fn)

Experimental feature.

Removes the given function from the list of callbacks that will be called each time asynhronous propagation of operation calls is completed.

Parameters:
Name Type Description
fn function function to be removed
Since:
  • 0.1.0
Source:
Throws:
Type
Error

(static) signOnForPostProcessing(fn)

Experimental feature.

Adds the given function to the list of callbacks that will be called each time asynhronous propagation of operation calls is completed.

Parameters:
Name Type Description
fn function function to be added
Since:
  • 0.1.0
Source:
Throws:
Type
Error

(static) tie(hkLp1, hkLp2)

Ties the two given hooks or loops according to the current context of execution. There is no requirement in terms of ordering of the two arguments.
Parameters:
Name Type Description
hkLp1 module:capsula.Hook | module:capsula.Loop hook or loop to be tied
hkLp2 module:capsula.Hook | module:capsula.Loop hook or loop to be tied
Since:
  • 0.1.0
Source:
Throws:
Type
Error

(static) wire(oper1, oper2)

Wires the two given operations or the given operation and function according to the current context of execution. At least one of the two arguments must be an operation. There is no requirement in terms of ordering of the two arguments.
Parameters:
Name Type Description
oper1 module:capsula.Operation | function operation or function to be wired
oper2 module:capsula.Operation | function operation or function to be wired
Since:
  • 0.1.0
Source:
Throws:
Type
Error