Changeset 7899

Show
Ignore:
Timestamp:
04/01/07 22:30:43 (22 months ago)
Author:
elazutkin
Message:

dnd2: everything is documented, some minor cleanup

Location:
trunk/src/dnd2
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/dnd2/avatar.js

    r7896 r7899  
    66 
    77dojo.dnd2.Avatar = function(manager){ 
     8        // summary: an object, which represents transferred DnD items visually 
     9        // manager: Object: a DnD manager object 
    810        this.manager = manager; 
    911        this.construct(); 
     12        // calculate various offsets 
     13        this.offX = dojo.dnd2._getOffset(this.node, "left"); 
     14        this.offY = dojo.dnd2._getOffset(this.node, "top"); 
    1015}; 
    1116 
    1217dojo.dnd2._getOffset = function(node, side){ 
     18        // summary: calculates an offset for a content box 
     19        // node: Node: a node 
     20        // side: String: a side of a box ("left", "right", "top", or "bottom") 
    1321        var h = dojo.html; 
    14         return h.getMarginExtent(node, side) + h.getBorderExtent(node, side) + h.getPaddingExtent(node, side); 
     22        return h.getMarginExtent(node, side) + h.getBorderExtent(node, side) + h.getPaddingExtent(node, side);  // Number 
    1523}; 
    1624 
    1725dojo.extend(dojo.dnd2.Avatar, { 
    1826        construct: function(){ 
     27                // summary: a constructor function; 
     28                //      it is separate so it can be (dynamically) overwritten in case of need 
    1929                var h = dojo.html; 
    2030                var a = dojo.doc().createElement("table"); 
     
    4353                a.appendChild(b); 
    4454                this.node = a; 
    45                 // calculate various offsets 
    46                 this.offX = dojo.dnd2._getOffset(a, "left"); 
    47                 this.offY = dojo.dnd2._getOffset(a, "top"); 
    4855        }, 
    4956        destroy: function(){ 
     57                // summary: a desctructor for the avatar, called to remove all references so it can be garbage-collected 
    5058                this.node.parentNode.removeChild(this.node); 
    5159                this.node = false; 
    5260        }, 
    5361        update: function(){ 
     62                // summary: updates the avatar to reflect the current DnD state 
    5463                dojo.html[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop"); 
    5564                // replace text 
     
    6473        }, 
    6574        _generateText: function(){ 
     75                // summary: generates a proper text to reflect copying or moving of items 
    6676                return (this.manager.copy ? "copy" : "mov") + "ing " + this.manager.nodes.length + " item" + (this.manager.nodes.length != 1 ? "s" : "");        
    6777        } 
  • trunk/src/dnd2/container.js

    r7896 r7899  
    1616 
    1717dojo.declare("dojo.dnd2.Container", null,  
     18        // summary: a Container object, which knows when mouse hovers over it,  
     19        //      and know over which element it hovers 
    1820function(node, params){ 
    19         // general variables 
     21        // summary: a constructor of the Container 
     22        // node: Node: node or node's id to build the container on 
     23        // params: Object: a dict of parameters, recognized parameters are: 
     24        //      filter: Function: a filter function, which is used to filter out children of the container 
     25        //      creator: Function: a creator function, which takes a data item, and returns an object like that: 
     26        //              {node: newNode, data: usedData, types: arrayOfStrings} 
    2027        this.node = dojo.byId(node); 
    2128        this.nodeFilter  = (params && params.filter)  ? params.filter  : function(n){ return n.nodeType == 1; }; 
     
    4956        dojo.event.connect(this.node, "onmouseout",  this, "onMouseOut"); 
    5057        // cancel text selection and text dragging 
    51         dojo.event.connect(this.node, "ondragstart",   this, "cancelEvent"); 
    52         dojo.event.connect(this.node, "onselectstart", this, "cancelEvent"); 
     58        dojo.event.connect(this.node, "ondragstart",   dojo.event.browser, "stopEvent"); 
     59        dojo.event.connect(this.node, "onselectstart", dojo.event.browser, "stopEvent"); 
    5360}, 
    5461{ 
    5562        // mouse events 
    5663        onMouseOver: function(e){ 
     64                // summary: event processor for onmouseover 
     65                // e: Event: mouse event 
    5766                if(!dojo.dom.isDescendantOf(e.relatedTarget, this.node)){ 
    58                         this.changeState("Container", "Over"); 
     67                        this._changeState("Container", "Over"); 
    5968                        this.onOverEvent(); 
    6069                } 
    61                 var node = this.getChildByEvent(e); 
     70                var node = this._getChildByEvent(e); 
    6271                if(this.current == node){ return; } 
    63                 if(this.current){ this.removeItemClass(this.current, "Over"); } 
    64                 if(node){ this.addItemClass(node, "Over"); } 
     72                if(this.current){ this._removeItemClass(this.current, "Over"); } 
     73                if(node){ this._addItemClass(node, "Over"); } 
    6574                this.current = node; 
    6675        }, 
    6776        onMouseOut: function(e){ 
     77                // summary: event processor for onmouseout 
     78                // e: Event: mouse event 
    6879                if(dojo.dom.isDescendantOf(e.relatedTarget, this.node)){ return; } 
    6980                if(this.current){ 
    70                         this.removeItemClass(this.current, "Over"); 
     81                        this._removeItemClass(this.current, "Over"); 
    7182                        this.current = null; 
    7283                } 
    73                 this.changeState("Container", ""); 
     84                this._changeState("Container", ""); 
    7485                this.onOutEvent(); 
    7586        }, 
    7687        // methods 
    7788        getAllNodes: function(){ 
     89                // summary: returns a list (an array) of all valid child nodes 
    7890                var t = []; 
    7991                var c = this.node.tagName.toLowerCase() == "table" ? this.parent.getElementsByTagName("tr") : this.node.childNodes; 
     
    8496                        } 
    8597                } 
    86                 return t; 
     98                return t;       // Array 
    8799        }, 
    88100        insertNodes: function(data, before, anchor){ 
     101                // summary: inserts an array of new nodes before/after an anchor node 
     102                // data: Array: a list of data items, which should be processed by the creator function 
     103                // before: Boolean: insert before the anchor, if true, and after the anchot otherwise 
     104                // anchor: Node: the anchor node to be used as a point of insertion 
    89105                if(!this.parent.firstChild){ 
    90106                        anchor = null; 
     
    111127                        } 
    112128                } 
    113                 return this; 
     129                return this;    // self 
    114130        }, 
    115131        // utilities 
    116         onOverEvent: function(){}, 
    117         onOutEvent: function(){}, 
    118         cancelEvent: function(e){ dojo.event.browser.stopEvent(e); }, 
    119         changeState: function(type, newState){ 
     132        onOverEvent: function(){ 
     133                // summary: this function is called once, when mouse is over our container 
     134        }, 
     135        onOutEvent: function(){ 
     136                // summary: this function is called once, when mouse is out of our container 
     137        }, 
     138        _changeState: function(type, newState){ 
     139                // summary: changes a named state to new state value 
     140                // type: String: a name of the state to change 
     141                // newState: String: new state 
    120142                var prefix = "dojoDnd" + type; 
    121143                var state  = type.toLowerCase() + "State"; 
     
    123145                this[state] = newState; 
    124146        }, 
    125         addItemClass:    function(node, type){ dojo.html.addClass(node, "dojoDndItem" + type); }, 
    126         removeItemClass: function(node, type){ dojo.html.removeClass(node, "dojoDndItem" + type); }, 
    127         getChildByEvent: function(e){ 
     147        _addItemClass: function(node, type){ 
     148                // summary: adds a class with prefix "dojoDndItem" 
     149                // node: Node: a node 
     150                // type: String: a variable suffix for a class name 
     151                dojo.html.addClass(node, "dojoDndItem" + type); 
     152        }, 
     153        _removeItemClass: function(node, type){ 
     154                // summary: removes a class with prefix "dojoDndItem" 
     155                // node: Node: a node 
     156                // type: String: a variable suffix for a class name 
     157                dojo.html.removeClass(node, "dojoDndItem" + type); 
     158        }, 
     159        _getChildByEvent: function(e){ 
     160                // summary: gets a child, which is under the mouse at the moment 
     161                // e: Event: a mouse event 
    128162                var node = e.target; 
    129163                if(node == this.node){ return null; } 
     
    133167                        parent = node.parentNode; 
    134168                } 
    135                 return (parent && this.nodeFilter(node)) ? node : null; 
     169                return (parent && this.nodeFilter(node)) ? node : null; // Node 
    136170        } 
    137171}); 
    138172 
    139173dojo.dnd2._createNode = function(tag){ 
     174        // summary: returns a function, which creates an element of given tag  
     175        //      (SPAN by default) and sets its innerHTML to given text 
     176        // tag: String: a tag name or empty for SPAN 
    140177        if(!tag){ return dojo.dnd2._createSpan; } 
    141         return function(text){ 
     178        return function(text){  // Function 
    142179                var n = dojo.doc().createElement(tag); 
    143180                n.innerHTML = text; 
     
    147184 
    148185dojo.dnd2._createTrTd = function(text){ 
     186        // summary: creates a TR/TD structure with given text as an innerHTML of TD 
     187        // text: String: a text for TD 
    149188        var tr = dojo.doc().createElement("tr"); 
    150189        var td = dojo.doc().createElement("td"); 
    151190        td.innerHTML = text; 
    152191        tr.appendChild(td); 
    153         return tr; 
     192        return tr;      // Node 
    154193}; 
    155194 
    156195dojo.dnd2._createSpan = function(text){ 
     196        // summary: creates a SPAN element with given text as its innerHTML 
     197        // text: String: a text for SPAN 
    157198        var n = dojo.doc().createElement("span"); 
    158199        n.innerHTML = text; 
    159         return n; 
    160 }; 
    161  
     200        return n;       // Node 
     201}; 
     202 
     203// dojo.dnd2._defaultCreatorNodes: Object: a dicitionary, which maps container tag names to child tag names 
    162204dojo.dnd2._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"}; 
     205 
    163206dojo.dnd2._defaultCreator = function(node){ 
     207        // summary: takes a container node, and returns an appropriate creator function 
     208        // node: Node: a container node 
    164209        var tag = node.tagName.toLowerCase(); 
    165210        var c = tag == "table" ? dojo.dnd2._createTrTd : dojo.dnd2._createNode(dojo.dnd2._defaultCreatorNodes[tag]); 
    166211        var r = dojo.lang.repr ? dojo.lang.repr : function(o){ return o + ""; }; 
    167         return function(data, hint){ 
     212        return function(data, hint){    // Function 
    168213                var t = r(data); 
    169214                var n = (hint == "avatar" ? dojo.dnd2._createSpan : c)(t); 
  • trunk/src/dnd2/manager.js

    r7896 r7899  
    77 
    88dojo.dnd2.Manager = function(){ 
     9        // summary: the manager of DnD operations (usually a singleton) 
    910        this.avatar  = null; 
    10          
    1111        this.source = null; 
    1212        this.nodes = []; 
    1313        this.copy  = true; 
    14          
    1514        this.target = null; 
    1615        this.canDropFlag = false; 
     
    2019        // methods 
    2120        overSource: function(source){ 
     21                // summary: called when a source detected a mouse-over conditiion 
     22                // source: Object: the reporter 
    2223                if(this.avatar){ 
    2324                        this.target = (source && source.targetState != "Disabled") ? source : null; 
     
    2728        }, 
    2829        outSource: function(source){ 
     30                // summary: called when a source detected a mouse-out conditiion 
     31                // source: Object: the reporter 
    2932                if(this.avatar){ 
    3033                        if(this.target == source){ 
     
    3942        }, 
    4043        startDrag: function(source, nodes, copy){ 
     44                // summary: called to initiate the DnD operation 
     45                // source: Object: the source which provides items 
     46                // nodes: Array: the list of transferred items 
     47                // copy: Boolean: copy items, if true, move items otherwise 
    4148                this.source = source; 
    4249                this.nodes  = nodes; 
     
    5259        }, 
    5360        canDrop: function(flag){ 
     61                // summary: called to notify if the current target can accept items 
    5462                var canDropFlag = this.target && flag; 
    5563                if(this.canDropFlag != canDropFlag){ 
     
    5967        }, 
    6068        stopDrag: function(){ 
     69                // summary: stop the DnD in progress 
    6170                dojo.html.removeClass(dojo.body(), "dojoDndCopy"); 
    6271                dojo.html.removeClass(dojo.body(), "dojoDndMove"); 
     
    7079                this.nodes = []; 
    7180        }, 
    72         makeAvatar: function(){ return new dojo.dnd2.Avatar(this); }, 
    73         updateAvatar: function(){ this.avatar.update(); }, 
     81        makeAvatar: function(){ 
     82                // summary: makes the avatar, it is separate to be overwritten dynamically, if needed 
     83                return new dojo.dnd2.Avatar(this); 
     84        }, 
     85        updateAvatar: function(){ 
     86                // summary: updates the avatar, it is separate to be overwritten dynamically, if needed 
     87                this.avatar.update(); 
     88        }, 
    7489        // mouse event processors 
    7590        onMouseMove: function(e){ 
     91                // summary: event processor for onmousemove 
     92                // e: Event: mouse event 
    7693                var a = this.avatar; 
    7794                if(a){ 
     
    7996                        s.left = (e.pageX + 10 + a.offX) + "px"; 
    8097                        s.top  = (e.pageY + 10 + a.offY) + "px"; 
    81                         if(this.copy != e.ctrlKey){ this.setCopyStatus(e.ctrlKey); } 
     98                        if(this.copy != e.ctrlKey){ this._setCopyStatus(e.ctrlKey); } 
    8299                } 
    83100        }, 
    84101        onMouseUp: function(e){ 
     102                // summary: event processor for onmouseup 
     103                // e: Event: mouse event 
    85104                if(this.avatar){ 
    86105                        if(this.target && this.canDropFlag){ 
     
    94113        // keyboard event processors 
    95114        onKeyDown: function(e){ 
    96                 if(this.avatar && e.keyCode == dojo.event.browser.keys.KEY_CTRL && !this.copy){ this.setCopyStatus(true); } 
     115                // summary: event processor for onkeydown, watching for CTRL for copy/move status 
     116                // e: Event: keyboard event 
     117                if(this.avatar && e.keyCode == dojo.event.browser.keys.KEY_CTRL && !this.copy){ this._setCopyStatus(true); } 
    97118        }, 
    98119        onKeyUp: function(e){ 
    99                 if(this.avatar && e.keyCode == dojo.event.browser.keys.KEY_CTRL && this.copy){ this.setCopyStatus(false); } 
     120                // summary: event processor for onkeyup, watching for CTRL for copy/move status 
     121                // e: Event: keyboard event 
     122                if(this.avatar && e.keyCode == dojo.event.browser.keys.KEY_CTRL && this.copy){ this._setCopyStatus(false); } 
    100123        }, 
    101124        // utilities 
    102         setCopyStatus: function(copy){ 
     125        _setCopyStatus: function(copy){ 
     126                // summary: changes the copy status 
     127                // copy: Boolean: the copy status 
    103128                this.copy = copy; 
    104                 this.source.markDndStatus(this.copy); 
     129                this.source._markDndStatus(this.copy); 
    105130                this.updateAvatar(); 
    106131                dojo.html.replaceClass(dojo.body(), "dojoDnd" + (this.copy ? "Copy" : "Move"), "dojoDnd" + (this.copy ? "Move" : "Copy")); 
     
    108133}); 
    109134 
     135// summary: the manager singleton variable, can be overwritten, if needed 
    110136dojo.dnd2._manager = null; 
    111137 
    112138dojo.dnd2.manager = function(){ 
     139        // summary: returns the current DnD manager, creates one if it is not created yet 
    113140        if(!dojo.dnd2._manager){ 
    114141                dojo.dnd2._manager = new dojo.dnd2.Manager(); 
    115142        } 
    116         return dojo.dnd2._manager; 
     143        return dojo.dnd2._manager;      // Object 
    117144}; 
  • trunk/src/dnd2/move.js

    r7896 r7899  
    55 
    66dojo.dnd2.Mover = function(node, e){ 
     7        // summary: an object, which makes a node follow the mouse 
     8        // node: Node: a node (or node's id) to be moved 
     9        // e: Event: a mouse event, which started the move; 
     10        //      only pageX and pageY properties are used 
    711        this.node = dojo.byId(node); 
    812        this.mouseX = e.pageX; 
     
    1014        var h = dojo.html; 
    1115        this.nodePos = h.abs(this.node, true, h.boxSizing.MARGIN_BOX); 
     16        dojo.event.connectOnce(dojo.doc(), "onmousemove", this, "_makeAbsolute"); 
    1217        dojo.event.connect(dojo.doc(), "onmousemove", this, "onMouseMove"); 
    13         dojo.event.connect(dojo.doc(), "onmouseup",   this, "onMouseUp"); 
     18        dojo.event.connect(dojo.doc(), "onmouseup",   this, "destroy"); 
    1419        // cancel text selection and text dragging 
    1520        dojo.event.connect(dojo.doc(), "ondragstart",   dojo.event.browser, "stopEvent"); 
     
    2025        // mouse event processors 
    2126        onMouseMove: function(e){ 
     27                // summary: event processor for onmousemove 
     28                // e: Event: mouse event 
    2229                var s = this.node.style; 
    23                 s.position = "absolute";        // enforcing the absolute mode 
    2430                s.left = (e.pageX - this.mouseX + this.nodePos.x) + "px"; 
    2531                s.top  = (e.pageY - this.mouseY + this.nodePos.y) + "px"; 
    2632        }, 
    27         onMouseUp: function(e){ 
    28                 this.cancel(); 
     33        // utilities 
     34        _makeAbsolute: function(){ 
     35                // summary: makes the node absolute; it is meant to be called only once 
     36                this.node.style.position = "absolute";  // enforcing the absolute mode 
    2937        }, 
    30         // utilities 
    31         cancel: function(){ 
     38        destroy: function(){ 
     39                // summary: stops the move, deletes all references, so the object can be garbage-collected 
     40                dojo.event.disconnect(dojo.doc(), "onmousemove", this, "_makeAbsolute"); 
    3241                dojo.event.disconnect(dojo.doc(), "onmousemove", this, "onMouseMove"); 
    3342                dojo.event.disconnect(dojo.doc(), "onmouseup",   this, "onMouseUp"); 
     
    3847}); 
    3948 
    40 dojo.dnd2.move = function(node, e){ return new dojo.dnd2.Mover(node, e); }; 
    41  
    4249dojo.dnd2.Moveable = function(node, handle){ 
     50        // summary: an object, which makes a node moveable 
     51        // node: Node: a node (or node's id) to be moved 
     52        // handle: Node: a node (or node's id), which is used as a mouse handle; 
     53        //      if omitted, the node itself is used as a handle 
    4354        if(!handle){ handle = node; } 
    4455        this.node = dojo.byId(node); 
     
    5465        // mouse event processors 
    5566        onMouseDown: function(e){ 
    56                 dojo.dnd2.move(this.node, e); 
     67                // summary: event processor for onmousedown, creates a Mover for the node 
     68                // e: Event: mouse event 
     69                new dojo.dnd2.Mover(this.node, e); 
    5770                dojo.event.browser.stopEvent(e); 
    5871        }, 
    5972        // utilities 
    60         cancel: function(){ 
     73        destroy: function(){ 
     74                // summary: stops watching for possible move, deletes all references, so the object can be garbage-collected 
    6175                dojo.event.disconnect(this.handle, "onmousedown", this, "onMouseDown"); 
    6276                dojo.event.disconnect(this.handle, "ondragstart",   dojo.event.browser, "stopEvent"); 
  • trunk/src/dnd2/selector.js

    r7896 r7899  
    1414*/ 
    1515 
    16 dojo.declare("dojo.dnd2.Selector", dojo.dnd2.Container,  
     16dojo.declare("dojo.dnd2.Selector", dojo.dnd2.Container, 
     17        // summary: a Selector object, which knows how to select its children 
    1718function(node, params){ 
    18         // general variables 
     19        // summary: a constructor of the Selector 
     20        // node: Node: node or node's id to build the selector on 
     21        // params: Object: a dict of parameters, recognized parameters are: 
     22        //      singular: Boolean: allows selection of only one element, if true 
     23        //      the rest of parameters are passed to the container 
    1924        this.singular = params && params.singular; 
    2025        // class-specific variables 
     
    2934        // mouse events 
    3035        onMouseDown: function(e){ 
     36                // summary: event processor for onmousedown 
     37                // e: Event: mouse event 
    3138                if(!this.current){ return; } 
    3239                if(!this.singular && !e.ctrlKey && !e.shiftKey && (this.current.id in this.selection)){ 
    3340                        this.simpleSelection = true; 
    34                         this.cancelEvent(e); 
     41                        dojo.event.browser.stopEvent(e); 
    3542                        return; 
    3643                } 
     
    4148                                        if(!(i in empty)){ 
    4249                                                var n = dojo.byId(i); 
    43                                                 this.removeItemClass(n, "Selected"); 
     50                                                this._removeItemClass(n, "Selected"); 
    4451                                        } 
    4552                                } 
     
    5461                                } 
    5562                                this.anchor = c[i]; 
    56                                 this.addItemClass(this.anchor, "Anchor"); 
     63                                this._addItemClass(this.anchor, "Anchor"); 
    5764                        } 
    5865                        this.selection[this.anchor.id] = 1; 
     
    6875                                        if(!this.nodeFilter(n)){ continue; } 
    6976                                        if(n == this.anchor || n == this.current){ break; } 
    70                                         this.addItemClass(n, "Selected"); 
     77                                        this._addItemClass(n, "Selected"); 
    7178                                        this.selection[n.id] = 1; 
    7279                                } 
    73                                 this.addItemClass(this.current, "Selected"); 
     80                                this._addItemClass(this.current, "Selected"); 
    7481                                this.selection[this.current.id] = 1; 
    7582                        } 
     
    7885                                if(this.anchor == this.current){ 
    7986                                        if(e.ctrlKey){ 
    80                                                 this.removeItemClass(this.anchor, "Anchor"); 
     87                                                this._removeItemClass(this.anchor, "Anchor"); 
    8188                                                this.anchor = null; 
    8289                                                this.selection = {}; 
     
    8491                                }else{ 
    8592                                        if(this.anchor){ 
    86                                                 this.removeItemClass(this.anchor, "Anchor"); 
     93                                                this._removeItemClass(this.anchor, "Anchor"); 
    8794                                        } 
    8895                                        this.anchor = this.current; 
    89                                         this.addItemClass(this.anchor, "Anchor"); 
     96                                        this._addItemClass(this.anchor, "Anchor"); 
    9097                                        this.selection = {}; 
    9198                                        this.selection[this.current.id] = 1; 
     
    94101                                if(e.ctrlKey){ 
    95102                                        if(this.anchor == this.current){ 
    96                                                 this.removeItemClass(this.anchor, "Anchor"); 
     103                                                this._removeItemClass(this.anchor, "Anchor"); 
    97104                                                delete this.selection[this.anchor.id]; 
    98105                                                this.anchor = null; 
    99106                                        }else{ 
    100107                                                if(this.current.id in this.selection){ 
    101                                                         this.removeItemClass(this.current, "Selected"); 
     108                                                        this._removeItemClass(this.current, "Selected"); 
    102109                                                        delete this.selection[this.current.id]; 
    103110                                                }else{ 
     
    106113                                                        } 
    107114                                                        this.anchor = this.current; 
    108                                                         this.addItemClass(this.current, "Anchor"); 
     115                                                        this._addItemClass(this.current, "Anchor"); 
    109116                                                        this.selection[this.current.id] = 1; 
    110117                                                }