⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.js

📁 struts hibernet spring
💻 JS
字号:
/*	Copyright (c) 2004-2006, The Dojo Foundation	All Rights Reserved.	Licensed under the Academic Free License version 2.1 or above OR the	modified BSD license. For more information on Dojo licensing, see:		http://dojotoolkit.org/community/licensing.shtml*//** * Tree model does all the drawing, visual node management etc. * Throws events about clicks on it, so someone may catch them and process * Tree knows nothing about DnD stuff, covered in TreeDragAndDrop and (if enabled) attached by controller*//** * TODO: use domNode.cloneNode instead of createElement for grid * Should be faster (lyxsus) */dojo.provide("dojo.widget.Tree");dojo.require("dojo.widget.*");dojo.require("dojo.event.*");dojo.require("dojo.io.*");dojo.require("dojo.widget.HtmlWidget");dojo.require("dojo.widget.TreeNode");dojo.require("dojo.html.common");dojo.require("dojo.html.selection");dojo.widget.defineWidget("dojo.widget.Tree", dojo.widget.HtmlWidget, function() {	this.eventNames = {};	this.tree = this;	this.DNDAcceptTypes = [];	this.actionsDisabled = [];},{	widgetType: "Tree",	eventNamesDefault: {		// new child does not get domNode filled in (only template draft)		// until addChild->createDOMNode is called(program way) OR createDOMNode (html-way)		// hook events to operate on new DOMNode, create dropTargets etc		createDOMNode: "createDOMNode",		// tree created.. Perform tree-wide actions if needed		treeCreate: "treeCreate",		treeDestroy: "treeDestroy",		// expand icon clicked		treeClick: "treeClick",		// node icon clicked		iconClick: "iconClick",		// node title clicked		titleClick: "titleClick",		moveFrom: "moveFrom",		moveTo: "moveTo",		addChild: "addChild",		removeNode: "removeNode",		expand: "expand",		collapse: "collapse"	},	isContainer: true,	DNDMode: "off",	lockLevel: 0, // lock ++ unlock --, so nested locking works fine	strictFolders: true,	DNDModes: {		BETWEEN: 1,		ONTO: 2	},	DNDAcceptTypes: "",	templateCssPath: dojo.uri.dojoUri("src/widget/templates/images/Tree/Tree.css"),	templateString: '<div class="dojoTree"></div>',	isExpanded: true, // consider this "root node" to be always expanded	isTree: true,	objectId: "",	// autoCreate if not "off"	// used to get the autocreated controller ONLY.	// generally, tree DOES NOT KNOW about its CONTROLLER, it just doesn't care	// controller gets messages via dojo.event	controller: "",	// autoCreate if not "off"	// used to get the autocreated selector ONLY.	// generally, tree DOES NOT KNOW its SELECTOR	// binding is made with dojo.event	selector: "",	// used ONLY at initialization time	menu: "", // autobind menu if menu's widgetId is set here	expandLevel: "", // expand to level automatically	//	// these icons control the grid and expando buttons for the whole tree	//	blankIconSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_blank.gif"),	gridIconSrcT: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_t.gif"), // for non-last child grid	gridIconSrcL: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_l.gif"), // for last child grid	gridIconSrcV: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_v.gif"), // vertical line	gridIconSrcP: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_p.gif"), // for under parent item child icons	gridIconSrcC: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_c.gif"), // for under child item child icons	gridIconSrcX: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_x.gif"), // grid for sole root item	gridIconSrcY: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_y.gif"), // grid for last rrot item	gridIconSrcZ: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_z.gif"), // for under root parent item child icon	expandIconSrcPlus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_plus.gif"),	expandIconSrcMinus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_minus.gif"),	expandIconSrcLoading: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_loading.gif"),	iconWidth: 18,	iconHeight: 18,	//	// tree options	//	showGrid: true,	showRootGrid: true,	actionIsDisabled: function(action) {		var _this = this;		return dojo.lang.inArray(_this.actionsDisabled, action)	},	actions: {    	ADDCHILD: "ADDCHILD"	},	getInfo: function() {		var info = {			widgetId: this.widgetId,			objectId: this.objectId		}		return info;	},	initializeController: function() {		if (this.controller != "off") {			if (this.controller) {				this.controller = dojo.widget.byId(this.controller);			}			else {				// create default controller here				dojo.require("dojo.widget.TreeBasicController");				this.controller = dojo.widget.createWidget("TreeBasicController",					{ DNDController: (this.DNDMode ? "create" : ""), dieWithTree: true }				 );			}			this.controller.listenTree(this); // controller listens to my events		} else {			this.controller = null;		}	},	initializeSelector: function() {		if (this.selector != "off") {			if (this.selector) {				this.selector = dojo.widget.byId(this.selector);			}			else {				// create default controller here				dojo.require("dojo.widget.TreeSelector");				this.selector = dojo.widget.createWidget("TreeSelector", {dieWithTree: true});			}			this.selector.listenTree(this);		} else {			this.selector = null;		}	},	initialize: function(args, frag){		var _this = this;		for(name in this.eventNamesDefault) {			if (dojo.lang.isUndefined(this.eventNames[name])) {				this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];			}		}		for(var i=0; i<this.actionsDisabled.length; i++) {			this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();		}		if (this.DNDMode == "off") {			this.DNDMode = 0;		} else if (this.DNDMode == "between") {			this.DNDMode = this.DNDModes.ONTO | this.DNDModes.BETWEEN;		} else if (this.DNDMode == "onto") {			this.DNDMode = this.DNDModes.ONTO;		}		this.expandLevel = parseInt(this.expandLevel);		this.initializeSelector();		this.initializeController();		if (this.menu) {			this.menu = dojo.widget.byId(this.menu);			this.menu.listenTree(this);		}		this.containerNode = this.domNode;	},	postCreate: function() {		this.createDOMNode();	},	createDOMNode: function() {		dojo.html.disableSelection(this.domNode);		for(var i=0; i<this.children.length; i++){			this.children[i].parent = this; // root nodes have tree as parent			var node = this.children[i].createDOMNode(this, 0);			this.domNode.appendChild(node);		}		if (!this.showRootGrid){			for(var i=0; i<this.children.length; i++){				this.children[i].expand();			}		}		dojo.event.topic.publish(this.eventNames.treeCreate, { source: this } );	},	destroy: function() {		dojo.event.topic.publish(this.tree.eventNames.treeDestroy, { source: this } );		return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);	},	addChild: function(child, index) {//		dojo.debug("doAddChild "+index+" called for "+child);		var message = {			child: child,			index: index,			parent: this,			// remember if dom was already initialized			// initialized => no createDOMNode => no createDOMNode event			domNodeInitialized: child.domNodeInitialized		}		this.doAddChild.apply(this, arguments);		dojo.event.topic.publish(this.tree.eventNames.addChild, message);	},	// not called for initial tree building. See createDOMNode instead.	// builds child html node if needed	// index is "last node" by default	/**	 * FIXME: Is it possible that removeNode from the tree will cause leaks cause of attached events ?	 * if yes, then only attach events in addChild and detach in remove.. Seems all ok yet.	*/	doAddChild: function(child, index){		if (dojo.lang.isUndefined(index)) {			index = this.children.length;		}		if (!child.isTreeNode){			dojo.raise("You can only add TreeNode widgets to a "+this.widgetType+" widget!");			return;		}		// usually it is impossible to change "isFolder" state, but if anyone wants to add a child to leaf,		// it is possible program-way.		if (this.isTreeNode){			if (!this.isFolder) { // just became a folder.				//dojo.debug("becoming folder "+this);				this.setFolder();			}		}		// adjust tree		var _this = this;		dojo.lang.forEach(child.getDescendants(), function(elem) { elem.tree = _this.tree; });		// fix parent		child.parent = this;		// no dynamic loading for those who become parents		if (this.isTreeNode) {			this.state = this.loadStates.LOADED;		}		// add new child into DOM after it was added into children		if (index < this.children.length) { // children[] already has child			//dojo.debug("Inserting before "+this.children[index].title);			dojo.html.insertBefore(child.domNode, this.children[index].domNode);		} else {			this.containerNode.appendChild(child.domNode);			if (this.isExpanded && this.isTreeNode) {				/* When I add children to hidden containerNode => show container w/ them */				this.showChildren();			}		}		this.children.splice(index, 0, child);		//dojo.debugShallow(this.children);		// if node exists - adjust its depth, otherwise build it		if (child.domNodeInitialized) {			var d = this.isTreeNode ? this.depth : -1;			child.adjustDepth( d - child.depth + 1 );			// update icons to link generated dom with Tree => updateParentGrid			// if I moved child from LastNode inside the tree => need to link it up'n'down =>			// updateExpandGridColumn			// if I change depth => need to update all grid..			child.updateIconTree();		} else {			//dojo.debug("Create domnode ");			child.depth = this.isTreeNode ? this.depth+1 : 0;			child.createDOMNode(child.tree, child.depth);		}		// Use-case:		// When previous sibling was created => it was last, no children after it		// so it did not create link down => let's add it for all descendants		// Use-case:		// a child was moved down under the last node so last node should be updated		var prevSibling = child.getPreviousSibling();		if (child.isLastChild() && prevSibling) {			prevSibling.updateExpandGridColumn();		}		//dojo.debug("Added child "+child);	},	makeBlankImg: function() {		var img = document.createElement('img');		img.style.width = this.iconWidth + 'px';		img.style.height = this.iconHeight + 'px';		img.src = this.blankIconSrc;		img.style.verticalAlign = 'middle';		return img;	},	updateIconTree: function(){		//dojo.debug("Update icons for "+this)		if (!this.isTree) {			this.updateIcons();		}		for(var i=0; i<this.children.length; i++){			this.children[i].updateIconTree();		}	},	toString: function() {		return "["+this.widgetType+" ID:"+this.widgetId+"]"	},	/**	 * Move child to newParent as last child	 * redraw tree and update icons.	 *	 * Called by target, saves source in event.	 * events are published for BOTH trees AFTER update.	*/	move: function(child, newParent, index) {		//dojo.debug(child+" "+newParent+" at "+index);		var oldParent = child.parent;		var oldTree = child.tree;		this.doMove.apply(this, arguments);		var newParent = child.parent;		var newTree = child.tree;		var message = {				oldParent: oldParent, oldTree: oldTree,				newParent: newParent, newTree: newTree,				child: child		};		/* publish events here about structural changes for both source and target trees */		dojo.event.topic.publish(oldTree.eventNames.moveFrom, message);		dojo.event.topic.publish(newTree.eventNames.moveTo, message);	},	/* do actual parent change here. Write remove child first */	doMove: function(child, newParent, index) {		//var parent = child.parent;		child.parent.doRemoveNode(child);		newParent.doAddChild(child, index);	},// ================================ removeNode ===================================	removeNode: function(child) {		if (!child.parent) return;		var oldTree = child.tree;		var oldParent = child.parent;		var removedChild = this.doRemoveNode.apply(this, arguments);		dojo.event.topic.publish(this.tree.eventNames.removeNode,			{ child: removedChild, tree: oldTree, parent: oldParent }		);		return removedChild;	},	doRemoveNode: function(child) {		if (!child.parent) return;		var parent = child.parent;		var children = parent.children;		var index = child.getParentIndex();		if (index < 0) {			dojo.raise("Couldn't find node "+child+" for removal");		}		children.splice(index,1);		dojo.html.removeNode(child.domNode);		if (parent.children.length == 0 && !parent.isTree) {			parent.containerNode.style.display = "none";		}		// if WAS last node (children.length decreased already) and has prevSibling		if (index == children.length && index>0) {			children[index-1].updateExpandGridColumn();		}		// if it WAS first node in WHOLE TREE -		// update link up of its former lower neighbour(if exists still)		if (parent instanceof dojo.widget.Tree && index == 0 && children.length>0) {			children[0].updateExpandGrid();		}		//parent.updateIconTree();		child.parent = child.tree = null;		return child;	},	markLoading: function() {		// no way to mark tree loading	},	unMarkLoading: function() {		// no way to show that tree finished loading	},	lock: function() {		!this.lockLevel && this.markLoading();		this.lockLevel++;	},	unlock: function() {		if (!this.lockLevel) {			dojo.raise("unlock: not locked");		}		this.lockLevel--;		!this.lockLevel && this.unMarkLoading();	},	isLocked: function() {		var node = this;		while (true) {			if (node.lockLevel) {				return true;			}			if (node instanceof dojo.widget.Tree) {				break;			}			node = node.parent;		}		return false;	},	flushLock: function() {		this.lockLevel = 0;		this.unMarkLoading();	}});

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -