milo

Scope

function
 Scope() 

Option name Type Description
rootEl Element

the root element of this scope

hostObject Object

the host

return Scope

Scope class.

function Scope(rootEl, hostObject) {
    _.defineProperties(this, {
        _rootEl: rootEl,
        _hostObject: hostObject
    }, _.WRIT); // writable
}

_.extendProto(Scope, {
    _add: Scope$_add,
    _safeAdd: Scope$_safeAdd,
    _copy: Scope$_copy,
    _each: Scope$_each,
    _move: Scope$_move,
    _merge: Scope$_merge,
    _length: Scope$_length,
    _any: Scope$_any,
    _remove: Scope$_remove,
    _clean: Scope$_clean,
    _detachElement: Scope$_detachElement,
    _has: Scope$_has,
    _filter: Scope$_filter
});


_.extend(Scope, {
    rename: Scope$$rename
});


module.exports = Scope;


var allowedNamePattern = /^[A-Za-z][A-Za-z0-9\_\$]*$/;

Scope$_add

function
 Scope$_add() 

Option name Type Description
object Component, ComponentInfo

component or component info to add to the scope

name String

the name of the component to add

Scope instance method.
Adds object to the scope, throwing if name is not unique

function Scope$_add(object, name) {
    if (typeof name == 'string')
        object.name = name;
    else
        name = object.name;
    
    if (this.hasOwnProperty(name))
        throw new Error('duplicate object name: ' + name);

    checkName(name);
    __add.call(this, object, name);
}

Scope$_safeAdd

function
 Scope$_safeAdd() 

Option name Type Description
object Component, ComponentInfo

component or component info to add to the scope

name String

the name of the component to add

Scope instance method
Adds object to scope renaming it if name is not unique

function Scope$_safeAdd(object, name) {
    if (typeof name == 'string')
        object.name = name;
    else
        name = object.name;

    var shouldRename = this.hasOwnProperty(name);
    if (shouldRename)
        logger.error('Scope: duplicate object name: ' + name);
    else {
        shouldRename = ! allowedNamePattern.test(name);
        if (shouldRename)
            logger.error('Scope: name should start from letter, this name is not allowed: ' + name);
    }

    if (shouldRename) {
        name = componentName();
        object.name = name;
    }

    __add.call(this, object, name);
}


function __add(object, name) {
    this[name] = object;
    object.scope = this;

    if (typeof object.postMessage === 'function')
        object.postMessage('addedtoscope'); 
}

Scope$_copy

function
 Scope$_copy() 

Option name Type Description
aScope Scope

the scope to copy

Instance method.
copies all objects from one scope to another,
throwing if some object is not unique

function Scope$_copy(aScope) {
    check(aScope, Scope);

    aScope._each(Scope$_add, this);
}

Scope$_move

function
 Scope$_move() 

Option name Type Description
component Component

the component to be moved

otherScope Scope

the scope to copy the component to

Instance method.
Moves a component from this scope to another scope.

function Scope$_move(component, otherScope) {
    otherScope._add(component);
    this._remove(component.name);
    component.scope = otherScope;
}

Scope$_merge

function
 Scope$_merge() 

Option name Type Description
scope Scope

the scope to absorb

Instance method.
Merges one scope into this scope

function Scope$_merge(scope) {
    scope._each(function (comp) {
        this._add(comp, comp.name);
        scope._remove(comp.name);
    }, this);
}

Scope$_each

function
 Scope$_each() 

Option name Type Description
callback Function

the function to execute for each component

thisArg Object

the context

Instance method.
Enumerates each component in the scope

function Scope$_each(callback, thisArg) {
    _.eachKey(this, callback, thisArg || this, true); // enumerates enumerable properties only
}

Scope$_filter

function
 Scope$_filter() 

Option name Type Description
callback Function

the function to execute for each component

thisArg Object

the context

return Array

Instance method.
Returns a filtered list of components based on a callback

function Scope$_filter(callback, thisArg) {
    return _.filterKeys(this, callback, thisArg || this, true);
}

checkName

function
 checkName() 

Option name Type Description
callback Function

the function to execute for each component

Checks the validity of a name.

function checkName(name) {
    if (! allowedNamePattern.test(name))
        throw new Error('name should start from letter, this name is not allowed: ' + name);
}

Scope$_length

function
 Scope$_length() 

Instance method.
Returns the number of objects in the scope

function Scope$_length() {
    return Object.keys(this).length;
}

Scope$_any

function
 Scope$_any() 

Instance method.
Returns a component from the scope. It may look like it returns the first component
but in reality given that scopes are hashes, there is no such thing.

function Scope$_any() {
    var key = Object.keys(this)[0];
    return key && this[key];
}

Scope$_remove

function
 Scope$_remove() 

Option name Type Description
name String

the name of the component to remove

quiet Boolean

optional true to suppress the warning message if the component is not in scope

Instance method.
Removes a component from the scope by it's name.

function Scope$_remove(name, quiet) {
    if (! (name in this)) {
        if (!quiet) logger.warn('removing object that is not in scope');
        return;
    }

    var object = this[name];

    delete this[name];

    if (typeof object.postMessage === 'function')
        object.postMessage('removedfromscope');
}

Scope$_clean

function
 Scope$_clean() 

Instance method.
Removes all components from the scope.

function Scope$_clean() {
    this._each(function(object, name) {
        delete this[name].scope;
        delete this[name];
    }, this);
}

function Scope$_detachElement() {
    this._rootEl = null;
}

Scope$_has

function
 Scope$_has() 

Option name Type Description
object Object
return Boolean

Checks if scope has object by object name

function Scope$_has(object) {
    return this.hasOwnProperty(object.name);
}

Scope$$rename

function
 Scope$$rename() 

Option name Type Description
obj Object
name String

new name

renameInScope Boolean

true by default

Change object name, renaming it in scope unless renameInScope is false

function Scope$$rename(obj, name, renameInScope) {
    if (obj.scope && renameInScope !== false) {
        obj.scope._remove(obj.name);
        obj.scope._add(obj, name);
    } else
        obj.name = name;
}