You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2006/04/14 01:47:17 UTC

svn commit: r393978 [18/25] - in /incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo: ./ demos/ demos/widget/ demos/widget/EditorTree/ demos/widget/EditorTree/static/ demos/widget/Mail/ demos/widget/images/ src/ src/alg/...

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeController.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeController.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeController.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeController.js Thu Apr 13 16:46:55 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: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeNode.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeNode.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeNode.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeNode.js Thu Apr 13 16:46:55 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: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeSelector.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeSelector.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeSelector.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/EditorTreeSelector.js Thu Apr 13 16:46:55 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
+
+});
+
+
+

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FisheyeList.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FisheyeList.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FisheyeList.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FisheyeList.js Thu Apr 13 16:46:55 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.FisheyeList");
+dojo.provide("dojo.widget.html.FisheyeList");
+dojo.provide("dojo.widget.html.FisheyeListItem");
+
+//
+// TODO
+// fix SVG support, and turn it on only if the browser supports it
+// fix really long labels in vertical mode
+//
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.Container");
+dojo.require("dojo.dom");
+dojo.require("dojo.html");
+dojo.require("dojo.style");
+dojo.require("dojo.event");
+
+dojo.widget.tags.addParseTreeHandler("dojo:FisheyeList");
+dojo.widget.tags.addParseTreeHandler("dojo:FisheyeListItem");
+
+dojo.widget.html.FisheyeList = function(){
+	dojo.widget.html.Container.call(this);
+}
+dojo.inherits(dojo.widget.html.FisheyeList, dojo.widget.html.Container);
+
+dojo.lang.extend(dojo.widget.html.FisheyeList, {
+
+	templateString: '<div class="dojoHtmlFisheyeListBar"></div>',
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlFisheyeList.css"),
+	widgetType: "FisheyeList",
+
+	EDGE: {
+		CENTER: 0,
+		LEFT: 1,
+		RIGHT: 2,
+		TOP: 3,
+		BOTTOM: 4
+	},
+
+	snarfChildDomOutput: true,
+	
+	pos: {x: -1, y: -1},		// current cursor position, relative to the grid
+	
+	// for conservative trigger mode, when triggered, timerScale is gradually increased from 0 to 1
+	timerScale: 1.0,
+
+	/////////////////////////////////////////////////////////////////
+	//
+	// i spy OPTIONS!!!!
+	//
+
+	itemWidth: 40,
+	itemHeight: 40,
+
+	itemMaxWidth: 150,
+	itemMaxHeight: 150,
+
+	orientation: 'horizontal',
+	
+	conservativeTrigger: false,		// don't active menu until mouse is over an image (macintosh style)
+
+	effectUnits: 2,
+	itemPadding: 10,
+
+	attachEdge: 'center',
+	labelEdge: 'bottom',
+
+	enableCrappySvgSupport: false,
+
+
+	//
+	//
+	//
+	/////////////////////////////////////////////////////////////////
+
+	fillInTemplate: function(args, frag) {
+		//dojo.debug(this.orientation);
+
+		dojo.html.disableSelection(this.domNode);
+
+		this.isHorizontal = (this.orientation == 'horizontal') ? 1 : 0;
+		this.selectedNode = -1;
+
+		this.isOver = false;
+		this.hitX1 = -1;
+		this.hitY1 = -1;
+		this.hitX2 = -1;
+		this.hitY2 = -1;
+
+		//
+		// only some edges make sense...
+		//
+
+		this.anchorEdge = this.toEdge(this.attachEdge, this.EDGE.CENTER);
+		this.labelEdge  = this.toEdge(this.labelEdge,  this.EDGE.TOP);
+
+		if ( this.isHorizontal && (this.anchorEdge == this.EDGE.LEFT  )){ this.anchorEdge = this.EDGE.CENTER; }
+		if ( this.isHorizontal && (this.anchorEdge == this.EDGE.RIGHT )){ this.anchorEdge = this.EDGE.CENTER; }
+		if (!this.isHorizontal && (this.anchorEdge == this.EDGE.TOP   )){ this.anchorEdge = this.EDGE.CENTER; }
+		if (!this.isHorizontal && (this.anchorEdge == this.EDGE.BOTTOM)){ this.anchorEdge = this.EDGE.CENTER; }
+
+		if (this.labelEdge == this.EDGE.CENTER){ this.labelEdge = this.EDGE.TOP; }
+		if ( this.isHorizontal && (this.labelEdge == this.EDGE.LEFT  )){ this.labelEdge = this.EDGE.TOP; }
+		if ( this.isHorizontal && (this.labelEdge == this.EDGE.RIGHT )){ this.labelEdge = this.EDGE.TOP; }
+		if (!this.isHorizontal && (this.labelEdge == this.EDGE.TOP   )){ this.labelEdge = this.EDGE.LEFT; }
+		if (!this.isHorizontal && (this.labelEdge == this.EDGE.BOTTOM)){ this.labelEdge = this.EDGE.LEFT; }
+
+
+		//
+		// figure out the proximity size
+		//
+
+		this.proximityLeft   = this.itemWidth  * (this.effectUnits - 0.5);
+		this.proximityRight  = this.itemWidth  * (this.effectUnits - 0.5);
+		this.proximityTop    = this.itemHeight * (this.effectUnits - 0.5);
+		this.proximityBottom = this.itemHeight * (this.effectUnits - 0.5);
+
+		if (this.anchorEdge == this.EDGE.LEFT){
+			this.proximityLeft = 0;
+		}
+		if (this.anchorEdge == this.EDGE.RIGHT){
+			this.proximityRight = 0;
+		}
+		if (this.anchorEdge == this.EDGE.TOP){
+			this.proximityTop = 0;
+		}
+		if (this.anchorEdge == this.EDGE.BOTTOM){
+			this.proximityBottom = 0;
+		}
+		if (this.anchorEdge == this.EDGE.CENTER){
+			this.proximityLeft   /= 2;
+			this.proximityRight  /= 2;
+			this.proximityTop    /= 2;
+			this.proximityBottom /= 2;
+		}
+	},
+	
+	postCreate: function(args, frag) {
+
+		this.itemCount = this.children.length;
+
+		this.barWidth  = (this.isHorizontal ? this.itemCount : 1) * this.itemWidth;
+		this.barHeight = (this.isHorizontal ? 1 : this.itemCount) * this.itemHeight;
+
+		this.totalWidth  = this.proximityLeft + this.proximityRight  + this.barWidth;
+		this.totalHeight = this.proximityTop  + this.proximityBottom + this.barHeight;
+
+		//
+		// calculate effect ranges for each item
+		//
+
+		for (var i=0; i<this.children.length; i++){
+
+			this.children[i].posX = this.itemWidth  * (this.isHorizontal ? i : 0);
+			this.children[i].posY = this.itemHeight * (this.isHorizontal ? 0 : i);
+
+			this.children[i].cenX = this.children[i].posX + (this.itemWidth  / 2);
+			this.children[i].cenY = this.children[i].posY + (this.itemHeight / 2);
+
+			var isz = this.isHorizontal ? this.itemWidth : this.itemHeight;
+			var r = this.effectUnits * isz;
+			var c = this.isHorizontal ? this.children[i].cenX : this.children[i].cenY;
+			var lhs = this.isHorizontal ? this.proximityLeft : this.proximityTop;
+			var rhs = this.isHorizontal ? this.proximityRight : this.proximityBottom;
+			var siz = this.isHorizontal ? this.barWidth : this.barHeight;
+
+			var range_lhs = r;
+			var range_rhs = r;
+
+			if (range_lhs > c+lhs){ range_lhs = c+lhs; }
+			if (range_rhs > (siz-c+rhs)){ range_rhs = siz-c+rhs; }
+
+			this.children[i].effectRangeLeft = range_lhs / isz;
+			this.children[i].effectRangeRght = range_rhs / isz;
+
+			//dojo.debug('effect range for '+i+' is '+range_lhs+'/'+range_rhs);
+		}
+
+
+		//
+		// create the bar
+		//
+
+		this.domNode.style.width = this.barWidth + 'px';
+		this.domNode.style.height = this.barHeight + 'px';
+
+
+		//
+		// position the items
+		//
+		for (var i=0; i<this.children.length; i++){
+			var itm = this.children[i];
+			var elm = itm.domNode;
+			elm.style.left   = itm.posX + 'px';
+			elm.style.top    = itm.posY + 'px';
+			elm.style.width  = this.itemWidth + 'px';
+			elm.style.height = this.itemHeight + 'px';
+			
+			if ( itm.svgNode ) {
+				itm.svgNode.style.position = 'absolute';
+				itm.svgNode.style.left = this.itemPadding+'%';
+				itm.svgNode.style.top = this.itemPadding+'%';
+				itm.svgNode.style.width = (100 - 2 * this.itemPadding) + '%';
+				itm.svgNode.style.height = (100 - 2 * this.itemPadding) + '%';
+				itm.svgNode.style.zIndex = 1;
+	
+				itm.svgNode.setSize(this.itemWidth, this.itemHeight);
+			} else {
+				itm.imgNode.style.left = this.itemPadding+'%';
+				itm.imgNode.style.top = this.itemPadding+'%';
+				itm.imgNode.style.width = (100 - 2 * this.itemPadding) + '%';
+				itm.imgNode.style.height = (100 - 2 * this.itemPadding) + '%';
+			}
+		}
+
+		//
+		// calc the grid
+		//
+
+		this.calcHitGrid();
+
+		//
+		// in liberal trigger mode, activate menu whenever mouse is close
+		//
+		if( !this.conservativeTrigger ){
+			dojo.event.connect(document.documentElement, "onmousemove", this, "mouseHandler");
+		}
+		
+		// Deactivate the menu if mouse is moved off screen (doesn't work for FF?)
+		dojo.event.connect(document.documentElement, "onmouseout", this, "onBodyOut");
+	},
+
+	onBodyOut: function(e){
+		// clicking over an object inside of body causes this event to fire; ignore that case
+		if( dojo.html.overElement(dojo.html.body(), e) ){
+			return;
+		}
+		this.setDormant(e);
+	},
+
+	// when mouse moves out of menu's range
+	setDormant: function(e){
+		if( !this.isOver ){ return; }	// already dormant?
+		this.isOver = false;
+
+		if ( this.conservativeTrigger ) {
+			// user can't re-trigger the menu expansion
+			// until he mouses over a icon again
+			dojo.event.disconnect(document.documentElement, "onmousemove", this, "mouseHandler");
+		}
+		this.onGridMouseMove(-1, -1);
+	},
+
+	// when mouse is moved into menu's range
+	setActive: function(e){
+		if( this.isOver ){ return; }	// already activated?
+		this.isOver = true;
+
+		if ( this.conservativeTrigger ) {
+			// switch event handlers so that we handle mouse events from anywhere near
+			// the menu
+			dojo.event.connect(document.documentElement, "onmousemove", this, "mouseHandler");
+
+			this.timerScale=0.0;
+
+			// call mouse handler to do some initial necessary calculations/positioning
+			this.mouseHandler(e);
+
+			// slowly expand the icon size so it isn't jumpy
+			this.expandSlowly();
+		}
+	},
+
+	// when mouse is moved
+	mouseHandler: function(e) {
+		var p = this.getCursorPos(e);
+
+		if ((p.x >= this.hitX1) && (p.x <= this.hitX2) &&
+			(p.y >= this.hitY1) && (p.y <= this.hitY2)){
+			if( !this.isOver ){
+				this.setActive(e);
+			}
+			this.onGridMouseMove(p.x-this.hitX1, p.y-this.hitY1);
+		}else{
+			if (this.isOver){
+				this.setDormant(e);
+			}
+		}
+	},
+
+	onResized: function() {
+		this.calcHitGrid();
+	},
+
+	onGridMouseMove: function(x, y){
+		this.pos = {x:x, y:y};
+		this.paint();
+	},
+	
+	paint: function(){
+		var x=this.pos.x;
+		var y=this.pos.y;
+
+		if( this.itemCount <= 0 ){ return; }
+
+		//
+		// figure out our main index
+		//
+
+		var pos = this.isHorizontal ? x : y;
+		var prx = this.isHorizontal ? this.proximityLeft : this.proximityTop;
+		var siz = this.isHorizontal ? this.itemWidth : this.itemHeight;
+		var sim = this.isHorizontal ? 
+			(1.0-this.timerScale)*this.itemWidth + this.timerScale*this.itemMaxWidth :
+			(1.0-this.timerScale)*this.itemHeight + this.timerScale*this.itemMaxHeight ;
+
+		var cen = ((pos - prx) / siz) - 0.5;
+		var max_off_cen = (sim / siz) - 0.5;
+
+		if (max_off_cen > this.effectUnits){ max_off_cen = this.effectUnits; }
+
+
+		//
+		// figure out our off-axis weighting
+		//
+
+		var off_weight = 0;
+
+		if (this.anchorEdge == this.EDGE.BOTTOM){
+			var cen2 = (y - this.proximityTop) / this.itemHeight;
+			off_weight = (cen2 > 0.5) ? 1 : y / (this.proximityTop + (this.itemHeight / 2));
+		}
+		if (this.anchorEdge == this.EDGE.TOP){
+			var cen2 = (y - this.proximityTop) / this.itemHeight;
+			off_weight = (cen2 < 0.5) ? 1 : (this.totalHeight - y) / (this.proximityBottom + (this.itemHeight / 2));
+		}
+		if (this.anchorEdge == this.EDGE.RIGHT){
+			var cen2 = (x - this.proximityLeft) / this.itemWidth;
+			off_weight = (cen2 > 0.5) ? 1 : x / (this.proximityLeft + (this.itemWidth / 2));
+		}
+		if (this.anchorEdge == this.EDGE.LEFT){
+			var cen2 = (x - this.proximityLeft) / this.itemWidth;
+			off_weight = (cen2 < 0.5) ? 1 : (this.totalWidth - x) / (this.proximityRight + (this.itemWidth / 2));
+		}
+		if (this.anchorEdge == this.EDGE.CENTER){
+
+			if (this.isHorizontal){
+				off_weight = y / (this.totalHeight);
+			}else{
+				off_weight = x / (this.totalWidth);
+			}
+
+			if (off_weight > 0.5){
+				off_weight = 1 - off_weight;
+			}
+
+			off_weight *= 2;
+		}
+
+
+		//
+		// set the sizes
+		//
+
+		for(var i=0; i<this.itemCount; i++){
+
+			var weight = this.weightAt(cen, i);
+
+			if (weight < 0){weight = 0;}
+
+			this.setitemsize(i, weight * off_weight);
+		}
+
+		//
+		// set the positions
+		//
+
+		var main_p = Math.round(cen);
+		var offset = 0;
+
+		if (cen < 0){
+			main_p = 0;
+
+		}else if (cen > this.itemCount - 1){
+
+			main_p = this.itemCount -1;
+
+		}else{
+
+			offset = (cen - main_p) * ((this.isHorizontal ? this.itemWidth : this.itemHeight) - this.children[main_p].sizeMain);
+		}
+
+		this.positionElementsFrom(main_p, offset);
+	},
+
+	weightAt: function(cen, i){
+
+		var dist = Math.abs(cen - i);
+
+		var limit = ((cen - i) > 0) ? this.children[i].effectRangeRght : this.children[i].effectRangeLeft;
+
+		return (dist > limit) ? 0 : (1 - dist / limit);
+	},
+
+	positionFromNode: function(p, w){
+
+		//
+		// we need to grow all the nodes growing out from node 'i'
+		//
+
+		this.setitemsize(p, w);
+
+		var wx = w;
+		for(var i=p; i<this.itemCount; i++){
+			wx = 0.8 * wx;
+			this.setitemsize(i, wx);
+		}
+
+		var wx = w;
+		for(var i=p; i>=0; i--){
+			wx = 0.8 * wx;
+			this.setitemsize(i, wx);
+		}
+	},
+
+	setitemsize: function(p, scale){
+		scale *= this.timerScale;
+		var w = Math.round(this.itemWidth  + ((this.itemMaxWidth  - this.itemWidth ) * scale));
+		var h = Math.round(this.itemHeight + ((this.itemMaxHeight - this.itemHeight) * scale));
+
+		if (this.isHorizontal){
+
+			this.children[p].sizeW = w;
+			this.children[p].sizeH = h;
+
+			this.children[p].sizeMain = w;
+			this.children[p].sizeOff  = h;
+
+			var y = 0;
+
+			if (this.anchorEdge == this.EDGE.TOP){
+
+				y = (this.children[p].cenY - (this.itemHeight / 2));
+
+			}else if (this.anchorEdge == this.EDGE.BOTTOM){
+
+				y = (this.children[p].cenY - (h - (this.itemHeight / 2)));
+
+			}else{
+
+				y = (this.children[p].cenY - (h / 2));
+			}
+
+			this.children[p].usualX = Math.round(this.children[p].cenX - (w / 2));
+			
+			this.children[p].domNode.style.top  = y + 'px';
+
+			this.children[p].domNode.style.left  = this.children[p].usualX + 'px';
+
+		}else{
+
+			this.children[p].sizeW = w;
+			this.children[p].sizeH = h;
+
+			this.children[p].sizeOff  = w;
+			this.children[p].sizeMain = h;
+
+			var x = 0;
+
+			if (this.anchorEdge == this.EDGE.LEFT){
+
+				x = this.children[p].cenX - (this.itemWidth / 2);
+
+			}else if (this.anchorEdge == this.EDGE.RIGHT){
+
+				x = this.children[p].cenX - (w - (this.itemWidth / 2));
+			}else{
+
+				x = this.children[p].cenX - (w / 2);
+			}
+
+			this.children[p].domNode.style.left = x + 'px';
+			this.children[p].usualY = Math.round(this.children[p].cenY - (h / 2));
+
+			this.children[p].domNode.style.top  = this.children[p].usualY + 'px';
+		}
+
+		this.children[p].domNode.style.width  = w + 'px';
+		this.children[p].domNode.style.height = h + 'px';
+
+		if (this.children[p].svgNode){
+			this.children[p].svgNode.setSize(w, h);
+		}
+	},
+
+	positionElementsFrom: function(p, offset){
+
+		var pos = 0;
+
+		if (this.isHorizontal){
+			pos = Math.round(this.children[p].usualX + offset);
+			this.children[p].domNode.style.left = pos + 'px';
+		}else{
+			pos = Math.round(this.children[p].usualY + offset);
+			this.children[p].domNode.style.top = pos + 'px';
+		}
+		this.positionLabel(this.children[p]);
+
+
+		//
+		// position before
+		//
+
+		var bpos = pos;
+
+		for(var i=p-1; i>=0; i--){
+
+			bpos -= this.children[i].sizeMain;
+
+			if (this.isHorizontal){
+				this.children[i].domNode.style.left = bpos + 'px';
+			}else{
+				this.children[i].domNode.style.top = bpos + 'px';
+			}
+			this.positionLabel(this.children[i]);
+		}
+
+		//
+		// position after
+		//
+
+		var apos = pos;
+
+		for(var i=p+1; i<this.itemCount; i++){
+
+			apos += this.children[i-1].sizeMain;
+
+			if (this.isHorizontal){
+				this.children[i].domNode.style.left = apos + 'px';
+			}else{
+				this.children[i].domNode.style.top = apos + 'px';
+			}
+			this.positionLabel(this.children[i]);
+		}
+
+	},
+
+	positionLabel: function(itm){
+
+		var x = 0;
+		var y = 0;
+		
+		var labelW = dojo.style.getOuterWidth(itm.lblNode);
+		var labelH = dojo.style.getOuterHeight(itm.lblNode);
+
+		if (this.labelEdge == this.EDGE.TOP){
+			x = Math.round((itm.sizeW / 2) - (labelW / 2));
+			y = -labelH;
+		}
+
+		if (this.labelEdge == this.EDGE.BOTTOM){
+			x = Math.round((itm.sizeW / 2) - (labelW / 2));
+			y = itm.sizeH;
+		}
+
+		if (this.labelEdge == this.EDGE.LEFT){
+			x = -labelW;
+			y = Math.round((itm.sizeH / 2) - (labelH / 2));
+		}
+
+		if (this.labelEdge == this.EDGE.RIGHT){
+			x = itm.sizeW;
+			y = Math.round((itm.sizeH / 2) - (labelH / 2));
+		}
+
+		itm.lblNode.style.left = x + 'px';
+		itm.lblNode.style.top  = y + 'px';
+	},
+
+	getCursorPos: function(e){
+		return {
+			'x': e.pageX || e.clientX + dojo.html.body().scrollLeft,
+			'y': e.pageY || e.clientY + dojo.html.body().scrollTop
+			};
+	},
+
+	calcHitGrid: function(){
+
+		var pos = dojo.style.getAbsolutePosition(this.domNode);
+
+		this.hitX1 = pos.x - this.proximityLeft;
+		this.hitY1 = pos.y - this.proximityTop;
+		this.hitX2 = this.hitX1 + this.totalWidth;
+		this.hitY2 = this.hitY1 + this.totalHeight;
+
+		//dojo.debug(this.hitX1+','+this.hitY1+' // '+this.hitX2+','+this.hitY2);
+	},
+
+	toEdge: function(inp, def){
+		return this.EDGE[inp.toUpperCase()] || def;
+	},
+	
+	// slowly expand the image to user specified max size
+	expandSlowly: function(){
+		if( !this.isOver ){ return; }
+		this.timerScale += 0.2;
+		this.paint();
+		if ( this.timerScale<1.0 ) {
+			dojo.lang.setTimeout(this, "expandSlowly", 10);
+		}
+	}
+
+});
+
+dojo.widget.html.FisheyeListItem = function(){
+	dojo.widget.HtmlWidget.call(this);
+}
+dojo.inherits(dojo.widget.html.FisheyeListItem, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.FisheyeListItem, {
+	widgetType: "FisheyeListItem",
+	
+	// Constructor arguments
+	iconSrc: "",
+	svgSrc: "",
+	caption: "",
+
+	blankImgPath: dojo.uri.dojoUri("src/widget/templates/images/blank.gif"),
+
+	templateString:
+		'<div class="dojoHtmlFisheyeListItem">' +
+		'  <img class="dojoHtmlFisheyeListItemImage" dojoAttachPoint="imgNode" dojoAttachEvent="onMouseOver;onMouseOut;onClick">' +
+		'  <div class="dojoHtmlFisheyeListItemLabel" dojoAttachPoint="lblNode"></div>' +
+		'</div>',
+	
+	imgNode: null,
+
+	fillInTemplate: function() {
+		//
+		// set image
+		// TODO: turn on/off SVG support based on browser version.
+		// this.parent.enableCrappySvgSupport is not available to this function
+		//
+		if (this.svgSrc != ""){
+			this.svgNode = this.createSvgNode(this.svgSrc);
+			this.domNode.appendChild(this.svgNode);
+			this.imgNode.style.display = 'none';
+		} else if((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4)==".png")&&(dojo.render.html.ie)){
+			this.imgNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='scale')";
+			this.imgNode.src = this.blankImgPath.toString();
+		} else {
+			this.imgNode.src = this.iconSrc;
+		}
+
+		//
+		// Label
+		//
+		if ( this.lblNode ) {
+			this.lblNode.appendChild(document.createTextNode(this.caption));
+		}
+		dojo.html.disableSelection(this.domNode);
+	},
+	
+	createSvgNode: function(src){
+
+		var elm = document.createElement('embed');
+		elm.src = src;
+		elm.type = 'image/svg+xml';
+		//elm.style.border = '1px solid black';
+		elm.style.width = '1px';
+		elm.style.height = '1px';
+		elm.loaded = 0;
+		elm.setSizeOnLoad = false;
+
+		elm.onload = function(){
+			this.svgRoot = this.getSVGDocument().rootElement;
+			this.svgDoc = this.getSVGDocument().documentElement;
+			this.zeroWidth = this.svgRoot.width.baseVal.value;
+			this.zeroHeight = this.svgRoot.height.baseVal.value;
+			this.loaded = true;
+
+			if (this.setSizeOnLoad){
+				this.setSize(this.setWidth, this.setHeight);
+			}
+		}
+
+		elm.setSize = function(w, h){
+			if (!this.loaded){
+				this.setWidth = w;
+				this.setHeight = h;
+				this.setSizeOnLoad = true;
+				return;
+			}
+
+			this.style.width = w+'px';
+			this.style.height = h+'px';
+			this.svgRoot.width.baseVal.value = w;
+			this.svgRoot.height.baseVal.value = h;
+
+			var scale_x = w / this.zeroWidth;
+			var scale_y = h / this.zeroHeight;
+
+			for(var i=0; i<this.svgDoc.childNodes.length; i++){
+				if (this.svgDoc.childNodes[i].setAttribute){
+					this.svgDoc.childNodes[i].setAttribute( "transform", "scale("+scale_x+","+scale_y+")" );
+				}
+			}
+		}
+
+		return elm;
+	},
+
+	onMouseOver: function(e) {
+		// in conservative mode, don't activate the menu until user mouses over an icon
+		if( !this.parent.isOver ){
+			this.parent.setActive(e);
+		}
+		if ( this.caption != "" ) {
+			dojo.html.addClass(this.lblNode, "selected");
+			this.parent.positionLabel(this);
+		}
+	},
+	
+	onMouseOut: function() {
+		dojo.html.removeClass(this.lblNode, "selected");
+	},
+
+	onClick: function() {
+	}
+});
+

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FloatingPane.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FloatingPane.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FloatingPane.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/FloatingPane.js Thu Apr 13 16:46:55 2006
@@ -0,0 +1,528 @@
+/*
+	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.FloatingPane");
+dojo.provide("dojo.widget.html.FloatingPane");
+
+//
+// this widget provides a window-like floating pane
+//
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Manager");
+dojo.require("dojo.html");
+dojo.require("dojo.style");
+dojo.require("dojo.dom");
+dojo.require("dojo.widget.ContentPane");
+dojo.require("dojo.widget.LayoutPane");
+dojo.require("dojo.dnd.HtmlDragMove");
+dojo.require("dojo.dnd.HtmlDragMoveSource");
+dojo.require("dojo.dnd.HtmlDragMoveObject");
+
+dojo.widget.html.FloatingPane = function(){
+	dojo.widget.html.LayoutPane.call(this);
+}
+
+dojo.inherits(dojo.widget.html.FloatingPane, dojo.widget.html.LayoutPane);
+
+dojo.lang.extend(dojo.widget.html.FloatingPane, {
+	widgetType: "FloatingPane",
+
+	// Constructor arguments
+	title: '',
+	iconSrc: '',
+	hasShadow: false,
+	constrainToContainer: false,
+	taskBarId: "",
+	resizable: true,	// note: if specified, user must include ResizeHandle
+	overflow: "",
+
+	resizable: false,
+	titleBarDisplay: "fancy",
+	titleHeight: 22,	// workaround to CSS loading race condition bug
+
+	href: "",
+	extractContent: true,
+	parseContent: true,
+	cacheContent: true,
+
+	// FloatingPane supports 3 modes for the client area (the part below the title bar)
+	//  default - client area  is a ContentPane, that can hold
+	//      either inlined data and/or data downloaded from a URL
+	//  layout - the client area is a layout pane
+	//  none - the user specifies a single widget which becomes the content pane
+	contentWrapper: "default",
+
+	containerNode: null,
+	domNode: null,
+	clientPane: null,
+	dragBar: null,
+
+	windowState: "normal",
+	displayCloseAction: false,
+
+	maxTaskBarConnectAttempts: 5,
+	taskBarConnectAttempts: 0,
+
+	minimizeIcon: dojo.uri.dojoUri("src/widget/templates/images/floatingPaneMinimize.gif"),
+	maximizeIcon: dojo.uri.dojoUri("src/widget/templates/images/floatingPaneMaximize.gif"),
+	restoreIcon: dojo.uri.dojoUri("src/widget/templates/images/floatingPaneRestore.gif"),
+	closeIcon: dojo.uri.dojoUri("src/widget/templates/images/floatingPaneClose.gif"),
+	titleBarBackground: dojo.uri.dojoUri("src/widget/templates/images/titlebar-bg.jpg"),
+
+	shadowPng: dojo.uri.dojoUri("src/widget/templates/images/shadow"),
+	shadowThickness: 8,
+	shadowOffset: 15,
+
+	templateString: '<div></div>',
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlFloatingPane.css"),
+
+	initialized: false,
+
+	addChild: function(child, overrideContainerNode, pos, ref, insertIndex) {
+		this.clientPane.addChild(child, overrideContainerNode, pos, ref, insertIndex);
+	},
+
+	// make a widget container to hold all the contents of the floating pane (other than the
+	// title and the resize bar at the bottom)
+	_makeClientPane: function(clientDiv){
+		var args = {
+			layoutAlign: "client", 
+			id:this.widgetId+"_client",
+			href: this.href, 
+			cacheContent: this.cacheContent, 
+			extractContent: this.extractContent,
+			parseContent: this.parseContent
+		};
+		var pane = this._createPane(this.contentWrapper=="layout"?"LayoutPane":"ContentPane", clientDiv, args);
+		return pane;
+	},
+
+	fillInTemplate: function(args, frag){
+		var source = this.getFragNodeRef(frag);
+
+		// Copy style info and id from input node to output node
+		this.domNode.style.cssText = source.style.cssText;
+		dojo.html.addClass(this.domNode, dojo.html.getClass(source));
+		dojo.html.addClass(this.domNode, "dojoFloatingPane");
+		this.domNode.style.position="absolute";
+		this.domNode.id = source.id;
+		if(dojo.render.html.safari){
+			dojo.html.body().appendChild(this.domNode);
+		}
+
+		// make client pane wrapper to hold the contents of this floating pane
+		if(this.contentWrapper!="none"){
+			var clientDiv = document.createElement('div');
+			dojo.dom.moveChildren(source, clientDiv, 0);
+			this.clientPane = this._makeClientPane(clientDiv);
+		}
+		
+		if (this.titleBarDisplay != "none") {
+			// this is our chrome
+			var chromeDiv = document.createElement('div');
+			dojo.html.addClass(chromeDiv, 'dojoFloatingPaneDragbar');
+			chromeDiv.style.height=this.titleHeight+"px";	// workaround CSS loading race condition bug
+			
+			this.dragBar = this._createPane("LayoutPane", chromeDiv, {layoutAlign: 'top', id:this.widgetId+"_chrome"});
+			dojo.html.disableSelection(this.dragBar.domNode);
+
+			if( this.titleBarDisplay == "fancy"){
+				// image background to get gradient
+				var img = document.createElement('img');
+				img.src = this.titleBarBackground;
+				dojo.html.addClass(img, 'dojoFloatingPaneDragbarBackground');
+				var backgroundPane = dojo.widget.createWidget("ContentPane", {layoutAlign:"flood", id:this.widgetId+"_titleBackground"}, img);
+				this.dragBar.addChild(backgroundPane);
+			}
+
+			//Title Bar
+			var titleBar = document.createElement('div');
+			dojo.html.addClass(titleBar, "dojoFloatingPaneTitleBar");
+			dojo.html.disableSelection(titleBar);
+
+			//TitleBarActions
+			var titleBarActions = document.createElement('div');
+			dojo.html.addClass(titleBarActions, "dojoFloatingPaneActions");
+
+			//Title Icon
+			if(this.iconSrc!=""){
+				var titleIcon = document.createElement('img');
+				dojo.html.addClass(titleIcon,"dojoTitleBarIcon");
+				titleIcon.src = this.iconSrc;						
+				titleBar.appendChild(titleIcon);
+			}
+
+			//Title text  
+			var titleText = document.createTextNode(this.title)
+			titleBar.appendChild(titleText);
+
+			if (this.resizable) {
+
+				//FloatingPane Action Minimize
+				this.minimizeAction = document.createElement("img");
+				dojo.html.addClass(this.minimizeAction, "dojoFloatingPaneActionItem");
+				this.minimizeAction.src = this.minimizeIcon;	
+				titleBarActions.appendChild(this.minimizeAction);
+				dojo.event.connect(this.minimizeAction, 'onclick', this, 'minimizeWindow');
+
+				//FloatingPane Action Restore
+				this.restoreAction = document.createElement("img");
+				dojo.html.addClass(this.restoreAction, "dojoFloatingPaneActionItem");
+				this.restoreAction.src = this.restoreIcon;	
+				titleBarActions.appendChild(this.restoreAction);
+				dojo.event.connect(this.restoreAction, 'onclick', this, 'restoreWindow');
+
+				if (this.windowState != "normal") {
+					this.restoreAction.style.display="inline";
+				} else {
+					this.restoreAction.style.display="none";
+				}
+
+				//FloatingPane Action Maximize
+				this.maximizeAction = document.createElement("img");
+				dojo.html.addClass(this.maximizeAction, "dojoFloatingPaneActionItem");
+				this.maximizeAction.src = this.maximizeIcon;	
+				titleBarActions.appendChild(this.maximizeAction);
+				dojo.event.connect(this.maximizeAction, 'onclick', this, 'maximizeWindow');
+
+				if (this.windowState != "maximized") {
+					this.maximizeAction.style.display="inline";	
+				} else {
+					this.maximizeAction.style.display="none";	
+				}	
+
+			}
+
+			if (this.displayCloseAction) {
+				//FloatingPane Action Close
+				var closeAction= document.createElement("img");
+				dojo.html.addClass(closeAction, "dojoFloatingPaneActionItem");
+				closeAction.src = this.closeIcon;	
+				titleBarActions.appendChild(closeAction);
+				dojo.event.connect(closeAction, 'onclick', this, 'closeWindow');
+			}
+
+
+			chromeDiv.appendChild(titleBar);
+			chromeDiv.appendChild(titleBarActions);
+		}
+
+		if ( this.resizable ) {
+			// add the resize handle
+			var resizeDiv = document.createElement('div');
+			dojo.html.addClass(resizeDiv, "dojoFloatingPaneResizebar");
+			dojo.html.disableSelection(resizeDiv);
+			var rh = dojo.widget.createWidget("ResizeHandle", {targetElmId: this.widgetId, id:this.widgetId+"_resize"});
+			this.resizePane = this._createPane("ContentPane", resizeDiv, {layoutAlign: "bottom"});
+			this.resizePane.addChild(rh);
+		}
+
+		// add a drop shadow
+		this._makeShadow();
+
+		dojo.event.connect(this.domNode, 'onmousedown', this, 'onMouseDown');
+
+		// Prevent IE bleed-through problem
+		this.bgIframe = new dojo.html.BackgroundIframe();
+		if( this.bgIframe.iframe ){
+			this.domNode.appendChild(this.bgIframe.iframe);
+		}
+		if ( this.isVisible() ) {
+			this.bgIframe.show();
+		};
+
+		if( this.taskBarId ){
+			this.taskBarSetup();
+		}
+
+		if (dojo.hostenv.post_load_) {
+			this.setInitialWindowState();
+		} else {
+			dojo.addOnLoad(this, "setInitialWindowState");
+		}
+		if(dojo.render.html.safari){
+			dojo.html.body().removeChild(this.domNode);
+		}
+
+		dojo.widget.html.FloatingPane.superclass.postCreate.call(this, args, frag);
+	},
+
+	postCreate: function(args, frag){
+		// Make the client pane.  It will either be the widget specified by the user,
+		// or a wrapper widget
+		if(this.contentWrapper=="none"){
+			// the user has specified a single widget which will become our content
+			this.clientPane = this.children[0];
+			this.domNode.appendChild(this.clientPane.domNode);
+		}else{
+			// move our 'children' into the client pane
+			// we already moved the domnodes, but now we need to move the 'children'
+			var kids = this.children.concat();
+			this.children = [];
+	
+			for(var i=0; i<kids.length; i++){
+				if (kids[i].ownerPane == this){
+					this.children.push(kids[i]);
+				}else{
+					if(this.contentWrapper=="layout"){
+						this.clientPane.addChild(kids[i]);
+					}else{
+						this.clientPane.children.push(kids[i]);
+					}
+				}
+			}
+		}
+		dojo.html.addClass(this.clientPane.domNode, 'dojoFloatingPaneClient');
+		this.clientPane.layoutAlign="client";
+		this.clientPane.ownerPane=this;
+		if (this.overflow != "") {
+			this.clientPane.domNode.style.overflow=this.overflow;
+		}
+
+		if (this.titleBarDisplay != "none") {
+			var drag = new dojo.dnd.HtmlDragMoveSource(this.domNode);
+	
+			if (this.constrainToContainer) {
+				drag.constrainTo();
+			}
+	
+			drag.setDragHandle(this.dragBar.domNode);
+		}
+
+		this.initialized=true;
+	},
+
+	_makeShadow: function(){
+		if ( this.hasShadow ) {
+			// make all the pieces of the shadow, and position/size them as much
+			// as possible (but a lot of the coordinates are set in sizeShadow
+			this.shadow={};
+			var x1 = -1 * this.shadowThickness;
+			var y0 = this.shadowOffset;
+			var y1 = this.shadowOffset + this.shadowThickness;
+			this._makeShadowPiece("ul", "top", y0, "left", x1);
+			this._makeShadowPiece("l", "top", y1, "left", x1, "scale");
+			this._makeShadowPiece("ur", "top", y0, "left", 0);
+			this._makeShadowPiece("r", "top", y1, "left", 0, "scale");
+			this._makeShadowPiece("bl", "top", 0, "left", x1);
+			this._makeShadowPiece("b", "top", 0, "left", 0, "crop");
+			this._makeShadowPiece("br", "top", 0, "left", 0);
+		}
+	},
+
+	_makeShadowPiece: function(name, vertAttach, vertCoord, horzAttach, horzCoord, sizing){
+		var img;
+		var url = this.shadowPng + name.toUpperCase() + ".png";
+		if(dojo.render.html.ie){
+			img=document.createElement("div");
+			img.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"'"+
+			(sizing?", sizingMethod='"+sizing+"'":"") + ")";
+		}else{
+			img=document.createElement("img");
+			img.src=url;
+		}
+		img.style.position="absolute";
+		img.style[vertAttach]=vertCoord+"px";
+		img.style[horzAttach]=horzCoord+"px";
+		img.style.width=this.shadowThickness+"px";
+		img.style.height=this.shadowThickness+"px";
+		this.shadow[name]=img;
+		this.domNode.appendChild(img);
+	},
+
+	_sizeShadow: function(width, height){
+		if ( this.shadow ) {
+			var sideHeight = height - (this.shadowOffset+this.shadowThickness+1);
+			this.shadow.l.style.height = sideHeight+"px";
+			this.shadow.r.style.height = sideHeight+"px";
+			this.shadow.b.style.width = (width-1)+"px";
+			this.shadow.bl.style.top = (height-1)+"px";
+			this.shadow.b.style.top = (height-1)+"px";
+			this.shadow.br.style.top = (height-1)+"px";
+			this.shadow.ur.style.left = (width-1)+"px";
+			this.shadow.r.style.left = (width-1)+"px";
+			this.shadow.br.style.left = (width-1)+"px";
+		}
+	},
+
+	maximizeWindow: function(evt) {
+		this.previousWidth= this.domNode.style.width;
+		this.previousHeight= this.domNode.style.height;
+		this.previousLeft = this.domNode.style.left;
+		this.previousTop = this.domNode.style.top;
+
+		this.domNode.style.left =
+			dojo.style.getPixelValue(this.domNode.parentNode, "padding-left", true) + "px";
+		this.domNode.style.top =
+			dojo.style.getPixelValue(this.domNode.parentNode, "padding-top", true) + "px";
+
+		if ((this.domNode.parentNode.nodeName.toLowerCase() == 'body')) {
+			dojo.style.setOuterWidth(this.domNode, dojo.html.getViewportWidth()-dojo.style.getPaddingWidth(dojo.html.body()));
+			dojo.style.setOuterHeight(this.domNode, dojo.html.getViewportHeight()-dojo.style.getPaddingHeight(dojo.html.body()));
+		} else {
+			dojo.style.setOuterWidth(this.domNode, dojo.style.getContentWidth(this.domNode.parentNode));
+			dojo.style.setOuterHeight(this.domNode, dojo.style.getContentHeight(this.domNode.parentNode));
+		}	
+		this.maximizeAction.style.display="none";	
+		this.restoreAction.style.display="inline";	
+		this.windowState="maximized";
+		this.onResized();
+	},
+
+	minimizeWindow: function(evt) {
+		this.hide();
+		if (this.resizable) {
+			this.maximizeAction.style.display="inline";	
+			this.restoreAction.style.display="inline";	
+		}
+
+		this.windowState = "minimized";
+	},
+
+	restoreWindow: function(evt) {
+		if (this.previousWidth && this.previousHeight && this.previousLeft && this.previousTop) {
+			this.domNode.style.width = this.previousWidth;
+			this.domNode.style.height = this.previousHeight;
+			this.domNode.style.left = this.previousLeft;
+			this.domNode.style.top = this.previousTop;
+			dojo.widget.html.FloatingPane.superclass.onResized.call(this);
+		}
+
+		if (this.widgetState != "maximized") {
+			this.show();
+		}
+
+		if (this.resizable) {
+			this.maximizeAction.style.display="inline";	
+			this.restoreAction.style.display="none";	
+		}
+
+		this.bringToTop();
+		this.windowState="normal";
+	},
+
+	closeWindow: function(evt) {
+		this.destroy();
+	},
+
+	onMouseDown: function(evt) {
+		this.bringToTop();
+	},
+
+	bringToTop: function() {
+		var floatingPaneStartingZ = 100;
+		var floatingPanes= dojo.widget.manager.getWidgetsByType("FloatingPane");
+		var windows = []
+		var y=0;
+		for (var x=0; x<floatingPanes.length; x++) {
+			if (this.widgetId != floatingPanes[x].widgetId) {
+					windows.push(floatingPanes[x]);
+			}
+		}
+
+		windows.sort(function(a,b) {
+			return a.domNode.style.zIndex - b.domNode.style.zIndex;
+		});
+		
+		windows.push(this);
+
+		for (x=0; x<windows.length;x++) {
+			windows[x].domNode.style.zIndex = floatingPaneStartingZ + x;
+		}
+	},
+
+	setInitialWindowState: function() {
+		if (this.windowState == "maximized") {
+			this.maximizeWindow();
+			this.show();
+			this.bringToTop();
+			return;
+		}
+
+		if (this.windowState=="normal") {
+			dojo.lang.setTimeout(this, this.onResized, 50);
+			this.show();
+			this.bringToTop();
+			return;
+		}
+
+		if (this.windowState=="minimized") {
+			this.hide();
+			return;
+		}
+
+		this.windowState="minimized";
+	},
+
+	// add icon to task bar, connected to me
+	taskBarSetup: function() {
+		var taskbar = dojo.widget.getWidgetById(this.taskBarId);
+		if (!taskbar){
+			if (this.taskBarConnectAttempts <  this.maxTaskBarConnectAttempts) {
+				dojo.lang.setTimeout(this, this.taskBarSetup, 50);
+				this.taskBarConnectAttempts++;
+			} else {
+				dojo.debug("Unable to connect to the taskBar");
+			}
+			return;
+		}
+		taskbar.addChild(this);
+	},
+
+	onResized: function(){
+		if( !this.isVisible() ){ return; }
+		var newHeight = dojo.style.getInnerHeight(this.domNode);
+		var newWidth = dojo.style.getInnerWidth(this.domNode);
+	
+		//if ( newWidth != this.width || newHeight != this.height ) {
+			this.width = newWidth;
+			this.height = newHeight;
+			this._sizeShadow(newWidth, newHeight);
+			dojo.widget.html.FloatingPane.superclass.onResized.call(this);
+		//}
+
+		// bgIframe is a child of this.domNode, so position should be relative to [0,0]
+		if(this.bgIframe){
+			this.bgIframe.size([0, 0, newWidth, newHeight]);
+		}
+	},
+
+	hide: function(){
+		dojo.widget.html.FloatingPane.superclass.hide.call(this);
+		if(this.bgIframe){
+			this.bgIframe.hide();
+		}
+	},
+
+	show: function(){
+		dojo.widget.html.FloatingPane.superclass.show.call(this);
+		if(this.bgIframe){
+			this.bgIframe.show();
+		}
+	},
+
+	_createPane: function(type, node, args){
+		var pane = dojo.widget.createWidget(type, args, node);
+		dojo.widget.html.FloatingPane.superclass.addChild.call(this,pane);
+		pane.ownerPane=this;
+		return pane;
+	},
+	
+	setUrl: function(url){
+		this.clientPane.setUrl(url);
+	},
+	
+	setContent: function(str){
+		this.clientPane.setContent(str);
+	}
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:FloatingPane");

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HslColorPicker.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HslColorPicker.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HslColorPicker.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HslColorPicker.js Thu Apr 13 16:46:55 2006
@@ -0,0 +1,25 @@
+/*
+	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.HslColorPicker");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Widget");
+dojo.require("dojo.graphics.color");
+dojo.widget.tags.addParseTreeHandler("dojo:hslcolorpicker");
+
+dojo.requireAfterIf(dojo.render.svg.support.builtin, "dojo.widget.svg.HslColorPicker");
+
+dojo.widget.HslColorPicker=function(){
+	dojo.widget.Widget.call(this);
+	this.widgetType = "HslColorPicker";
+	this.isContainer = false;
+}
+dojo.inherits(dojo.widget.HslColorPicker, dojo.widget.Widget);

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HtmlWidget.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HtmlWidget.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HtmlWidget.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/HtmlWidget.js Thu Apr 13 16:46:55 2006
@@ -0,0 +1,226 @@
+/*
+	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.HtmlWidget");
+dojo.require("dojo.widget.DomWidget");
+dojo.require("dojo.html");
+dojo.require("dojo.string");
+
+dojo.widget.HtmlWidget = function(args){
+	// mixin inheritance
+	dojo.widget.DomWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.HtmlWidget, dojo.widget.DomWidget);
+
+dojo.lang.extend(dojo.widget.HtmlWidget, {
+	widgetType: "HtmlWidget",
+
+	templateCssPath: null,
+	templatePath: null,
+	allowResizeX: true,
+	allowResizeY: true,
+
+	resizeGhost: null,
+	initialResizeCoords: null,
+
+	// for displaying/hiding widget
+	toggle: "plain",
+	toggleDuration: 150,
+
+	animationInProgress: false,
+
+	initialize: function(args, frag){
+	},
+
+	postMixInProperties: function(args, frag){
+		// now that we know the setting for toggle, define show()&hide()
+		dojo.lang.mixin(this,
+			dojo.widget.HtmlWidget.Toggle[dojo.string.capitalize(this.toggle)] ||
+			dojo.widget.HtmlWidget.Toggle.Plain);
+	},
+
+	getContainerHeight: function(){
+		// NOTE: container height must be returned as the INNER height
+		dj_unimplemented("dojo.widget.HtmlWidget.getContainerHeight");
+	},
+
+	getContainerWidth: function(){
+		return this.parent.domNode.offsetWidth;
+	},
+
+	setNativeHeight: function(height){
+		var ch = this.getContainerHeight();
+	},
+
+	startResize: function(coords){
+		// get the left and top offset of our dom node
+		coords.offsetLeft = dojo.html.totalOffsetLeft(this.domNode);
+		coords.offsetTop = dojo.html.totalOffsetTop(this.domNode);
+		coords.innerWidth = dojo.html.getInnerWidth(this.domNode);
+		coords.innerHeight = dojo.html.getInnerHeight(this.domNode);
+		if(!this.resizeGhost){
+			this.resizeGhost = document.createElement("div");
+			var rg = this.resizeGhost;
+			rg.style.position = "absolute";
+			rg.style.backgroundColor = "white";
+			rg.style.border = "1px solid black";
+			dojo.html.setOpacity(rg, 0.3);
+			dojo.html.body().appendChild(rg);
+		}
+		with(this.resizeGhost.style){
+			left = coords.offsetLeft + "px";
+			top = coords.offsetTop + "px";
+		}
+		this.initialResizeCoords = coords;
+		this.resizeGhost.style.display = "";
+		this.updateResize(coords, true);
+	},
+
+	updateResize: function(coords, override){
+		var dx = coords.x-this.initialResizeCoords.x;
+		var dy = coords.y-this.initialResizeCoords.y;
+		with(this.resizeGhost.style){
+			if((this.allowResizeX)||(override)){
+				width = this.initialResizeCoords.innerWidth + dx + "px";
+			}
+			if((this.allowResizeY)||(override)){
+				height = this.initialResizeCoords.innerHeight + dy + "px";
+			}
+		}
+	},
+
+	endResize: function(coords){
+		// FIXME: need to actually change the size of the widget!
+		var dx = coords.x-this.initialResizeCoords.x;
+		var dy = coords.y-this.initialResizeCoords.y;
+		with(this.domNode.style){
+			if(this.allowResizeX){
+				width = this.initialResizeCoords.innerWidth + dx + "px";
+			}
+			if(this.allowResizeY){
+				height = this.initialResizeCoords.innerHeight + dy + "px";
+			}
+		}
+		this.resizeGhost.style.display = "none";
+	},
+
+	resizeSoon: function(){
+		if ( this.isVisible() ) {
+			dojo.lang.setTimeout(this, this.onResized, 0);
+		}
+	},
+
+	createNodesFromText: function(txt, wrap){
+		return dojo.html.createNodesFromText(txt, wrap);
+	},
+
+	_old_buildFromTemplate: dojo.widget.DomWidget.prototype.buildFromTemplate,
+
+	buildFromTemplate: function(args, frag){
+		if(dojo.widget.DomWidget.templates[this.widgetType]){
+			var ot = dojo.widget.DomWidget.templates[this.widgetType];
+			dojo.widget.DomWidget.templates[this.widgetType] = {};
+		}
+		if(args["templatecsspath"]){
+			args["templateCssPath"] = args["templatecsspath"];
+		}
+		if(args["templatepath"]){
+			args["templatePath"] = args["templatepath"];
+		}
+		dojo.widget.buildFromTemplate(this, args["templatePath"], args["templateCssPath"]);
+		this._old_buildFromTemplate(args, frag);
+		dojo.widget.DomWidget.templates[this.widgetType] = ot;
+	},
+
+	destroyRendering: function(finalize){
+		try{
+			var tempNode = this.domNode.parentNode.removeChild(this.domNode);
+			if(!finalize){
+				dojo.event.browser.clean(tempNode);
+			}
+			delete tempNode;
+		}catch(e){ /* squelch! */ }
+	},
+
+	// Displaying/hiding the widget
+
+	isVisible: function(){
+		return dojo.html.isVisible(this.domNode);
+	},
+	doToggle: function(){
+		this.isVisible() ? this.hide() : this.show();
+	},
+	show: function(){
+		this.animationInProgress=true;
+		this.showMe();
+	},
+	onShow: function(){
+		this.animationInProgress=false;
+	},
+	hide: function(){
+		this.animationInProgress=true;
+		this.hideMe();
+	},
+	onHide: function(){
+		this.animationInProgress=false;
+	}
+});
+
+
+/**** 
+	Strategies for displaying/hiding widget
+*****/
+
+dojo.widget.HtmlWidget.Toggle={}
+
+dojo.widget.HtmlWidget.Toggle.Plain = {
+	showMe: function(){
+		dojo.html.show(this.domNode);
+		if(dojo.lang.isFunction(this.onShow)){ this.onShow(); }
+	},
+
+	hideMe: function(){
+		dojo.html.hide(this.domNode);
+		if(dojo.lang.isFunction(this.onHide)){ this.onHide(); }
+	}
+}
+
+dojo.widget.HtmlWidget.Toggle.Fade = {
+	showMe: function(){
+		dojo.fx.html.fadeShow(this.domNode, this.toggleDuration, dojo.lang.hitch(this, this.onShow));
+	},
+
+	hideMe: function(){
+		dojo.fx.html.fadeHide(this.domNode, this.toggleDuration, dojo.lang.hitch(this, this.onHide));
+	}
+}
+
+dojo.widget.HtmlWidget.Toggle.Wipe = {
+	showMe: function(){
+		dojo.fx.html.wipeIn(this.domNode, this.toggleDuration, dojo.lang.hitch(this, this.onShow));
+	},
+
+	hideMe: function(){
+		dojo.fx.html.wipeOut(this.domNode, this.toggleDuration, dojo.lang.hitch(this, this.onHide));
+	}
+}
+
+dojo.widget.HtmlWidget.Toggle.Explode = {
+	showMe: function(){
+		dojo.fx.html.explode(this.explodeSrc, this.domNode, this.toggleDuration,
+			dojo.lang.hitch(this, this.onShow));
+	},
+
+	hideMe: function(){
+		dojo.fx.html.implode(this.domNode, this.explodeSrc, this.toggleDuration,
+			dojo.lang.hitch(this, this.onHide));
+	}
+}

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/InlineEditBox.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/InlineEditBox.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/InlineEditBox.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/InlineEditBox.js Thu Apr 13 16:46:55 2006
@@ -0,0 +1,196 @@
+/*
+	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.InlineEditBox");
+dojo.provide("dojo.widget.html.InlineEditBox");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.fx.*");
+dojo.require("dojo.graphics.color");
+dojo.require("dojo.string");
+dojo.require("dojo.style");
+dojo.require("dojo.html");
+
+dojo.widget.tags.addParseTreeHandler("dojo:inlineeditbox");
+
+dojo.widget.html.InlineEditBox = function(){
+	dojo.widget.HtmlWidget.call(this);
+	// mutable objects need to be in constructor to give each instance its own copy
+	this.history = [];
+	this.storage = document.createElement("span");
+}
+
+dojo.inherits(dojo.widget.html.InlineEditBox, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.InlineEditBox, {
+	templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlInlineEditBox.html"),
+	templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlInlineEditBox.css"),
+	widgetType: "InlineEditBox",
+
+	form: null,
+	editBox: null,
+	edit: null,
+	text: null,
+	textarea: null,
+	submitButton: null,
+	cancelButton: null,
+	mode: "text",
+
+	minWidth: 100, //px. minimum width of edit box
+	minHeight: 200, //px. minimum width of edit box, if it's a TA
+
+	editing: false,
+	textValue: "",
+	defaultText: "",
+	doFade: false,
+
+	onSave: function(newValue, oldValue){},
+	onUndo: function(value){},
+
+	// overwrite buildRendering so we don't clobber our list
+	buildRendering: function(args, frag){
+		this.nodeRef = frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"];
+		var node = this.nodeRef;
+		if(node.normalize){ node.normalize(); }
+
+		dojo.widget.buildAndAttachTemplate(this);
+
+		this.editable = document.createElement("span");
+		// this.editable.appendChild(node.firstChild);
+		while(node.firstChild){
+			this.editable.appendChild(node.firstChild);
+		}
+		// this.textValue = this.editable.firstChild.nodeValue;
+		this.textValue = dojo.string.trim(this.editable.innerHTML);
+		if(dojo.string.trim(this.textValue).length == 0){
+			this.editable.innerHTML = this.defaultText;
+		}
+		/*
+		if(node.hasChildNodes()) {
+			node.insertBefore(this.editable, node.firstChild);
+		} else {
+		}
+		*/
+		node.appendChild(this.editable);
+
+		// delay to try and show up before stylesheet
+		var _this = this;
+		setTimeout(function(){
+			_this.editable.appendChild(_this.edit);
+		}, 30);
+
+		dojo.event.connect(this.editable, "onmouseover", this, "mouseover");
+		dojo.event.connect(this.editable, "onmouseout", this, "mouseout");
+		dojo.event.connect(this.editable, "onclick", this, "beginEdit");
+
+		this.fillInTemplate(args, frag);
+	},
+
+	mouseover: function(e){
+		if(!this.editing){
+			dojo.html.addClass(this.editable, "editableRegion");
+			if(this.mode == "textarea"){
+				dojo.html.addClass(this.editable, "editableTextareaRegion");
+			}
+		}
+	},
+
+	mouseout: function(e){
+		// if((e)&&(e.target != this.domNode)){ return; }
+		if(!this.editing){
+			dojo.html.removeClass(this.editable, "editableRegion");
+			dojo.html.removeClass(this.editable, "editableTextareaRegion");
+		}
+	},
+
+	beginEdit: function(e){
+		if(this.editing){ return; }
+		this.mouseout();
+		this.editing = true;
+
+		var ee = this[this.mode.toLowerCase()];
+
+		ee.style.display = "";
+		ee.value = dojo.string.trim(this.textValue);
+		ee.style.fontSize = dojo.style.getStyle(this.editable, "font-size");
+		ee.style.fontWeight = dojo.style.getStyle(this.editable, "font-weight");
+		ee.style.fontStyle = dojo.style.getStyle(this.editable, "font-style");
+		//this.text.style.fontFamily = dojo.dom.getStyle(this.editable, "font-family");
+
+		ee.style.width = Math.max(dojo.html.getInnerWidth(this.editable), this.minWidth) + "px";
+		// ee.style.width = "100%";
+
+		if(this.mode.toLowerCase()=="textarea"){
+			ee.style.display = "block";
+			ee.style.height = Math.max(dojo.html.getInnerHeight(this.editable), this.minHeight) + "px";
+		}
+		this.editable.style.display = "none";
+		this.nodeRef.appendChild(this.form);
+		ee.select();
+		this.submitButton.disabled = true;
+	},
+
+	saveEdit: function(e){
+		e.preventDefault();
+		e.stopPropagation();
+		var ee = this[this.mode.toLowerCase()];
+		if((this.textValue != ee.value)&&
+			(dojo.string.trim(ee.value) != "")){
+			this.doFade = true;
+			this.history.push(this.textValue);
+			this.onSave(ee.value, this.textValue);
+			this.textValue = ee.value;
+			this.editable.innerHTML = this.textValue;
+		}else{
+			this.doFade = false;
+		}
+		this.finishEdit(e);
+	},
+
+	cancelEdit: function(e){
+		if(!this.editing){ return false; }
+		this.editing = false;
+		this.nodeRef.removeChild(this.form);
+		this.editable.style.display = "";
+		return true;
+	},
+
+	finishEdit: function(e){
+		if(!this.cancelEdit(e)){ return; }
+		if(this.doFade) {
+			dojo.fx.highlight(this.editable, dojo.graphics.color.hex2rgb("#ffc"), 700, 300);
+		}
+		this.doFade = false;
+	},
+
+	setText: function(txt){
+		// sets the text without informing the server
+		var tt = dojo.string.trim(txt);
+		this.textValue = tt
+		this.editable.innerHTML = tt;
+	},
+
+	undo: function(){
+		if(this.history.length > 0){
+			var value = this.history.pop();
+			this.editable.innerHTML = value;
+			this.textValue = value;
+			this.onUndo(value);
+		}
+	},
+
+	checkForValueChange: function(){
+		var ee = this[this.mode.toLowerCase()];
+		if((this.textValue != ee.value)&&
+			(dojo.string.trim(ee.value) != "")){
+			this.submitButton.disabled = false;
+		}
+	}
+});

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LayoutPane.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LayoutPane.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LayoutPane.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LayoutPane.js Thu Apr 13 16:46:55 2006
@@ -0,0 +1,17 @@
+/*
+	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.LayoutPane");
+
+dojo.require("dojo.widget.*");
+dojo.requireAfterIf("html", "dojo.widget.html.LayoutPane");
+dojo.widget.tags.addParseTreeHandler("dojo:LayoutPane");
+
+// NOTE: there's no stub file for this widget

Added: incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LinkPane.js
URL: http://svn.apache.org/viewcvs/incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LinkPane.js?rev=393978&view=auto
==============================================================================
--- incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LinkPane.js (added)
+++ incubator/webwork2/action/src/main/resources/org/apache/struts/action2/static/dojo/src/widget/LinkPane.js Thu Apr 13 16:46:55 2006
@@ -0,0 +1,17 @@
+/*
+	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.LinkPane");
+
+dojo.require("dojo.widget.*");
+dojo.requireAfterIf("html", "dojo.widget.html.LinkPane");
+dojo.widget.tags.addParseTreeHandler("dojo:LinkPane");
+
+// NOTE: there's no stub file for this widget



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org