src/cm/media/js/lib/yui/yui3-3.15.0/build/tree-selectable/tree-selectable.js
changeset 602 e16a97fb364a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cm/media/js/lib/yui/yui3-3.15.0/build/tree-selectable/tree-selectable.js	Mon Mar 10 15:19:48 2014 +0100
@@ -0,0 +1,289 @@
+YUI.add('tree-selectable', function (Y, NAME) {
+
+/*jshint expr:true, onevar:false */
+
+/**
+Extension for `Tree` that adds the concept of selection state for nodes.
+
+@module tree
+@submodule tree-selectable
+@main tree-selectable
+**/
+
+var Do = Y.Do;
+
+/**
+Extension for `Tree` that adds the concept of selection state for nodes.
+
+@class Tree.Selectable
+@constructor
+@extensionfor Tree
+**/
+
+/**
+Fired when a node is selected.
+
+@event select
+@param {Tree.Node} node Node being selected.
+@preventable _defSelectFn
+**/
+var EVT_SELECT = 'select';
+
+/**
+Fired when a node is unselected.
+
+@event unselect
+@param {Tree.Node} node Node being unselected.
+@preventable _defUnselectFn
+**/
+var EVT_UNSELECT = 'unselect';
+
+function Selectable() {}
+
+Selectable.prototype = {
+    // -- Protected Properties -------------------------------------------------
+
+    /**
+    Mapping of node ids to node instances for nodes in this tree that are
+    currently selected.
+
+    @property {Object} _selectedMap
+    @protected
+    **/
+
+    // -- Lifecycle ------------------------------------------------------------
+    initializer: function () {
+        this.nodeExtensions = this.nodeExtensions.concat(Y.Tree.Node.Selectable);
+        this._selectedMap   = {};
+
+        Do.after(this._selectableAfterDefAddFn, this, '_defAddFn');
+        Do.after(this._selectableAfterDefClearFn, this, '_defClearFn');
+        Do.after(this._selectableAfterDefRemoveFn, this, '_defRemoveFn');
+
+        this._selectableEvents = [
+            this.after('multiSelectChange', this._afterMultiSelectChange)
+        ];
+    },
+
+    destructor: function () {
+        (new Y.EventHandle(this._selectableEvents)).detach();
+
+        this._selectableEvents = null;
+        this._selectedMap      = null;
+    },
+
+    // -- Public Methods -------------------------------------------------------
+
+    /**
+    Returns an array of nodes that are currently selected.
+
+    @method getSelectedNodes
+    @return {Tree.Node.Selectable[]} Array of selected nodes.
+    **/
+    getSelectedNodes: function () {
+        return Y.Object.values(this._selectedMap);
+    },
+
+    /**
+    Selects the specified node.
+
+    @method selectNode
+    @param {Tree.Node.Selectable} node Node to select.
+    @param {Object} [options] Options.
+        @param {Boolean} [options.silent=false] If `true`, the `select` event
+            will be suppressed.
+        @param {String} [options.src] Source of the change, to be passed along
+            to the event facade of the resulting event. This can be used to
+            distinguish between changes triggered by a user and changes
+            triggered programmatically, for example.
+    @chainable
+    **/
+    selectNode: function (node, options) {
+        // Instead of calling node.isSelected(), we look for the node in this
+        // tree's selectedMap, which ensures that the `select` event will fire
+        // in cases such as a node being added to this tree with its selected
+        // state already set to true.
+        if (!this._selectedMap[node.id]) {
+            this._fireTreeEvent(EVT_SELECT, {
+                node: node,
+                src : options && options.src
+            }, {
+                defaultFn: this._defSelectFn,
+                silent   : options && options.silent
+            });
+        }
+
+        return this;
+    },
+
+    /**
+    Unselects all selected nodes.
+
+    @method unselect
+    @param {Object} [options] Options.
+        @param {Boolean} [options.silent=false] If `true`, the `unselect` event
+            will be suppressed.
+        @param {String} [options.src] Source of the change, to be passed along
+            to the event facade of the resulting event. This can be used to
+            distinguish between changes triggered by a user and changes
+            triggered programmatically, for example.
+    @chainable
+    **/
+    unselect: function (options) {
+        for (var id in this._selectedMap) {
+            if (this._selectedMap.hasOwnProperty(id)) {
+                this.unselectNode(this._selectedMap[id], options);
+            }
+        }
+
+        return this;
+    },
+
+    /**
+    Unselects the specified node.
+
+    @method unselectNode
+    @param {Tree.Node.Selectable} node Node to unselect.
+    @param {Object} [options] Options.
+        @param {Boolean} [options.silent=false] If `true`, the `unselect` event
+            will be suppressed.
+        @param {String} [options.src] Source of the change, to be passed along
+            to the event facade of the resulting event. This can be used to
+            distinguish between changes triggered by a user and changes
+            triggered programmatically, for example.
+    @chainable
+    **/
+    unselectNode: function (node, options) {
+        if (node.isSelected() || this._selectedMap[node.id]) {
+            this._fireTreeEvent(EVT_UNSELECT, {
+                node: node,
+                src : options && options.src
+            }, {
+                defaultFn: this._defUnselectFn,
+                silent   : options && options.silent
+            });
+        }
+
+        return this;
+    },
+
+    // -- Protected Methods ----------------------------------------------------
+    _selectableAfterDefAddFn: function (e) {
+        // If the node is marked as selected, we need go through the select
+        // flow.
+        if (e.node.isSelected()) {
+            this.selectNode(e.node);
+        }
+    },
+
+    _selectableAfterDefClearFn: function () {
+        this._selectedMap = {};
+    },
+
+    _selectableAfterDefRemoveFn: function (e) {
+        delete e.node.state.selected;
+        delete this._selectedMap[e.node.id];
+    },
+
+    // -- Protected Event Handlers ---------------------------------------------
+    _afterMultiSelectChange: function () {
+        this.unselect();
+    },
+
+    _defSelectFn: function (e) {
+        if (!this.get('multiSelect')) {
+            this.unselect();
+        }
+
+        e.node.state.selected = true;
+        this._selectedMap[e.node.id] = e.node;
+    },
+
+    _defUnselectFn: function (e) {
+        delete e.node.state.selected;
+        delete this._selectedMap[e.node.id];
+    }
+};
+
+Selectable.ATTRS = {
+    /**
+    Whether or not to allow multiple nodes to be selected at once.
+
+    @attribute {Boolean} multiSelect
+    @default false
+    **/
+    multiSelect: {
+        value: false
+    }
+};
+
+Y.Tree.Selectable = Selectable;
+/**
+@module tree
+@submodule tree-selectable
+**/
+
+/**
+`Tree.Node` extension that adds methods useful for nodes in trees that use the
+`Tree.Selectable` extension.
+
+@class Tree.Node.Selectable
+@constructor
+@extensionfor Tree.Node
+**/
+
+function NodeSelectable() {}
+
+NodeSelectable.prototype = {
+    /**
+    Returns `true` if this node is currently selected.
+
+    @method isSelected
+    @return {Boolean} `true` if this node is currently selected, `false`
+        otherwise.
+    **/
+    isSelected: function () {
+        return !!this.state.selected;
+    },
+
+    /**
+    Selects this node.
+
+    @method select
+    @param {Object} [options] Options.
+        @param {Boolean} [options.silent=false] If `true`, the `select` event
+            will be suppressed.
+        @param {String} [options.src] Source of the change, to be passed along
+            to the event facade of the resulting event. This can be used to
+            distinguish between changes triggered by a user and changes
+            triggered programmatically, for example.
+    @chainable
+    **/
+    select: function (options) {
+        this.tree.selectNode(this, options);
+        return this;
+    },
+
+    /**
+    Unselects this node.
+
+    @method unselect
+    @param {Object} [options] Options.
+        @param {Boolean} [options.silent=false] If `true`, the `unselect` event
+            will be suppressed.
+        @param {String} [options.src] Source of the change, to be passed along
+            to the event facade of the resulting event. This can be used to
+            distinguish between changes triggered by a user and changes
+            triggered programmatically, for example.
+    @chainable
+    **/
+    unselect: function (options) {
+        this.tree.unselectNode(this, options);
+        return this;
+    }
+};
+
+Y.Tree.Node.Selectable = NodeSelectable;
+
+
+}, '@VERSION@', {"requires": ["tree"]});