You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/09/29 05:43:06 UTC
svn commit: r451106 [33/40] - in /tapestry/tapestry4/trunk: ./
tapestry-framework/src/java/org/apache/tapestry/asset/
tapestry-framework/src/js/dojo/ tapestry-framework/src/js/dojo/src/
tapestry-framework/src/js/dojo/src/animation/ tapestry-framework/s...
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,216 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+
+dojo.provide("dojo.widget.TreeContextMenu");
+dojo.provide("dojo.widget.TreeMenuItem");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.Menu2");
+
+dojo.deprecated("dojo.widget.TreeContextMenu", "use TreeV3 and TreeContextMenuV3 instead", "0.5");
+
+
+dojo.widget.tags.addParseTreeHandler("dojo:TreeContextMenu");
+dojo.widget.tags.addParseTreeHandler("dojo:TreeMenuItem");
+
+
+
+dojo.widget.TreeContextMenu = function() {
+ dojo.widget.PopupMenu2.call(this);
+
+ this.listenedTrees = [];
+
+}
+
+
+dojo.inherits(dojo.widget.TreeContextMenu, dojo.widget.PopupMenu2);
+
+dojo.lang.extend(dojo.widget.TreeContextMenu, {
+
+ widgetType: "TreeContextMenu",
+
+ 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;
+ },
+
+ listenTree: function(tree) {
+ /* add context menu to all nodes that exist already */
+ var nodes = tree.getDescendants();
+
+ for(var i=0; i<nodes.length; i++) {
+ if (!nodes[i].isTreeNode) continue;
+ this.bindDomNode(nodes[i].labelNode);
+ }
+
+
+ /* bind context menu to all nodes that will be created in the future (e.g loaded from server)*/
+ var _this = this;
+ dojo.event.topic.subscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
+ dojo.event.topic.subscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
+ dojo.event.topic.subscribe(tree.eventNames.moveTo, this, "onMoveTo");
+ dojo.event.topic.subscribe(tree.eventNames.removeNode, this, "onRemoveNode");
+ dojo.event.topic.subscribe(tree.eventNames.addChild, this, "onAddChild");
+ dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
+
+ this.listenedTrees.push(tree);
+
+ },
+
+ unlistenTree: function(tree) {
+ /* clear event listeners */
+
+ dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
+ dojo.event.topic.unsubscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
+ dojo.event.topic.unsubscribe(tree.eventNames.moveTo, this, "onMoveTo");
+ dojo.event.topic.unsubscribe(tree.eventNames.removeNode, this, "onRemoveNode");
+ dojo.event.topic.unsubscribe(tree.eventNames.addChild, this, "onAddChild");
+ dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
+
+ for(var i=0; i<this.listenedTrees.length; i++){
+ if(this.listenedTrees[i] === tree){
+ this.listenedTrees.splice(i, 1);
+ break;
+ }
+ }
+ },
+
+ onTreeDestroy: function(message) {
+ this.unlistenTree(message.source);
+ },
+
+ bindTreeNode: function(node) {
+ var _this = this;
+ //dojo.debug("bind to "+node);
+ dojo.lang.forEach(node.getDescendants(),
+ function(e) {_this.bindDomNode(e.labelNode); }
+ );
+ },
+
+
+ unBindTreeNode: function(node) {
+ var _this = this;
+ //dojo.debug("Unbind from "+node);
+ dojo.lang.forEach(node.getDescendants(),
+ function(e) {_this.unBindDomNode(e.labelNode); }
+ );
+ },
+
+ onCreateDOMNode: function(message) {
+ this.bindTreeNode(message.source);
+ },
+
+
+ onMoveFrom: function(message) {
+ if (!dojo.lang.inArray(this.listenedTrees, message.newTree)) {
+ this.unBindTreeNode(message.child);
+ }
+ },
+
+ onMoveTo: function(message) {
+ if (dojo.lang.inArray(this.listenedTrees, message.newTree)) {
+ this.bindTreeNode(message.child);
+ }
+ },
+
+ onRemoveNode: function(message) {
+ this.unBindTreeNode(message.child);
+ },
+
+ onAddChild: function(message) {
+ if (message.domNodeInitialized) {
+ // dom node was there already => I did not process onNodeDomCreate
+ this.bindTreeNode(message.child);
+ }
+ }
+
+
+});
+
+
+
+
+
+
+dojo.widget.TreeMenuItem = function() {
+ dojo.widget.MenuItem2.call(this);
+
+}
+
+
+dojo.inherits(dojo.widget.TreeMenuItem, dojo.widget.MenuItem2);
+
+
+dojo.lang.extend(dojo.widget.TreeMenuItem, {
+
+ widgetType: "TreeMenuItem",
+
+ // treeActions menu item performs following actions (to be checked for permissions)
+ treeActions: "",
+
+ initialize: function(args, frag) {
+
+ this.treeActions = this.treeActions.split(",");
+ for(var i=0; i<this.treeActions.length; i++) {
+ this.treeActions[i] = this.treeActions[i].toUpperCase();
+ }
+
+ },
+
+ getTreeNode: function() {
+ var menu = this;
+
+ while (! (menu instanceof dojo.widget.TreeContextMenu) ) {
+ menu = menu.parent;
+ }
+
+ var source = menu.getTopOpenEvent().target;
+
+ while (!source.getAttribute('treeNode') && source.tagName != 'body') {
+ source = source.parentNode;
+ }
+ if (source.tagName == 'body') {
+ dojo.raise("treeNode not detected");
+ }
+ var treeNode = dojo.widget.manager.getWidgetById(source.getAttribute('treeNode'));
+
+ return treeNode;
+ },
+
+
+ menuOpen: function(message) {
+ var treeNode = this.getTreeNode();
+
+ this.setDisabled(false); // enable by default
+
+ var _this = this;
+ dojo.lang.forEach(_this.treeActions,
+ function(action) {
+ _this.setDisabled( treeNode.actionIsDisabled(action) );
+ }
+ );
+
+ },
+
+ toString: function() {
+ return "["+this.widgetType+" node "+this.getTreeNode()+"]";
+ }
+
+});
+
+
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenu.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenuV3.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenuV3.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenuV3.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenuV3.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,123 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.TreeContextMenuV3");
+dojo.provide("dojo.widget.TreeMenuItemV3");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.Menu2");
+dojo.require("dojo.widget.TreeCommon");
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeContextMenuV3",
+ [dojo.widget.PopupMenu2, dojo.widget.TreeCommon],
+ function() {
+ this.listenedTrees = {};
+ },
+{
+ 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;
+ },
+
+ listenTreeEvents: ["afterChangeTree","beforeTreeDestroy"],
+ listenNodeFilter: function(elem) { return elem instanceof dojo.widget.Widget},
+
+ onBeforeTreeDestroy: function(message) {
+ this.unlistenTree(message.source);
+ },
+
+
+ onAfterChangeTree: function(message) {
+ //dojo.debugShallow(message);
+
+
+ if (!message.newTree || !this.listenedTrees[message.newTree.widgetId]) {
+ // I got this message because node leaves me (oldtree)
+ this.processDescendants(message.node, this.listenNodeFilter, this.unlistenNode);
+ }
+
+ if (!message.oldTree || !this.listenedTrees[message.oldTree.widgetId]) {
+ // we have new node
+ this.processDescendants(message.node, this.listenNodeFilter, this.listenNode);
+ }
+
+ //dojo.profile.end("onTreeChange");
+ },
+
+
+ listenNode: function(node) {
+ this.bindDomNode(node.labelNode);
+ },
+
+
+ unlistenNode: function(node) {
+ this.unBindDomNode(node.labelNode);
+ }
+});
+
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeMenuItemV3",
+ [dojo.widget.MenuItem2, dojo.widget.TreeCommon],
+ function() {
+ this.treeActions = [];
+ },
+{
+ // treeActions menu item performs following actions (to be checked for permissions)
+ treeActions: "",
+
+ initialize: function(args, frag) {
+ for(var i=0; i<this.treeActions.length; i++) {
+ this.treeActions[i] = this.treeActions[i].toUpperCase();
+ }
+ },
+
+ getTreeNode: function() {
+ var menu = this;
+
+ // FIXME: change to dojo.widget[this.widgetType]
+ while (! (menu instanceof dojo.widget.TreeContextMenuV3) ) {
+ menu = menu.parent;
+ }
+
+ var source = menu.getTopOpenEvent().target;
+
+ var treeNode = this.domElement2TreeNode(source);
+
+ return treeNode;
+ },
+
+
+ menuOpen: function(message) {
+ var treeNode = this.getTreeNode();
+
+ this.setDisabled(false); // enable by default
+
+ var _this = this;
+ dojo.lang.forEach(_this.treeActions,
+ function(action) {
+ _this.setDisabled( treeNode.actionIsDisabledNow(action) );
+ }
+ );
+
+ },
+
+ toString: function() {
+ return "["+this.widgetType+" node "+this.getTreeNode()+"]";
+ }
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeContextMenuV3.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeControllerExtension.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeControllerExtension.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeControllerExtension.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeControllerExtension.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,94 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/**
+ * Additional tree utils
+ *
+ */
+dojo.provide("dojo.widget.TreeControllerExtension");
+
+dojo.declare(
+ "dojo.widget.TreeControllerExtension",
+ null,
+{
+ saveExpandedIndices: function(node, field) {
+ var obj = {};
+
+ for(var i=0; i<node.children.length; i++) {
+ if (node.children[i].isExpanded) {
+ var key = dojo.lang.isUndefined(field) ? i : node.children[i][field];
+ obj[key] = this.saveExpandedIndices(node.children[i], field);
+ }
+ }
+
+ return obj;
+ },
+
+
+ restoreExpandedIndices: function(node, savedIndices, field) {
+ var _this = this;
+
+ var handler = function(node, savedIndices) {
+ this.node = node; //.children[i];
+ this.savedIndices = savedIndices; //[i];
+ // recursively read next savedIndices level and apply to opened node
+ this.process = function() {
+ //dojo.debug("Callback applied for "+this.node);
+ _this.restoreExpandedIndices(this.node, this.savedIndices, field);
+ };
+ }
+
+
+ for(var i=0; i<node.children.length; i++) {
+ var child = node.children[i];
+
+ var found = false;
+ var key = -1;
+
+ //dojo.debug("Check "+child)
+ // process field set case
+ if (dojo.lang.isUndefined(field) && savedIndices[i]) {
+ found = true;
+ key = i;
+ }
+
+ // process case when field is not set
+ if (field) {
+ for(var key in savedIndices) {
+ //dojo.debug("Compare "+key+" "+child[field])
+ if (key == child[field]) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ // if we found anything - expand it
+ if (found) {
+ //dojo.debug("Found at "+key)
+ var h = new handler(child, savedIndices[key]);
+ _this.expand(child, false, h, h.process);
+ } else if (child.isExpanded) { // not found, so collapse
+ //dojo.debug("Collapsing all descendants "+node.children[i])
+ dojo.lang.forEach(child.getDescendants(), function(elem) { _this.collapse(elem); });
+ //this.collapse(node.children[i]);
+ }
+
+ }
+
+
+ }
+
+});
+
+
+
+
+
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeControllerExtension.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDemo.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDemo.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDemo.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDemo.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,123 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeDemo");
+dojo.require("dojo.Deferred");
+
+dojo.widget.TreeDemo = {
+
+ reportIfDefered: function(res) {
+ if (res instanceof dojo.Deferred) {
+ res.addCallbacks(
+ function(res) { /* dojo.debug("OK " + (res ? res: '')); */ return res },
+ function(err) { dojo.debug("Error"); dojo.debugShallow(err); }
+ );
+ }
+ },
+
+ resetRandomChildren: function(maxCount) {
+ this.randomChildrenMaxCount = maxCount;
+ this.randomChildrenCount = 0;
+ this.randomChildrenDepth = 0;
+ },
+
+
+ makeRandomChildren: function(title) {
+
+ this.randomChildrenDepth++;
+
+ var children = [];
+ for (var i=1; i<=5; i++) {
+
+ var t = title+(this.randomChildrenDepth==1 ? '' : '.')+i;
+ var node = {title: t};
+
+ children.push(node);
+ this.randomChildrenCount++
+ if (this.randomChildrenCount >= this.randomChildrenMaxCount) {
+ break;
+ }
+ }
+
+ var i=1;
+ var _this = this;
+ dojo.lang.forEach(children, function(child) {
+ var t = title+(_this.randomChildrenDepth==1 ? '' : '.')+i;
+ i++;
+
+ // first node is always folder for tests
+ if (_this.randomChildrenCount<_this.randomChildrenMaxCount && (
+ _this.randomChildrenDepth==1 && child === children[0] || _this.randomChildrenDepth<5 && Math.random()>0.3 )
+ ) {
+ //dojo.debug("add child "+t);
+ child.children = _this.makeRandomChildren(t);
+ }
+ });
+
+
+ //dojo.debug("out "+nodeOrTree);
+
+ this.randomChildrenDepth--;
+
+ return children;
+ },
+
+ bindDemoMenu: function(controller) {
+ var _t = this;
+
+ dojo.event.topic.subscribe('treeContextMenuDestroy/engage',
+ function (menuItem) {
+ var node = menuItem.getTreeNode();
+ //if (confirm("Delete node with descendants: "+node.title.replace(/(<([^>]+)>)/ig," ") +" ?")) {
+ _t.reportIfDefered(controller.destroyChild(node));
+
+ }
+ );
+
+
+ dojo.event.topic.subscribe('treeContextMenuCreate/engage',
+ function (menuItem) {
+ var node = menuItem.getTreeNode();
+ var d = controller.createAndEdit(node, 0);
+ _t.reportIfDefered(d);
+ }
+ );
+
+
+ dojo.event.topic.subscribe('treeContextMenuUp/engage',
+ function (menuItem) {
+ var node = menuItem.getTreeNode();
+ if (node.isFirstChild()) return;
+ _t.reportIfDefered(controller.move(node, node.parent, node.getParentIndex()-1));
+ }
+ );
+
+
+ dojo.event.topic.subscribe('treeContextMenuDown/engage',
+ function (menuItem) {
+ var node = menuItem.getTreeNode();
+ if (node.isLastChild()) return;
+ _t.reportIfDefered(controller.move(node, node.parent, node.getParentIndex()+1));
+ }
+ );
+
+ dojo.event.topic.subscribe('treeContextMenuEdit/engage',
+ function (menuItem) {
+ var node = menuItem.getTreeNode();
+ _t.reportIfDefered(controller.editLabelStart(node));
+ }
+ );
+
+ }
+
+
+
+}
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDemo.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDeselectOnDblselect.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDeselectOnDblselect.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDeselectOnDblselect.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDeselectOnDblselect.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,36 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeDeselectOnDblselect");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.TreeSelectorV3");
+
+// selector extension to emphase node
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeDeselectOnDblselect",
+ [dojo.widget.HtmlWidget],
+{
+ selector: "",
+
+ initialize: function() {
+ this.selector = dojo.widget.byId(this.selector);
+ //dojo.debug("OK "+this.selector);
+ dojo.event.topic.subscribe(this.selector.eventNames.dblselect, this, "onDblselect");
+ },
+
+ onDblselect: function(message) {
+ //dojo.debug("happen "+this.selector);
+ //dojo.debug(message.node);
+ this.selector.deselect(message.node);
+ }
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDeselectOnDblselect.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDisableWrapExtension.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDisableWrapExtension.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDisableWrapExtension.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDisableWrapExtension.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide( "dojo.widget.TreeDisableWrapExtension" );
+
+dojo.require( "dojo.widget.HtmlWidget" );
+dojo.require( "dojo.widget.TreeExtension" );
+
+// selector extension to emphase node
+dojo.widget.defineWidget(
+ "dojo.widget.TreeDisableWrapExtension",
+ dojo.widget.TreeExtension,
+{
+ /**
+ * can't unlisten
+ */
+ templateCssPath: dojo.uri.dojoUri( "src/widget/templates/TreeDisableWrap.css" ),
+
+ listenTree: function(tree) {
+
+ var wrappingDiv = document.createElement( "div" );
+ var clazz = tree.classPrefix+"DisableWrap";
+ if (dojo.render.html.ie) {
+ clazz = clazz+' '+ tree.classPrefix+"IEDisableWrap";
+ }
+ dojo.html.setClass(wrappingDiv, clazz);
+
+ var table = document.createElement( "table" );
+ wrappingDiv.appendChild( table );
+
+ var tbody = document.createElement( "tbody" );
+ table.appendChild( tbody );
+
+ var tr = document.createElement( "tr" );
+ tbody.appendChild( tr );
+
+ var td = document.createElement( "td" );
+ tr.appendChild( td );
+
+ if( tree.domNode.parentNode ) {
+ tree.domNode.parentNode.replaceChild( wrappingDiv, tree.domNode );
+ }
+
+ td.appendChild( tree.domNode );
+ tree.domNode = wrappingDiv;
+ }
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDisableWrapExtension.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDndControllerV3.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDndControllerV3.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDndControllerV3.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDndControllerV3.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,137 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeDndControllerV3");
+
+dojo.require("dojo.dnd.TreeDragAndDropV3");
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeDndControllerV3",
+ [dojo.widget.HtmlWidget, dojo.widget.TreeCommon],
+ function() {
+ this.dragSources = {};
+ this.dropTargets = {};
+ this.listenedTrees = {};
+ },
+{
+ listenTreeEvents: ["afterChangeTree","beforeTreeDestroy", "afterAddChild"],
+ listenNodeFilter: function(elem) { return elem instanceof dojo.widget.Widget},
+
+ initialize: function(args) {
+ this.treeController = dojo.lang.isString(args.controller) ? dojo.widget.byId(args.controller) : args.controller;
+
+ if (!this.treeController) {
+ dojo.raise("treeController must be declared");
+ }
+
+ },
+
+ onBeforeTreeDestroy: function(message) {
+ this.unlistenTree(message.source);
+ },
+
+ // first Dnd registration happens in addChild
+ // because I have information about parent on this stage and can use it
+ // to check locking or other things
+ onAfterAddChild: function(message) {
+ //dojo.debug("Dnd addChild "+message.child);
+ this.listenNode(message.child);
+ },
+
+
+ onAfterChangeTree: function(message) {
+ /* catch new nodes on afterAddChild, because I need parent */
+ if (!message.oldTree) return;
+
+ //dojo.debug("HERE");
+
+ if (!message.newTree || !this.listenedTrees[message.newTree.widgetId]) {
+ this.processDescendants(message.node, this.listenNodeFilter, this.unlistenNode);
+ }
+
+ if (!this.listenedTrees[message.oldTree.widgetId]) {
+ // we have new node
+ this.processDescendants(message.node, this.listenNodeFilter, this.listenNode);
+ }
+ //dojo.profile.end("onTreeChange");
+ },
+
+
+ /**
+ * 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
+ */
+ listenNode: function(node) {
+
+ //dojo.debug("listen dnd "+node);
+ //dojo.debug((new Error()).stack)
+ //dojo.profile.start("Dnd listenNode "+node);
+ if (!node.tree.DndMode) return;
+ if (this.dragSources[node.widgetId] || this.dropTargets[node.widgetId]) return;
+
+
+ /* I drag label, not domNode, because large domNodes are very slow to copy and large to drag */
+
+ var source = null;
+ var target = null;
+
+
+ if (!node.actionIsDisabled(node.actions.MOVE)) {
+ //dojo.debug("reg source")
+
+ //dojo.profile.start("Dnd source "+node);
+ var source = this.makeDragSource(node);
+ //dojo.profile.end("Dnd source "+node);
+
+ this.dragSources[node.widgetId] = source;
+ }
+
+ //dojo.profile.start("Dnd target "+node);
+ //dojo.debug("reg target");
+ var target = this.makeDropTarget(node);
+ //dojo.profile.end("Dnd target "+node);
+
+ this.dropTargets[node.widgetId] = target;
+
+ //dojo.profile.end("Dnd listenNode "+node);
+
+
+ },
+
+ /**
+ * Factory method, override it to create special source
+ */
+ makeDragSource: function(node) {
+ return new dojo.dnd.TreeDragSourceV3(node.contentNode, this, node.tree.widgetId, node);
+ },
+
+
+ /**
+ * Factory method, override it to create special target
+ */
+ makeDropTarget: function(node) {
+ return new dojo.dnd.TreeDropTargetV3(node.contentNode, this.treeController, node.tree.DndAcceptTypes, node);
+ },
+
+ unlistenNode: function(node) {
+
+ if (this.dragSources[node.widgetId]) {
+ dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]);
+ delete this.dragSources[node.widgetId];
+ }
+
+ if (this.dropTargets[node.widgetId]) {
+ dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]);
+ delete this.dropTargets[node.widgetId];
+ }
+ }
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDndControllerV3.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDocIconExtension.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDocIconExtension.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDocIconExtension.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDocIconExtension.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,117 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeDocIconExtension");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.TreeExtension");
+
+// selector extension to emphase node
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeDocIconExtension",
+ [dojo.widget.TreeExtension],
+{
+ /**
+ * can't unlisten
+ */
+
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/TreeDocIcon.css"),
+
+
+ listenTreeEvents: ["afterChangeTree","afterSetFolder","afterUnsetFolder"],
+
+ listenNodeFilter: function(elem) { return elem instanceof dojo.widget.Widget },
+
+ getNodeType: function(node) {
+ var nodeType = node.getNodeType();
+ if (!nodeType) { // set default type
+ nodeType = node.isFolder ? "Folder" : "Document";
+ }
+ return nodeType;
+ },
+
+ setNodeTypeClass: function(node) {
+
+ var reg = new RegExp("(^|\\s)"+node.tree.classPrefix+"Icon\\w+",'g');
+
+ var clazz = dojo.html.getClass(node.iconNode).replace(reg,'') + ' ' + node.tree.classPrefix+'Icon'+this.getNodeType(node);
+ dojo.html.setClass(node.iconNode, clazz);
+ },
+
+
+ onAfterSetFolder: function(message) {
+ //dojo.debug("FOLDER");
+ if (message.source.iconNode) {
+ // on node-initialize time when folder is set there is no iconNode
+ // this case will be processed in treeChange anyway
+ this.setNodeTypeClass(message.source);
+ }
+ },
+
+
+ onAfterUnsetFolder: function(message) {
+ this.setNodeTypeClass(message.source);
+ },
+
+
+ listenNode: function(node) {
+ /**
+ * add node with document type icon to node template and Tree.iconNodeTemplate
+ * it will be set to TreeNode.iconNode on node creation
+ * we do not assign document type yet, its node specific
+ */
+ //dojo.debug("listenNode in "+node);
+
+ node.contentIconNode = document.createElement("div");
+ var clazz = node.tree.classPrefix+"IconContent";
+ if (dojo.render.html.ie) {
+ clazz = clazz+' '+ node.tree.classPrefix+"IEIconContent";
+ }
+ dojo.html.setClass(node.contentIconNode, clazz);
+
+ node.contentNode.parentNode.replaceChild(node.contentIconNode, node.expandNode);
+
+ node.iconNode = document.createElement("div");
+ dojo.html.setClass(node.iconNode, node.tree.classPrefix+"Icon"+' '+node.tree.classPrefix+'Icon'+this.getNodeType(node));
+
+ node.contentIconNode.appendChild(node.expandNode);
+ node.contentIconNode.appendChild(node.iconNode);
+
+ dojo.dom.removeNode(node.contentNode);
+ node.contentIconNode.appendChild(node.contentNode);
+
+
+
+ //dojo.html.insertAfter(node.iconNode, node.expandNode);
+
+ //dojo.debug("listenNode out "+node);
+
+ },
+
+
+ onAfterChangeTree: function(message) {
+ var _this = this;
+
+ //dojo.debug(message.node)
+
+ if (!message.oldTree || !this.listenedTrees[message.oldTree.widgetId]) {
+ // moving from old tree to our tree
+ this.processDescendants(message.node,
+ this.listenNodeFilter,
+ this.listenNode
+ );
+ }
+
+ }
+
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeDocIconExtension.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEditor.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEditor.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEditor.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEditor.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,115 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.RichText");
+
+dojo.provide("dojo.widget.TreeEditor");
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeEditor",
+ dojo.widget.HtmlWidget,
+{
+
+
+ singleLineMode: false, // enter saves
+ saveOnBlur: true, // blur or new edit saves current
+ sync: false, // finish editing in sync/async mode
+ selectOnOpen: true,
+
+ controller: null,
+
+ node: null,
+
+ richTextParams: {},
+
+
+
+ getContents: function() {
+ return this.richText.getEditorContent();
+ },
+
+ open: function(node) {
+
+ if (!this.richText) {
+ this.richText = dojo.widget.createWidget("RichText", this.richTextParams, node.labelNode);
+
+ dojo.event.connect("around", this.richText, "onKeyDown", this, "richText_onKeyDown" );
+ dojo.event.connect(this.richText, "onBlur", this, "richText_onBlur" );
+
+ var self = this;
+ dojo.event.connect(this.richText, "onLoad", function(){
+ if (self.selectOnOpen) {
+ self.richText.execCommand("selectall");
+ }
+ });
+ } else {
+ this.richText.open(node.labelNode);
+ }
+
+ this.node = node;
+ },
+
+ close: function(save) {
+
+ this.richText.close(save);
+
+
+ this.node = null;
+ },
+
+ isClosed: function() {
+ return !this.richText || this.richText.isClosed;
+ },
+
+ execCommand: function() {
+ this.richText.execCommand.apply(this.richText, arguments);
+ },
+
+ richText_onKeyDown: function(invocation) {
+ var e = invocation.args[0];
+ if((!e)&&(this.object)) {
+ e = dojo.event.browser.fixEvent(this.editor.window.event);
+ }
+
+ switch (e.keyCode) {
+ case e.KEY_ESCAPE:
+ this.finish(false);
+ dojo.event.browser.stopEvent(e);
+ break;
+ case e.KEY_ENTER:
+ if( e.ctrlKey && !this.singleLineMode ) {
+ this.execCommand( "inserthtml", "<br/>" );
+
+ }
+ else {
+ this.finish(true);
+ //dojo.debug("finish");
+ }
+ dojo.event.browser.stopEvent(e);
+ break;
+ default:
+ return invocation.proceed();
+ }
+ },
+
+ richText_onBlur: function() {
+ this.finish(this.saveOnBlur);
+ },
+
+
+ finish: function(save) {
+ return this.controller.editLabelFinish(save, this.sync);
+ }
+
+
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEditor.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEmphaseOnSelect.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEmphaseOnSelect.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEmphaseOnSelect.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEmphaseOnSelect.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,56 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeEmphaseOnSelect");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.TreeSelectorV3");
+dojo.require("dojo.html.selection");
+
+// selector extension to emphase node
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeEmphaseOnSelect",
+ dojo.widget.HtmlWidget,
+ function() {
+ this.saveSelected = {}
+ },
+{
+ selector: "",
+
+ initialize: function() {
+ this.selector = dojo.widget.byId(this.selector);
+
+ dojo.event.topic.subscribe(this.selector.eventNames.select, this, "onSelect");
+ dojo.event.topic.subscribe(this.selector.eventNames.deselect, this, "onDeselect");
+ },
+
+
+ onSelect: function(message) {
+ var domNode = message.node.labelNode;
+
+ dojo.html.clearSelection(domNode);
+
+
+ dojo.html.addClass(domNode, message.node.tree.classPrefix+'NodeEmphased');
+ //dojo.debug("after select "+dojo.html.getClass(message.node.labelNode))
+
+ },
+
+ onDeselect: function(message) {
+ var domNode = message.node.labelNode;
+
+ //dojo.debug(dojo.html.getClass(message.node.labelNode))
+ dojo.html.removeClass(domNode, message.node.tree.classPrefix+'NodeEmphased');
+ }
+
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeEmphaseOnSelect.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeExtension.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeExtension.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeExtension.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeExtension.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,24 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeExtension");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.TreeCommon");
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeExtension",
+ [dojo.widget.HtmlWidget, dojo.widget.TreeCommon],
+ function() {
+ this.listenedTrees = {};
+ },
+ {}
+);
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeExtension.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLinkExtension.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLinkExtension.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLinkExtension.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLinkExtension.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeLinkExtension");
+
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.TreeExtension");
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeLinkExtension",
+ dojo.widget.TreeExtension,
+ function() {
+ this.params = {};
+ },
+{
+ /**
+ * can only listen, no unlisten
+ */
+
+ listenTreeEvents: ["afterChangeTree"],
+
+ listenTree: function(tree) {
+
+ dojo.widget.TreeCommon.prototype.listenTree.call(this,tree);
+
+ var labelNode = tree.labelNodeTemplate;
+ var newLabel = this.makeALabel();
+ dojo.html.setClass(newLabel, dojo.html.getClass(labelNode));
+ labelNode.parentNode.replaceChild(newLabel, labelNode);
+ },
+
+
+
+ makeALabel: function() {
+ var newLabel = document.createElement("a");
+
+ for(var key in this.params) {
+ if (key in {}) continue;
+ newLabel.setAttribute(key, this.params[key]);
+ }
+
+ return newLabel;
+ },
+
+
+ onAfterChangeTree: function(message) {
+ var _this = this;
+
+
+ // only for new nodes
+ if (!message.oldTree) {
+ this.listenNode(message.node);
+ }
+
+ },
+
+ listenNode: function(node) {
+ for(var key in node.object) {
+ if (key in {}) continue;
+ node.labelNode.setAttribute(key, node.object[key]);
+ }
+ }
+
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLinkExtension.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,219 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeLoadingController");
+
+dojo.require("dojo.widget.TreeBasicController");
+dojo.require("dojo.event.*");
+dojo.require("dojo.json")
+dojo.require("dojo.io.*");
+
+dojo.deprecated("dojo.widget.TreeLoadingController", "use TreeV3 and TreeLoadingControllerV3 instead", "0.5");
+
+
+dojo.widget.tags.addParseTreeHandler("dojo:TreeLoadingController");
+
+
+dojo.widget.TreeLoadingController = function() {
+ dojo.widget.TreeBasicController.call(this);
+}
+
+dojo.inherits(dojo.widget.TreeLoadingController, dojo.widget.TreeBasicController);
+
+
+dojo.lang.extend(dojo.widget.TreeLoadingController, {
+ widgetType: "TreeLoadingController",
+
+ RPCUrl: "",
+
+ RPCActionParam: "action", // used for GET for RPCUrl
+
+
+ /**
+ * Common RPC error handler (dies)
+ */
+ RPCErrorHandler: function(type, obj, evt) {
+ alert( "RPC Error: " + (obj.message||"no message"));
+ },
+
+ preventCache: true,
+
+ getRPCUrl: function(action) {
+
+ // RPCUrl=local meant SOLELY for DEMO and LOCAL TESTS.
+ // May lead to widgetId collisions
+ if (this.RPCUrl == "local") {
+ 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 ? "&" : "?") + this.RPCActionParam+"="+action;
+ },
+
+
+ /**
+ * Add all loaded nodes from array obj as node children and expand it
+ */
+ loadProcessResponse: function(node, result, callObj, callFunc) {
+
+ if (!dojo.lang.isUndefined(result.error)) {
+ this.RPCErrorHandler("server", result.error);
+ return false;
+ }
+
+ //dojo.debugShallow(result);
+
+ var newChildren = result;
+
+ if (!dojo.lang.isArray(newChildren)) {
+ dojo.raise('loadProcessResponse: Not array loaded: '+newChildren);
+ }
+
+ for(var i=0; i<newChildren.length; i++) {
+ // looks like dojo.widget.manager needs no special "add" command
+ newChildren[i] = dojo.widget.createWidget(node.widgetType, newChildren[i]);
+ node.addChild(newChildren[i]);
+ }
+
+
+ //node.addAllChildren(newChildren);
+
+ node.state = node.loadStates.LOADED;
+
+ //dojo.debug(callFunc);
+
+ if (dojo.lang.isFunction(callFunc)) {
+ callFunc.apply(dojo.lang.isUndefined(callObj) ? this : callObj, [node, newChildren]);
+ }
+ //this.expand(node);
+ },
+
+ getInfo: function(obj) {
+ return obj.getInfo();
+ },
+
+ runRPC: function(kw) {
+ var _this = this;
+
+ var handle = function(type, data, evt) {
+ // unlock BEFORE any processing is done
+ // so errorHandler may apply locking
+ if (kw.lock) {
+ dojo.lang.forEach(kw.lock,
+ function(t) { t.unlock() }
+ );
+ }
+
+ if(type == "load"){
+ kw.load.call(this, data);
+ }else{
+ this.RPCErrorHandler(type, data, evt);
+ }
+
+ }
+
+ if (kw.lock) {
+ dojo.lang.forEach(kw.lock,
+ function(t) { t.lock() }
+ );
+ }
+
+
+ dojo.io.bind({
+ url: kw.url,
+ /* I hitch to get this.loadOkHandler */
+ handle: dojo.lang.hitch(this, handle),
+ mimetype: "text/json",
+ preventCache: _this.preventCache,
+ sync: kw.sync,
+ content: { data: dojo.json.serialize(kw.params) }
+ });
+ },
+
+
+
+ /**
+ * Load children of the node from server
+ * Synchroneous loading doesn't break control flow
+ * I need sync mode for DnD
+ */
+ loadRemote: function(node, sync, callObj, callFunc){
+ var _this = this;
+
+ var params = {
+ node: this.getInfo(node),
+ tree: this.getInfo(node.tree)
+ };
+
+ //dojo.debug(callFunc)
+
+ this.runRPC({
+ url: this.getRPCUrl('getChildren'),
+ load: function(result) {
+ _this.loadProcessResponse(node, result, callObj, callFunc) ;
+ },
+ sync: sync,
+ lock: [node],
+ params: params
+ });
+
+ },
+
+
+ expand: function(node, sync, callObj, callFunc) {
+
+ if (node.state == node.loadStates.UNCHECKED && node.isFolder) {
+
+ this.loadRemote(node, sync,
+ this,
+ function(node, newChildren) {
+ this.expand(node, sync, callObj, callFunc);
+ }
+ );
+
+ return;
+ }
+
+ dojo.widget.TreeBasicController.prototype.expand.apply(this, arguments);
+
+ },
+
+
+
+ doMove: function(child, newParent, index) {
+ /* load nodes into newParent in sync mode, if needed, first */
+ if (newParent.isTreeNode && newParent.state == newParent.loadStates.UNCHECKED) {
+ this.loadRemote(newParent, true);
+ }
+
+ return dojo.widget.TreeBasicController.prototype.doMove.apply(this, arguments);
+ },
+
+
+ doCreateChild: function(parent, index, data, callObj, callFunc) {
+
+ /* load nodes into newParent in sync mode, if needed, first */
+ if (parent.state == parent.loadStates.UNCHECKED) {
+ this.loadRemote(parent, true);
+ }
+
+ return dojo.widget.TreeBasicController.prototype.doCreateChild.apply(this, arguments);
+ }
+
+
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingController.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingControllerV3.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingControllerV3.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingControllerV3.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingControllerV3.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,462 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+dojo.provide("dojo.widget.TreeLoadingControllerV3");
+
+dojo.require("dojo.widget.TreeBasicControllerV3");
+dojo.require("dojo.event.*");
+dojo.require("dojo.json")
+dojo.require("dojo.io.*");
+dojo.require("dojo.Deferred");
+dojo.require("dojo.DeferredList");
+
+dojo.declare(
+ "dojo.Error",
+ Error,
+ function(message, extra) {
+ this.message = message;
+ this.extra = extra;
+ this.stack = (new Error()).stack;
+ }
+);
+
+dojo.declare(
+ "dojo.CommunicationError",
+ dojo.Error,
+ function() {
+ this.name="CommunicationError";
+ }
+);
+
+dojo.declare(
+ "dojo.LockedError",
+ dojo.Error,
+ function() {
+ this.name="LockedError";
+ }
+);
+
+dojo.declare(
+ "dojo.FormatError",
+ dojo.Error,
+ function() {
+ this.name="FormatError";
+ }
+);
+
+dojo.declare(
+ "dojo.RpcError",
+ dojo.Error,
+ function() {
+ this.name="RpcError";
+ }
+);
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeLoadingControllerV3",
+ dojo.widget.TreeBasicControllerV3,
+{
+ RpcUrl: "",
+
+ RpcActionParam: "action", // used for GET for RpcUrl
+
+ preventCache: true,
+
+ checkValidRpcResponse: function(type, obj) {
+ if (type != "load") {
+ var extra = {}
+ for(var i=1; i<arguments.length;i++) {
+ dojo.lang.mixin(extra, arguments[i]);
+ }
+ return new dojo.CommunicationError(obj, extra);
+ }
+
+ if (typeof obj != 'object') {
+ return new dojo.FormatError("Wrong server answer format "+(obj && obj.toSource ? obj.toSource() : obj)+" type "+(typeof obj), obj);
+ }
+
+ //dojo.debugShallow(obj);
+
+ if (!dojo.lang.isUndefined(obj.error)) {
+ return new dojo.RpcError(obj.error, obj);
+ }
+
+ return false;
+ },
+
+
+ getDeferredBindHandler: function(/* dojo.rpc.Deferred */ deferred){
+ // summary
+ // create callback that calls the Deferred's callback method
+
+ return dojo.lang.hitch(this,
+ function(type, obj){
+ //dojo.debug("getDeferredBindHandler "+obj.toSource());
+
+ var error = this.checkValidRpcResponse.apply(this, arguments);
+
+ if (error) {
+ deferred.errback(error);
+ return;
+ }
+
+ deferred.callback(obj);
+ }
+ );
+
+ },
+
+ getRpcUrl: function(action) {
+
+ // RpcUrl=local meant SOLELY for DEMO and LOCAL TESTS
+ if (this.RpcUrl == "local") {
+ var dir = document.location.href.substr(0, document.location.href.lastIndexOf('/'));
+ var localUrl = dir+"/local/"+action;
+ //dojo.debug(localUrl);
+ return localUrl;
+ }
+
+ if (!this.RpcUrl) {
+ dojo.raise("Empty RpcUrl: can't load");
+ }
+
+ var url = this.RpcUrl;
+
+ if (url.indexOf("/") != 0) { // not absolute
+ var protocol = document.location.href.replace(/:\/\/.*/,'');
+ var prefix = document.location.href.substring(protocol.length+3);
+
+ if (prefix.lastIndexOf("/") != prefix.length-1) {
+ prefix = prefix.replace(/\/[^\/]+$/,'/'); // strip file name
+ }
+ if (prefix.lastIndexOf("/") != prefix.length-1) {
+ prefix = prefix+'/'; // add / if not exists it all
+ }
+ //dojo.debug(url);
+ url = protocol + '://' + prefix + url;
+ }
+
+
+ return url + (url.indexOf("?")>-1 ? "&" : "?") + this.RpcActionParam+"="+action;
+ },
+
+
+ /**
+ * Add all loaded nodes from array obj as node children and expand it
+ */
+ loadProcessResponse: function(node, result) {
+ //dojo.debug("Process response "+node);
+
+ if (!dojo.lang.isArray(result)) {
+ throw new dojo.FormatError('loadProcessResponse: Not array loaded: '+result);
+ }
+
+ node.setChildren(result);
+
+ },
+
+ /**
+ * kw = { url, sync, params }
+ */
+ runRpc: function(kw) {
+ var _this = this;
+
+ var deferred = new dojo.Deferred();
+
+ dojo.io.bind({
+ url: kw.url,
+ handle: this.getDeferredBindHandler(deferred),
+ mimetype: "text/javascript",
+ preventCache: this.preventCache,
+ sync: kw.sync,
+ content: { data: dojo.json.serialize(kw.params) }
+ });
+
+ return deferred;
+
+ },
+
+
+
+ /**
+ * Load children of the node from server
+ * Synchroneous loading doesn't break control flow
+ * I need sync mode for DnD
+ */
+ loadRemote: function(node, sync){
+ var _this = this;
+
+ var params = {
+ node: this.getInfo(node),
+ tree: this.getInfo(node.tree)
+ };
+
+
+ var deferred = this.runRpc({
+ url: this.getRpcUrl('getChildren'),
+ sync: sync,
+ params: params
+ });
+
+ deferred.addCallback(function(res) { return _this.loadProcessResponse(node,res) });
+
+
+
+ return deferred;
+
+ },
+
+ batchExpandTimeout: 0,
+
+ recurseToLevel: function(widget, level, callFunc, callObj, skipFirst, sync) {
+ if (level == 0) return;
+
+
+
+ if (!skipFirst) {
+ var deferred = callFunc.call(callObj, widget, sync);
+ } else {
+ var deferred = dojo.Deferred.prototype.makeCalled();
+ }
+
+ //dojo.debug("expand deferred saved "+node+" sync "+sync);
+
+
+ var _this = this;
+
+ var recurseOnExpand = function() {
+ var children = widget.children;
+ var deferreds = [];
+ for(var i=0; i<children.length; i++) {
+ //dojo.debug("push recursive call for "+node.children[i]+" level "+level);
+ deferreds.push(_this.recurseToLevel(children[i], level-1, callFunc, callObj, sync));
+ }
+ return new dojo.DeferredList(deferreds);
+ }
+
+ deferred.addCallback(recurseOnExpand);
+
+ return deferred;
+ },
+
+ expandToLevel: function(nodeOrTree, level, sync) {
+ return this.recurseToLevel(nodeOrTree, nodeOrTree.isTree ? level+1 : level, this.expand, this, nodeOrTree.isTree, sync);
+ },
+
+ loadToLevel: function(nodeOrTree, level, sync) {
+ return this.recurseToLevel(nodeOrTree, nodeOrTree.isTree ? level+1 : level, this.loadIfNeeded, this, nodeOrTree.isTree, sync);
+ },
+
+
+ loadAll: function(nodeOrTree, sync) {
+ return this.loadToLevel(nodeOrTree, Number.POSITIVE_INFINITY, sync);
+ },
+
+
+
+ expand: function(node, sync) {
+ // widget which children are data objects, is UNCHECKED, but has children and shouldn't be loaded
+ // so I put children check here too
+
+ var _this = this;
+
+ var deferred = this.startProcessing(node);
+
+ deferred.addCallback(function() {
+ return _this.loadIfNeeded(node, sync);
+ });
+
+ deferred.addCallback(function(res) {
+ //dojo.debug("Activated callback dojo.widget.TreeBasicControllerV3.prototype.expand(node); "+res);
+ dojo.widget.TreeBasicControllerV3.prototype.expand(node);
+ return res;
+ });
+
+ deferred.addBoth(function(res) {
+ _this.finishProcessing(node);
+ return res;
+ });
+
+
+
+ return deferred;
+ },
+
+
+ loadIfNeeded: function(node, sync) {
+ var deferred
+ if (node.state == node.loadStates.UNCHECKED && node.isFolder && !node.children.length) {
+ // populate deferred with other things to pre-do
+ deferred = this.loadRemote(node, sync);
+ } else {
+ /* "fake action" here */
+ deferred = new dojo.Deferred();
+ deferred.callback();
+ }
+
+ return deferred;
+ },
+
+ /**
+ * 1) if specified, run check, return false if failed
+ * 2) if specified, run prepare
+ * 3) run make if prepare if no errors
+ * 4) run finalize no matter what happened, pass through make result
+ * 5) if specified, run expose if no errors
+ */
+ runStages: function(check, prepare, make, finalize, expose, args) {
+ var _this = this;
+
+ if (check && !check.apply(this, args)) {
+ return false;
+ }
+
+ var deferred = dojo.Deferred.prototype.makeCalled();
+
+
+ if (prepare) {
+ deferred.addCallback(function() {
+ return prepare.apply(_this, args);
+ });
+ }
+
+
+ //deferred.addCallback(function(res) { dojo.debug("Prepare fired "+res); return res});
+
+ var _this = this;
+ deferred.addCallback(function() {
+ var res = make.apply(_this, args);
+ //res.addBoth(function(r) {dojo.debugShallow(r); return r;});
+ return res;
+ });
+
+ //deferred.addCallback(function(res) { dojo.debug("Main fired "+res); return res});
+
+ if (finalize) {
+ deferred.addBoth(function(res) {
+ finalize.apply(_this, args);
+ return res;
+ });
+ }
+
+
+ // exposer does not affect result
+ if (expose) {
+ deferred.addCallback(function(res) {
+ expose.apply(_this, args);
+ return res;
+ });
+ }
+
+ return deferred;
+ },
+
+ startProcessing: function(nodesArray) {
+ var deferred = new dojo.Deferred();
+
+
+ var nodes = dojo.lang.isArray(nodesArray) ? nodesArray : arguments;
+
+ /*
+ for(var i=0;i<nodes.length;i++) {
+ dojo.debug(nodes[i]);
+ }*/
+
+ for(var i=0;i<nodes.length;i++) {
+ if (nodes[i].isLocked()) {
+ deferred.errback(new dojo.LockedError("item locked "+nodes[i], nodes[i]));
+ //dojo.debug("startProcessing errback "+arguments[i]);
+ return deferred;
+ }
+ if (nodes[i].isTreeNode) {
+ //dojo.debug("mark "+nodes[i]);
+ nodes[i].markProcessing();
+ }
+ nodes[i].lock();
+ }
+
+ //dojo.debug("startProcessing callback");
+
+ deferred.callback();
+
+ return deferred;
+ },
+
+ finishProcessing: function(nodesArray) {
+
+ var nodes = dojo.lang.isArray(nodesArray) ? nodesArray : arguments;
+
+ for(var i=0;i<nodes.length;i++) {
+ if (!nodes[i].hasLock()) {
+ // is not processed. probably we locked it and then met bad node in startProcessing
+ continue;
+ }
+ //dojo.debug("has lock");
+ nodes[i].unlock();
+ if (nodes[i].isTreeNode) {
+ nodes[i].unmarkProcessing();
+ }
+ }
+ },
+
+ refresh: function(nodeOrTree, sync) {
+ nodeOrTree.destroyChildren();
+
+ nodeOrTree.state == nodeOrTree.loadStates.UNCHECKED;
+
+
+ return this.loadRemote(nodeOrTree, sync);
+ },
+
+ // ----------------- move -----------------
+
+ prepareMove: function(child, newParent, index, sync) {
+ var deferred = this.startProcessing(newParent);
+ deferred.addCallback(dojo.lang.hitch(this, function() {
+ return this.loadIfNeeded(newParent, sync);
+ }));
+ return deferred;
+ },
+
+ finalizeMove: function(child, newParent) {
+ this.finishProcessing(newParent);
+ },
+
+ // -------------------- createChild ------------
+
+ prepareCreateChild: function(parent, index, data, sync) {
+ var deferred = this.startProcessing(parent);
+
+ deferred.addCallback(dojo.lang.hitch(this, function() {
+ return this.loadIfNeeded(parent, sync);
+ }));
+ return deferred;
+ },
+
+ finalizeCreateChild: function(parent) {
+ this.finishProcessing(parent);
+ },
+
+ // ---------------- clone ---------------
+
+ prepareClone: function(child, newParent, index, deep, sync) {
+ var deferred = this.startProcessing(child, newParent);
+ deferred.addCallback(dojo.lang.hitch(this, function() {
+ return this.loadIfNeeded(newParent, sync);
+ }));
+ return deferred;
+ },
+
+ finalizeClone: function(child, newParent) {
+ this.finishProcessing(child, newParent);
+ }
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeLoadingControllerV3.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,534 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.TreeNode");
+
+dojo.require("dojo.html.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+
+// make it a tag
+dojo.widget.tags.addParseTreeHandler("dojo:TreeNode");
+
+
+// # //////////
+
+dojo.widget.TreeNode = function() {
+ dojo.widget.HtmlWidget.call(this);
+
+ this.actionsDisabled = [];
+}
+
+dojo.inherits(dojo.widget.TreeNode, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.TreeNode, {
+ widgetType: "TreeNode",
+
+ loadStates: {
+ UNCHECKED: "UNCHECKED",
+ LOADING: "LOADING",
+ LOADED: "LOADED"
+ },
+
+
+ actions: {
+ MOVE: "MOVE",
+ REMOVE: "REMOVE",
+ EDIT: "EDIT",
+ ADDCHILD: "ADDCHILD"
+ },
+
+ isContainer: true,
+
+ lockLevel: 0, // lock ++ unlock --, so nested locking works fine
+
+
+ templateString: ('<div class="dojoTreeNode"> '
+ + '<span treeNode="${this.widgetId}" class="dojoTreeNodeLabel" dojoAttachPoint="labelNode"> '
+ + ' <span dojoAttachPoint="titleNode" dojoAttachEvent="onClick: onTitleClick" class="dojoTreeNodeLabelTitle">${this.title}</span> '
+ + '</span> '
+ + '<span class="dojoTreeNodeAfterLabel" dojoAttachPoint="afterLabelNode">${this.afterLabel}</span> '
+ + '<div dojoAttachPoint="containerNode" style="display:none"></div> '
+ + '</div>').replace(/(>|<)\s+/g, '$1'), // strip whitespaces between nodes
+
+
+ childIconSrc: "",
+ childIconFolderSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/closed.gif"), // for under root parent item child icon,
+ childIconDocumentSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/document.gif"), // for under root parent item child icon,
+
+ childIcon: null,
+ isTreeNode: true,
+
+ objectId: "", // the widget represents an object
+
+ afterLabel: "",
+ afterLabelNode: null, // node to the left of labelNode
+
+ // an icon left from childIcon: imgs[-2].
+ // if +/- for folders, blank for leaves
+ expandIcon: null,
+
+ title: "",
+ object: "", // node may have object attached, settable from HTML
+ isFolder: false,
+
+ labelNode: null, // the item label
+ titleNode: null, // the item title
+ imgs: null, // an array of icons imgs
+
+ expandLevel: "", // expand to level
+
+ tree: null,
+
+ depth: 0,
+
+ isExpanded: false,
+
+ state: null, // after creation will change to loadStates: "loaded/loading/unchecked"
+ domNodeInitialized: false, // domnode is initialized with icons etc
+
+
+ isFirstChild: function() {
+ return this.getParentIndex() == 0 ? true: false;
+ },
+
+ isLastChild: function() {
+ return this.getParentIndex() == this.parent.children.length-1 ? true : false;
+ },
+
+ lock: function(){ return this.tree.lock.apply(this, arguments) },
+ unlock: function(){ return this.tree.unlock.apply(this, arguments) },
+ isLocked: function(){ return this.tree.isLocked.apply(this, arguments) },
+ cleanLock: function(){ return this.tree.cleanLock.apply(this, arguments) },
+
+ actionIsDisabled: function(action) {
+ var _this = this;
+
+ var disabled = false;
+
+ if (this.tree.strictFolders && action == this.actions.ADDCHILD && !this.isFolder) {
+ disabled = true;
+ }
+
+ if (dojo.lang.inArray(_this.actionsDisabled, action)) {
+ disabled = true;
+ }
+
+ if (this.isLocked()) {
+ disabled = true;
+ }
+
+ return disabled;
+ },
+
+ getInfo: function() {
+ // No title here (title may be widget)
+ var info = {
+ widgetId: this.widgetId,
+ objectId: this.objectId,
+ index: this.getParentIndex(),
+ isFolder: this.isFolder
+ }
+
+ return info;
+ },
+
+ initialize: function(args, frag){
+
+ //dojo.debug(this.title)
+
+ this.state = this.loadStates.UNCHECKED;
+
+ for(var i=0; i<this.actionsDisabled.length; i++) {
+ this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
+ }
+
+ this.expandLevel = parseInt(this.expandLevel);
+
+ },
+
+
+ /**
+ * 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);
+ dojo.html.insertBefore(this.imgs[0], this.domNode.firstChild);
+
+ }
+ }
+ if (depthDiff<0) {
+ for(var i=0; i<-depthDiff;i++) {
+ this.imgs.shift();
+ dojo.html.removeNode(this.domNode.firstChild);
+ }
+ }
+
+ },
+
+
+ markLoading: function() {
+ this._markLoadingSavedIcon = this.expandIcon.src;
+ this.expandIcon.src = this.tree.expandIconSrcLoading;
+ },
+
+ // if icon is "Loading" then
+ unMarkLoading: function() {
+ if (!this._markLoadingSavedIcon) return;
+
+ var im = new Image();
+ im.src = this.tree.expandIconSrcLoading;
+
+ //dojo.debug("Unmark "+this.expandIcon.src+" : "+im.src);
+ if (this.expandIcon.src == im.src) {
+ this.expandIcon.src = this._markLoadingSavedIcon;
+ }
+ this._markLoadingSavedIcon = null;
+ },
+
+
+ setFolder: function() {
+ dojo.event.connect(this.expandIcon, 'onclick', this, 'onTreeClick');
+ this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
+ this.isFolder = true;
+ },
+
+
+ createDOMNode: function(tree, depth){
+
+ this.tree = tree;
+ this.depth = depth;
+
+
+ //
+ // 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.labelNode);
+
+ this.imgs.push(img);
+ }
+
+
+ this.expandIcon = this.imgs[this.imgs.length-1];
+
+
+ this.childIcon = this.tree.makeBlankImg();
+
+ // add to images before the title
+ this.imgs.push(this.childIcon);
+
+ dojo.html.insertBefore(this.childIcon, this.titleNode);
+
+ // node with children(from source html) becomes folder on build stage.
+ if (this.children.length || this.isFolder) {
+ this.setFolder();
+ }
+ else {
+ // leaves are always loaded
+ //dojo.debug("Set "+this+" state to loaded");
+ this.state = this.loadStates.LOADED;
+ }
+
+ dojo.event.connect(this.childIcon, 'onclick', this, 'onIconClick');
+
+
+ //
+ // create the child rows
+ //
+
+
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].parent = this;
+
+ var node = this.children[i].createDOMNode(this.tree, this.depth+1);
+
+ this.containerNode.appendChild(node);
+ }
+
+
+ if (this.children.length) {
+ this.state = this.loadStates.LOADED;
+ }
+
+ this.updateIcons();
+
+ this.domNodeInitialized = true;
+
+ dojo.event.topic.publish(this.tree.eventNames.createDOMNode, { 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');
+ },
+
+ updateExpandIcon: function() {
+ if (this.isFolder){
+ this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
+ } else {
+ this.expandIcon.src = this.tree.blankIconSrc;
+ }
+ },
+
+ /* set the grid under the expand icon */
+ updateExpandGrid: function() {
+
+ if (this.tree.showGrid){
+ if (this.depth){
+ this.setGridImage(-2, this.isLastChild() ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
+ }else{
+ if (this.isFirstChild()){
+ this.setGridImage(-2, this.isLastChild() ? this.tree.gridIconSrcX : this.tree.gridIconSrcY);
+ }else{
+ this.setGridImage(-2, this.isLastChild() ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
+ }
+ }
+ }else{
+ this.setGridImage(-2, this.tree.blankIconSrc);
+ }
+
+ },
+
+ /* set the grid under the child icon */
+ updateChildGrid: function() {
+
+ 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);
+ }
+ }
+
+
+ },
+
+ updateParentGrid: function() {
+ var parent = this.parent;
+
+ //dojo.debug("updateParentGrid "+this);
+
+ for(var i=0; i<this.depth; i++){
+
+ //dojo.debug("Parent "+parent);
+
+ var idx = this.imgs.length-(3+i);
+ var img = (this.tree.showGrid && !parent.isLastChild()) ? this.tree.gridIconSrcV : this.tree.blankIconSrc;
+
+ //dojo.debug("Image "+img+" for "+idx);
+
+ this.setGridImage(idx, img);
+
+ parent = parent.parent;
+ }
+ },
+
+ updateExpandGridColumn: function() {
+ if (!this.tree.showGrid) return;
+
+ var _this = this;
+
+ var icon = this.isLastChild() ? this.tree.blankIconSrc : this.tree.gridIconSrcV;
+
+ dojo.lang.forEach(_this.getDescendants(),
+ function(node) { node.setGridImage(_this.depth, icon); }
+ );
+
+ this.updateExpandGrid();
+ },
+
+ updateIcons: function(){
+
+
+ //dojo.profile.start("updateIcons")
+
+ //dojo.debug("Update icons for "+this)
+ //dojo.debug(this.isFolder)
+
+ this.imgs[0].style.display = this.tree.showRootGrid ? 'inline' : 'none';
+
+
+ //
+ // set the expand icon
+ //
+
+
+ //
+ // set the child icon
+ //
+ this.buildChildIcon();
+
+ this.updateExpandGrid();
+ this.updateChildGrid();
+ this.updateParentGrid();
+
+
+
+ dojo.profile.stop("updateIcons")
+
+ },
+
+ buildChildIcon: function() {
+ // IE (others?) tries to download whatever is on src attribute so setting "url()" like before isnt a good idea
+ // Only results in a 404
+ if(this.childIconSrc){
+ this.childIcon.src = this.childIconSrc;
+ }
+ this.childIcon.style.display = this.childIconSrc ? 'inline' : 'none';
+ },
+
+ 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.isExpanded) return;
+
+ if (this.children.length) {
+ this.showChildren();
+ }
+
+ this.isExpanded = true;
+
+ this.updateExpandIcon();
+
+ dojo.event.topic.publish(this.tree.eventNames.expand, {source: this} );
+ },
+
+ collapse: function(){
+ if (!this.isExpanded) return;
+
+ this.hideChildren();
+ this.isExpanded = false;
+
+ this.updateExpandIcon();
+
+ dojo.event.topic.publish(this.tree.eventNames.collapse, {source: this} );
+ },
+
+ hideChildren: function(){
+ this.tree.toggleObj.hide(
+ this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onHide")
+ );
+
+ /* if dnd is in action, recalculate changed coordinates */
+ if(dojo.exists(dojo, 'dnd.dragManager.dragObjects') && dojo.dnd.dragManager.dragObjects.length) {
+ dojo.dnd.dragManager.cacheTargetLocations();
+ }
+ },
+
+ showChildren: function(){
+ this.tree.toggleObj.show(
+ this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onShow")
+ );
+
+ /* if dnd is in action, recalculate changed coordinates */
+ if(dojo.exists(dojo, 'dnd.dragManager.dragObjects') && dojo.dnd.dragManager.dragObjects.length) {
+ dojo.dnd.dragManager.cacheTargetLocations();
+ }
+ },
+
+ addChild: function(){
+ return this.tree.addChild.apply(this, arguments);
+ },
+
+ doAddChild: function(){
+ return this.tree.doAddChild.apply(this, arguments);
+ },
+
+
+
+ /* Edit current node : change properties and update contents */
+ edit: function(props) {
+ dojo.lang.mixin(this, props);
+ if (props.title) {
+ this.titleNode.innerHTML = this.title;
+ }
+
+ if (props.afterLabel) {
+ this.afterLabelNode.innerHTML = this.afterLabel;
+ }
+
+ if (props.childIconSrc) {
+ this.buildChildIcon();
+ }
+
+
+ },
+
+
+ removeNode: function(){ return this.tree.removeNode.apply(this, arguments) },
+ doRemoveNode: function(){ return this.tree.doRemoveNode.apply(this, arguments) },
+
+
+ toString: function() {
+ return "["+this.widgetType+" Tree:"+this.tree+" ID:"+this.widgetId+" Title:"+this.title+"]";
+
+ }
+
+});
+
+
+
+
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNode.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNodeV3.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNodeV3.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNodeV3.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNodeV3.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,726 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.TreeNodeV3");
+
+dojo.require("dojo.html.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.TreeWithNode");
+
+dojo.widget.defineWidget(
+ "dojo.widget.TreeNodeV3",
+ [dojo.widget.HtmlWidget, dojo.widget.TreeWithNode],
+ function() {
+ this.actionsDisabled = [];
+ },
+{
+ tryLazyInit: true,
+
+ /*
+ * Basic actions one can perform on nodes and, some(addchild) on trees
+ */
+ actions: {
+ MOVE: "MOVE",
+ DETACH: "DETACH",
+ EDIT: "EDIT",
+ ADDCHILD: "ADDCHILD",
+ SELECT: "SELECT"
+ },
+
+
+ labelClass: "",
+ contentClass: "",
+
+ expandNode: null,
+ labelNode: null,
+
+
+ nodeType: "",
+ selected: false,
+
+ getNodeType: function() {
+ return this.nodeType;
+ },
+
+ cloneProperties: ["actionsDisabled","tryLazyInit","nodeType","objectId","object",
+ "title","isFolder","isExpanded","state"],
+
+
+ /**
+ * copy cloneProperties with recursion into them
+ * contains "copy constructor"
+ */
+ clone: function(deep) {
+ var ret = new this.constructor();
+
+ //dojo.debug("start cloning props "+this);
+
+ for(var i=0; i<this.cloneProperties.length; i++) {
+ var prop = this.cloneProperties[i];
+ //dojo.debug("cloning "+prop+ ":" +this[prop]);
+ ret[prop] = dojo.lang.shallowCopy(this[prop], true);
+ }
+
+ if (this.tree.unsetFolderOnEmpty && !deep && this.isFolder) {
+ ret.isFolder = false;
+ }
+
+ //dojo.debug("cloned props "+this);
+
+ ret.toggleObj = this.toggleObj;
+
+ dojo.widget.manager.add(ret);
+
+ ret.tree = this.tree;
+ ret.buildRendering({},{});
+ ret.initialize({},{});
+
+ if (deep && this.children.length) {
+ //dojo.debug("deeper copy start");
+ for(var i=0; i<this.children.length; i++) {
+ var child = this.children[i];
+ //dojo.debug("copy child "+child);
+ if (child.clone) {
+ ret.children.push(child.clone(deep));
+ } else {
+ ret.children.push(dojo.lang.shallowCopy(child, deep));
+ }
+ }
+ //dojo.debug("deeper copy end");
+ ret.setChildren();
+ }
+
+
+
+ return ret;
+ },
+
+
+ markProcessing: function() {
+ this.markProcessingSavedClass = dojo.html.getClass(this.expandNode);
+ dojo.html.setClass(this.expandNode, this.tree.classPrefix+'ExpandLoading');
+ },
+
+ unmarkProcessing: function() {
+ dojo.html.setClass(this.expandNode, this.markProcessingSavedClass);
+ },
+
+
+
+
+ /**
+ * get information from args & parent, then build rendering
+ */
+ buildRendering: function(args, fragment, parent) {
+ //dojo.debug("Build for "+args.toSource());
+
+ if (args.tree) {
+ this.tree = dojo.lang.isString(args.tree) ? dojo.widget.manager.getWidgetById(args.tree) : args.tree;
+ } else if (parent && parent.tree) {
+ this.tree = parent.tree;
+ }
+
+ if (!this.tree) {
+ dojo.raise("Can't evaluate tree from arguments or parent");
+ }
+
+
+ //dojo.profile.start("buildRendering - cloneNode");
+
+ this.domNode = this.tree.nodeTemplate.cloneNode(true);
+ this.expandNode = this.domNode.firstChild;
+ this.contentNode = this.domNode.childNodes[1];
+ this.labelNode = this.contentNode.firstChild;
+
+ if (this.labelClass) {
+ dojo.html.addClass(this.labelNode, this.labelClass);
+ }
+
+ if (this.contentClass) {
+ dojo.html.addClass(this.contentNode, this.contentClass);
+ }
+
+
+ //dojo.profile.end("buildRendering - cloneNode");
+
+
+ this.domNode.widgetId = this.widgetId;
+
+ //dojo.profile.start("buildRendering - innerHTML");
+ this.labelNode.innerHTML = this.title;
+ //dojo.profile.end("buildRendering - innerHTML");
+
+ },
+
+
+ isTreeNode: true,
+
+
+ object: {},
+
+ title: "",
+
+ isFolder: null, // set by widget depending on children/args
+
+ contentNode: null, // the item label
+
+ expandClass: "",
+
+
+ isExpanded: false,
+
+
+ containerNode: null,
+
+
+ getInfo: function() {
+ // No title here (title may be widget)
+ var info = {
+ widgetId: this.widgetId,
+ objectId: this.objectId,
+ index: this.getParentIndex()
+ }
+
+ return info;
+ },
+
+ setFolder: function() {
+ //dojo.debug("SetFolder in "+this);
+ this.isFolder = true;
+ this.viewSetExpand();
+ if (!this.containerNode) { // maybe this node was unfolderized and still has container
+ this.viewAddContainer(); // all folders have container.
+ }
+ //dojo.debug("publish "+this.tree.eventNames.setFolder);
+ dojo.event.topic.publish(this.tree.eventNames.afterSetFolder, { source: this });
+ },
+
+
+
+ initialize: function(args, frag, parent) {
+
+ //dojo.profile.start("initialize");
+
+ /**
+ * first we populate current widget from args,
+ * then use its data to initialize
+ * args may be empty, all data inside widget for copy constructor
+ */
+ if (args.isFolder) {
+ this.isFolder = true;
+ }
+
+ if (this.children.length || this.isFolder) {
+ //dojo.debug("children found");
+ //dojo.debug(this.children);
+ //dojo.debug("isFolder "+args.isFolder);
+
+ // viewSetExpand for Folder is set here also
+ this.setFolder();
+ } else {
+ // set expandicon for leaf
+ this.viewSetExpand();
+ }
+
+ for(var i=0; i<this.actionsDisabled.length;i++) {
+ this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
+ }
+ //dojo.debug("publish "+this.tree.eventNames.changeTree);
+
+ dojo.event.topic.publish(this.tree.eventNames.afterChangeTree, {oldTree:null, newTree:this.tree, node:this} );
+
+
+ //dojo.profile.end("initialize");
+
+ //dojo.debug("initialize out "+this);
+ //dojo.debug(this+" parent "+parent);
+ },
+
+ unsetFolder: function() {
+ this.isFolder = false;
+ this.viewSetExpand();
+ dojo.event.topic.publish(this.tree.eventNames.afterUnsetFolder, { source: this });
+ },
+
+
+ insertNode: function(parent, index) {
+
+ if (!index) index = 0;
+ //dojo.debug("insertNode "+this+" parent "+parent+" before "+index);
+
+ if (index==0) {
+ dojo.html.prependChild(this.domNode, parent.containerNode);
+ } else {
+ dojo.html.insertAfter(this.domNode, parent.children[index-1].domNode);
+ }
+ },
+
+ updateTree: function(newTree) {
+
+ if (this.tree === newTree) {
+ return;
+ }
+
+ var oldTree = this.tree;
+
+
+ dojo.lang.forEach(this.getDescendants(),
+ function(elem) {
+ elem.tree = newTree;
+ });
+
+ /**
+ * UNTESTED
+ * changes class prefix for all domnodes when moving between trees
+ */
+ if (oldTree.classPrefix != newTree.classPrefix) {
+ var stack = [this.domNode]
+ var elem;
+ var reg = new RegExp("(^|\\s)"+oldTree.classPrefix, "g");
+
+ while (elem = stack.pop()) {
+ for(var i=0; i<elem.childNodes.length; i++) {
+ var childNode = elem.childNodes[i]
+ if (childNode.nodeType != 1) continue;
+ // change prefix for classes
+ dojo.html.setClass(childNode, dojo.html.getClass(childNode).replace(reg, '$1'+newTree.classPrefix));
+ stack.push(childNode);
+ }
+ }
+
+ }
+
+ var message = {oldTree:oldTree, newTree:newTree, node:this}
+
+ dojo.event.topic.publish(this.tree.eventNames.afterChangeTree, message );
+ dojo.event.topic.publish(newTree.eventNames.afterChangeTree, message );
+
+
+ },
+
+
+ /**
+ * called every time the widget is added with createWidget or created wia markup
+ * from addChild -> registerChild or from postInitialize->registerChild
+ * not called in batch procession
+ * HTML & widget.createWidget only
+ * Layout MUST be removed when node is detached
+ *
+ */
+ addedTo: function(parent, index, dontPublishEvent) {
+ //dojo.profile.start("addedTo");
+ //dojo.debug(this + " addedTo "+parent+" index "+index);
+ //dojo.debug(parent.children);
+ //dojo.debug(parent.containerNode.innerHTML);
+
+ //dojo.debug((new Error()).stack);
+
+
+ if (this.tree !== parent.tree) {
+ this.updateTree(parent.tree);
+ }
+
+ if (parent.isTreeNode) {
+ if (!parent.isFolder) {
+ //dojo.debug("folderize parent "+parent);
+ parent.setFolder();
+ parent.state = parent.loadStates.LOADED;
+ }
+ }
+
+
+ var siblingsCount = parent.children.length;
+
+ // setFolder works BEFORE insertNode
+ this.insertNode(parent, index);
+
+
+ this.viewAddLayout();
+
+
+ //dojo.debug("siblings "+parent.children);
+
+ if (siblingsCount > 1) {
+ if (index == 0 && parent.children[1] instanceof dojo.widget.Widget) {
+ parent.children[1].viewUpdateLayout();
+ }
+ if (index == siblingsCount-1 && parent.children[siblingsCount-2] instanceof dojo.widget.Widget) {
+ parent.children[siblingsCount-2].viewUpdateLayout();
+ }
+ } else if (parent.isTreeNode) {
+ // added as the first child
+ //dojo.debug("added as first");
+ parent.viewSetHasChildren();
+ }
+
+ if (!dontPublishEvent) {
+
+ var message = {
+ child: this,
+ index: index,
+ parent: parent
+ }
+
+ dojo.event.topic.publish(this.tree.eventNames.afterAddChild, message);
+ }
+
+ //dojo.profile.end("addedTo");
+
+
+ },
+
+ /**
+ * Fast program-only hacky creation of widget
+ *
+ */
+ createSimple: function(args, parent) {
+ // I pass no args and ignore default controller
+ //dojo.profile.start(this.widgetType+" createSimple");
+ //dojo.profile.start(this.widgetType+" createSimple constructor");
+ if (args.tree) {
+ var tree = args.tree;
+ } else if (parent) {
+ var tree = parent.tree;
+ } else {
+ dojo.raise("createSimple: can't evaluate tree");
+ }
+ tree = dojo.widget.byId(tree);
+
+ //dojo.debug(tree);
+
+ var treeNode = new tree.defaultChildWidget();
+ //dojo.profile.end(this.widgetType+" createSimple constructor");
+
+ //dojo.profile.start(this.widgetType+" createSimple mixin");
+ for(var x in args){ // fastMixIn
+ treeNode[x] = args[x];
+ }
+
+
+ //dojo.profile.end(this.widgetType+" createSimple mixin");
+
+
+ // HtmlWidget.postMixIn
+ treeNode.toggleObj = dojo.lfx.toggle[treeNode.toggle.toLowerCase()] || dojo.lfx.toggle.plain;
+
+ //dojo.profile.start(this.widgetType + " manager");
+ dojo.widget.manager.add(treeNode);
+ //dojo.profile.end(this.widgetType + " manager");
+
+ //dojo.profile.start(this.widgetType + " buildRendering");
+ treeNode.buildRendering(args, {}, parent);
+ //dojo.profile.end(this.widgetType + " buildRendering");
+
+ treeNode.initialize(args, {}, parent);
+
+ //dojo.profile.end(this.widgetType+"createSimple");
+ if (treeNode.parent) {
+ delete dojo.widget.manager.topWidgets[treeNode.widgetId];
+ }
+
+ return treeNode;
+ },
+
+
+
+ // can override e.g for case of div with +- text inside
+ viewUpdateLayout: function() {
+ //dojo.profile.start("viewUpdateLayout");
+ //dojo.debug("UpdateLayout in "+this);
+
+ this.viewRemoveLayout();
+ this.viewAddLayout();
+ //dojo.profile.end("viewUpdateLayout");
+ },
+
+
+ viewAddContainer: function() {
+ // make controller only if children exist
+ this.containerNode = this.tree.containerNodeTemplate.cloneNode(true);
+ this.domNode.appendChild(this.containerNode);
+ },
+ /*
+ viewRemoveContainer: function() {
+ // make controller only if children exist
+ this.domNode.removeChild(this.containerNode);
+ this.containerNode = null;
+ },
+ */
+
+ viewAddLayout: function() {
+ //dojo.profile.start("viewAddLayout");
+ //dojo.debug("viewAddLayout in "+this);
+
+ if (this.parent["isTree"]) {
+ //dojo.debug("Parent isTree => add isTreeRoot");
+
+ // use setClass, not addClass for speed
+ dojo.html.setClass(this.domNode, dojo.html.getClass(this.domNode) + ' '+this.tree.classPrefix+'IsRoot')
+ }
+ //dojo.debug(this.parent.children.length);
+ //dojo.debug(this.parent.children[this.parent.children.length-1]);
+ if (this.isLastChild()) {
+ //dojo.debug("Checked last node for "+this);
+ //dojo.debug("Parent last is "+this.parent.children[this.parent.children.length-1]);
+ //dojo.debug("last node => add isTreeLast for "+this);
+ dojo.html.setClass(this.domNode, dojo.html.getClass(this.domNode) + ' '+this.tree.classPrefix+'IsLast')
+ }
+ //dojo.profile.end("viewAddLayout");
+ //dojo.debug("viewAddLayout out");
+
+ },
+
+
+ viewRemoveLayout: function() {
+ //dojo.debug("viewRemoveLayout in "+this);
+ //dojo.profile.start("viewRemoveLayout");
+ //dojo.debug((new Error()).stack);
+ dojo.html.removeClass(this.domNode, this.tree.classPrefix+"IsRoot");
+ dojo.html.removeClass(this.domNode, this.tree.classPrefix+"IsLast");
+ //dojo.profile.end("viewRemoveLayout");
+ },
+
+ viewGetExpandClass: function() {
+ if (this.isFolder) {
+ return this.isExpanded ? "ExpandOpen" : "ExpandClosed";
+ } else {
+ return "ExpandLeaf";
+ }
+ },
+
+ viewSetExpand: function() {
+ //dojo.profile.start("viewSetExpand");
+
+ //dojo.debug("viewSetExpand in "+this);
+
+ var expand = this.tree.classPrefix+this.viewGetExpandClass();
+ var reg = new RegExp("(^|\\s)"+this.tree.classPrefix+"Expand\\w+",'g');
+
+ dojo.html.setClass(this.domNode, dojo.html.getClass(this.domNode).replace(reg,'') + ' '+expand);
+
+ //dojo.debug(dojo.html.getClass(this.domNode))
+ //dojo.profile.end("viewSetExpand");
+ this.viewSetHasChildrenAndExpand();
+ },
+
+ viewGetChildrenClass: function() {
+ return 'Children'+(this.children.length ? 'Yes' : 'No');
+ },
+
+ viewSetHasChildren: function() {
+ //dojo.debug(this+' '+this.children.length)
+
+ var clazz = this.tree.classPrefix+this.viewGetChildrenClass();
+
+ var reg = new RegExp("(^|\\s)"+this.tree.classPrefix+"Children\\w+",'g');
+
+ dojo.html.setClass(this.domNode, dojo.html.getClass(this.domNode).replace(reg,'') + ' '+clazz);
+
+ this.viewSetHasChildrenAndExpand();
+ },
+
+ /**
+ * set TreeStateChildrenYes-ExpandClosed pair
+ * needed for IE, because IE reads only last class from .TreeChildrenYes.TreeExpandClosed pair
+ */
+ viewSetHasChildrenAndExpand: function() {
+ var clazz = this.tree.classPrefix+'State'+this.viewGetChildrenClass()+'-'+this.viewGetExpandClass();
+
+ var reg = new RegExp("(^|\\s)"+this.tree.classPrefix+"State[\\w-]+",'g');
+
+ dojo.html.setClass(this.domNode, dojo.html.getClass(this.domNode).replace(reg,'') + ' '+clazz);
+ },
+
+ viewUnfocus: function() {
+ dojo.html.removeClass(this.labelNode, this.tree.classPrefix+"LabelFocused");
+ },
+
+ viewFocus: function() {
+ dojo.html.addClass(this.labelNode, this.tree.classPrefix+"LabelFocused");
+ },
+
+
+
+// ================================ detach from parent ===================================
+
+ detach: function() {
+ if (!this.parent) return;
+
+ var parent = this.parent;
+ var index = this.getParentIndex();
+
+ this.doDetach.apply(this, arguments);
+
+ dojo.event.topic.publish(this.tree.eventNames.afterDetach,
+ { child: this, parent: parent, index:index }
+ );
+
+ },
+
+
+ /* node does not leave tree */
+ doDetach: function() {
+ //dojo.debug("doDetach in "+this+" parent "+this.parent+" class "+dojo.html.getClass(this.domNode));
+
+ var parent = this.parent;
+
+ //dojo.debug(parent.containerNode.style.display)
+
+ if (!parent) return;
+
+ var index = this.getParentIndex();
+
+
+ this.viewRemoveLayout();
+
+ dojo.widget.DomWidget.prototype.removeChild.call(parent, this);
+
+ var siblingsCount = parent.children.length;
+
+ //dojo.debug("siblingsCount "+siblingsCount);
+
+ if (siblingsCount > 0) {
+ if (index == 0) { // deleted first node => update new first
+ parent.children[0].viewUpdateLayout();
+ }
+ if (index == siblingsCount) { // deleted last node
+ parent.children[siblingsCount-1].viewUpdateLayout();
+ }
+ } else {
+ if (parent.isTreeNode) {
+ parent.viewSetHasChildren();
+ }
+ }
+
+ if (this.tree.unsetFolderOnEmpty && !parent.children.length && parent.isTreeNode) {
+ parent.unsetFolder();
+ }
+
+ //dojo.debug(parent.containerNode.style.display)
+
+ this.parent = null;
+ },
+
+
+ /**
+ * publish destruction event so that controller may unregister/unlisten
+ */
+ destroy: function() {
+
+ dojo.event.topic.publish(this.tree.eventNames.beforeNodeDestroy, { source: this } );
+
+ this.detach();
+
+ return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);
+ },
+
+
+ expand: function(){
+
+ if (this.isExpanded) return;
+
+
+ //dojo.profile.start("expand "+this);
+
+ //dojo.debug("expand in "+this);
+
+ //dojo.profile.start("expand - lazy init "+this);
+ if (this.tryLazyInit) {
+ this.setChildren();
+ this.tryLazyInit = false;
+ }
+
+ //dojo.profile.end("expand - lazy init "+this);
+
+
+ this.isExpanded = true;
+
+ this.viewSetExpand();
+
+ //dojo.profile.start("expand - showChildren "+this);
+
+ /**
+ * no matter if I have children or not. need to show/hide container anyway.
+ * use case: empty folder is expanded => then child is added, container already shown all fine
+ */
+ this.showChildren();
+
+ //dojo.profile.end("expand - showChildren "+this);
+
+
+ //dojo.profile.end("expand "+this);
+ },
+
+
+ collapse: function(){
+
+ if (!this.isExpanded) return;
+
+ this.isExpanded = false;
+
+ this.hideChildren();
+ },
+
+
+ hideChildren: function(){
+ this.tree.toggleObj.hide(
+ this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onHideChildren")
+ );
+ },
+
+
+ showChildren: function(){
+ //dojo.profile.start("showChildren"+this);
+
+ this.tree.toggleObj.show(
+ this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onShowChildren")
+ );
+
+ //dojo.profile.end("showChildren"+this);
+ },
+
+
+
+ onShowChildren: function() {
+
+ //dojo.profile.start("onShowChildren"+this);
+
+ this.onShow();
+
+ //dojo.profile.end("onShowChildren"+this);
+
+ dojo.event.topic.publish(this.tree.eventNames.afterExpand, {source: this} );
+ },
+
+ onHideChildren: function() {
+
+ this.viewSetExpand();
+ this.onHide();
+ dojo.event.topic.publish(this.tree.eventNames.afterCollapse, {source: this} );
+ },
+
+ /* Edit current node : change properties and update contents */
+ setTitle: function(title) {
+ var oldTitle = this.title;
+
+ this.labelNode.innerHTML = this.title = title;
+
+ dojo.event.topic.publish(this.tree.eventNames.afterSetTitle, { source: this, oldTitle:oldTitle });
+
+ },
+
+
+ toString: function() {
+ return '['+this.widgetType+', '+this.title+']';
+ }
+
+
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/TreeNodeV3.js
------------------------------------------------------------------------------
svn:eol-style = native