You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2006/01/27 00:58:20 UTC

svn commit: r372668 [11/16] - in /myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource: ./ src/ src/alg/ src/animation/ src/collections/ src/crypto/ src/data/ src/dnd/ src/event/ src/flash/ src/flash/flash6/ sr...

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Editor.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Editor.js?rev=372668&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Editor.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Editor.js Thu Jan 26 15:56:50 2006
@@ -0,0 +1,619 @@
+/*
+	Copyright (c) 2004-2005, 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
+*/
+
+/* TODO:
+ * - font selector
+ * - test, bug fix, more features :)
+*/
+dojo.provide("dojo.widget.Editor");
+dojo.provide("dojo.widget.html.Editor");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Toolbar");
+dojo.require("dojo.widget.RichText");
+dojo.require("dojo.widget.ColorPalette");
+
+dojo.widget.tags.addParseTreeHandler("dojo:Editor");
+
+dojo.widget.html.Editor = function() {
+	dojo.widget.HtmlWidget.call(this);
+	this.contentFilters = [];
+}
+dojo.inherits(dojo.widget.html.Editor, dojo.widget.HtmlWidget);
+
+dojo.widget.html.Editor.itemGroups = {
+	textGroup: ["bold", "italic", "underline", "strikethrough"],
+	blockGroup: ["formatBlock", "fontName"],
+	justifyGroup: ["justifyleft", "justifycenter", "justifyright"],
+	commandGroup: ["save", "cancel"],
+	colorGroup: ["forecolor", "hilitecolor"],
+	listGroup: ["insertorderedlist", "insertunorderedlist"],
+	indentGroup: ["outdent", "indent"],
+	linkGroup: ["createlink", "insertimage"]
+};
+
+dojo.widget.html.Editor.formatBlockValues = {
+	"Normal": "p",
+	"Main heading": "h2",
+	"Sub heading": "h3",
+	"Sub sub headering": "h4",
+	"Preformatted": "pre"
+};
+
+dojo.widget.html.Editor.fontNameValues = {
+	"Arial": "Arial, Helvetica, sans-serif",
+	"Verdana": "Verdana, sans-serif",
+	"Times New Roman": "Times New Roman, serif",
+	"Courier": "Courier New, monospace"
+};
+
+dojo.widget.html.Editor.defaultItems = [
+	"commandGroup", "|", "linkGroup", "|", "textGroup", "|", "justifyGroup", "|", "listGroup", "indentGroup", "|", "colorGroup"
+];
+
+// ones we support by default without asking the RichText component
+// NOTE: you shouldn't put buttons like bold, italic, etc in here
+dojo.widget.html.Editor.supportedCommands = ["save", "cancel", "|", "-", "/", " "];
+
+dojo.lang.extend(dojo.widget.html.Editor, {
+	widgetType: "Editor",
+
+	items: dojo.widget.html.Editor.defaultItems,
+	formatBlockItems: dojo.lang.shallowCopy(dojo.widget.html.Editor.formatBlockValues),
+	fontNameItems: dojo.lang.shallowCopy(dojo.widget.html.Editor.fontNameValues),
+
+	// used to get the properties of an item if it is given as a string
+	getItemProperties: function(name) {
+		var props = {};
+		switch(name.toLowerCase()) {
+			case "bold":
+			case "italic":
+			case "underline":
+			case "strikethrough":
+				props.toggleItem = true;
+				break;
+
+			case "justifygroup":
+				props.defaultButton = "justifyleft";
+				props.preventDeselect = true;
+				props.buttonGroup = true;
+				break;
+
+			case "listgroup":
+				props.buttonGroup = true;
+				break;
+
+			case "save":
+			case "cancel":
+				props.label = dojo.string.capitalize(name);
+				break;
+
+			case "forecolor":
+			case "hilitecolor":
+				props.name = name;
+				props.toggleItem = true; // FIXME: they aren't exactly toggle items
+				props.icon = this.getCommandImage(name);
+				break;
+
+			case "formatblock":
+				props.name = "formatBlock";
+				props.values = this.formatBlockItems;
+				break;
+
+			case "fontname":
+				props.name = "fontName";
+				props.values = this.fontNameItems;
+		}
+		return props;
+	},
+
+	validateItems: true, // set to false to add items, regardless of support
+	focusOnLoad: true,
+	minHeight: "1em",
+
+	_richText: null, // RichText widget
+	_richTextType: "RichText",
+
+	_toolbarContainer: null, // ToolbarContainer widget
+	_toolbarContainerType: "ToolbarContainer",
+
+	_toolbars: [],
+	_toolbarType: "Toolbar",
+
+	_toolbarItemType: "ToolbarItem",
+
+	buildRendering: function(args, frag) {
+		// get the node from args/frag
+		var node = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
+		var trt = dojo.widget.createWidget(this._richTextType, {
+			focusOnLoad: this.focusOnLoad,
+			minHeight: this.minHeight
+		}, node)
+		var _this = this;
+		// this appears to fix a weird timing bug on Safari
+		setTimeout(function(){
+			_this.setRichText(trt);
+
+			_this.initToolbar();
+
+			_this.fillInTemplate(args, frag);
+		}, 0);
+	},
+
+	setRichText: function(richText) {
+		if(this._richText && this._richText == richText) {
+			dojo.debug("Already set the richText to this richText!");
+			return;
+		}
+
+		if(this._richText && !this._richText.isClosed) {
+			dojo.debug("You are switching richTexts yet you haven't closed the current one. Losing reference!");
+		}
+		this._richText = richText;
+		dojo.event.connect(this._richText, "close", this, "onClose");
+		dojo.event.connect(this._richText, "onLoad", this, "onLoad");
+		dojo.event.connect(this._richText, "onDisplayChanged", this, "updateToolbar");
+		if(this._toolbarContainer) {
+			this._toolbarContainer.enable();
+			this.updateToolbar(true);
+		}
+	},
+
+	initToolbar: function() {
+		// var tic = new Date();
+		if(this._toolbarContainer) { return; } // only create it once
+		this._toolbarContainer = dojo.widget.createWidget(this._toolbarContainerType);
+		var tb = this.addToolbar();
+		var last = true;
+		for(var i = 0; i < this.items.length; i++) {
+			if(this.items[i] == "\n") { // new row
+				tb = this.addToolbar();
+			} else {
+				if((this.items[i] == "|")&&(!last)){
+					last = true;
+				}else{
+					last = this.addItem(this.items[i], tb);
+				}
+			}
+		}
+		this.insertToolbar(this._toolbarContainer.domNode, this._richText.domNode);
+		// alert(new Date - tic);
+	},
+
+	// allow people to override this so they can make their own placement logic
+	insertToolbar: function(tbNode, richTextNode) {
+		dojo.html.insertBefore(tbNode, richTextNode);
+		//dojo.html.insertBefore(this._toolbarContainer.domNode, this._richText.domNode);
+	},
+
+	addToolbar: function(toolbar) {
+		this.initToolbar();
+		if(!(toolbar instanceof dojo.widget.html.Toolbar)) {
+			toolbar = dojo.widget.createWidget(this._toolbarType);
+		}
+		this._toolbarContainer.addChild(toolbar);
+		this._toolbars.push(toolbar);
+		return toolbar;
+	},
+
+	addItem: function(item, tb, dontValidate) {
+		if(!tb) { tb = this._toolbars[0]; }
+		var cmd = ((item)&&(!dojo.lang.isUndefined(item["getValue"]))) ?  cmd = item["getValue"](): item;
+
+		var groups = dojo.widget.html.Editor.itemGroups;
+		if(item instanceof dojo.widget.ToolbarItem) {
+			tb.addChild(item);
+		} else if(groups[cmd]) {
+			var group = groups[cmd];
+			var worked = true;
+			if(cmd == "justifyGroup" || cmd == "listGroup") {
+				var btnGroup = [cmd];
+				for(var i = 0 ; i < group.length; i++) {
+					if(dontValidate || this.isSupportedCommand(group[i])) {
+						btnGroup.push(this.getCommandImage(group[i]));
+					}else{
+						worked = false;
+					}
+				}
+				if(btnGroup.length) {
+					var btn = tb.addChild(btnGroup, null, this.getItemProperties(cmd));
+					dojo.event.connect(btn, "onClick", this, "_action");
+					dojo.event.connect(btn, "onChangeSelect", this, "_action");
+				}
+				return worked;
+			} else {
+				for(var i = 0; i < group.length; i++) {
+					if(!this.addItem(group[i], tb)){
+						worked = false;
+					}
+				}
+				return worked;
+			}
+		} else {
+			if((!dontValidate)&&(!this.isSupportedCommand(cmd))){
+				return false;
+			}
+			if(dontValidate || this.isSupportedCommand(cmd)) {
+				cmd = cmd.toLowerCase();
+				if(cmd == "formatblock") {
+					var select = dojo.widget.createWidget("ToolbarSelect", {
+						name: "formatBlock",
+						values: this.formatBlockItems
+					});
+					tb.addChild(select);
+					var _this = this;
+					dojo.event.connect(select, "onSetValue", function(item, value) {
+						_this.onAction("formatBlock", value);
+					});
+				} else if(cmd == "fontname") {
+					var select = dojo.widget.createWidget("ToolbarSelect", {
+						name: "fontName",
+						values: this.fontNameItems
+					});
+					tb.addChild(select);
+					dojo.event.connect(select, "onSetValue", dojo.lang.hitch(this, function(item, value) {
+						this.onAction("fontName", value);
+					}));
+				} else if(dojo.lang.inArray(cmd, ["forecolor", "hilitecolor"])) {
+					var btn = tb.addChild(dojo.widget.createWidget("ToolbarColorDialog", this.getItemProperties(cmd)));
+					dojo.event.connect(btn, "onSetValue", this, "_setValue");
+				} else {
+					var btn = tb.addChild(this.getCommandImage(cmd), null, this.getItemProperties(cmd));
+					if(dojo.lang.inArray(cmd, ["save", "cancel"])) {
+						dojo.event.connect(btn, "onClick", this, "_close");
+					} else {
+						dojo.event.connect(btn, "onClick", this, "_action");
+						dojo.event.connect(btn, "onChangeSelect", this, "_action");
+					}
+				}
+			}
+		}
+		return true;
+	},
+
+	enableToolbar: function() {
+		if(this._toolbarContainer) {
+			this._toolbarContainer.domNode.style.display = "";
+			this._toolbarContainer.enable();
+		}
+	},
+
+	disableToolbar: function(hide){
+		if(hide){
+			if(this._toolbarContainer){
+				this._toolbarContainer.domNode.style.display = "none";
+			}
+		}else{
+			if(this._toolbarContainer){
+				this._toolbarContainer.disable();
+			}
+		}
+	},
+
+	_updateToolbarLastRan: null,
+	_updateToolbarTimer: null,
+	_updateToolbarFrequency: 500,
+
+	updateToolbar: function(force) {
+		if(!this._toolbarContainer) { return; }
+
+		// keeps the toolbar from updating too frequently
+		// TODO: generalize this functionality?
+		var diff = new Date() - this._updateToolbarLastRan;
+		if(!force && this._updateToolbarLastRan && (diff < this._updateToolbarFrequency)) {
+			clearTimeout(this._updateToolbarTimer);
+			var _this = this;
+			this._updateToolbarTimer = setTimeout(function() {
+				_this.updateToolbar();
+			}, this._updateToolbarFrequency/2);
+			return;
+		} else {
+			this._updateToolbarLastRan = new Date();
+		}
+		// end frequency checker
+
+		var items = this._toolbarContainer.getItems();
+		for(var i = 0; i < items.length; i++) {
+			var item = items[i];
+			if(item instanceof dojo.widget.html.ToolbarSeparator) { continue; }
+			var cmd = item._name;
+			if (cmd == "save" || cmd == "cancel") { continue; }
+			else if(cmd == "justifyGroup") {
+				try {
+					if(!this._richText.queryCommandEnabled("justifyleft")) {
+						item.disable(false, true);
+					} else {
+						item.enable(false, true);
+						var jitems = item.getItems();
+						for(var j = 0; j < jitems.length; j++) {
+							var name = jitems[j]._name;
+							var value = this._richText.queryCommandValue(name);
+							if(typeof value == "boolean" && value) {
+								value = name;
+								break;
+							} else if(typeof value == "string") {
+								value = "justify"+value;
+							} else {
+								value = null;
+							}
+						}
+						if(!value) { value = "justifyleft"; } // TODO: query actual style
+						item.setValue(value, false, true);
+					}
+				} catch(err) {}
+			} else if(cmd == "listGroup") {
+				var litems = item.getItems();
+				for(var j = 0; j < litems.length; j++) {
+					this.updateItem(litems[j]);
+				}
+			} else {
+				this.updateItem(item);
+			}
+		}
+	},
+
+	updateItem: function(item) {
+		try {
+			var cmd = item._name;
+			var enabled = this._richText.queryCommandEnabled(cmd);
+			item.setEnabled(enabled, false, true);
+
+			var active = this._richText.queryCommandState(cmd);
+			if(active && cmd == "underline") {
+				// don't activate underlining if we are on a link
+				active = !this._richText.queryCommandEnabled("unlink");
+			}
+			item.setSelected(active, false, true);
+			return true;
+		} catch(err) {
+			return false;
+		}
+	},
+
+	supportedCommands: dojo.widget.html.Editor.supportedCommands.concat(),
+
+	isSupportedCommand: function(cmd) {
+		// FIXME: how do we check for ActiveX?
+		var yes = dojo.lang.inArray(cmd, this.supportedCommands);
+		if(!yes) {
+			try {
+				var richText = this._richText || dojo.widget.html.RichText.prototype;
+				yes = richText.queryCommandAvailable(cmd);
+			} catch(E) {}
+		}
+		return yes;
+	},
+
+	getCommandImage: function(cmd) {
+		if(cmd == "|") {
+			return cmd;
+		} else {
+			return dojo.uri.dojoUri("src/widget/templates/buttons/" + cmd + ".gif");
+		}
+	},
+
+	_action: function(e) {
+		// djConfig.isDebug = true;
+		// dojo.debug(e);
+		// dojo.debug(e.getValue());
+		this._fire("onAction", e.getValue());
+	},
+
+	_setValue: function(a, b) {
+		this._fire("onAction", a.getValue(), b);
+	},
+
+	_close: function(e) {
+		if(!this._richText.isClosed) {
+			this._richText.close(e.getName().toLowerCase() == "save");
+		}
+	},
+
+	onAction: function(cmd, value) {
+		switch(cmd) {
+			case "createlink":
+				if(!(value = prompt("Please enter the URL of the link:", "http://"))) {
+					return;
+				}
+				break;
+			case "insertimage":
+				if(!(value = prompt("Please enter the URL of the image:", "http://"))) {
+					return;
+				}
+				break;
+		}
+		this._richText.execCommand(cmd, value);
+	},
+
+	fillInTemplate: function(args, frag) {
+		// dojo.event.connect(this, "onResized", this._richText, "onResized");
+	},
+
+	_fire: function(eventName) {
+		if(dojo.lang.isFunction(this[eventName])) {
+			var args = [];
+			if(arguments.length == 1) {
+				args.push(this);
+			} else {
+				for(var i = 1; i < arguments.length; i++) {
+					args.push(arguments[i]);
+				}
+			}
+			this[eventName].apply(this, args);
+		}
+	},
+
+	getHtml: function(){
+		this._richText.contentFilters = this.contentFilters;
+		return this._richText.getEditorContent();
+	},
+
+	getEditorContent: function(){
+		return this.getHtml();
+	},
+
+	onClose: function(save, hide){
+		this.disableToolbar(hide);
+		if(save) {
+			this._fire("onSave");
+		} else {
+			this._fire("onCancel");
+		}
+	},
+
+	// events baby!
+	onLoad: function(){},
+	onSave: function(){},
+	onCancel: function(){}
+});
+
+/*
+function dontRunMe() {
+function createToolbar() {
+	tick("createToolbar");
+	tick("ct-init");
+	tbCont = dojo.widget.createWidget("toolbarContainer");
+	tb = dojo.widget.createWidget("toolbar");
+	tbCont.addChild(tb);
+
+	var saveBtn = tb.addChild("Save");
+	dojo.event.connect(saveBtn, "onClick", function() { editor.close(true); });
+	var cancelBtn = tb.addChild("Cancel");
+	dojo.event.connect(cancelBtn, "onClick", function() { editor.close(false); });
+	tb.addChild("|");
+
+	var headings = dojo.widget.createWidget("ToolbarSelect", {
+		name: "formatBlock",
+		values: {
+			"Normal": "p",
+			"Main heading": "h2",
+			"Sub heading": "h3",
+			"Sub sub heading": "h4",
+			"Preformatted": "pre"
+		}
+	});
+	dojo.event.connect(headings, "onSetValue", function(item, val) {
+		editor.execCommand("formatBlock", val);
+	});
+	tb.addChild(headings);
+	tb.addChild("|");
+	tock("ct-init");
+
+	// toolbar layout (2 rows):
+	// Save Cancel | WikiWord | Link Img | Table
+	// Heading FontFace | B I U | Alignment | OL UL < > | FG BG
+	var rows = [
+		["save", "cancel", "|", "wikiword", "|", "createlink", "insertimage", "|", "table"],
+		["formatBlock", "font", "|", "bold", "italic", "underline", "|", "justification", "|", "ol", "ul", "forecolor", "hilitecolor"]
+	];
+
+	tick("command array");
+	var commands = [
+		{ values: ["bold", "italic", "underline", "strikethrough"], toggleItem: true },
+		{ values: [
+				dojo.widget.createWidget("ToolbarColorDialog", {toggleItem: true, name: "forecolor", icon: cmdImg("forecolor")}),
+				dojo.widget.createWidget("ToolbarColorDialog", {toggleItem: true, name: "hilitecolor", icon: cmdImg("hilitecolor")})
+		]},
+		{ values: ["justifyleft", "justifycenter", "justifyright"], name: "justify", defaultButton: "justifyleft", buttonGroup: true, preventDeselect: true },
+		{ values: ["createlink", "insertimage"] },
+		{ values: ["outdent", "indent"] },
+		{ values: ["insertorderedlist", "insertunorderedlist"], name: "list", buttonGroup: true },
+		{ values: ["undo", "redo"] },
+		{ values: ["wikiword"], title: "WikiWord" }
+	];
+	tock("command array");
+
+	tick("processCommands");
+	for(var i = 0; i < commands.length; i++) {
+		var set = commands[i];
+		var values = set.values;
+		var btnGroup = [set.name];
+		for(var j = 0; j < values.length; j++) {
+			if(typeof values[j] == "string") {
+				var cmd = values[j];
+				if(cmd == "wikiword") {
+					var btn = tb.addChild(cmdImg(cmd), null, {name:cmd, label:"WikiWord"});
+					//dojo.event.connect(bt, "onClick", listenWikiWord);
+					//dojo.event.connect(bt, "onChangeSelect", listenWikiWord);
+				} else if(dojo.widget.html.RichText.prototype.queryCommandAvailable(cmd)) {
+					if(set.buttonGroup) {
+						btnGroup.push(cmdImg(cmd));
+					} else {
+						var btn = tb.addChild(cmdImg(cmd), null, {name:cmd, toggleItem:set.toggleItem});
+						dojo.event.connect(btn, "onClick", listen);
+						dojo.event.connect(btn, "onChangeSelect", listen);
+					}
+				}
+			} else {
+				if(dojo.widget.html.RichText.prototype.queryCommandAvailable(values[j].getName())) {
+					var btn = tb.addChild(values[j]);
+					dojo.event.connect(btn, "onSetValue", colorListen, values[j].getName());
+				}
+			}
+		}
+		if(set.buttonGroup && btnGroup.length > 1) {
+			var btn = tb.addChild(btnGroup, null, {defaultButton:set.defaultButton});
+			dojo.event.connect(btn, "onClick", listen);
+			dojo.event.connect(btn, "onChangeSelect", listen);
+		}
+
+		if(i + 1 != commands.length
+			&& !(tb.children[tb.children.length-1] instanceof dojo.widget.html.ToolbarSeparator)) {
+			tb.addChild("|");
+		}
+	}
+	tock("processCommands");
+	tock("createToolbar");
+	return tbCont;
+}
+function cmdImg(cmd) {
+	return dojo.uri.dojoUri("src/widget/templates/buttons/" + cmd + ".gif");
+}
+function createWysiwyg(node) {
+	tick("createWysiwyg");
+	tick("editor");
+	editor = dojo.widget.createWidget("RichText", {}, node);
+	tock("editor");
+	dojo.event.connect(editor, "close", function(changed) {
+		if(changed) { setTimeout(save, 5); }
+		setTimeout(function() {
+			dojo.io.bind({
+				url: location,
+				content: {
+					edit: "0",
+					cancel: "Cancel"
+				},
+				handler: function() {
+					hideLoad();
+				}
+			});
+		}, 15);
+		finishEdit();
+	});
+	autolinkWikiWords(editor);
+	cleanupWord(editor);
+	//createToolbar();
+	dojo.event.connect(editor, "onDisplayChanged", updateToolbar);
+
+	if(editor && tbCont && tb) {
+		var top = document.getElementById("jot-topbar");
+		dojo.html.addClass(top, "hidden");
+		//placeToolbar(tbCont.domNode);
+		//top.appendChild(tbCont.domNode);
+		//document.getElementById("jot-bottombar").innerHTML = "&nbsp;";
+	} else {
+		alert("Something went wrong trying to create the toolbar + editor.");
+	}
+	tock("createWysiwyg");
+	
+	return editor;
+}
+
+}
+*/

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTree.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTree.js?rev=372668&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTree.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTree.js Thu Jan 26 15:56:50 2006
@@ -0,0 +1,499 @@
+/*
+	Copyright (c) 2004-2005, 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
+*/
+dojo.provide("dojo.widget.EditorTree");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.dnd.*");
+dojo.require("dojo.fx.html");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.Container");
+dojo.require("dojo.widget.Tree");
+dojo.require("dojo.widget.EditorTreeNode");
+
+// make it a tag
+dojo.widget.tags.addParseTreeHandler("dojo:EditorTree");
+
+
+dojo.widget.EditorTree = function() {
+	dojo.widget.html.Container.call(this);
+	this.acceptDropSources = [];
+
+	this.eventNames = {
+		// new node built.. Well, just built
+		nodeCreate: "",
+		// expand icon clicked
+		treeClick: "",
+		// node icon clicked
+		iconClick: "",
+		// node title clicked
+		titleClick: ""
+	};
+}
+dojo.inherits(dojo.widget.EditorTree, dojo.widget.html.Container);
+
+/* extend DOES NOT copy recursively */
+dojo.lang.extend(dojo.widget.EditorTree, {
+	widgetType: "EditorTree",
+
+	domNode: null,
+
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/EditorTree.css"),
+
+	templateString: '<div class="dojoTree"></div>',
+
+	/* Model events */
+	eventNames: null,
+
+	toggler: null,
+
+	//
+	// these icons control the grid and expando buttons for the whole tree
+	//
+
+	blankIconSrc: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_blank.gif").toString(),
+
+	gridIconSrcT: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_t.gif").toString(), // for non-last child grid
+	gridIconSrcL: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_l.gif").toString(), // for last child grid
+	gridIconSrcV: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_v.gif").toString(), // vertical line
+	gridIconSrcP: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_p.gif").toString(), // for under parent item child icons
+	gridIconSrcC: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_c.gif").toString(), // for under child item child icons
+	gridIconSrcX: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_x.gif").toString(), // grid for sole root item
+	gridIconSrcY: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_y.gif").toString(), // grid for last rrot item
+	gridIconSrcZ: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_grid_z.gif").toString(), // for under root parent item child icon
+
+	expandIconSrcPlus: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_expand_plus.gif").toString(),
+	expandIconSrcMinus: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_expand_minus.gif").toString(),
+	expandIconSrcLoading: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/treenode_loading.gif").toString(),
+
+
+	iconWidth: 18,
+	iconHeight: 18,
+
+
+	//
+	// tree options
+	//
+
+	showGrid: true,
+	showRootGrid: true,
+
+	toggle: "default",
+	toggleDuration: 150,
+	title: "My Tree", // used for debug only
+	selector: null,
+
+	initialize: function(args, frag){
+
+		var sources;
+		if ( (sources = args['acceptDropSources']) || (sources = args['acceptDropSources']) ) {
+			this.acceptDropSources = sources.split(',');
+		}
+
+		switch (this.toggle) {
+
+			case "fade": this.toggler = new dojo.widget.Tree.FadeToggle(); break;
+			// buggy - try to open many nodes in FF (IE is ok)
+			case "wipe": this.toggler = new dojo.widget.Tree.WipeToggle(); break;
+			default    : this.toggler = new dojo.widget.Tree.DefaultToggle();
+		}
+
+
+		if (args['eventNaming'] == "default" || args['eventnaming'] == "default" ) { // IE || FF
+
+			for (eventName in this.eventNames) {
+				this.eventNames[eventName] = this.widgetId+"/"+eventName;
+			}
+			/*
+			this.eventNames.watch("nodeCreate",
+   				function (id,oldval,newval) {
+      				alert("o." + id + " changed from " + oldval + " to " + newval);
+      				return newval;
+			   }
+			  );
+			 */
+
+		//	alert(dojo.widget.manager.getWidgetById('firstTree').widgetId)
+		//	alert(dojo.widget.manager.getWidgetById('firstTree').eventNames.nodeCreate);
+
+		}
+
+
+		if (args['controller']) {
+			var controller = dojo.widget.manager.getWidgetById(args['controller']);
+
+			controller.subscribeTree(this); // controller listens to my events
+		}
+
+		if (args['selector']) {
+			this.selector = dojo.widget.manager.getWidgetById(args['selector']);
+		}
+		else {
+			this.selector = new dojo.widget.createWidget("dojo.widget.EditorTreeSelector");
+		}
+
+	},
+
+
+
+	postCreate: function() {
+		this.buildTree();
+	},
+
+	buildTree: function() {
+
+		dojo.html.disableSelection(this.domNode);
+
+		for(var i=0; i<this.children.length; i++){
+
+			this.children[i].isFirstNode = (i == 0) ? true : false;
+			this.children[i].isLastNode = (i == this.children.length-1) ? true : false;
+			this.children[i].parentNode = this; // root nodes have tree as parent
+
+			var node = this.children[i].buildNode(this, 0);
+
+
+			this.domNode.appendChild(node);
+		}
+
+
+		//
+		// when we don't show root toggles, we need to auto-expand root nodes
+		//
+
+		if (!this.showRootGrid){
+			for(var i=0; i<this.children.length; i++){
+				this.children[i].expand();
+			}
+		}
+
+
+		for(var i=0; i<this.children.length; i++){
+			this.children[i].startMe();
+		}
+	},
+
+
+
+	/**
+	 * Move child to newParent as last child
+	 * redraw tree and update icons
+	*/
+	changeParent: function(child, newParent) {
+		//dojo.debug("Move "+child.title+" to "+newParent.title)
+
+		/* do actual parent change here. Write remove child first */
+		child.parentNode.removeChild(child);
+
+		newParent.addChild(child, 0);
+
+	},
+
+	removeChild: function(child) {
+
+		var parentNode = child.parentNode;
+
+		var children = parentNode.children;
+
+		for(var i=0; i<children.length; i++){
+			if(children[i] === child){
+				if (children.length>1) {
+					if (i==0) {
+						children[i+1].isFirstNode = true;
+					}
+					if (i==children.length-1) {
+						children[i-1].isLastNode = true;
+					}
+				}
+				children.splice(i, 1);
+				break;
+			}
+		}
+
+		child.domNode.parentNode.removeChild(child.domNode);
+
+
+		//dojo.debug("removeChild: "+child.title+" from "+parentNode.title);
+
+		if (children.length == 0) {
+			// toggle empty container off
+			if (parentNode.widgetType == 'EditorTreeNode') { // if has container
+				parentNode.containerNode.style.display = 'none';
+			}
+
+		}
+
+		parentNode.updateIconTree();
+
+		return child;
+
+	},
+
+
+
+	// not called for initial tree building. See buildNode instead.
+	// builds child html node if needed
+	// index is "last node" by default
+	addChild: function(child, index){
+		//dojo.debug("This "+this.title+" Child "+child.title+" index "+index);
+
+		if (dojo.lang.isUndefined(index)) {
+			index = this.children.length;
+		}
+
+		//
+		// this function gets called to add nodes to both trees and nodes, so it's a little confusing :)
+		//
+
+		if (child.widgetType != 'EditorTreeNode'){
+			dojo.raise("You can only add EditorTreeNode widgets to a "+this.widgetType+" widget!");
+			return;
+		}
+
+		// set/clean isFirstNode and isLastNode
+		if (this.children.length){
+			if (index == 0) {
+				this.children[0].isFirstNode = false;
+				child.isFirstNode = true;
+			}
+			else {
+				child.isFirstNode = false;
+			}
+			if (index == this.children.length) {
+				this.children[index-1].isLastNode = false;
+				child.isLastNode = true;
+			}
+			else {
+				child.isLastNode = false;
+			}
+		}
+		else {
+			child.isLastNode = true;
+			child.isFirstNode = true;
+		}
+
+
+
+		// 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.widgetType == 'EditorTreeNode'){
+			this.isFolder = true;
+			//this.isExpanded = false;
+		}
+
+		// adjust tree
+		var tree = this.widgetType == 'EditorTreeNode' ? this.tree : this;
+		dojo.lang.forEach(child.getDescendants(), function(elem) { elem.tree = tree; });
+
+		/*
+		var stack = [child];
+		var elem;
+		// change tree for all subnodes
+		while (elem = stack.pop()) {
+			//dojo.debug("Tree for "+elem.title);
+			elem.tree = tree;
+			dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); });
+		}
+		*/
+
+		// fix parent
+		child.parentNode = this;
+
+
+		// no dynamic loading for those who are parents already
+		if (this.widgetType == 'EditorTreeNode') {
+			this.loaded = this.loadStates.LOADED;
+		}
+
+		// if node exists - adjust its depth, otherwise build it
+		if (child.domNodeInitialized) {
+			//dojo.debug(this.widgetType)
+			var d = (this.widgetType == 'EditorTreeNode') ? this.depth : 0;
+			//dojo.debug('Depth is '+this.depth);
+			child.adjustDepth(d-child.depth+1);
+		}
+		else {
+			child.depth = this.widgetType == 'EditorTreeNode' ? this.depth+1 : 0;
+			child.buildNode(child.tree, child.depth);
+		}
+
+
+
+		//dojo.debug(child.domNode.outerHTML)
+
+		if (index < this.children.length) {
+
+			//dojo.debug('insert '+index)
+			//dojo.debugShallow(child);
+
+			// insert
+			this.children[index].domNode.parentNode.insertBefore(child.domNode, this.children[index].domNode);
+		}
+		else {
+			if (this.widgetType == 'EditorTree') {
+				this.domNode.appendChild(node);
+			}
+			else {
+
+				//dojo.debug('append '+index)
+
+			// enable container, cause I add first child into it
+				this.containerNode.style.display = 'block';
+
+				//this.domNode.insertBefore(child.domNode, this.containerNode);
+
+				//dojo.debugShallow(this.containerNode);
+				this.containerNode.appendChild(child.domNode);
+				//dojo.debugShallow(this.containerNode);
+			}
+		}
+
+		this.children.splice(index, 0, child);
+
+		//dojo.lang.forEach(this.children, function(child) { dojo.debug("Child "+child.title); } );
+
+		//dojo.debugShallow(child);
+
+		this.updateIconTree();
+
+		child.startMe();
+
+
+	},
+
+	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;
+	},
+
+
+	/* Swap nodes with SAME parent */
+	swapNodes: function(node1, node2) {
+		if (node1 === node2) return;
+
+		if (node1.parentNode !== node2.parentNode) {
+			dojo.raise("You may only swap nodes with same parent")
+		}
+
+		var parentNode = node1.parentNode;
+
+		var nodeIndex1 = node1.getParentIndex();
+		var nodeIndex2 = node2.getParentIndex();
+
+		/* Fix children order */
+		parentNode.children[nodeIndex1] = node2;
+		parentNode.children[nodeIndex2] = node1;
+
+		/* swap isFirst/isLast flags */
+		var a = node1.isLastNode;
+		var b = node1.isFirstNode;
+		node1.isLastNode = node2.isLastNode;
+		node1.isFirstNode = node2.isFirstNode;
+		node2.isLastNode = a;
+		node2.isFirstNode = b;
+
+		//dojo.debug(node1.title+" : "+node2.title)
+
+		this.swapDomNodes(node1.domNode, node2.domNode);
+		//parentNode.containerNode.insertBefore(node2.domNode, node1.domNode);
+		//parentNode.containerNode.insertBefore(node1.domNode, node2.domNode);
+
+		//parentNode.containerNode.removeChild(this.domNode);
+
+		parentNode.updateIconTree();
+
+
+	},
+
+
+	/* Should go dojo.dom */
+	swapDomNodes: function(node1, node2) {
+		// replace node1 with node2
+		//dojo.debug(node1.parentNode)
+
+		// may have siblings only in n1 -> n2 order
+		if (node2.nextSibling === node1) return this.swapDomNodes(node2, node1);
+
+		var parentNode1 = node1.parentNode;
+		var parentNode2 = node2.parentNode;
+
+		var inserter1;
+		var inserter2;
+		var removed1;
+		var removed2;
+
+		if (node1.nextSibling === node2) {			// node1->node2
+			if (node2.nextSibling) {
+				var a2n = node2.nextSibling;
+				inserter1 = function(newNode) { parentNode1.insertBefore(newNode, a2n); }
+				inserter2 = function(newNode) { parentNode1.insertBefore(newNode, a2n); }
+			}
+			else {
+				inserter1 = function(newNode) { parentNode1.appendChild(newNode); }
+				inserter2 = function(newNode) { parentNode1.appendChild(newNode); }
+			}
+		}
+		else {
+			if (node1.nextSibling) {
+				inserter1 = function(newNode) { parentNode1.insertBefore(newNode, node1.nextSibling); }
+			}
+			else {
+				inserter1 = function(newNode) { parentNode1.appendChild(newNode); }
+			}
+
+			if (node2.nextSibling) {
+				inserter2 = function(newNode) { parentNode2.insertBefore(newNode, node2.nextSibling); }
+			}
+			else {
+				inserter2 = function(newNode) { parentNode2.appendChild(newNode); }
+			}
+		}
+
+
+		removed1 = parentNode1.removeChild(node1);
+		removed2 = parentNode2.removeChild(node2);
+
+		// order is important cause of n1->n2 case
+		inserter1.apply(this, [removed2]);
+		inserter2.apply(this, [removed1]);
+
+
+	},
+
+
+	updateIconTree: function(){
+
+		if (this.widgetType=='EditorTreeNode') {
+			this.updateIcons();
+		}
+
+		for(var i=0; i<this.children.length; i++){
+			this.children[i].updateIconTree();
+		}
+
+	}
+
+
+
+
+
+});
+

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeContextMenu.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeContextMenu.js?rev=372668&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeContextMenu.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeContextMenu.js Thu Jan 26 15:56:50 2006
@@ -0,0 +1,136 @@
+/*
+	Copyright (c) 2004-2005, 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
+*/
+
+dojo.provide("dojo.widget.EditorTreeContextMenu");
+dojo.provide("dojo.widget.EditorTreeMenuItem");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.dnd.*");
+dojo.require("dojo.fx.html");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.Container");
+dojo.require("dojo.widget.Menu2");
+
+
+dojo.widget.tags.addParseTreeHandler("dojo:EditorTreeContextMenu");
+dojo.widget.tags.addParseTreeHandler("dojo:EditorTreeMenuItem");
+
+
+
+dojo.widget.EditorTreeContextMenu = function() {
+	dojo.widget.PopupMenu2.call(this);
+	this.widgetType = "EditorTreeContextMenu";
+
+	this.eventNames =  {
+		open: ""
+	};
+
+
+}
+
+
+dojo.inherits(dojo.widget.EditorTreeContextMenu, dojo.widget.PopupMenu2);
+
+dojo.lang.extend(dojo.widget.EditorTreeContextMenu, {
+
+	initialize: function(args, frag) {
+
+		var result = dojo.widget.PopupMenu2.prototype.initialize.apply(this, arguments);
+
+		if (args['eventNaming'] == "default" || args['eventnaming'] == "default" ) { // IE || FF
+			for (eventName in this.eventNames) {
+				this.eventNames[eventName] = this.widgetId+"/"+eventName;
+			}
+		}
+
+		return result;
+
+	},
+
+	postCreate: function(){
+		var result = dojo.widget.PopupMenu2.prototype.postCreate.apply(this, arguments);
+
+		var subItems = this.getChildrenOfType('EditorTreeMenuItem')
+
+		for(var i=0; i<subItems.length; i++) {
+			dojo.event.topic.subscribe(this.eventNames.open, subItems[i], "menuOpen")
+		}
+
+
+		return result;
+	},
+
+	open: function(x, y, parentMenu, explodeSrc){
+
+		var result = dojo.widget.PopupMenu2.prototype.open.apply(this, arguments);
+
+		/* publish many events here about structural changes */
+		dojo.event.topic.publish(this.eventNames.open, { menu:this });
+
+		return result;
+	}
+
+
+
+});
+
+
+
+
+
+
+dojo.widget.EditorTreeMenuItem = function() {
+	dojo.widget.MenuItem2.call(this);
+	this.widgetType = "EditorTreeMenuItem";
+
+}
+
+
+dojo.inherits(dojo.widget.EditorTreeMenuItem, dojo.widget.MenuItem2);
+
+dojo.lang.extend(dojo.widget.EditorTreeMenuItem, {
+	for_folders: true,
+
+
+	getTreeNode: function() {
+		var menu = this;
+
+		while (menu.widgetType != 'EditorTreeContextMenu') {
+			menu = menu.parent;
+		}
+
+		var source = menu.getTopOpenEvent().target;
+
+		while (!source.treeNode && source.tagName != 'body') {
+			source = source.parentNode;
+		}
+		if (source.tagName == 'body') {
+			dojo.raise("treeNode not detected");
+		}
+		var treeNode = dojo.widget.manager.getWidgetById(source.treeNode);
+
+		return treeNode;
+	},
+
+	menuOpen: function(message) {
+		var treeNode = this.getTreeNode();
+
+		/* manage for folders status */
+		if (!treeNode.isFolder && this.for_folders==false) {
+			this.setDisabled(true);
+		}
+		else {
+			this.setDisabled(false);
+		}
+	}
+
+
+
+});
\ No newline at end of file

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeController.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeController.js?rev=372668&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeController.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeController.js Thu Jan 26 15:56:50 2006
@@ -0,0 +1,742 @@
+/*
+	Copyright (c) 2004-2005, 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
+*/
+
+
+dojo.provide("dojo.widget.EditorTreeController");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.dnd.*");
+dojo.require("dojo.dnd.TreeDragAndDrop");
+dojo.require("dojo.fx.html");
+dojo.require("dojo.json")
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.Container");
+dojo.require("dojo.widget.Tree");
+
+
+dojo.widget.tags.addParseTreeHandler("dojo:EditorTreeController");
+
+
+dojo.widget.EditorTreeController = function() {
+	dojo.widget.HtmlWidget.call(this);
+
+	this.eventNames = {
+		select : "",
+		collapse: "",
+		expand: "",
+		dblselect: "", // select already selected node.. Edit or whatever
+
+		swap: "", // nodes of same parent were swapped
+		move: "", // a child was moved from one place to another with parent change
+		remove: ""
+	};
+
+
+	this.dragSources = {};
+	this.dropTargets = {};
+}
+
+dojo.inherits(dojo.widget.EditorTreeController, dojo.widget.HtmlWidget);
+
+
+dojo.lang.extend(dojo.widget.EditorTreeController, {
+	widgetType: "EditorTreeController",
+
+	//RPCUrl: "http://test.country-info.ru/json_tree.php",
+	//RPCUrl: "http://tmp.x/jstree/www/json_tree.php",
+	RPCUrl: "local",
+
+	initialize: function(args, frag){
+
+		if (args['eventNaming'] == "default" || args['eventnaming'] == "default" ) { // IE || FF
+			for (eventName in this.eventNames) {
+				this.eventNames[eventName] = this.widgetId+"/"+eventName;
+			}
+		}
+
+	},
+
+
+	enabledDND: true,
+
+	/**
+	 * Binds controller to tree events
+	*/
+	subscribeTree: function(tree) {
+
+		if (!tree.eventNames.nodeCreate) dojo.raise("Can't subscribe controller to empty nodeCreate")
+		if (!tree.eventNames.treeClick) dojo.raise("Can't subscribe controller to empty treeClick")
+		if (!tree.eventNames.iconClick) dojo.raise("Can't subscribe controller to empty iconClick")
+		if (!tree.eventNames.titleClick) dojo.raise("Can't subscribe controller to empty titleClick")
+
+		dojo.event.topic.subscribe(tree.eventNames.nodeCreate, this, "onNodeCreate");
+		dojo.event.topic.subscribe(tree.eventNames.treeClick, this, "onTreeClick");
+		dojo.event.topic.subscribe(tree.eventNames.iconClick, this, "onIconClick");
+		dojo.event.topic.subscribe(tree.eventNames.titleClick, this, "onTitleClick");
+	},
+
+
+	/**
+	 * Checks whether it is ok to change parent of child to newParent
+	 * May incur type checks etc
+	 */
+	canChangeParent: function(child, newParent){
+
+//		dojo.debug('check for '+child+' '+newParent)
+
+		// Can't move parent under child. check whether new parent is child of "child".
+		var node = newParent;
+		while(node.widgetType !== 'EditorTree') {
+			//dojo.debugShallow(node.title)
+
+
+			if (node === child) {
+				// parent of newParent is child
+				return false;
+			}
+			node = node.parentNode;
+		}
+
+		// check for newParent being a folder
+		if (!newParent.isFolder) {
+			return false;
+		}
+
+		// check if newParent is parent for child already
+		for(var i=0;i<newParent.children.length; i++) {
+			if (newParent.children[i] == child) return false;
+		}
+
+		return true;
+	},
+
+
+	getRPCUrl: function(action) {
+
+		if (this.RPCUrl == "local") { // for demo and tests. May lead to widgetId collisions
+			var dir = document.location.href.substr(0, document.location.href.lastIndexOf('/'));
+			var localUrl = dir+"/"+action;
+			//dojo.debug(localUrl);
+			return localUrl;
+		}
+
+
+		if (!this.RPCUrl) {
+			dojo.raise("Empty RPCUrl: can't load");
+		}
+
+		return this.RPCUrl + ( this.RPCUrl.indexOf("?") > -1 ? "&" : "?") + "action="+action;
+	},
+
+	/**
+	 * Make request to server about moving children.
+	 *
+	 * Request returns "true" if move succeeded,
+	 * object with error field if failed
+	 *
+	 * I can't leave DragObject floating until async request returns, need to return false/true
+	 * so making it sync way...
+	 *
+	 * Also, "loading" icon is not shown until function finishes execution, so no indication for remote request.
+	*/
+	changeParentRemote: function(child, newParent){
+
+			newParent.markLoading();
+
+			var params = {
+				// where from
+				childId: child.widgetId,
+				childTreeId: child.tree.widgetId,
+				childOldParentId: child.parentNode.widgetId,
+				// where to
+				newParentId: newParent.widgetId,
+				newParentTreeId: newParent.tree.widgetId
+			}
+
+			var query = dojo.io.argsFromMap(params);
+			var requestUrl = this.getRPCUrl('changeParent');
+			if(query != "") {
+				requestUrl += (requestUrl.indexOf("?") > -1 ? "&" : "?") + query;
+			}
+
+			var response;
+			var result;
+
+			try{
+				response = dojo.hostenv.getText(requestUrl);
+				result = dj_eval("("+response+")");
+			}catch(e){
+				dojo.debug(e);
+				dojo.debug(response);
+				dojo.raise("Failed to load node");
+			}
+
+
+			//dojo.debugShallow(result)
+
+			if (result == true) {
+				/* change parent succeeded */
+				child.tree.changeParent(child, newParent)
+				this.updateDND(child);
+				return true;
+			}
+			else if (dojo.lang.isObject(result)) {
+				dojo.raise(result.error);
+			}
+			else {
+				dojo.raise("Invalid response "+response)
+			}
+
+
+	},
+
+
+	/**
+	 * return true on success, false on failure
+	*/
+	changeParent: function(child, newParent) {
+		// dojo.debug("Drop registered")
+		/* move sourceTreeNode to new parent */
+		if (!this.canChangeParent(child, newParent)) {
+			return false;
+		}
+
+		/* load nodes into newParent in sync mode, if needed, first */
+		if (newParent.state == newParent.loadStates.UNCHECKED) {
+			this.loadRemote(newParent, true);
+		}
+
+		var oldParent = child.parentNode;
+
+		var result = this.changeParentRemote(child, newParent);
+
+		if (!result) return result;
+
+
+		/* publish many events here about structural changes */
+		dojo.event.topic.publish(this.eventNames.move,
+			{ oldParent: oldParent, newParent: child.parentNode, child: child }
+		);
+
+		this.expand(newParent);
+
+		return result;
+	},
+
+
+
+	/**
+	 * Common RPC error handler (dies)
+	*/
+	RPCErrorHandler: function(type, obj) {
+		dojo.raise("RPC error occured! Application restart/tree refresh recommended.");
+	},
+
+
+
+	/**
+	 * Add all loaded nodes from array obj as node children and expand it
+	*/
+	loadProcessResponse: function(node, newChildren) {
+		if (!dojo.lang.isArray(newChildren)) {
+			dojo.raise('Not array loaded: '+newChildren);
+		}
+		for(var i=0; i<newChildren.length; i++) {
+			// looks like dojo.widget.manager needs no special "add" command
+			var newChild = dojo.widget.createWidget(node.widgetType, newChildren[i]);
+			node.addChild(newChild);
+
+			//dojo.debug(dojo.widget.manager.getWidgetById(newChild.widgetId))
+		}
+		node.state = node.loadStates.LOADED;
+		this.expand(node);
+	},
+
+
+	/**
+	 * Load children of the node from server
+	 * Synchroneous loading doesn't break control flow
+	 * I need sync mode for DnD
+	*/
+	loadRemote: function(node, sync){
+			node.markLoading();
+
+
+			var params = {
+				treeId: node.tree.widgetId,
+				nodeId: node.widgetId
+			};
+
+			var requestUrl = this.getRPCUrl('getChildren');
+			//dojo.debug(requestUrl)
+
+			if (!sync) {
+				dojo.io.bind({
+					url: requestUrl,
+					/* I hitch to get this.loadOkHandler */
+					load: dojo.lang.hitch(this, function(type, obj) { this.loadProcessResponse(node, obj) } ),
+					error: dojo.lang.hitch(this, this.RPCErrorHandler),
+					mimetype: "text/json",
+					preventCache: true,
+					sync: sync,
+					content: params
+				});
+
+				return;
+			}
+			else {
+				var query = dojo.io.argsFromMap(params);
+				if(query != "") {
+					requestUrl += (requestUrl.indexOf("?") > -1 ? "&" : "?") + query;
+				}
+
+				var newChildren;
+
+				try{
+					var response = dojo.hostenv.getText(requestUrl);
+					newChildren = dj_eval("("+response+")");
+				}catch(e){
+					dojo.debug(e);
+					dojo.debug(response);
+					dojo.raise("Failed to load node");
+				}
+
+				this.loadProcessResponse(node, newChildren);
+
+			}
+	},
+
+	onTreeClick: function(message){
+
+		//dojo.debug("EXPAND")
+
+		var node = message.source;
+
+		if (node.state == node.loadStates.UNCHECKED) {
+			this.loadRemote(node);
+		}
+		else if (node.isExpanded){
+			this.collapse(node);
+		}
+		else {
+			this.expand(node);
+		}
+	},
+
+
+	onIconClick: function(message){
+		this.onTitleClick(message);
+	},
+
+	onTitleClick: function(message){
+		var node = message.source;
+		var e = message.event;
+
+		if (node.tree.selector.selectedNode === node){
+			dojo.event.topic.publish(this.eventNames.dblselect, { source: node });
+			return;
+		}
+
+		/* deselect old node */
+		if (node.tree.selector.selectedNode) {
+			this.deselect(node.tree.selector.selectedNode);
+		}
+
+		node.tree.selector.selectedNode = node;
+		this.select(node);
+	},
+
+
+	/**
+	 * Process drag'n'drop -> drop
+	 * NOT event-driven, because its result is important (success/false)
+	 * in event system subscriber can't return a result into _current function control-flow_
+	 * @return true on success, false on failure
+	*/
+	processDrop: function(sourceNode, targetNode){
+		//dojo.debug('drop')
+		return this.changeParent(sourceNode, targetNode)
+	},
+
+
+	onNodeCreate: function(message) {
+		this.registerDNDNode(message.source);
+	},
+
+	select: function(node){
+		node.markSelected();
+
+		dojo.event.topic.publish(this.eventNames.select, {source: node} );
+	},
+
+	deselect: function(node){
+		node.unMarkSelected();
+
+		node.tree.selector.selectedNode = null;
+	},
+
+	expand: function(node) {
+		if (node.isExpanded) return;
+		node.expand();
+		dojo.event.topic.publish(this.eventNames.expand, {source: node} );
+	},
+
+	collapse: function(node) {
+		if (!node.isExpanded) return;
+
+		node.collapse();
+		dojo.event.topic.publish(this.eventNames.collapse, {source: node} );
+	},
+
+
+	/**
+	 * Controller(node model) creates DNDNodes because it passes itself to node for synchroneous drops processing
+	 * I can't process DnD with events cause an event can't return result success/false
+	*/
+	registerDNDNode: function(node) {
+
+
+		//dojo.debug("registerDNDNode node "+node.title+" tree "+node.tree+" accepted sources "+node.tree.acceptDropSources);
+
+		/* I drag label, not domNode, because large domNodes are very slow to copy and large to drag */
+
+		var source = null;
+		var target = null;
+
+		var source = new dojo.dnd.TreeDragSource(node.labelNode, this, node.tree.widgetId, node);
+		this.dragSources[node.widgetId] = source;
+
+		//dojo.debugShallow(node.tree.widgetId)
+		var target = new dojo.dnd.TreeDropTarget(node.labelNode, this, node.tree.acceptDropSources, node);
+		this.dropTargets[node.widgetId] = target;
+
+
+		if (!this.enabledDND) {
+			if (source) dojo.dnd.dragManager.unregisterDragSource(source);
+			if (target) dojo.dnd.dragManager.unregisterDropTarget(target);
+		}
+
+		//dojo.debug("registerDNDNode "+this.dragSources[node.widgetId].treeNode.title)
+
+
+	},
+
+	unregisterDNDNode: function(node) {
+
+		//dojo.debug("unregisterDNDNode "+node.title)
+		//dojo.debug("unregisterDNDNode "+this.dragSources[node.widgetId].treeNode.title)
+
+		if (this.dragSources[node]) {
+			dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]);
+			delete this.dragSources[node.widgetId];
+		}
+
+		if (this.dropTargets[node]) {
+			dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]);
+			delete this.dropTargets[node.widgetId];
+		}
+	},
+
+	// update types for DND right accept
+	// E.g when move from one tree to another tree
+	updateDND: function(node) {
+
+		this.unregisterDNDNode(node);
+
+		this.registerDNDNode(node);
+
+
+		//dojo.debug("!!!"+this.dropTargets[node].acceptedTypes)
+
+		for(var i=0; i<node.children.length; i++) {
+			// dojo.debug(node.children[i].title);
+			this.updateDND(node.children[i]);
+		}
+
+	},
+
+
+
+
+	// -----------------------------------------------------------------------------
+	//                             Swap & move nodes stuff
+	// -----------------------------------------------------------------------------
+
+
+	/* after all local checks I run remote call for swap */
+	swapNodesRemote: function(node1, node2, callback) {
+
+			var params = {
+				treeId: this.widgetId,
+				node1Id: node1.widgetId,
+				node1Idx: node1.getParentIndex(),
+				node2Id: node2.widgetId,
+				node2Idx: node2.getParentIndex()
+			}
+
+			dojo.io.bind({
+					url: this.getRPCUrl('swapNodes'),
+					/* I hitch to get this.loadOkHandler */
+					load: dojo.lang.hitch(this, function(type, obj) {
+						this.swapNodesProcessResponse(node1, node2, callback, obj) }
+					),
+					error: dojo.lang.hitch(this, this.RPCErrorHandler),
+					mimetype: "text/json",
+					preventCache: true,
+					content: params
+			});
+
+	},
+
+	swapNodesProcessResponse: function(node1, node2, callback, result) {
+		if (result == true) {
+			/* change parent succeeded */
+			this.doSwapNodes(node1, node2);
+			if (callback) {
+				// provide context manually e.g with dojo.lang.hitch.
+				callback.apply(this, [node1, node2]);
+			}
+
+			return true;
+		}
+		else if (dojo.lang.isObject(result)) {
+			dojo.raise(result.error);
+		}
+		else {
+			dojo.raise("Invalid response "+obj)
+		}
+
+
+	},
+
+	/* node swapping requires remote checks. This function does the real job only w/o any checks */
+	doSwapNodes: function(node1, node2) {
+		/* publish many events here about structural changes */
+
+		node1.tree.swapNodes(node1, node2);
+
+		// nodes AFTER swap
+		dojo.event.topic.publish(this.eventNames.swap,
+			{ node1: node1, node2: node2 }
+		);
+
+	},
+
+	canSwapNodes: function(node1, node2) {
+		return true;
+	},
+
+	/* main command for node swaps, with remote call */
+	swapNodes: function(node1, node2, callback) {
+		if (!this.canSwapNodes(node1, node2)) {
+			return false;
+		}
+
+		return this.swapNodesRemote(node1, node2, callback);
+
+	},
+
+	// return false if local check failed
+	moveUp: function(node, callback) {
+
+		var prevNode = node.getLeftSibling();
+
+		if (!prevNode) return false;
+
+		return this.swapNodes(prevNode, node, callback);
+	},
+
+
+	// return false if local check failed
+	moveDown: function(node, callback) {
+
+		var nextNode = node.getRightSibling();
+
+		if (!nextNode) return false;
+
+		return this.swapNodes(nextNode, node, callback);
+	},
+
+
+	// -----------------------------------------------------------------------------
+	//                             Remove nodes stuff
+	// -----------------------------------------------------------------------------
+
+
+
+	canRemoveNode: function(node) {
+		return true;
+	},
+
+	removeNode: function(node, callback) {
+		if (!this.canRemoveNode(node)) {
+			return false;
+		}
+
+		return this.removeNodeRemote(node, callback);
+
+	},
+
+
+	removeNodeRemote: function(node, callback) {
+
+			var params = {
+				treeId: node.tree.widgetId,
+				nodeId: node.widgetId
+			}
+
+			dojo.io.bind({
+					url: this.getRPCUrl('removeNode'),
+					/* I hitch to get this.loadOkHandler */
+					load: dojo.lang.hitch(this, function(type, obj) {
+						this.removeNodeProcessResponse(node, callback, obj) }
+					),
+					error: dojo.lang.hitch(this, this.RPCErrorHandler),
+					mimetype: "text/json",
+					preventCache: true,
+					content: params
+			});
+
+	},
+
+	removeNodeProcessResponse: function(node, callback, result) {
+		if (result == true) {
+			/* change parent succeeded */
+			this.doRemoveNode(node, node);
+			if (callback) {
+				// provide context manually e.g with dojo.lang.hitch.
+				callback.apply(this, [node]);
+			}
+
+			return true;
+		}
+		else if (dojo.lang.isObject(result)) {
+			dojo.raise(result.error);
+		}
+		else {
+			dojo.raise("Invalid response "+obj)
+		}
+
+
+	},
+
+
+	/* node swapping requires remote checks. This function does the real job only w/o any checks */
+	doRemoveNode: function(node) {
+		/* publish many events here about structural changes */
+
+		if (node.tree.selector.selectedNode === node) {
+			this.deselect(node);
+		}
+
+		this.unregisterDNDNode(node);
+
+		removed_node = node.tree.removeChild(node);
+
+		// nodes AFTER swap
+		dojo.event.topic.publish(this.eventNames.remove,
+			{ node: removed_node }
+		);
+
+	},
+
+
+	// -----------------------------------------------------------------------------
+	//                             Create node stuff
+	// -----------------------------------------------------------------------------
+
+
+
+
+	canCreateNode: function(parent, index, data) {
+		if (!parent.isFolder) return false;
+
+		return true;
+	},
+
+
+	/* send data to server and add child from server */
+	/* data may contain an almost ready child, or anything else, suggested to server */
+	/* server responds with child data to be inserted */
+	createNode: function(parent, index, data, callback) {
+		if (!this.canCreateNode(parent, index, data)) {
+			return false;
+		}
+
+
+		/* load nodes into newParent in sync mode, if needed, first */
+		if (parent.state == parent.loadStates.UNCHECKED) {
+			this.loadRemote(parent, true);
+		}
+
+
+		return this.createNodeRemote(parent, index, data, callback);
+
+	},
+
+
+	createNodeRemote: function(parent, index, data, callback) {
+
+			var params = {
+				treeId: parent.tree.widgetId,
+				parentId: parent.widgetId,
+				index: index,
+				data: dojo.json.serialize(data)
+			}
+
+			dojo.io.bind({
+					url: this.getRPCUrl('createNode'),
+					/* I hitch to get this.loadOkHandler */
+					load: dojo.lang.hitch(this, function(type, obj) {
+						this.createNodeProcessResponse(parent, index, data, callback, obj) }
+					),
+					error: dojo.lang.hitch(this, this.RPCErrorHandler),
+					mimetype: "text/json",
+					preventCache: true,
+					content: params
+			});
+
+	},
+
+	createNodeProcessResponse: function(parent, index, data, callback, response) {
+
+		if (parent.widgetType != 'EditorTreeNode') {
+			dojo.raise("Can only add children to EditorTreeNode")
+		}
+
+		if (!dojo.lang.isObject(response)) {
+			dojo.raise("Invalid response "+response)
+		}
+		if (!dojo.lang.isUndefined(response.error)) {
+			dojo.raise(response.error);
+		}
+
+
+		this.doCreateNode(parent, index, response);
+
+		if (callback) {
+			// provide context manually e.g with dojo.lang.hitch.
+			callback.apply(this, [parent, index, response]);
+		}
+
+	},
+
+
+	doCreateNode: function(parent, index, child) {
+
+		var newChild = dojo.widget.createWidget("EditorTreeNode", child);
+
+		parent.addChild(newChild, index);
+
+		this.expand(parent);
+	}
+
+
+});
\ No newline at end of file

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeNode.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeNode.js?rev=372668&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeNode.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeNode.js Thu Jan 26 15:56:50 2006
@@ -0,0 +1,454 @@
+/*
+	Copyright (c) 2004-2005, 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
+*/
+
+dojo.provide("dojo.widget.EditorTreeNode");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.dnd.*");
+dojo.require("dojo.fx.html");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.Container");
+dojo.require("dojo.widget.Tree");
+
+// make it a tag
+dojo.widget.tags.addParseTreeHandler("dojo:EditorTreeNode");
+
+
+dojo.widget.EditorTreeNode = function() {
+	dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.EditorTreeNode, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.EditorTreeNode, {
+	widgetType: "EditorTreeNode",
+
+	loadStates: {
+		UNCHECKED: 1,
+    	LOADING: 2,
+    	LOADED: 3
+	},
+
+
+	isContainer: true,
+
+	domNode: null,
+	continerNode: null,
+
+	templateString: '<div class="dojoTreeNode"><div dojoAttachPoint="containerNode"></div></div>',
+
+	//childIconSrc: null,
+	childIconSrc: null,
+	childIconFolderSrc: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/closed.gif").toString(), // for under root parent item child icon,
+	childIconDocumentSrc: dojo.uri.dojoUri("src/widget/templates/images/EditorTree/document.gif").toString(), // for under root parent item child icon,
+
+	childIcon: null,
+
+	// an icon left from childIcon: imgs[-2].
+	// if +/- for folders, blank for leaves
+	expandIcon: null,
+
+	title: "",
+	isFolder: "",
+
+	labelNode: null, // the item label
+	titleNode: null, // the item title
+	imgs: null, // an array of icons imgs
+	rowNode: null, // the tr
+
+	tree: null,
+	parentNode: null,
+	depth: 0,
+
+	isFirstNode: false,
+	isLastNode: false,
+	isExpanded: false,
+	booted: false,
+	state: null,  // after creation will change to loadStates: "loaded/loading/unchecked"
+	domNodeInitialized: false,  // domnode is initialized with icons etc
+
+
+	initialize: function(args, frag){
+		this.state = this.loadStates.UNCHECKED
+		//this.domNode.treeNode = this; // domNode knows about its treeNode owner. E.g for DnD
+	},
+
+	/**
+	 * Change visible node depth by appending/prepending with blankImgs
+	 * @param depthDiff Integer positive => move right, negative => move left
+	*/
+	adjustDepth: function(depthDiff) {
+
+		for(var i=0; i<this.children.length; i++) {
+			this.children[i].adjustDepth(depthDiff);
+		}
+
+		this.depth += depthDiff;
+
+		if (depthDiff>0) {
+			for(var i=0; i<depthDiff; i++) {
+				var img = this.tree.makeBlankImg();
+				this.imgs.unshift(img);
+				//dojo.debugShallow(this.domNode);
+				this.domNode.insertBefore(this.imgs[0], this.domNode.firstChild);
+
+			}
+		}
+		if (depthDiff<0) {
+			for(var i=0; i<-depthDiff;i++) {
+				this.imgs.shift();
+				this.domNode.removeChild(this.domNode.firstChild);
+			}
+		}
+
+	},
+
+
+	markLoading: function() {
+		this.expandIcon.src = this.tree.expandIconSrcLoading;
+//		this.expandIcon.src = this.tree.expandIconSrcMinus;
+
+	},
+
+
+
+
+	buildNode: function(tree, depth){
+
+		this.tree = tree;
+		this.depth = depth;
+
+		// node with children(from source html) becomes folder on build stage.
+		if (this.children.length) {
+			this.isFolder = true;
+		}
+		//
+		// add the tree icons
+		//
+
+		this.imgs = [];
+
+		for(var i=0; i<this.depth+1; i++){
+
+			var img = this.tree.makeBlankImg();
+
+			this.domNode.insertBefore(img, this.containerNode);
+
+			this.imgs.push(img);
+		}
+
+
+		this.expandIcon = this.imgs[this.imgs.length-1];
+
+
+		//
+		// add the cell label
+		//
+
+
+		this.labelNode = document.createElement('span');
+		this.labelNode.treeNode = this.widgetId; // link label node w/ real treeNode object(w/ self)
+		dojo.html.addClass(this.labelNode, 'dojoTreeNodeLabel');
+
+		// add child icon to label
+		this.childIcon = this.tree.makeBlankImg();
+		//this.childIcon.treeNode = this.widgetId;
+
+		// add to images before the title
+		this.imgs.push(this.childIcon);
+
+		this.labelNode.appendChild(this.childIcon);
+
+		// add title to label
+		this.titleNode = document.createElement('span');
+		//this.titleNode.treeNode = this.widgetId;
+
+		var textNode = document.createTextNode(this.title);
+		this.titleNode.appendChild(textNode);
+
+
+		this.labelNode.appendChild(this.titleNode);
+
+		this.domNode.insertBefore(this.labelNode, this.containerNode);
+
+		dojo.html.addClass(this.titleNode, 'dojoTreeNodeLabelTitle');
+
+
+		if (this.isFolder) {
+			dojo.event.connect(this.expandIcon, 'onclick', this, 'onTreeClick');
+		}
+		dojo.event.connect(this.childIcon, 'onclick', this, 'onIconClick');
+		dojo.event.connect(this.titleNode, 'onclick', this, 'onTitleClick');
+
+
+		//
+		// create the child rows
+		//
+
+
+		for(var i=0; i<this.children.length; i++){
+
+			this.children[i].isFirstNode = (i == 0) ? true : false;
+			this.children[i].isLastNode = (i == this.children.length-1) ? true : false;
+			this.children[i].parentNode = this;
+
+			var node = this.children[i].buildNode(this.tree, this.depth+1);
+
+			this.containerNode.appendChild(node);
+		}
+
+
+		if (this.children.length) {
+			this.state = this.loadStates.LOADED;
+		}
+
+		this.collapse();
+
+		this.domNodeInitialized = true;
+
+		dojo.event.topic.publish(this.tree.eventNames.nodeCreate, { source: this } );
+
+		return this.domNode;
+	},
+
+	onTreeClick: function(e){
+		dojo.event.topic.publish(this.tree.eventNames.treeClick, { source: this, event: e });
+	},
+
+	onIconClick: function(e){
+		dojo.event.topic.publish(this.tree.eventNames.iconClick, { source: this, event: e });
+	},
+
+	onTitleClick: function(e){
+		dojo.event.topic.publish(this.tree.eventNames.titleClick, { source: this, event: e });
+	},
+
+	markSelected: function() {
+		dojo.html.addClass(this.titleNode, 'dojoTreeNodeLabelSelected');
+	},
+
+
+	unMarkSelected: function() {
+		//dojo.debug('unmark')
+		dojo.html.removeClass(this.titleNode, 'dojoTreeNodeLabelSelected');
+	},
+
+	updateIcons: function(){
+
+		//dojo.debug("Update icons for "+this.title)
+		//dojo.debug(this.isFolder)
+
+		this.imgs[0].style.display = this.tree.showRootGrid ? 'inline' : 'none';
+
+
+		//
+		// set the expand icon
+		//
+
+		if (this.isFolder){
+			this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
+		}else{
+			this.expandIcon.src = this.tree.blankIconSrc;
+		}
+
+		//
+		// set the child icon
+		//
+		this.buildChildIcon();
+
+
+		//
+		// set the grid under the expand icon
+		//
+
+		if (this.tree.showGrid){
+			if (this.depth){
+				this.setGridImage(-2, this.isLastNode ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
+			}else{
+				if (this.isFirstNode){
+					this.setGridImage(-2, this.isLastNode ? this.tree.gridIconSrcX : this.tree.gridIconSrcY);
+				}else{
+					this.setGridImage(-2, this.isLastNode ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
+				}
+			}
+		}else{
+			this.setGridImage(-2, this.tree.blankIconSrc);
+		}
+
+
+
+		//
+		// set the grid under the child icon
+		//
+
+		if ((this.depth || this.tree.showRootGrid) && this.tree.showGrid){
+			this.setGridImage(-1, (this.children.length && this.isExpanded) ? this.tree.gridIconSrcP : this.tree.gridIconSrcC);
+		}else{
+			if (this.tree.showGrid && !this.tree.showRootGrid){
+				this.setGridImage(-1, (this.children.length && this.isExpanded) ? this.tree.gridIconSrcZ : this.tree.blankIconSrc);
+			}else{
+				this.setGridImage(-1, this.tree.blankIconSrc);
+			}
+		}
+
+
+		//
+		// set the vertical grid icons
+		//
+
+		var parent = this.parentNode;
+
+		for(var i=0; i<this.depth; i++){
+
+			var idx = this.imgs.length-(3+i);
+
+			this.setGridImage(
+				idx,
+				(this.tree.showGrid && !parent.isLastNode) ? this.tree.gridIconSrcV : this.tree.blankIconSrc
+			);
+
+			parent = parent.parentNode;
+		}
+	},
+
+	buildChildIcon: function() {
+		/* no child icon */
+		if (this.childIconSrc == "none") {
+			this.childIcon.style.display = 'none';
+			return;
+		}
+
+		/* assign default icon if not set */
+		if (!this.childIconSrc) {
+			if (this.isFolder){
+				this.childIconSrc = this.childIconFolderSrc;
+			}
+			else {
+				this.childIconSrc = this.childIconDocumentSrc;
+			}
+		}
+
+		this.childIcon.style.display = 'inline';
+		this.childIcon.src = this.childIconSrc;
+	},
+
+	setGridImage: function(idx, src){
+
+		if (idx < 0){
+			idx = this.imgs.length + idx;
+		}
+
+		//if (idx >= this.imgs.length-2) return;
+		this.imgs[idx].style.backgroundImage = 'url(' + src + ')';
+	},
+
+
+	updateIconTree: function(){
+		this.tree.updateIconTree.call(this);
+	},
+
+
+
+	expand: function(){
+
+		if (this.children.length) this.showChildren();
+		this.isExpanded = true;
+
+		this.updateIcons();
+	},
+
+	collapse: function(){
+		this.hideChildren();
+		this.isExpanded = false;
+		this.updateIcons();
+	},
+
+	hideChildren: function(){
+
+		if (this.booted){
+			this.tree.toggler.hide(this.containerNode);
+		}else{
+			this.containerNode.style.display = 'none';
+		}
+	},
+
+	showChildren: function(){
+		if (this.booted){
+			this.tree.toggler.show(this.containerNode);
+		}
+		else {
+			this.containerNode.style.display = 'block';
+
+		}
+	},
+
+	startMe: function(){
+
+		this.booted = true;
+		for(var i=0; i<this.children.length; i++){
+			this.children[i].startMe();
+		}
+	},
+
+	addChild: function(){
+		return this.tree.addChild.apply(this, arguments);
+	},
+
+	removeChild: function(){
+		return this.tree.removeChild.apply(this, arguments);
+	},
+
+
+	getLeftSibling: function() {
+		var idx = this.getParentIndex();
+
+		 // first node is idx=0 not found is idx<0
+		if (idx<=0) return null;
+
+		return this.getSiblings()[idx-1];
+	},
+
+	getSiblings: function() {
+		return this.parentNode.children;
+	},
+
+	getParentIndex: function() {
+		return dojo.lang.indexOf( this.getSiblings(), this, true);
+	},
+
+	getRightSibling: function() {
+
+		var idx = this.getParentIndex();
+
+		if (idx == this.getSiblings().length-1) return null; // last node
+		if (idx < 0) return null; // not found
+
+		return this.getSiblings()[idx+1];
+
+	},
+
+	/* Edit current node : change properties and update contents */
+	edit: function(props) {
+		dojo.lang.mixin(this, props);
+		if (props.title) {
+			var textNode = document.createTextNode(this.title);
+			this.titleNode.replaceChild(textNode, this.titleNode.firstChild)
+		}
+
+		if (props.childIconSrc) {
+			this.childIcon.src = this.childIconSrc;
+		}
+	}
+
+});
+
+
+
+

Added: myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeSelector.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeSelector.js?rev=372668&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeSelector.js (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/EditorTreeSelector.js Thu Jan 26 15:56:50 2006
@@ -0,0 +1,34 @@
+/*
+	Copyright (c) 2004-2005, 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
+*/
+
+
+dojo.provide("dojo.widget.EditorTreeSelector");
+
+dojo.require("dojo.widget.Container");
+dojo.require("dojo.widget.Tree");
+
+dojo.widget.tags.addParseTreeHandler("dojo:EditorTreeSelector");
+
+
+dojo.widget.EditorTreeSelector = function() {
+	dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.EditorTreeSelector, dojo.widget.HtmlWidget);
+
+
+dojo.lang.extend(dojo.widget.EditorTreeSelector, {
+	widgetType: "EditorTreeSelector",
+	selectedNode: null
+
+});
+
+
+