mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2025-10-25 01:37:34 +02:00
First version of the newly restructured repository
This commit is contained in:
58
frontend/beta/js/YUI-extensions/tree/AsyncTreeNode.js
Normal file
58
frontend/beta/js/YUI-extensions/tree/AsyncTreeNode.js
Normal file
@@ -0,0 +1,58 @@
|
||||
YAHOO.ext.tree.AsyncTreeNode = function(config){
|
||||
this.loaded = false;
|
||||
this.loading = false;
|
||||
YAHOO.ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
|
||||
this.events['beforeload'] = true;
|
||||
this.events['load'] = true;
|
||||
};
|
||||
YAHOO.extendX(YAHOO.ext.tree.AsyncTreeNode, YAHOO.ext.tree.TreeNode, {
|
||||
expand : function(deep, anim, callback){
|
||||
if(this.loading){ // if an async load is already running, waiting til it's done
|
||||
var timer;
|
||||
var f = function(){
|
||||
if(!this.loading){ // done loading
|
||||
clearInterval(timer);
|
||||
this.expand(deep, anim, callback);
|
||||
}
|
||||
}.createDelegate(this);
|
||||
timer = setInterval(f, 200);
|
||||
}
|
||||
if(!this.loaded){
|
||||
if(this.fireEvent('beforeload', this) === false){
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
this.ui.beforeLoad(this);
|
||||
var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
|
||||
if(loader){
|
||||
loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
YAHOO.ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);
|
||||
},
|
||||
|
||||
isLoading : function(){
|
||||
return this.loading;
|
||||
},
|
||||
|
||||
loadComplete : function(deep, anim, callback){
|
||||
this.loading = false;
|
||||
this.loaded = true;
|
||||
this.ui.afterLoad(this);
|
||||
this.fireEvent('load', this);
|
||||
this.expand(deep, anim, callback);
|
||||
},
|
||||
|
||||
isLoaded : function(){
|
||||
return this.loaded;
|
||||
},
|
||||
|
||||
hasChildNodes : function(){
|
||||
if(!this.isLeaf() && !this.loaded){
|
||||
return true;
|
||||
}else{
|
||||
return YAHOO.ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
43
frontend/beta/js/YUI-extensions/tree/TreeDragZone.js
Normal file
43
frontend/beta/js/YUI-extensions/tree/TreeDragZone.js
Normal file
@@ -0,0 +1,43 @@
|
||||
YAHOO.ext.tree.TreeDragZone = function(tree, config){
|
||||
YAHOO.ext.tree.TreeDragZone.superclass.constructor.call(this, tree.getEl(), config);
|
||||
this.tree = tree;
|
||||
};
|
||||
|
||||
YAHOO.extendX(YAHOO.ext.tree.TreeDragZone, YAHOO.ext.dd.DragZone, {
|
||||
ddGroup : 'TreeDD',
|
||||
|
||||
onBeforeDrag : function(data, e){
|
||||
var n = data.node;
|
||||
return n && n.draggable && !n.disabled;
|
||||
},
|
||||
|
||||
onInitDrag : function(e){
|
||||
var data = this.dragData;
|
||||
this.tree.getSelectionModel().select(data.node);
|
||||
this.proxy.update('');
|
||||
data.node.ui.appendDDGhost(this.proxy.ghost.dom);
|
||||
this.tree.fireEvent('startdrag', this.tree, data.node, e);
|
||||
},
|
||||
|
||||
getRepairXY : function(e, data){
|
||||
return data.node.ui.getDDRepairXY();
|
||||
},
|
||||
|
||||
onEndDrag : function(data, e){
|
||||
this.tree.fireEvent('enddrag', this.tree, data.node, e);
|
||||
},
|
||||
|
||||
onValidDrop : function(dd, e, id){
|
||||
this.tree.fireEvent('dragdrop', this.tree, this.dragData.node, dd, e);
|
||||
this.hideProxy();
|
||||
},
|
||||
|
||||
beforeInvalidDrop : function(e, id){
|
||||
if(YAHOO.util.Anim){
|
||||
// this scrolls the original position back into view
|
||||
var sm = this.tree.getSelectionModel();
|
||||
sm.clearSelections();
|
||||
sm.select(this.dragData.node);
|
||||
}
|
||||
}
|
||||
});
|
||||
228
frontend/beta/js/YUI-extensions/tree/TreeDropZone.js
Normal file
228
frontend/beta/js/YUI-extensions/tree/TreeDropZone.js
Normal file
@@ -0,0 +1,228 @@
|
||||
YAHOO.ext.tree.TreeDropZone = function(tree, config){
|
||||
this.allowParentInsert = false;
|
||||
this.allowContainerDrop = false;
|
||||
this.appendOnly = false;
|
||||
YAHOO.ext.tree.TreeDropZone.superclass.constructor.call(this, tree.container, config);
|
||||
this.tree = tree;
|
||||
this.lastInsertClass = 'ytree-no-status';
|
||||
this.dragOverData = {};
|
||||
};
|
||||
|
||||
YAHOO.extendX(YAHOO.ext.tree.TreeDropZone, YAHOO.ext.dd.DropZone, {
|
||||
ddGroup : 'TreeDD',
|
||||
|
||||
expandDelay : 1000,
|
||||
|
||||
expandNode : function(node){
|
||||
if(node.hasChildNodes() && !node.isExpanded()){
|
||||
node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
|
||||
}
|
||||
},
|
||||
|
||||
queueExpand : function(node){
|
||||
this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
|
||||
},
|
||||
|
||||
cancelExpand : function(){
|
||||
if(this.expandProcId){
|
||||
clearTimeout(this.expandProcId);
|
||||
this.expandProcId = false;
|
||||
}
|
||||
},
|
||||
|
||||
isValidDropPoint : function(n, pt, dd, e, data){
|
||||
if(!n || !data){ return false; }
|
||||
var targetNode = n.node;
|
||||
var dropNode = data.node;
|
||||
// default drop rules
|
||||
if(!(targetNode && targetNode.isTarget && pt)){
|
||||
return false;
|
||||
}
|
||||
if(pt == 'append' && targetNode.allowChildren === false){
|
||||
return false;
|
||||
}
|
||||
if((pt == 'above' || pt == 'below') && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
|
||||
return false;
|
||||
}
|
||||
if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
|
||||
return false;
|
||||
}
|
||||
// reuse the object
|
||||
var overEvent = this.dragOverData;
|
||||
overEvent.tree = this.tree;
|
||||
overEvent.target = targetNode;
|
||||
overEvent.data = data;
|
||||
overEvent.point = pt;
|
||||
overEvent.source = dd;
|
||||
overEvent.rawEvent = e;
|
||||
overEvent.dropNode = dropNode;
|
||||
overEvent.cancel = false;
|
||||
var result = this.tree.fireEvent('nodedragover', overEvent);
|
||||
return overEvent.cancel === false && result !== false;
|
||||
},
|
||||
|
||||
getDropPoint : function(e, n, dd){
|
||||
var tn = n.node;
|
||||
if(tn.isRoot){
|
||||
return tn.allowChildren !== false ? 'ap-pend' : false; // always append for root
|
||||
}
|
||||
var dragEl = n.ddel;
|
||||
var t = YAHOO.util.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
|
||||
var y = YAHOO.util.Event.getPageY(e);
|
||||
var noAppend = tn.allowChildren === false || tn.isLeaf();
|
||||
if(this.appendOnly || tn.parentNode.allowChildren === false){
|
||||
return noAppend ? false : 'append';
|
||||
}
|
||||
var noBelow = false;
|
||||
if(!this.allowParentInsert){
|
||||
noBelow = tn.hasChildNodes() && tn.isExpanded();
|
||||
}
|
||||
var q = (b - t) / (noAppend ? 2 : 3);
|
||||
if(y >= t && y < t + q){
|
||||
return 'above';
|
||||
}else if(!noBelow && (noAppend || y >= b-q && y <= b)){
|
||||
return 'below';
|
||||
}else{
|
||||
return 'append';
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
onNodeEnter : function(n, dd, e, data){
|
||||
this.cancelExpand();
|
||||
},
|
||||
|
||||
onNodeOver : function(n, dd, e, data){
|
||||
var pt = this.getDropPoint(e, n, dd);
|
||||
var node = n.node;
|
||||
|
||||
// auto node expand check
|
||||
if(!this.expandProcId && pt == 'append' && node.hasChildNodes() && !n.node.isExpanded()){
|
||||
this.queueExpand(node);
|
||||
}else if(pt != 'append'){
|
||||
this.cancelExpand();
|
||||
}
|
||||
|
||||
// set the insert point style on the target node
|
||||
var returnCls = this.dropNotAllowed;
|
||||
if(this.isValidDropPoint(n, pt, dd, e, data)){
|
||||
if(pt){
|
||||
var el = n.ddel;
|
||||
var cls, returnCls;
|
||||
if(pt == 'above'){
|
||||
returnCls = n.node.isFirst() ? 'ytree-drop-ok-above' : 'ytree-drop-ok-between';
|
||||
cls = 'ytree-drag-insert-above';
|
||||
}else if(pt == 'below'){
|
||||
returnCls = n.node.isLast() ? 'ytree-drop-ok-below' : 'ytree-drop-ok-between';
|
||||
cls = 'ytree-drag-insert-below';
|
||||
}else{
|
||||
returnCls = 'ytree-drop-ok-append';
|
||||
cls = 'ytree-drag-append';
|
||||
}
|
||||
if(this.lastInsertClass != cls){
|
||||
YAHOO.util.Dom.replaceClass(el, this.lastInsertClass, cls);
|
||||
this.lastInsertClass = cls;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnCls;
|
||||
},
|
||||
|
||||
onNodeOut : function(n, dd, e, data){
|
||||
this.cancelExpand();
|
||||
this.removeDropIndicators(n);
|
||||
},
|
||||
|
||||
onNodeDrop : function(n, dd, e, data){
|
||||
var point = this.getDropPoint(e, n, dd);
|
||||
var targetNode = n.node;
|
||||
targetNode.ui.startDrop();
|
||||
if(!this.isValidDropPoint(n, point, dd, e, data)){
|
||||
targetNode.ui.endDrop();
|
||||
return false;
|
||||
}
|
||||
// first try to find the drop node
|
||||
var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
|
||||
var dropEvent = {
|
||||
tree : this.tree,
|
||||
target: targetNode,
|
||||
data: data,
|
||||
point: point,
|
||||
source: dd,
|
||||
rawEvent: e,
|
||||
dropNode: dropNode,
|
||||
cancel: dropNode ? false : true
|
||||
};
|
||||
var retval = this.tree.fireEvent('beforenodedrop', dropEvent);
|
||||
if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
|
||||
targetNode.ui.endDrop();
|
||||
return false;
|
||||
}
|
||||
if(point == 'append' && !targetNode.isExpanded()){
|
||||
targetNode.expand(false, null, function(){
|
||||
this.completeDrop(dropEvent);
|
||||
}.createDelegate(this));
|
||||
}else{
|
||||
this.completeDrop(dropEvent);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
completeDrop : function(de){
|
||||
var ns = de.dropNode, p = de.point, t = de.target;
|
||||
if(!(ns instanceof Array)){
|
||||
ns = [ns];
|
||||
}
|
||||
var n;
|
||||
for(var i = 0, len = ns.length; i < len; i++){
|
||||
n = ns[i];
|
||||
if(p == 'above'){
|
||||
t.parentNode.insertBefore(n, t);
|
||||
}else if(p == 'below'){
|
||||
t.parentNode.insertBefore(n, t.nextSibling);
|
||||
}else{
|
||||
t.appendChild(n);
|
||||
}
|
||||
}
|
||||
n.select(); // select and highlight the last insert
|
||||
if(this.tree.hlDrop){
|
||||
n.ui.highlight();
|
||||
}
|
||||
t.ui.endDrop();
|
||||
this.tree.fireEvent('nodedrop', de);
|
||||
},
|
||||
|
||||
afterNodeMoved : function(dd, data, e, targetNode, dropNode){
|
||||
if(this.tree.hlDrop){
|
||||
dropNode.select();
|
||||
dropNode.ui.highlight();
|
||||
}
|
||||
this.tree.fireEvent('nodedrop', this.tree, targetNode, data, dd, e);
|
||||
},
|
||||
|
||||
getTree : function(){
|
||||
return this.tree;
|
||||
},
|
||||
|
||||
removeDropIndicators : function(n){
|
||||
if(n && n.ddel){
|
||||
var el = n.ddel;
|
||||
YAHOO.util.Dom.removeClass(el, 'ytree-drag-insert-above');
|
||||
YAHOO.util.Dom.removeClass(el, 'ytree-drag-insert-below');
|
||||
YAHOO.util.Dom.removeClass(el, 'ytree-drag-append');
|
||||
this.lastInsertClass = '_noclass';
|
||||
}
|
||||
},
|
||||
|
||||
beforeDragDrop : function(target, e, id){
|
||||
this.cancelExpand();
|
||||
return true;
|
||||
},
|
||||
|
||||
afterRepair : function(data){
|
||||
if(data){
|
||||
data.node.ui.highlight();
|
||||
}
|
||||
this.hideProxy();
|
||||
}
|
||||
});
|
||||
105
frontend/beta/js/YUI-extensions/tree/TreeFilter.js
Normal file
105
frontend/beta/js/YUI-extensions/tree/TreeFilter.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* This doesn't update the indent (lines) or expand collapse icons of the nodes
|
||||
*/
|
||||
YAHOO.ext.tree.TreeFilter = function(tree, config){
|
||||
this.tree = tree;
|
||||
this.filtered = {};
|
||||
YAHOO.ext.util.Config.apply(this, config, {
|
||||
clearBlank:false,
|
||||
reverse:false,
|
||||
autoClear:false,
|
||||
remove:false
|
||||
});
|
||||
};
|
||||
|
||||
YAHOO.ext.tree.TreeFilter.prototype = {
|
||||
/**
|
||||
* Filter the data by a specific attribute.
|
||||
* @param {String/RegExp} value Either string that the attribute value
|
||||
* should start with or a RegExp to test against the attribute
|
||||
* @param {String} attr (optional) The attribute passed in your node's attributes collection. Defaults to "text".
|
||||
* @param {TreeNode} startNode (optional) The node to start the filter at.
|
||||
*/
|
||||
filter : function(value, attr, startNode){
|
||||
attr = attr || 'text';
|
||||
var f;
|
||||
if(typeof value == 'string'){
|
||||
var vlen = value.length;
|
||||
// auto clear empty filter
|
||||
if(vlen == 0 && this.clearBlank){
|
||||
this.clearFilter();
|
||||
return;
|
||||
}
|
||||
value = value.toLowerCase();
|
||||
f = function(n){
|
||||
return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
|
||||
}
|
||||
}else if(value.exec){ // regex?
|
||||
f = function(n){
|
||||
return value.test(n.attributes[attr]);
|
||||
}
|
||||
}else{
|
||||
throw 'Illegal filter type, must be string or regex';
|
||||
}
|
||||
this.filterBy(f, null, startNode);
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter by a function. The passed function will be called with each
|
||||
* node in the tree (or from the startNode). If the function returns true, the node is kept
|
||||
* otherwise it is filtered. If a node is filtered, it's children are also filtered.
|
||||
* @param {Function} fn The filter function
|
||||
* @param {Object} scope (optional) The scope of the function (defaults to the current node)
|
||||
*/
|
||||
filterBy : function(fn, scope, startNode){
|
||||
startNode = startNode || this.tree.root;
|
||||
if(this.autoClear){
|
||||
this.clearFilter();
|
||||
}
|
||||
var af = this.filtered, rv = this.reverse;
|
||||
var f = function(n){
|
||||
if(n == startNode){
|
||||
return true;
|
||||
}
|
||||
if(af[n.id]){
|
||||
return false;
|
||||
}
|
||||
var m = fn.call(scope || n, n);
|
||||
if(!m || rv){
|
||||
af[n.id] = n;
|
||||
n.ui.hide();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
startNode.cascade(f);
|
||||
if(this.remove){
|
||||
for(var id in af){
|
||||
if(typeof id != 'function'){
|
||||
var n = af[id];
|
||||
if(n && n.parentNode){
|
||||
n.parentNode.removeChild(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the current filter. Note: with the "remove" option
|
||||
* set a filter cannot be cleared.
|
||||
*/
|
||||
clear : function(){
|
||||
var t = this.tree;
|
||||
var af = this.filtered;
|
||||
for(var id in af){
|
||||
if(typeof id != 'function'){
|
||||
var n = af[id];
|
||||
if(n){
|
||||
n.ui.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.filtered = {};
|
||||
}
|
||||
};
|
||||
107
frontend/beta/js/YUI-extensions/tree/TreeLoader.js
Normal file
107
frontend/beta/js/YUI-extensions/tree/TreeLoader.js
Normal file
@@ -0,0 +1,107 @@
|
||||
YAHOO.ext.tree.TreeLoader = function(config){
|
||||
this.baseParams = {};
|
||||
this.requestMethod = 'POST';
|
||||
YAHOO.ext.util.Config.apply(this, config);
|
||||
|
||||
this.events = {
|
||||
'beforeload' : true,
|
||||
'load' : true,
|
||||
'loadexception' : true
|
||||
};
|
||||
};
|
||||
|
||||
YAHOO.extendX(YAHOO.ext.tree.TreeLoader, YAHOO.ext.util.Observable, {
|
||||
load : function(node, callback){
|
||||
if(node.attributes.children){ // preloaded json children
|
||||
var cs = node.attributes.children;
|
||||
for(var i = 0, len = cs.length; i < len; i++){
|
||||
node.appendChild(this.createNode(cs[i]));
|
||||
}
|
||||
if(typeof callback == 'function'){
|
||||
callback();
|
||||
}
|
||||
}else if(this.dataUrl){
|
||||
this.requestData(node, callback);
|
||||
}
|
||||
},
|
||||
|
||||
getParams: function(node){
|
||||
var buf = [], bp = this.baseParams;
|
||||
for(var key in bp){
|
||||
if(typeof bp[key] != 'function'){
|
||||
buf.push(encodeURIComponent(key), '=', encodeURIComponent(bp[key]), '&');
|
||||
}
|
||||
}
|
||||
buf.push('node=', encodeURIComponent(node.id));
|
||||
return buf.join('');
|
||||
},
|
||||
|
||||
requestData : function(node, callback){
|
||||
if(this.fireEvent('beforeload', this, node, callback) !== false){
|
||||
var params = this.getParams(node);
|
||||
var cb = {
|
||||
success: this.handleResponse,
|
||||
failure: this.handleFailure,
|
||||
scope: this,
|
||||
argument: {callback: callback, node: node}
|
||||
};
|
||||
this.transId = YAHOO.util.Connect.asyncRequest(this.requestMethod, this.dataUrl, cb, params);
|
||||
}else{
|
||||
// if the load is cancelled, make sure we notify
|
||||
// the node that we are done
|
||||
if(typeof callback == 'function'){
|
||||
callback();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isLoading : function(){
|
||||
return this.transId ? true : false;
|
||||
},
|
||||
|
||||
abort : function(){
|
||||
if(this.isLoading()){
|
||||
YAHOO.util.Connect.abort(this.transId);
|
||||
}
|
||||
},
|
||||
|
||||
createNode : function(attr){
|
||||
if(this.applyLoader !== false){
|
||||
attr.loader = this;
|
||||
}
|
||||
return(attr.leaf ?
|
||||
new YAHOO.ext.tree.TreeNode(attr) :
|
||||
new YAHOO.ext.tree.AsyncTreeNode(attr));
|
||||
},
|
||||
|
||||
processResponse : function(response, node, callback){
|
||||
var json = response.responseText;
|
||||
try {
|
||||
var o = eval('('+json+')');
|
||||
for(var i = 0, len = o.length; i < len; i++){
|
||||
node.appendChild(this.createNode(o[i]));
|
||||
}
|
||||
if(typeof callback == 'function'){
|
||||
callback();
|
||||
}
|
||||
}catch(e){
|
||||
this.handleFailure(response);
|
||||
}
|
||||
},
|
||||
|
||||
handleResponse : function(response){
|
||||
this.transId = false;
|
||||
var a = response.argument;
|
||||
this.processResponse(response, a.node, a.callback);
|
||||
this.fireEvent('load', this, a.node, response);
|
||||
},
|
||||
|
||||
handleFailure : function(response){
|
||||
this.transId = false;
|
||||
var a = response.argument;
|
||||
this.fireEvent('loadexception', this, a.node, response);
|
||||
if(typeof a.callback == 'function'){
|
||||
a.callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
300
frontend/beta/js/YUI-extensions/tree/TreeNode.js
Normal file
300
frontend/beta/js/YUI-extensions/tree/TreeNode.js
Normal file
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* @class YAHOO.ext.tree.TreeNode
|
||||
* @extends YAHOO.ext.data.Node
|
||||
* @cfg {Boolean} leaf true if this node is a leaf and does not have or cannot have children
|
||||
* @cfg {Boolean} expanded true to start the node expanded
|
||||
* @cfg {Boolean} draggable false to make this node undraggable if DD is on (default to true)
|
||||
* @cfg {Boolean} isTarget false if this node cannot be drop on
|
||||
* @cfg {Boolean} disabled true to start the node disabled
|
||||
* @constructor
|
||||
* @param {Object} attributes The attributes/config for the node
|
||||
*/
|
||||
YAHOO.ext.tree.TreeNode = function(attributes){
|
||||
attributes = attributes || {};
|
||||
if(typeof attributes == 'string'){
|
||||
attributes = {text: attributes};
|
||||
}
|
||||
this.el = null;
|
||||
this.childrenRendered = false;
|
||||
this.rendered = false;
|
||||
YAHOO.ext.tree.TreeNode.superclass.constructor.call(this, attributes);
|
||||
this.expanded = attributes.expanded === true;
|
||||
this.isTarget = attributes.isTarget !== false;
|
||||
this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
|
||||
this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
|
||||
this.text = attributes.text;
|
||||
this.disabled = attributes.disabled === true;
|
||||
|
||||
YAHOO.ext.util.Config.apply(this.events, {
|
||||
'textchange' : true,
|
||||
'beforeexpand' : true,
|
||||
'beforecollapse' : true,
|
||||
'expand' : true,
|
||||
'disabledchange' : true,
|
||||
'collapse' : true,
|
||||
'beforeclick':true,
|
||||
'click':true,
|
||||
'dblclick':true,
|
||||
'contentmenu':true,
|
||||
'beforechildrenrendered':true
|
||||
});
|
||||
|
||||
var uiClass = this.attributes.uiProvider || YAHOO.ext.tree.TreeNodeUI;
|
||||
this.ui = new uiClass(this);
|
||||
};
|
||||
YAHOO.extendX(YAHOO.ext.tree.TreeNode, YAHOO.ext.data.Node, {
|
||||
isExpanded : function(){
|
||||
return this.expanded;
|
||||
},
|
||||
|
||||
getUI : function(){
|
||||
return this.ui;
|
||||
},
|
||||
|
||||
setFirstChild : function(node){
|
||||
var of = this.firstChild;
|
||||
YAHOO.ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
|
||||
if(this.childrenRendered && of && node != of){
|
||||
of.renderIndent(true, true);
|
||||
}
|
||||
if(this.rendered){
|
||||
this.renderIndent(true, true);
|
||||
}
|
||||
},
|
||||
|
||||
setLastChild : function(node){
|
||||
var ol = this.lastChild;
|
||||
YAHOO.ext.tree.TreeNode.superclass.setLastChild.call(this, node);
|
||||
if(this.childrenRendered && ol && node != ol){
|
||||
ol.renderIndent(true, true);
|
||||
}
|
||||
if(this.rendered){
|
||||
this.renderIndent(true, true);
|
||||
}
|
||||
},
|
||||
|
||||
// these methods are overridden to provide lazy rendering support
|
||||
appendChild : function(){
|
||||
var node = YAHOO.ext.tree.TreeNode.superclass.appendChild.apply(this, arguments);
|
||||
if(node && this.childrenRendered){
|
||||
node.render();
|
||||
}
|
||||
this.ui.updateExpandIcon();
|
||||
return node;
|
||||
},
|
||||
|
||||
removeChild : function(node){
|
||||
this.ownerTree.getSelectionModel().unselect(node);
|
||||
YAHOO.ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
|
||||
// if it's been rendered remove dom node
|
||||
if(this.childrenRendered){
|
||||
node.ui.remove();
|
||||
}
|
||||
if(this.childNodes.length < 1){
|
||||
this.collapse(false, false);
|
||||
}else{
|
||||
this.ui.updateExpandIcon();
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
insertBefore : function(node, refNode){
|
||||
var newNode = YAHOO.ext.tree.TreeNode.superclass.insertBefore.apply(this, arguments);
|
||||
if(newNode && refNode && this.childrenRendered){
|
||||
node.render();
|
||||
}
|
||||
this.ui.updateExpandIcon();
|
||||
return newNode;
|
||||
},
|
||||
|
||||
setText : function(text){
|
||||
var oldText = this.text;
|
||||
this.text = text;
|
||||
this.attributes.text = text;
|
||||
if(this.rendered){ // event without subscribing
|
||||
this.ui.onTextChange(this, text, oldText);
|
||||
}
|
||||
this.fireEvent('textchange', this, text, oldText);
|
||||
},
|
||||
|
||||
select : function(){
|
||||
this.getOwnerTree().getSelectionModel().select(this);
|
||||
},
|
||||
|
||||
unselect : function(){
|
||||
this.getOwnerTree().getSelectionModel().unselect(this);
|
||||
},
|
||||
|
||||
isSelected : function(){
|
||||
return this.getOwnerTree().getSelectionModel().isSelected(node);
|
||||
},
|
||||
|
||||
expand : function(deep, anim, callback){
|
||||
if(!this.expanded){
|
||||
if(this.fireEvent('beforeexpand', this, deep, anim) === false){
|
||||
return;
|
||||
}
|
||||
if(!this.childrenRendered){
|
||||
this.renderChildren();
|
||||
}
|
||||
this.expanded = true;
|
||||
if((this.getOwnerTree().animate && anim !== false) || anim){
|
||||
this.ui.animExpand(function(){
|
||||
this.fireEvent('expand', this);
|
||||
if(typeof callback == 'function'){
|
||||
callback(this);
|
||||
}
|
||||
if(deep === true){
|
||||
this.expandChildNodes(true);
|
||||
}
|
||||
}.createDelegate(this));
|
||||
return;
|
||||
}else{
|
||||
this.ui.expand();
|
||||
this.fireEvent('expand', this);
|
||||
if(typeof callback == 'function'){
|
||||
callback(this);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(typeof callback == 'function'){
|
||||
callback(this);
|
||||
}
|
||||
}
|
||||
if(deep === true){
|
||||
this.expandChildNodes(true);
|
||||
}
|
||||
},
|
||||
|
||||
collapse : function(deep, anim){
|
||||
if(this.expanded && (!this.isRoot || (this.isRoot && this.getOwnerTree().rootVisible))){
|
||||
if(this.fireEvent('beforecollapse', this, deep, anim) === false){
|
||||
return;
|
||||
}
|
||||
this.expanded = false;
|
||||
if((this.getOwnerTree().animate && anim !== false) || anim){
|
||||
this.ui.animCollapse(function(){
|
||||
this.fireEvent('collapse', this);
|
||||
if(deep === true){
|
||||
this.collapseChildNodes(true);
|
||||
}
|
||||
}.createDelegate(this));
|
||||
return;
|
||||
}else{
|
||||
this.ui.collapse();
|
||||
this.fireEvent('collapse', this);
|
||||
}
|
||||
}
|
||||
if(deep === true){
|
||||
var cs = this.childNodes;
|
||||
for(var i = 0, len = cs.length; i < len; i++) {
|
||||
cs[i].collapse(true)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
delayedExpand : function(delay){
|
||||
if(!this.expandProcId){
|
||||
this.expandProcId = this.expand.defer(delay, this);
|
||||
}
|
||||
},
|
||||
|
||||
cancelExpand : function(){
|
||||
if(this.expandProcId){
|
||||
clearTimeout(this.expandProcId);
|
||||
}
|
||||
this.expandProcId = false;
|
||||
},
|
||||
|
||||
toggle : function(){
|
||||
if(this.expanded){
|
||||
this.collapse();
|
||||
}else{
|
||||
this.expand();
|
||||
}
|
||||
},
|
||||
|
||||
ensureVisible : function(){
|
||||
if(this.parentNode){
|
||||
this.parentNode.bubble(function(){
|
||||
this.expand(false, false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
expandChildNodes : function(deep){
|
||||
var cs = this.childNodes;
|
||||
for(var i = 0, len = cs.length; i < len; i++) {
|
||||
cs[i].expand(deep);
|
||||
}
|
||||
},
|
||||
|
||||
collapseChildNodes : function(deep){
|
||||
var cs = this.childNodes;
|
||||
for(var i = 0, len = cs.length; i < len; i++) {
|
||||
cs[i].expand(deep);
|
||||
}
|
||||
},
|
||||
|
||||
disable : function(){
|
||||
this.disabled = true;
|
||||
this.unselect();
|
||||
if(this.rendered && this.ui.onDisableChange){ // event without subscribing
|
||||
this.ui.onDisableChange(this, true);
|
||||
}
|
||||
this.fireEvent('disabledchange', this, true);
|
||||
},
|
||||
|
||||
enable : function(){
|
||||
this.disabled = false;
|
||||
if(this.rendered && this.ui.onDisableChange){ // event without subscribing
|
||||
this.ui.onDisableChange(this, false);
|
||||
}
|
||||
this.fireEvent('disabledchange', this, false);
|
||||
},
|
||||
|
||||
renderChildren : function(suppressEvent){
|
||||
if(suppressEvent !== false){
|
||||
this.fireEvent('beforechildrenrendered', this);
|
||||
}
|
||||
var cs = this.childNodes;
|
||||
for(var i = 0, len = cs.length; i < len; i++){
|
||||
cs[i].render(true);
|
||||
}
|
||||
this.childrenRendered = true;
|
||||
},
|
||||
|
||||
sort : function(fn, scope){
|
||||
YAHOO.ext.tree.TreeNode.superclass.sort.apply(this, arguments);
|
||||
if(this.childrenRendered){
|
||||
var cs = this.childNodes;
|
||||
for(var i = 0, len = cs.length; i < len; i++){
|
||||
cs[i].render(true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render : function(bulkRender){
|
||||
this.ui.render(bulkRender);
|
||||
if(!this.rendered){
|
||||
this.rendered = true;
|
||||
if(this.expanded){
|
||||
this.expanded = false;
|
||||
this.expand(false, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
renderIndent : function(deep, refresh){
|
||||
if(refresh){
|
||||
this.ui.childIndent = null;
|
||||
}
|
||||
this.ui.renderIndent();
|
||||
if(deep === true && this.childrenRendered){
|
||||
var cs = this.childNodes;
|
||||
for(var i = 0, len = cs.length; i < len; i++){
|
||||
cs[i].renderIndent(true, refresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
452
frontend/beta/js/YUI-extensions/tree/TreeNodeUI.js
Normal file
452
frontend/beta/js/YUI-extensions/tree/TreeNodeUI.js
Normal file
@@ -0,0 +1,452 @@
|
||||
/**
|
||||
* The TreeNode UI implementation is separate from the
|
||||
* tree implementation. Unless you are customizing the tree UI,
|
||||
* you should never have to use this directly.
|
||||
*/
|
||||
YAHOO.ext.tree.TreeNodeUI = function(node){
|
||||
this.node = node;
|
||||
this.rendered = false;
|
||||
this.animating = false;
|
||||
};
|
||||
|
||||
YAHOO.ext.tree.TreeNodeUI.prototype = {
|
||||
emptyIcon : Ext.BLANK_IMAGE_URL,
|
||||
|
||||
removeChild : function(node){
|
||||
if(this.rendered){
|
||||
this.ctNode.removeChild(node.ui.getEl());
|
||||
}
|
||||
},
|
||||
|
||||
beforeLoad : function(){
|
||||
YAHOO.util.Dom.addClass(this.elNode, 'ytree-node-loading');
|
||||
},
|
||||
|
||||
afterLoad : function(){
|
||||
YAHOO.util.Dom.removeClass(this.elNode, 'ytree-node-loading');
|
||||
},
|
||||
|
||||
onTextChange : function(node, text, oldText){
|
||||
if(this.rendered){
|
||||
this.textNode.innerHTML = text;
|
||||
}
|
||||
},
|
||||
|
||||
onDisableChange : function(node, state){
|
||||
this.disabled = state;
|
||||
if(state){
|
||||
YAHOO.util.Dom.addClass(this.elNode, 'ytree-node-disabled');
|
||||
}else{
|
||||
YAHOO.util.Dom.removeClass(this.elNode, 'ytree-node-disabled');
|
||||
}
|
||||
},
|
||||
|
||||
onSelectedChange : function(state){
|
||||
if(state){
|
||||
this.focus();
|
||||
YAHOO.util.Dom.addClass(this.elNode, 'ytree-selected');
|
||||
}else{
|
||||
this.blur();
|
||||
YAHOO.util.Dom.removeClass(this.elNode, 'ytree-selected');
|
||||
}
|
||||
},
|
||||
|
||||
onMove : function(tree, node, oldParent, newParent, index, refNode){
|
||||
this.childIndent = null;
|
||||
if(this.rendered){
|
||||
var targetNode = newParent.ui.getContainer();
|
||||
if(!targetNode){//target not rendered
|
||||
this.holder = document.createElement('div');
|
||||
this.holder.appendChild(this.wrap);
|
||||
return;
|
||||
}
|
||||
var insertBefore = refNode ? refNode.ui.getEl() : null;
|
||||
if(insertBefore){
|
||||
targetNode.insertBefore(this.wrap, insertBefore);
|
||||
}else{
|
||||
targetNode.appendChild(this.wrap);
|
||||
}
|
||||
this.node.renderIndent(true);
|
||||
}
|
||||
},
|
||||
|
||||
remove : function(){
|
||||
if(this.rendered){
|
||||
this.holder = document.createElement('div');
|
||||
this.holder.appendChild(this.wrap);
|
||||
}
|
||||
},
|
||||
|
||||
fireEvent : function(){
|
||||
this.node.fireEvent.apply(this.node, arguments);
|
||||
},
|
||||
|
||||
initEvents : function(){
|
||||
this.node.on('move', this.onMove, this, true);
|
||||
//this.node.on('hiddenchange', this.onHiddenChange, this, true);
|
||||
|
||||
// these were optimized out but a custom UI could use them
|
||||
//this.node.on('remove', this.onChildRemoved, this, true);
|
||||
//this.node.on('selectedstatechange', this.onSelectedChange, this, true);
|
||||
//this.node.on('disabledchange', this.onDisableChange, this, true);
|
||||
//this.node.on('textchange', this.onTextChange, this, true);
|
||||
|
||||
var E = YAHOO.util.Event;
|
||||
var a = this.anchor;
|
||||
|
||||
var el = YAHOO.ext.Element.fly(a);
|
||||
|
||||
if(YAHOO.ext.util.Browser.isOpera){ // opera render bug ignores the CSS
|
||||
el.setStyle('text-decoration', 'none');
|
||||
}
|
||||
|
||||
el.mon('click', this.onClick, this, true);
|
||||
el.mon('dblclick', this.onDblClick, this, true);
|
||||
el.mon('contextmenu', this.onContextMenu, this, true);
|
||||
|
||||
//el.on('focus', function(){
|
||||
// this.node.getOwnerTree().getSelectionModel().select(this.node);
|
||||
//}, this, true);
|
||||
|
||||
var icon = YAHOO.ext.Element.fly(this.iconNode);
|
||||
icon.mon('click', this.onClick, this, true);
|
||||
icon.mon('dblclick', this.onDblClick, this, true);
|
||||
icon.mon('contextmenu', this.onContextMenu, this, true);
|
||||
E.on(this.ecNode, 'click', this.ecClick, this, true);
|
||||
|
||||
if(this.node.disabled){
|
||||
YAHOO.util.Dom.addClass(this.elNode, 'ytree-node-disabled');
|
||||
}
|
||||
if(this.node.hidden){
|
||||
YAHOO.util.Dom.addClass(this.elNode, 'ytree-node-disabled');
|
||||
}
|
||||
var dd = this.node.ownerTree.enableDD || this.node.ownerTree.enableDrag || this.node.ownerTree.enableDrop;
|
||||
if(dd && (!this.node.isRoot || this.node.ownerTree.rootVisible)){
|
||||
YAHOO.ext.dd.Registry.register(this.elNode, {
|
||||
node: this.node,
|
||||
handles: [this.iconNode, this.textNode],
|
||||
isHandle: false
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
hide : function(){
|
||||
if(this.rendered){
|
||||
this.wrap.style.display = 'none';
|
||||
}
|
||||
},
|
||||
|
||||
show : function(){
|
||||
if(this.rendered){
|
||||
this.wrap.style.display = '';
|
||||
}
|
||||
},
|
||||
|
||||
onContextMenu : function(e){
|
||||
e.preventDefault();
|
||||
this.focus();
|
||||
this.fireEvent('contextmenu', this.node, e);
|
||||
},
|
||||
|
||||
onClick : function(e){
|
||||
if(this.dropping){
|
||||
return;
|
||||
}
|
||||
if(this.fireEvent('beforeclick', this.node, e) !== false){
|
||||
if(!this.disabled && this.node.attributes.href){
|
||||
this.focus();
|
||||
this.fireEvent('click', this.node, e);
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
if(this.disabled){
|
||||
return;
|
||||
}
|
||||
this.focus();
|
||||
this.fireEvent('click', this.node, e);
|
||||
}else{
|
||||
e.stopEvent();
|
||||
}
|
||||
},
|
||||
|
||||
onDblClick : function(e){
|
||||
e.preventDefault();
|
||||
if(this.disabled){
|
||||
return;
|
||||
}
|
||||
if(!this.animating && this.node.hasChildNodes()){
|
||||
this.node.toggle();
|
||||
}
|
||||
this.fireEvent('dblclick', this.node, e);
|
||||
},
|
||||
|
||||
ecClick : function(e){
|
||||
if(!this.animating && this.node.hasChildNodes()){
|
||||
this.node.toggle();
|
||||
}
|
||||
},
|
||||
|
||||
startDrop : function(){
|
||||
this.dropping = true;
|
||||
},
|
||||
|
||||
// delayed drop so the click event doesn't get fired on a drop
|
||||
endDrop : function(){
|
||||
setTimeout(function(){
|
||||
this.dropping = false;
|
||||
}.createDelegate(this), 50);
|
||||
},
|
||||
|
||||
expand : function(){
|
||||
this.updateExpandIcon();
|
||||
this.ctNode.style.display = '';
|
||||
},
|
||||
|
||||
focus : function(){
|
||||
try{
|
||||
this.anchor.focus();
|
||||
}catch(e){}
|
||||
},
|
||||
|
||||
blur : function(){
|
||||
try{
|
||||
this.anchor.blur();
|
||||
}catch(e){}
|
||||
},
|
||||
|
||||
animExpand : function(callback){
|
||||
if(this.animating && this.anim){
|
||||
this.anim.stop();
|
||||
}
|
||||
this.animating = true;
|
||||
this.updateExpandIcon();
|
||||
var ct = this.ctNode;
|
||||
var cs = ct.style;
|
||||
cs.position = 'absolute';
|
||||
cs.visibility = 'hidden';
|
||||
cs.display = '';
|
||||
var h = ct.clientHeight;
|
||||
cs.overflow = 'hidden';
|
||||
cs.height = '1px';
|
||||
cs.position = '';
|
||||
cs.visibility = '';
|
||||
var anim = new YAHOO.util.Anim(ct, {
|
||||
height: {to: h}
|
||||
}, this.node.ownerTree.duration || .25, YAHOO.util.Easing.easeOut);
|
||||
anim.onComplete.subscribe(function(){
|
||||
cs.overflow = '';
|
||||
cs.height = '';
|
||||
this.animating = false;
|
||||
this.anim = null;
|
||||
if(typeof callback == 'function'){
|
||||
callback();
|
||||
}
|
||||
}, this, true);
|
||||
this.anim = anim;
|
||||
anim.animate();
|
||||
},
|
||||
|
||||
highlight : function(){
|
||||
var tree = this.node.getOwnerTree();
|
||||
var hlColor = tree.hlColor || 'C3DAF9';
|
||||
var hlBaseColor = tree.hlBaseColor || 'FFFFFF';
|
||||
var anim = new YAHOO.util.ColorAnim(this.wrap, {
|
||||
backgroundColor: {from: hlColor, to: hlBaseColor}
|
||||
}, .75, YAHOO.util.Easing.easeNone);
|
||||
anim.onComplete.subscribe(function(){
|
||||
YAHOO.util.Dom.setStyle(this.wrap, 'background-color', '');
|
||||
}, this, true);
|
||||
anim.animate();
|
||||
},
|
||||
|
||||
collapse : function(){
|
||||
this.updateExpandIcon();
|
||||
this.ctNode.style.display = 'none';
|
||||
},
|
||||
|
||||
animCollapse : function(callback){
|
||||
if(this.animating && this.anim){
|
||||
this.anim.stop();
|
||||
}
|
||||
this.animating = true;
|
||||
this.updateExpandIcon();
|
||||
var ct = this.ctNode;
|
||||
var cs = ct.style;
|
||||
cs.height = ct.offsetHeight +'px';
|
||||
cs.overflow = 'hidden';
|
||||
var anim = new YAHOO.util.Anim(ct, {
|
||||
height: {to: 1}
|
||||
}, this.node.ownerTree.duration || .25, YAHOO.util.Easing.easeOut);
|
||||
anim.onComplete.subscribe(function(){
|
||||
cs.display = 'none';
|
||||
cs.overflow = '';
|
||||
cs.height = '';
|
||||
this.animating = false;
|
||||
this.anim = null;
|
||||
if(typeof callback == 'function'){
|
||||
callback();
|
||||
}
|
||||
}, this, true);
|
||||
this.anim = anim;
|
||||
anim.animate();
|
||||
},
|
||||
|
||||
getContainer : function(){
|
||||
return this.ctNode;
|
||||
},
|
||||
|
||||
getEl : function(){
|
||||
return this.wrap;
|
||||
},
|
||||
|
||||
appendDDGhost : function(ghostNode){
|
||||
ghostNode.appendChild(this.elNode.cloneNode(true));
|
||||
},
|
||||
|
||||
getDDRepairXY : function(){
|
||||
return YAHOO.util.Dom.getXY(this.iconNode);
|
||||
},
|
||||
|
||||
onRender : function(){
|
||||
this.render();
|
||||
},
|
||||
|
||||
render : function(bulkRender){
|
||||
var n = this.node;
|
||||
var targetNode = n.parentNode ?
|
||||
n.parentNode.ui.getContainer() : n.ownerTree.container.dom;
|
||||
if(!this.rendered){
|
||||
this.rendered = true;
|
||||
var a = n.attributes;
|
||||
|
||||
// add some indent caching, this helps performance when rendering a large tree
|
||||
this.indentMarkup = '';
|
||||
if(n.parentNode){
|
||||
this.indentMarkup = n.parentNode.ui.getChildIndent();
|
||||
}
|
||||
|
||||
var buf = ['<li class="ytree-node"><div class="ytree-node-el ', n.attributes.cls,'">',
|
||||
'<span class="ytree-node-indent">',this.indentMarkup,'</span>',
|
||||
'<img src="', this.emptyIcon, '" class="ytree-ec-icon">',
|
||||
'<img src="', a.icon || this.emptyIcon, '" class="ytree-node-icon',(a.icon ? ' ytree-node-inline-icon' : ''),'" unselectable="on">',
|
||||
'<a href="',a.href ? a.href : '#','" tabIndex="1" ',
|
||||
a.hrefTarget ? ' target="'+a.hrefTarget+'"' : '','><span unselectable="on">',n.text,'</span></a></div>',
|
||||
'<ul class="ytree-node-ct" style="display:none;"></ul>',
|
||||
'</li>'];
|
||||
|
||||
if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
|
||||
this.wrap = YAHOO.ext.DomHelper.insertHtml('beforeBegin',
|
||||
n.nextSibling.ui.getEl(), buf.join(''));
|
||||
}else{
|
||||
this.wrap = YAHOO.ext.DomHelper.insertHtml('beforeEnd', targetNode, buf.join(''));
|
||||
}
|
||||
this.elNode = this.wrap.childNodes[0];
|
||||
this.ctNode = this.wrap.childNodes[1];
|
||||
var cs = this.elNode.childNodes;
|
||||
this.indentNode = cs[0];
|
||||
this.ecNode = cs[1];
|
||||
this.iconNode = cs[2];
|
||||
this.anchor = cs[3];
|
||||
this.textNode = cs[3].firstChild;
|
||||
if(a.qtip){
|
||||
if(this.textNode.setAttributeNS){
|
||||
this.textNode.setAttributeNS('y', 'qtip', a.qtip);
|
||||
if(a.qtipTitle){
|
||||
this.textNode.setAttributeNS('y', 'qtitle', a.qtipTitle);
|
||||
}
|
||||
}else{
|
||||
this.textNode.setAttribute('y:qtip', a.qtip);
|
||||
if(a.qtipTitle){
|
||||
this.textNode.setAttribute('y:qtitle', a.qtipTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.initEvents();
|
||||
//this.renderIndent(); cached above now instead call updateExpandIcon
|
||||
this.updateExpandIcon();
|
||||
}else{
|
||||
if(bulkRender === true) {
|
||||
targetNode.appendChild(this.wrap);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getAnchor : function(){
|
||||
return this.anchor;
|
||||
},
|
||||
|
||||
getTextEl : function(){
|
||||
return this.textNode;
|
||||
},
|
||||
|
||||
getIconEl : function(){
|
||||
return this.iconNode;
|
||||
},
|
||||
|
||||
updateExpandIcon : function(){
|
||||
if(this.rendered){
|
||||
var n = this.node;
|
||||
var cls = n.isLast() ? "ytree-elbow-end" : "ytree-elbow";
|
||||
var hasChild = n.hasChildNodes();
|
||||
if(hasChild){
|
||||
cls += n.expanded ? '-minus' : '-plus';
|
||||
var c1 = n.expanded ? 'ytree-node-collapsed' : 'ytree-node-expanded';
|
||||
var c2 = n.expanded ? 'ytree-node-expanded' : 'ytree-node-collapsed';
|
||||
YAHOO.util.Dom.removeClass(this.elNode, 'ytree-node-leaf');
|
||||
YAHOO.util.Dom.replaceClass(this.elNode, c1, c2);
|
||||
}else{
|
||||
YAHOO.util.Dom.replaceClass(this.elNode, 'ytree-node-expanded', 'ytree-node-leaf');
|
||||
}
|
||||
this.ecNode.className = 'ytree-ec-icon '+cls;
|
||||
}
|
||||
},
|
||||
|
||||
getChildIndent : function(){
|
||||
if(!this.childIndent){
|
||||
var buf = [];
|
||||
var p = this.node;
|
||||
while(p){
|
||||
if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
|
||||
if(!p.isLast()) {
|
||||
buf.unshift('<img src="'+this.emptyIcon+'" class="ytree-elbow-line">');
|
||||
} else {
|
||||
buf.unshift('<img src="'+this.emptyIcon+'" class="ytree-icon">');
|
||||
}
|
||||
}
|
||||
p = p.parentNode;
|
||||
}
|
||||
this.childIndent = buf.join('');
|
||||
}
|
||||
return this.childIndent;
|
||||
},
|
||||
|
||||
renderIndent : function(){
|
||||
if(this.rendered){
|
||||
var indent = '';
|
||||
var p = this.node.parentNode;
|
||||
if(p){
|
||||
indent = p.ui.getChildIndent();
|
||||
}
|
||||
if(this.indentMarkup != indent){ // don't rerender if not required
|
||||
this.indentNode.innerHTML = indent;
|
||||
this.indentMarkup = indent;
|
||||
}
|
||||
this.updateExpandIcon();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
YAHOO.ext.tree.RootTreeNodeUI = function(){
|
||||
YAHOO.ext.tree.RootTreeNodeUI.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
YAHOO.extendX(YAHOO.ext.tree.RootTreeNodeUI, YAHOO.ext.tree.TreeNodeUI);
|
||||
YAHOO.ext.tree.RootTreeNodeUI.prototype.render = function(){
|
||||
if(!this.rendered){
|
||||
var targetNode = this.node.ownerTree.container.dom;
|
||||
this.node.expanded = true;
|
||||
targetNode.innerHTML = '<div class="ytree-root-node"></div>';
|
||||
this.wrap = this.ctNode = targetNode.firstChild;
|
||||
}
|
||||
};
|
||||
YAHOO.ext.tree.RootTreeNodeUI.prototype.collapse = function(){
|
||||
};
|
||||
213
frontend/beta/js/YUI-extensions/tree/TreePanel.js
Normal file
213
frontend/beta/js/YUI-extensions/tree/TreePanel.js
Normal file
@@ -0,0 +1,213 @@
|
||||
YAHOO.namespace('ext.tree');
|
||||
|
||||
YAHOO.ext.tree.TreePanel = function(el, config){
|
||||
YAHOO.ext.tree.TreePanel.superclass.constructor.call(this);
|
||||
this.el = getEl(el);
|
||||
this.id = this.el.id;
|
||||
YAHOO.ext.util.Config.apply(this, config || {}, {
|
||||
rootVisible : true,
|
||||
lines : true,
|
||||
enableDD : false,
|
||||
hlDrop : true/*,
|
||||
hlColor: null,
|
||||
ddGroup : 'TreeDD'
|
||||
hlBaseColor : 'FFFFFF'*/
|
||||
|
||||
});
|
||||
YAHOO.ext.util.Config.apply(this.events, {
|
||||
'beforeload' : true,
|
||||
'load' : true,
|
||||
'textchange' : true,
|
||||
'beforeexpand' : true,
|
||||
'beforecollapse' : true,
|
||||
'expand' : true,
|
||||
'collapse' : true,
|
||||
'disabledchange' : true,
|
||||
'beforeclick':true,
|
||||
'click':true,
|
||||
'dblclick':true,
|
||||
'contentmenu':true,
|
||||
'beforechildrenrendered':true,
|
||||
/**
|
||||
* @event startdrag
|
||||
* Fires when a node starts being dragged
|
||||
* @param {YAHOO.ext.tree.TreePanel} this
|
||||
* @param {YAHOO.ext.tree.TreeNode} node
|
||||
* @param {event} e The raw browser event
|
||||
*/
|
||||
'startdrag' : true,
|
||||
/**
|
||||
* @event enddrag
|
||||
* Fires when a drag operation is complete
|
||||
* @param {YAHOO.ext.tree.TreePanel} this
|
||||
* @param {YAHOO.ext.tree.TreeNode} node
|
||||
* @param {event} e The raw browser event
|
||||
*/
|
||||
'enddrag' : true,
|
||||
/**
|
||||
* @event dragdrop
|
||||
* Fires when a dragged node is dropped on a valid DD target
|
||||
* @param {YAHOO.ext.tree.TreePanel} this
|
||||
* @param {YAHOO.ext.tree.TreeNode} node
|
||||
* @param {DD} dd The dd it was dropped on
|
||||
* @param {event} e The raw browser event
|
||||
*/
|
||||
'dragdrop' : true,
|
||||
/**
|
||||
* @event beforenodedrop
|
||||
* Fires when a DD object is dropped on a node in this tree for preprocessing. This event can cancel.
|
||||
* @param {Object} dropEvent
|
||||
*/
|
||||
'beforenodedrop' : true,
|
||||
/**
|
||||
* @event nodedrop
|
||||
* Fires after a DD object is dropped on a node in this tree
|
||||
* @param {Object} dropEvent
|
||||
*/
|
||||
'nodedrop' : true,
|
||||
/**
|
||||
* @event nodedragover
|
||||
* Fires when a tree node is being target
|
||||
* @param {Object} dragOverEvent
|
||||
*/
|
||||
'nodedragover' : true
|
||||
});
|
||||
if(this.singleExpand){
|
||||
this.on('beforeexpand', this.restrictExpand, this, true);
|
||||
}
|
||||
// problem with safari and animation
|
||||
// I am investigating
|
||||
if(YAHOO.ext.util.Browser.isSafari){
|
||||
this.animate = false;
|
||||
}
|
||||
};
|
||||
YAHOO.extendX(YAHOO.ext.tree.TreePanel, YAHOO.ext.data.Tree, {
|
||||
restrictExpand : function(node){
|
||||
var p = node.parentNode;
|
||||
if(p){
|
||||
if(p.expandedChild && p.expandedChild.parentNode == p){
|
||||
p.expandedChild.collapse();
|
||||
}
|
||||
p.expandedChild = node;
|
||||
}
|
||||
},
|
||||
|
||||
setRootNode : function(node){
|
||||
YAHOO.ext.tree.TreePanel.superclass.setRootNode.call(this, node);
|
||||
if(!this.rootVisible){
|
||||
node.ui = new YAHOO.ext.tree.RootTreeNodeUI(node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
getEl : function(){
|
||||
return this.el;
|
||||
},
|
||||
|
||||
getLoader : function(){
|
||||
return this.loader;
|
||||
},
|
||||
|
||||
expandAll : function(){
|
||||
this.root.expand(true);
|
||||
},
|
||||
|
||||
collapseAll : function(){
|
||||
this.root.collapse(true);
|
||||
},
|
||||
|
||||
getSelectionModel : function(){
|
||||
if(!this.selModel){
|
||||
this.selModel = new YAHOO.ext.tree.DefaultSelectionModel();
|
||||
}
|
||||
return this.selModel;
|
||||
},
|
||||
|
||||
expandPath : function(path, attr, callback){
|
||||
attr = attr || 'id';
|
||||
var keys = path.split(this.pathSeparator);
|
||||
var curNode = this.root;
|
||||
if(curNode.attributes[attr] != keys[1]){ // invalid root
|
||||
if(callback){
|
||||
callback(false, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var index = 1;
|
||||
var f = function(){
|
||||
if(++index == keys.length){
|
||||
if(callback){
|
||||
callback(true, curNode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var c = curNode.findChild(attr, keys[index]);
|
||||
if(!c){
|
||||
if(callback){
|
||||
callback(false, curNode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
curNode = c;
|
||||
c.expand(false, false, f);
|
||||
}
|
||||
curNode.expand(false, false, f);
|
||||
},
|
||||
|
||||
selectPath : function(path, attr, callback){
|
||||
attr = attr || 'id';
|
||||
var keys = path.split(this.pathSeparator);
|
||||
var v = keys.pop();
|
||||
if(keys.length > 0){
|
||||
var f = function(success, node){
|
||||
if(success && node){
|
||||
var n = node.findChild(attr, v);
|
||||
if(n){
|
||||
n.select();
|
||||
if(callback){
|
||||
callback(true, n);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(callback){
|
||||
callback(false, n);
|
||||
}
|
||||
}
|
||||
};
|
||||
this.expandPath(keys.join(this.pathSeparator), attr, f);
|
||||
}else{
|
||||
this.root.select();
|
||||
if(callback){
|
||||
callback(true, this.root);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render : function(){
|
||||
this.container = this.el.createChild({tag:'ul',
|
||||
cls:'ytree-root-ct ' +
|
||||
(this.lines ? 'ytree-lines' : 'ytree-no-lines')});
|
||||
|
||||
if(this.containerScroll){
|
||||
YAHOO.ext.dd.ScrollManager.register(this.el);
|
||||
}
|
||||
|
||||
if((this.enableDD || this.enableDrop) && !this.dropZone){
|
||||
this.dropZone = new YAHOO.ext.tree.TreeDropZone(this, this.dropConfig || {
|
||||
ddGroup: this.ddGroup || 'TreeDD'
|
||||
});
|
||||
}
|
||||
if((this.enableDD || this.enableDrag) && !this.dragZone){
|
||||
this.dragZone = new YAHOO.ext.tree.TreeDragZone(this, this.dragConfig || {
|
||||
ddGroup: this.ddGroup || 'TreeDD',
|
||||
scroll: this.ddScroll
|
||||
});
|
||||
}
|
||||
this.getSelectionModel().init(this);
|
||||
this.root.render();
|
||||
if(!this.rootVisible){
|
||||
this.root.renderChildren();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
195
frontend/beta/js/YUI-extensions/tree/TreeSelectionModel.js
Normal file
195
frontend/beta/js/YUI-extensions/tree/TreeSelectionModel.js
Normal file
@@ -0,0 +1,195 @@
|
||||
YAHOO.ext.tree.DefaultSelectionModel = function(){
|
||||
this.selNode = null;
|
||||
|
||||
this.events = {
|
||||
'selectionchange' : true
|
||||
};
|
||||
};
|
||||
|
||||
YAHOO.extendX(YAHOO.ext.tree.DefaultSelectionModel, YAHOO.ext.util.Observable, {
|
||||
init : function(tree){
|
||||
this.tree = tree;
|
||||
tree.el.mon('keydown', this.onKeyDown, this, true);
|
||||
tree.on('click', this.onNodeClick, this, true);
|
||||
},
|
||||
|
||||
onNodeClick : function(node, e){
|
||||
this.select(node);
|
||||
},
|
||||
|
||||
select : function(node){
|
||||
if(this.selNode && this.selNode != node){
|
||||
this.selNode.ui.onSelectedChange(false);
|
||||
}
|
||||
this.selNode = node;
|
||||
node.ui.onSelectedChange(true);
|
||||
this.fireEvent('selectionchange', this, node);
|
||||
return node;
|
||||
},
|
||||
|
||||
unselect : function(node){
|
||||
if(this.selNode == node){
|
||||
this.clearSelections();
|
||||
}
|
||||
},
|
||||
|
||||
clearSelections : function(){
|
||||
var n = this.selNode;
|
||||
if(n){
|
||||
n.ui.onSelectedChange(false);
|
||||
this.selNode = null;
|
||||
this.fireEvent('selectionchange', this, null);
|
||||
}
|
||||
return n;
|
||||
},
|
||||
|
||||
getSelectedNode : function(){
|
||||
return this.selNode;
|
||||
},
|
||||
|
||||
isSelected : function(node){
|
||||
return this.selNode == node;
|
||||
},
|
||||
|
||||
onKeyDown : function(e){
|
||||
var s = this.selNode || this.lastSelNode;
|
||||
// undesirable, but required
|
||||
var sm = this;
|
||||
if(!s){
|
||||
return;
|
||||
}
|
||||
var k = e.getKey();
|
||||
//alert(k)
|
||||
switch(k){
|
||||
case e.DOWN:
|
||||
e.preventDefault();
|
||||
if(s.firstChild && s.isExpanded()){
|
||||
this.select(s.firstChild, e);
|
||||
}else if(s.nextSibling){
|
||||
this.select(s.nextSibling, e);
|
||||
}else if(s.parentNode){
|
||||
s.parentNode.bubble(function(){
|
||||
if(this.nextSibling){
|
||||
sm.select(this.nextSibling, e);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case e.UP:
|
||||
e.preventDefault();
|
||||
var ps = s.previousSibling;
|
||||
if(ps){
|
||||
if(!ps.isExpanded()){
|
||||
this.select(ps, e);
|
||||
}else{
|
||||
var lc = ps.lastChild;
|
||||
while(lc && lc.isExpanded()){
|
||||
lc = lc.lastChild;
|
||||
}
|
||||
this.select(lc, e);
|
||||
}
|
||||
}else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
|
||||
this.select(s.parentNode, e);
|
||||
}
|
||||
break;
|
||||
case e.RIGHT:
|
||||
e.preventDefault();
|
||||
if(s.hasChildNodes()){
|
||||
if(!s.isExpanded()){
|
||||
s.expand();
|
||||
}else if(s.firstChild){
|
||||
this.select(s.firstChild, e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case e.LEFT:
|
||||
e.preventDefault();
|
||||
if(s.hasChildNodes() && s.isExpanded()){
|
||||
s.collapse();
|
||||
}else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
|
||||
this.select(s.parentNode, e);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
YAHOO.ext.tree.MultiSelectionModel = function(){
|
||||
this.selNodes = [];
|
||||
this.selMap = {};
|
||||
this.events = {
|
||||
'selectionchange' : true
|
||||
};
|
||||
};
|
||||
|
||||
YAHOO.extendX(YAHOO.ext.tree.MultiSelectionModel, YAHOO.ext.util.Observable, {
|
||||
init : function(tree){
|
||||
this.tree = tree;
|
||||
tree.el.mon('keydown', this.onKeyDown, this, true);
|
||||
tree.on('click', this.onNodeClick, this, true);
|
||||
},
|
||||
|
||||
onNodeClick : function(node, e){
|
||||
this.select(node, e, e.ctrlKey);
|
||||
},
|
||||
|
||||
select : function(node, e, keepExisting){
|
||||
if(keepExisting !== true){
|
||||
this.clearSelections(true);
|
||||
}
|
||||
this.selNodes.push(node);
|
||||
this.selMap[node.id] = node;
|
||||
this.lastSelNode = node;
|
||||
node.ui.onSelectedChange(true);
|
||||
this.fireEvent('selectionchange', this, this.selNodes);
|
||||
return node;
|
||||
},
|
||||
|
||||
unselect : function(node){
|
||||
if(this.selMap[node.id]){
|
||||
node.ui.onSelectedChange(false);
|
||||
var sn = this.selNodes;
|
||||
var index = -1;
|
||||
if(sn.indexOf){
|
||||
index = sn.indexOf(node);
|
||||
}else{
|
||||
for(var i = 0, len = sn.length; i < len; i++){
|
||||
if(sn[i] == node){
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(index != -1){
|
||||
this.selNodes.splice(index, 1);
|
||||
}
|
||||
delete this.selMap[node.id];
|
||||
this.fireEvent('selectionchange', this, this.selNodes);
|
||||
}
|
||||
},
|
||||
|
||||
clearSelections : function(suppressEvent){
|
||||
var sn = this.selNodes;
|
||||
if(sn.length > 0){
|
||||
for(var i = 0, len = sn.length; i < len; i++){
|
||||
sn[i].ui.onSelectedChange(false);
|
||||
}
|
||||
this.selNodes = [];
|
||||
this.selMap = {};
|
||||
if(suppressEvent !== true){
|
||||
this.fireEvent('selectionchange', this, this.selNodes);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isSelected : function(node){
|
||||
return this.selMap[node.id] ? true : false;
|
||||
},
|
||||
|
||||
getSelectedNodes : function(){
|
||||
return this.selNodes;
|
||||
},
|
||||
|
||||
onKeyDown : YAHOO.ext.tree.DefaultSelectionModel.prototype.onKeyDown
|
||||
});
|
||||
49
frontend/beta/js/YUI-extensions/tree/TreeSorter.js
Normal file
49
frontend/beta/js/YUI-extensions/tree/TreeSorter.js
Normal file
@@ -0,0 +1,49 @@
|
||||
YAHOO.ext.tree.TreeSorter = function(tree, config){
|
||||
YAHOO.ext.util.Config.apply(this, config);
|
||||
tree.on('beforechildrenrendered', this.doSort, this, true);
|
||||
tree.on('append', this.updateSort, this, true);
|
||||
tree.on('insert', this.updateSort, this, true);
|
||||
|
||||
var dsc = this.dir && this.dir.toLowerCase() == 'desc';
|
||||
var p = this.property || 'text';
|
||||
var sortType = this.sortType;
|
||||
var fs = this.folderSort;
|
||||
var cs = this.caseSensitive === true;
|
||||
|
||||
this.sortFn = function(n1, n2){
|
||||
if(fs){
|
||||
if(n1.leaf && !n2.leaf){
|
||||
return 1;
|
||||
}
|
||||
if(!n1.leaf && n2.leaf){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
var v1 = sortType ? sortType(n1) : (cs ? n1[p] : n1[p].toUpperCase());
|
||||
var v2 = sortType ? sortType(n2) : (cs ? n2[p] : n2[p].toUpperCase());
|
||||
if(v1 < v2){
|
||||
return dsc ? +1 : -1;
|
||||
}else if(v1 > v2){
|
||||
return dsc ? -1 : +1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
YAHOO.ext.tree.TreeSorter.prototype = {
|
||||
doSort : function(node){
|
||||
node.sort(this.sortFn);
|
||||
},
|
||||
|
||||
compareNodes : function(n1, n2){
|
||||
|
||||
return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
|
||||
},
|
||||
|
||||
updateSort : function(tree, node){
|
||||
if(node.childrenRendered){
|
||||
this.doSort.defer(1, this, [node]);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user