[Dojo-checkins] ilia - r3460 - in trunk: src/widget
tests/widget/tree
dojo-checkins-admin at dojotoolkit.org
dojo-checkins-admin at dojotoolkit.org
Fri Apr 7 05:07:27 MDT 2006
Author: ilia
Date: Fri Apr 7 05:07:27 2006
New Revision: 3460
Added:
trunk/tests/widget/tree/test_Tree_5_1.html
Modified:
trunk/src/widget/Tree.js
trunk/src/widget/TreeBasicController.js
trunk/src/widget/TreeLoadingController.js
trunk/src/widget/TreeNode.js
trunk/src/widget/TreeRPCController.js
Log:
* added nested locking (alpha)
* runRPC added
* callFunc, callObj order changed to callObj, callFunc
Modified: trunk/src/widget/Tree.js
==============================================================================
--- trunk/src/widget/Tree.js (original)
+++ trunk/src/widget/Tree.js Fri Apr 7 05:07:27 2006
@@ -63,6 +63,8 @@
DNDMode: "off",
+ lockLevel: 0, // lock ++ unlock --, so nested locking works fine
+
strictFolders: true,
DNDModes: {
@@ -506,8 +508,30 @@
child.parent = child.tree = null;
return child;
- }
+ },
+ markLoading: function() {
+ // no way to mark tree loading
+ },
+
+ unMarkLoading: function() {
+ // no way to show that tree finished loading
+ },
+
+
+ lock: function() {
+ !this.lockLevel && this.markLoading();
+ this.lockLevel++;
+ },
+ unlock: function() {
+ this.lockLevel--;
+ !this.lockLevel && this.unMarkLoading();
+ },
+ isLocked: function() { return this.lockLevel > 0; },
+ flushLock: function() {
+ this.lockLevel = 0;
+ this.unMarkLoading();
+ }
});
Modified: trunk/src/widget/TreeBasicController.js
==============================================================================
--- trunk/src/widget/TreeBasicController.js (original)
+++ trunk/src/widget/TreeBasicController.js Fri Apr 7 05:07:27 2006
@@ -216,16 +216,16 @@
},
- removeNode: function(node, callFunc, callObj) {
+ removeNode: function(node, callObj, callFunc) {
if (!this.canRemoveNode(node)) {
return false;
}
- return this.doRemoveNode(node, callFunc, callObj);
+ return this.doRemoveNode(node, callObj, callFunc);
},
- doRemoveNode: function(node, callFunc, callObj) {
+ doRemoveNode: function(node, callObj, callFunc) {
node.tree.removeNode(node);
if (callFunc) {
@@ -249,7 +249,7 @@
/* send data to server and add child from server */
/* data may contain an almost ready child, or anything else, suggested to server */
/*in RPC controllers server responds with child data to be inserted */
- createChild: function(parent, index, data, callFunc, callObj) {
+ createChild: function(parent, index, data, callObj, callFunc) {
if (!this.canCreateChild(parent, index, data)) {
return false;
}
@@ -257,7 +257,7 @@
return this.doCreateChild.apply(this, arguments);
},
- doCreateChild: function(parent, index, data, callFunc, callObj) {
+ doCreateChild: function(parent, index, data, callObj, callFunc) {
var widgetType = data.widgetType ? data.widgetType : "TreeNode";
Modified: trunk/src/widget/TreeLoadingController.js
==============================================================================
--- trunk/src/widget/TreeLoadingController.js (original)
+++ trunk/src/widget/TreeLoadingController.js Fri Apr 7 05:07:27 2006
@@ -28,7 +28,7 @@
/**
* Common RPC error handler (dies)
*/
- RPCErrorHandler: function(type, obj) {
+ RPCErrorHandler: function(type, obj, evt) {
alert( "RPC Error: " + (obj.message||"no message"));
},
@@ -56,17 +56,19 @@
/**
* Add all loaded nodes from array obj as node children and expand it
*/
- loadProcessResponse: function(type, node, result, callFunc, callObj) {
+ 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('Not array loaded: '+newChildren);
+ dojo.raise('loadProcessResponse: Not array loaded: '+newChildren);
}
for(var i=0; i<newChildren.length; i++) {
@@ -80,6 +82,8 @@
node.state = node.loadStates.LOADED;
+ //dojo.debug(callFunc);
+
if (dojo.lang.isFunction(callFunc)) {
callFunc.apply(dojo.lang.isUndefined(callObj) ? this : callObj, [node, newChildren]);
}
@@ -90,39 +94,71 @@
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: true,
+ 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, callFunc, callObj){
- node.markLoading();
-
-
+ loadRemote: function(node, sync, callObj, callFunc){
+ var _this = this;
+
var params = {
node: this.getInfo(node),
tree: this.getInfo(node.tree)
};
+
+ //dojo.debug(callFunc)
- var requestUrl = this.getRPCUrl('getChildren');
- //dojo.debug(requestUrl)
-
- dojo.io.bind({
- url: requestUrl,
- /* I hitch to get this.loadOkHandler */
- load: dojo.lang.hitch(this,
- function(type, result) {
- this.loadProcessResponse(type, node, result, callFunc, callObj) ;
- }
- ),
- error: this.RPCErrorHandler,
- mimetype: "text/json",
- preventCache: true,
+ this.runRPC({
+ url: this.getRPCUrl('getChildren'),
+ load: function(result) {
+ _this.loadProcessResponse(node, result, callObj, callFunc) ;
+ },
sync: sync,
- content: { data: dojo.json.serialize(params) }
+ lock: [node],
+ params: params
});
-
-
+
},
@@ -131,6 +167,7 @@
if (node.state == node.loadStates.UNCHECKED && node.isFolder) {
this.loadRemote(node, sync,
+ this,
function(node, newChildren) {
this.expand(node, sync, callObj, callFunc);
}
@@ -155,7 +192,7 @@
},
- doCreateChild: function(parent, index, data, callFunc, callObj) {
+ doCreateChild: function(parent, index, data, callObj, callFunc) {
/* load nodes into newParent in sync mode, if needed, first */
if (parent.state == parent.loadStates.UNCHECKED) {
Modified: trunk/src/widget/TreeNode.js
==============================================================================
--- trunk/src/widget/TreeNode.js (original)
+++ trunk/src/widget/TreeNode.js Fri Apr 7 05:07:27 2006
@@ -37,6 +37,8 @@
},
isContainer: true,
+
+ lockLevel: 0, // lock ++ unlock --, so nested locking works fine
templateString: ('<div class="dojoTreeNode"> '
@@ -92,10 +94,37 @@
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;
-
- return (this.tree.strictFolders && action == this.actions.ADDCHILD && !this.isFolder) || dojo.lang.inArray(_this.actionsDisabled, action);
+
+ var disabled = false;
+
+ if (this.tree.strictFolders &&action == this.actions.ADDCHILD && !this.isFolder) {
+ disabled = true;
+ }
+
+ if (dojo.lang.inArray(_this.actionsDisabled, action)) {
+ disabled = true;
+ }
+
+ var node = this;
+ while (true) {
+ if (node.isLocked()) {
+ disabled = true;
+ break;
+ }
+ if (node instanceof dojo.widget.Tree) {
+ break;
+ }
+ node = node.parent;
+ }
+
+ return disabled;
},
getInfo: function() {
@@ -157,9 +186,24 @@
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');
@@ -257,8 +301,8 @@
},
- unMarkSelected: function() {
- //dojo.debug('unmark')
+ unMarkSelected: function() {
+ //dojo.debug('unmark')
dojo.html.removeClass(this.titleNode, 'dojoTreeNodeLabelSelected');
},
Modified: trunk/src/widget/TreeRPCController.js
==============================================================================
--- trunk/src/widget/TreeRPCController.js (original)
+++ trunk/src/widget/TreeRPCController.js Fri Apr 7 05:07:27 2006
@@ -47,26 +47,22 @@
var success;
- dojo.io.bind({
+ this.runRPC({
url: this.getRPCUrl('move'),
/* I hitch to get this.loadOkHandler */
- load: dojo.lang.hitch(this,
- function(type, response) {
- success = this.doMoveProcessResponse(type, response, child, newParent, index) ;
- }
- ),
- error: this.RPCErrorHandler,
- mimetype: "text/json",
- preventCache: true,
+ load: function(response) {
+ success = this.doMoveProcessResponse(response, child, newParent, index) ;
+ },
sync: true,
- content: { data: dojo.json.serialize(params) }
+ lock: [child, newParent],
+ params: params
});
return success;
},
- doMoveProcessResponse: function(type, response, child, newParent, index) {
+ doMoveProcessResponse: function(response, child, newParent, index) {
if (!dojo.lang.isUndefined(response.error)) {
this.RPCErrorHandler("server", response.error);
@@ -79,29 +75,27 @@
},
- doRemoveNode: function(node, callFunc, callObj) {
+ doRemoveNode: function(node, callObj, callFunc) {
var params = {
node: this.getInfo(node),
tree: this.getInfo(node.tree)
}
- dojo.io.bind({
+ this.runRPC({
url: this.getRPCUrl('removeNode'),
/* I hitch to get this.loadOkHandler */
- load: dojo.lang.hitch(this, function(type, response) {
- this.doRemoveNodeProcessResponse(type, response, node, callFunc, callObj) }
- ),
- error: this.RPCErrorHandler,
- mimetype: "text/json",
- preventCache: true,
- content: {data: dojo.json.serialize(params) }
+ load: function(response) {
+ this.doRemoveNodeProcessResponse(response, node, callObj, callFunc)
+ },
+ params: params,
+ lock: [node]
});
},
- doRemoveNodeProcessResponse: function(type, response, node, callFunc, callObj) {
+ doRemoveNodeProcessResponse: function(response, node, callObj, callFunc) {
if (!dojo.lang.isUndefined(response.error)) {
this.RPCErrorHandler("server", response.error);
return false;
@@ -111,7 +105,7 @@
if (response == true) {
/* change parent succeeded */
- var args = [ node, callFunc, callObj ];
+ var args = [ node, callObj, callFunc ];
dojo.widget.TreeLoadingController.prototype.doRemoveNode.apply(this, args);
return;
@@ -131,7 +125,7 @@
// -----------------------------------------------------------------------------
- doCreateChild: function(parent, index, output, callFunc, callObj) {
+ doCreateChild: function(parent, index, output, callObj, callFunc) {
var params = {
tree: this.getInfo(parent.tree),
@@ -140,37 +134,31 @@
data: output
}
- dojo.io.bind({
- url: this.getRPCUrl('createChild'),
- /* I hitch to get this.loadOkHandler */
- load: dojo.lang.hitch(this, function(type, response) {
- // suggested data is dead, fresh data from server is used
- this.doCreateChildProcessResponse(type, response, parent, index, callFunc, callObj) }
- ),
- error: this.RPCErrorHandler,
- mimetype: "text/json",
- preventCache: true,
- content: {data: dojo.json.serialize(params) }
+ this.runRPC({
+ url: this.getRPCUrl('createChild'),
+ load: function(response) {
+ // suggested data is dead, fresh data from server is used
+ this.doCreateChildProcessResponse( response, parent, index, callObj, callFunc)
+ },
+ params: params,
+ lock: [parent]
});
},
- doCreateChildProcessResponse: function(type, response, parent, index, callFunc, callObj) {
+ doCreateChildProcessResponse: function(response, parent, index, callObj, callFunc) {
if (!dojo.lang.isUndefined(response.error)) {
this.RPCErrorHandler("server",response.error);
return false;
}
- if (!parent.isTreeNode) {
- dojo.raise("Can only add children to TreeNode")
- }
-
if (!dojo.lang.isObject(response)) {
dojo.raise("Invalid result "+response)
}
- var args = [parent, index, response, callFunc, callObj];
+ var args = [parent, index, response, callObj, callFunc];
+
dojo.widget.TreeLoadingController.prototype.doCreateChild.apply(this, args);
}
Added: trunk/tests/widget/tree/test_Tree_5_1.html
==============================================================================
--- (empty file)
+++ trunk/tests/widget/tree/test_Tree_5_1.html Fri Apr 7 05:07:27 2006
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+
+<script type="text/javascript">
+ var djConfig = {isDebug: true, debugAtAllCosts: true };
+</script>
+<script type="text/javascript" src="../../../dojo.js"></script>
+<script type="text/javascript">
+ dojo.require("dojo.lang.*");
+ dojo.require("dojo.widget.*");
+ dojo.require("dojo.widget.Tree");
+ dojo.require("dojo.widget.TreeLoadingController");
+ dojo.hostenv.writeIncludes();
+</script>
+
+
+</head>
+<body>
+
+<ul>
+<li>New nodes are loaded dynamically.
+<li>Tree is expanded to level 1, some nodes are autoexpanded also.
+<li>DND is working in between mode.
+</ul>
+
+<div dojoType="TreeLoadingController" RPCUrl="local" widgetId="treeController" DNDcontroller="create"></div>
+
+
+
+<div dojoType="Tree" expandLevel="1" widgetId="firstTree" controller="treeController" DNDMode="between" DNDAcceptTypes="firstTree">
+ <div dojoType="TreeNode" title="folder" isFolder="true">
+ </div>
+
+</div>
+
+
+
+</body>
+</html>
More information about the Dojo-checkins
mailing list