[Zope3-checkins] SVN: Zope3/trunk/ Work on skin 'Rotterdam':

Florent Xicluna laxyf at yahoo.fr
Sun Oct 8 07:09:15 EDT 2006


Log message for revision 70571:
  Work on skin 'Rotterdam':
  - highlight selected item in navigation tree.
  - do not display multiple "Loading..." messages if you click again.
  - hide '+' icon for empty folders.
  - handle case when unable to retrieve XML tree
  - normalize indentation in JS file.
  - removed 'import zapi'.
  (see collector 720)

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/app/rotterdam/editingwidgets.py
  U   Zope3/trunk/src/zope/app/rotterdam/tests/output/test1.xml
  U   Zope3/trunk/src/zope/app/rotterdam/tests/output/test5.xml
  U   Zope3/trunk/src/zope/app/rotterdam/tests/output/test6.xml
  U   Zope3/trunk/src/zope/app/rotterdam/tests/output/test7.xml
  U   Zope3/trunk/src/zope/app/rotterdam/tests/output/test8.xml
  U   Zope3/trunk/src/zope/app/rotterdam/xmlobject.py
  U   Zope3/trunk/src/zope/app/rotterdam/xmltree.js
  U   Zope3/trunk/src/zope/app/rotterdam/zope3.css
  U   Zope3/trunk/src/zope/app/rotterdam/zope3_tablelayout.css

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/doc/CHANGES.txt	2006-10-08 11:09:13 UTC (rev 70571)
@@ -10,6 +10,10 @@
 
     New features
 
+      - Improved the asynchronous navigation tree of the 'Rotterdam' skin:
+        highlight current object, do not display '+' icon if object contains
+        no element, remove message "Loading" if unable to retrieve XML tree.
+
       - Revamped i18n for German for all user-readable strings
 
       - The getForm() method on testbrowser instances no longer needs

Modified: Zope3/trunk/src/zope/app/rotterdam/editingwidgets.py
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/editingwidgets.py	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/editingwidgets.py	2006-10-08 11:09:13 UTC (rev 70571)
@@ -16,6 +16,7 @@
 $Id$
 """
 from zope.interface import implements
+
 from zope.app.form.interfaces import IInputWidget
 from zope.app.form.browser import TextAreaWidget
 from zope.app.form.browser.widget import renderElement

Modified: Zope3/trunk/src/zope/app/rotterdam/tests/output/test1.xml
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/tests/output/test1.xml	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/tests/output/test1.xml	2006-10-08 11:09:13 UTC (rev 70571)
@@ -1 +1 @@
-<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[top]" baseURL="http://127.0.0.1/" length="3" icon_url="" isroot=""><collection name="folder1" length="2" icon_url=""></collection><collection name="folder2" length="1" icon_url=""/><collection name="папка3" length="1" icon_url=""/><collection name="++etc++site" length="1" icon_url=""/></collection></children>
+<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[top]" baseURL="http://127.0.0.1/" length="3" icon_url="" isroot=""><collection name="folder1" length="2" icon_url="">selected</collection><collection name="folder2" length="1" icon_url=""/><collection name="папка3" length="1" icon_url=""/><collection name="++etc++site" length="1" icon_url=""/></collection></children>

Modified: Zope3/trunk/src/zope/app/rotterdam/tests/output/test5.xml
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/tests/output/test5.xml	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/tests/output/test5.xml	2006-10-08 11:09:13 UTC (rev 70571)
@@ -1 +1 @@
-<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[top]" baseURL="http://127.0.0.1/" length="3" icon_url="" isroot=""><collection name="folder1" length="2" icon_url=""><collection name="folder1_1" length="2" icon_url=""><collection name="folder1_1_1" length="1" icon_url=""></collection><collection name="folder1_1_2" length="0" icon_url=""/><item name="++etc++site" icon_url="" /></collection><collection name="folder1_2" length="1" icon_url=""/><item name="++etc++site" icon_url="" /></collection><collection name="folder2" length="1" icon_url=""/><collection name="папка3" length="1" icon_url=""/><collection name="++etc++site" length="1" icon_url=""/></collection></children>
+<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[top]" baseURL="http://127.0.0.1/" length="3" icon_url="" isroot=""><collection name="folder1" length="2" icon_url=""><collection name="folder1_1" length="2" icon_url=""><collection name="folder1_1_1" length="1" icon_url="">selected</collection><collection name="folder1_1_2" length="0" icon_url=""/><item name="++etc++site" icon_url="" /></collection><collection name="folder1_2" length="1" icon_url=""/><item name="++etc++site" icon_url="" /></collection><collection name="folder2" length="1" icon_url=""/><collection name="папка3" length="1" icon_url=""/><collection name="++etc++site" length="1" icon_url=""/></collection></children>

Modified: Zope3/trunk/src/zope/app/rotterdam/tests/output/test6.xml
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/tests/output/test6.xml	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/tests/output/test6.xml	2006-10-08 11:09:13 UTC (rev 70571)
@@ -1 +1 @@
-<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[subsite]" baseURL="http://127.0.0.1/" length="2" icon_url="" isroot=""></collection></children>
+<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[subsite]" baseURL="http://127.0.0.1/" length="2" icon_url="" isroot="">selected</collection></children>

Modified: Zope3/trunk/src/zope/app/rotterdam/tests/output/test7.xml
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/tests/output/test7.xml	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/tests/output/test7.xml	2006-10-08 11:09:13 UTC (rev 70571)
@@ -1 +1 @@
-<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[subsite]" baseURL="http://127.0.0.1/" length="2" icon_url="" isroot=""><collection name="subfolder1" length="0" icon_url=""></collection><collection name="subfolder2" length="1" icon_url=""/><collection name="++etc++site" length="1" icon_url=""/></collection></children>
+<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[subsite]" baseURL="http://127.0.0.1/" length="2" icon_url="" isroot=""><collection name="subfolder1" length="0" icon_url="">selected</collection><collection name="subfolder2" length="1" icon_url=""/><collection name="++etc++site" length="1" icon_url=""/></collection></children>

Modified: Zope3/trunk/src/zope/app/rotterdam/tests/output/test8.xml
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/tests/output/test8.xml	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/tests/output/test8.xml	2006-10-08 11:09:13 UTC (rev 70571)
@@ -1 +1 @@
-<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[subsite]" baseURL="http://127.0.0.1/" length="2" icon_url="" isroot=""><collection name="subfolder1" length="0" icon_url=""/><collection name="subfolder2" length="1" icon_url=""><collection name="subfolder2_1" length="0" icon_url=""></collection><item name="++etc++site" icon_url="" /></collection><collection name="++etc++site" length="1" icon_url=""/></collection></children>
+<?xml version="1.0" ?><children title_tpl="Contains $${num} item(s)" loading_msg="Loading..."><collection name="[subsite]" baseURL="http://127.0.0.1/" length="2" icon_url="" isroot=""><collection name="subfolder1" length="0" icon_url=""/><collection name="subfolder2" length="1" icon_url=""><collection name="subfolder2_1" length="0" icon_url="">selected</collection><item name="++etc++site" icon_url="" /></collection><collection name="++etc++site" length="1" icon_url=""/></collection></children>

Modified: Zope3/trunk/src/zope/app/rotterdam/xmlobject.py
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/xmlobject.py	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/xmlobject.py	2006-10-08 11:09:13 UTC (rev 70571)
@@ -18,6 +18,7 @@
 from rfc822 import formatdate, time
 from xml.sax.saxutils import quoteattr
 
+from zope.component import getMultiAdapter, queryMultiAdapter
 from zope.interface import Interface
 from zope.proxy import sameProxiedObjects
 from zope.security.interfaces import Unauthorized, Forbidden
@@ -25,7 +26,6 @@
 from zope.traversing.api import getParents, getParent, traverse
 from zope.publisher.browser import BrowserView
 
-from zope.app import zapi
 from zope.app.container.interfaces import IReadContainer
 from zope.app.i18n import ZopeMessageFactory as _
 
@@ -81,7 +81,7 @@
 
     def getIconUrl(self, item):
         result = ''
-        icon = zapi.queryMultiAdapter((item, self.request), name='zmi_icon')
+        icon = queryMultiAdapter((item, self.request), name='zmi_icon')
         if icon:
             result = icon.url()
         return result
@@ -142,12 +142,12 @@
         their respective siblings.
 
         """
-        result = ''
+        result = 'selected'
         oldItem = self.context
 
         vh = self.request.getVirtualHostRoot()
         if vh:
-            vhrootView = zapi.getMultiAdapter(
+            vhrootView = getMultiAdapter(
                     (vh, self.request), name='absolute_url')
             baseURL = vhrootView() + '/'
             try:
@@ -229,7 +229,7 @@
         parent = getParent(self.context)
         while parent is not None:
                 if IReadContainer.providedBy(parent):
-                    view = zapi.queryMultiAdapter(
+                    view = queryMultiAdapter(
                         (parent, self.request), name='singleBranchTree.xml')
                     return view()
                 else:

Modified: Zope3/trunk/src/zope/app/rotterdam/xmltree.js
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/xmltree.js	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/xmltree.js	2006-10-08 11:09:13 UTC (rev 70571)
@@ -19,6 +19,7 @@
 
 // globals
 var loadingMsg = 'Loading...';
+var abortMsg = 'Unavailable';
 var titleTemplate = 'Contains ' + NUM_TEMPLATE + ' item(s)';
 var baseurl;
 var navigationTree;
@@ -29,437 +30,434 @@
 
 //class navigationTreeNode
 function navigationTreeNode (domNode) {
-        this.childNodes = new Array();
-        this.isEmpty = 1;
-        this.isCollapsed = 1;
-        this.domNode = domNode;
-        this.loadingNode = null;
-        this.path = '';
-        this.parentNode = null;
+    this.childNodes = new Array();
+    this.isEmpty = 1;
+    this.isCollapsed = 1;
+    this.domNode = domNode;
+    this.loadingNode = null;
+    this.path = '';
+    this.parentNode = null;
 }
 
 navigationTreeNode.prototype.appendChild = function(node) {
-        this.childNodes.push(node);
-        this.domNode.appendChild(node.domNode);
-        node.parentNode = this;
+    this.childNodes.push(node);
+    this.domNode.appendChild(node.domNode);
+    node.parentNode = this;
 }
 
 navigationTreeNode.prototype.setPath = function(path) {
-        this.path = path;
-        this.domNode.setAttribute("path", path);
+    this.path = path;
+    this.domNode.setAttribute("path", path);
 }
 
+navigationTreeNode.prototype.setSelected = function() {
+    this.domNode.getElementsByTagName('icon')[0].className='selected';
+}
+
 navigationTreeNode.prototype.collapse = function() {
-        this.isCollapsed = 1;
-        this.changeExpandIcon("pl.gif");
+    this.isCollapsed = 1;
+    this.changeExpandIcon("pl.gif");
 }
 
 navigationTreeNode.prototype.expand = function() {
-        this.isCollapsed = 0;
-        this.changeExpandIcon("mi.gif");
+    this.isCollapsed = 0;
+    this.changeExpandIcon("mi.gif");
 }
 
 navigationTreeNode.prototype.changeExpandIcon = function(icon) {
-        var expand = this.domNode.getElementsByTagName('expand')[0];
-        expand.style.backgroundImage = 'url("' + baseurl + '@@/' + icon + '")';
-        }
+    var expand = this.domNode.getElementsByTagName('expand')[0];
+    expand.style.backgroundImage = 'url("' + baseurl + '@@/' + icon + '")';
+}
 
 navigationTreeNode.prototype.getNodeByPath = function(path) {
-        var numchildren = this.childNodes.length;
-        if (path == this.path) {
-                return this;
-                }
-        else {
-                for (var i=0; i< numchildren; i++) {
-                        foundChild = this.childNodes[i].getNodeByPath(path);
-                        if (foundChild) {
-                                return foundChild;
-                                }
-                        }
-                }
-        return null;
+    var numchildren = this.childNodes.length;
+    if (path == this.path) return this;
+    else {
+        for (var i=0; i<numchildren; i++) {
+            foundChild = this.childNodes[i].getNodeByPath(path);
+            if (foundChild) return foundChild;
+        }
+    }
+    return null;
 }
 
 navigationTreeNode.prototype.toggleExpansion = function() {
-with (this) {
+    with (this) {
         prettydump('toggleExpansion', LG_TRACE);
         // If this collection is empty, load it from server
         // todo xxx optimize for the case where collection has null length
-        if (isEmpty) {
-                startLoadingChildren();
-                }
-        else
-                {
-                refreshExpansion();
-                }
-
-        }
+        if (isEmpty) startLoadingChildren();
+        else refreshExpansion();
+    }
 }
 
 navigationTreeNode.prototype.startLoadingChildren = function() {
-with (this) {
+    with (this) {
+        //already loading?
+        if (loadingNode) return;
         loadingNode = createLoadingNode();
         domNode.appendChild(loadingNode);
         //var url = baseurl + path + XML_CHILDREN_VIEW;
         var url = path + XML_CHILDREN_VIEW;
         loadtreexml(url, this);
-        }
+    }
 }
 
 navigationTreeNode.prototype.finishLoadingChildren = function() {
-with (this) {
+    with (this) {
         isEmpty = 0;
         refreshExpansion();
         domNode.removeChild(loadingNode);
         loadingNode = null;
-        }
+    }
 }
 
+navigationTreeNode.prototype.abortLoadingChildren = function() {
+    with (this) {
+        domNode.removeChild(loadingNode);
+        loadingNode = null;
+    }
+}
+
 navigationTreeNode.prototype.refreshExpansion = function() {
-with (this) {
+    with (this) {
         if (isCollapsed) {
-                expand();
-                showChildren();
+            expand();
+            showChildren();
         }
         else {
-                collapse();
-                hideChildren();
+            collapse();
+            hideChildren();
         }
-        }
+    }
 }
 
 
 navigationTreeNode.prototype.hideChildren = function() {
-with (this) {
+    with (this) {
         prettydump('hideChildren', LG_TRACE);
         var num = childNodes.length;
-        for (var i = num - 1; i >=0; i--) {
-                childNodes[i].domNode.style.display = 'none';
+        for (var i=num-1; i>=0; i--) {
+            childNodes[i].domNode.style.display = 'none';
         }
-        }
+    }
 }
 
 navigationTreeNode.prototype.showChildren = function() {
-with (this) {
+    with (this) {
         prettydump('showChildren', LG_TRACE);
         var num = childNodes.length;
-        for (var i = num - 1; i >=0; i--) {
-                childNodes[i].domNode.style.display = 'block';
-            }
+        for (var i=num-1; i>=0; i--) {
+            childNodes[i].domNode.style.display = 'block';
         }
+    }
 }
 
 // utilities
 function prettydump(s, locallog) {
-        // Put the string "s" in a box on the screen as an log message
-        if (locallog <= loglevel) {
-                var logger = document.getElementById('logger');
-                var msg = document.createElement('code');
-                var br1 = document.createElement('br');
-                var br2 = document.createElement('br');
-                var msg_text = document.createTextNode(s);
-                msg.appendChild(msg_text);
-                logger.insertBefore(br1, logger.firstChild);
-                logger.insertBefore(br2, logger.firstChild);
-                logger.insertBefore(msg, logger.firstChild);
-        }
-        }
+    // Put the string "s" in a box on the screen as an log message
+    if (locallog > loglevel) return;
 
+    var logger = document.getElementById('logger');
+    var msg = document.createElement('code');
+    var br1 = document.createElement('br');
+    var br2 = document.createElement('br');
+    var msg_text = document.createTextNode(s);
+    msg.appendChild(msg_text);
+    logger.insertBefore(br1, logger.firstChild);
+    logger.insertBefore(br2, logger.firstChild);
+    logger.insertBefore(msg, logger.firstChild);
+}
 
+
 function debug(s) {
-        var oldlevel = loglevel;
-        loglevel = LG_DEBUG;
-        prettydump("Debug : " + s, LG_DEBUG);
-        loglevel = oldlevel;
+    var oldlevel = loglevel;
+    loglevel = LG_DEBUG;
+    prettydump("Debug : " + s, LG_DEBUG);
+    loglevel = oldlevel;
 }
 
 // DOM utilities
 function getTreeEventTarget(e) {
-        var elem;
-        if(e.target) {
-                // Mozilla uses this
-                if (e.target.nodeType == TEXT_NODE) {
-                        elem=e.target.parentNode;
+    var elem;
+    if (e.target) {
+        // Mozilla uses this
+        if (e.target.nodeType == TEXT_NODE) {
+            elem=e.target.parentNode;
         }
-        else {
-                elem=e.target;
-                }
-                }
-        else {
-                // IE uses this
-                elem=e.srcElement;
-                }
-        return elem;
-        }
+        else elem=e.target;
+    } else {
+        // IE uses this
+        elem=e.srcElement;
+    }
+    return elem;
+}
 
 function isCollection(elem) {
-        return (checkTagName(elem, COLLECTION));
-        }
+    return checkTagName(elem, COLLECTION);
+}
 
 
 function isIcon(elem) {
-        return (checkTagName(elem, ICON));
-        }
+    return checkTagName(elem, ICON);
+}
 
 function isExpand(elem) {
-        return (checkTagName(elem, EXPAND));
-        }
+    return checkTagName(elem, EXPAND);
+}
 
 function checkTagName(elem, tagName) {
-        return (elem.tagName.toUpperCase() == tagName);
-        }
+    return elem.tagName.toUpperCase() == tagName;
+}
 
 function getCollectionChildNodes(xmlDomElem) {
-        // get collection element nodes among childNodes of elem
-        var result = new Array();
+    // get collection element nodes among childNodes of elem
+    var result = new Array();
 
-        var items = xmlDomElem.childNodes;
-        var numitems = items.length;
-        var currentItem;
-        for (var i = 0; i < numitems; i++) {
-                currentItem = items[i];
+    var items = xmlDomElem.childNodes;
+    var numitems = items.length;
+    var currentItem;
+    for (var i=0; i<numitems; i++) {
+        currentItem = items[i];
 
-                if (currentItem.nodeType != ELEMENT_NODE) {
-                        continue;
-                        }
-
-                if (!isCollection(currentItem)) {
-                        continue;
-                        }
-                result.push(currentItem);
-                }
-        return result;
+        if (currentItem.nodeType == ELEMENT_NODE && isCollection(currentItem)) {
+            result.push(currentItem);
         }
+    }
+    return result;
+}
 
 //events
-function treeclicked (e) {
-        prettydump('treeclicked', LG_TRACE_EVENTS);
-        var elem = getTreeEventTarget(e);
-        if (elem.id == 'navtree') return;
+function treeclicked(e) {
+    prettydump('treeclicked', LG_TRACE_EVENTS);
+    var elem = getTreeEventTarget(e);
+    if (elem.id == 'navtree') return;
 
-        // if node clicked is expand elem, toggle expansion
-        if (isExpand(elem)) {
-                //get collection node
-                elem = elem.parentNode;
-                var navTreeNode = navigationTree.getNodeByPath(elem.getAttribute('path'));
-                navTreeNode.toggleExpansion();
-                }
-        }
+    // if node clicked is expand elem, toggle expansion
+    if (isExpand(elem) && !elem.getAttribute('disabled')) {
+        //get collection node
+        elem = elem.parentNode;
+        var navTreeNode = navigationTree.getNodeByPath(elem.getAttribute('path'));
+        navTreeNode.toggleExpansion();
+    }
+}
 
 // helpers
 function getControlPrefix() {
-        if (getControlPrefix.prefix)
-                return getControlPrefix.prefix;
+    if (getControlPrefix.prefix)
+        return getControlPrefix.prefix;
 
-        var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
-        var o, o2;
-        for (var i = 0; i < prefixes.length; i++) {
-                try {
-                        // try to create the objects
-                        o = new ActiveXObject(prefixes[i] + ".XmlHttp");
-                        o2 = new ActiveXObject(prefixes[i] + ".XmlDom");
-                        return getControlPrefix.prefix = prefixes[i];
-                        }
-                catch (ex) {};
-                }
-
-        throw new Error("Could not find an installed XML parser");
+    var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
+    var o, o2;
+    for (var i=0; i<prefixes.length; i++) {
+        try {
+            // try to create the objects
+            o = new ActiveXObject(prefixes[i] + ".XmlHttp");
+            o2 = new ActiveXObject(prefixes[i] + ".XmlDom");
+            return getControlPrefix.prefix = prefixes[i];
         }
+        catch (ex) {};
+    }
 
+    throw new Error("Could not find an installed XML parser");
+}
 
+
 // XmlHttp factory
 function XmlHttp() {}
 
 
-XmlHttp.create = function () {
-if (window.XMLHttpRequest) {
+XmlHttp.create = function() {
+    if (window.XMLHttpRequest) {
         var req = new XMLHttpRequest();
 
         // some older versions of Moz did not support the readyState property
         // and the onreadystate event so we patch it!
         if (req.readyState == null) {
-                req.readyState = 1;
-                req.addEventListener("load", function () {
-                                req.readyState = 4;
-                                if (typeof req.onreadystatechange == "function")
-                                req.onreadystatechange();}, false);
-                }
-
-                return req;
+            req.readyState = 1;
+            req.addEventListener("load", function() {
+                req.readyState = 4;
+                if (typeof req.onreadystatechange == "function")
+                req.onreadystatechange();}, false);
         }
-if (window.ActiveXObject) {
+
+        return req;
+    }
+    if (window.ActiveXObject) {
         s = getControlPrefix() + '.XmlHttp';
         return new ActiveXObject(getControlPrefix() + ".XmlHttp");
-        }
-return;
+    }
+    return;
 };
 
 function loadtreexml (url, node) {
-        var xmlHttp = XmlHttp.create();
-        if (xmlHttp) {
-                prettydump('URL ' + url, LG_INFO);
-                xmlHttp.open('GET', url, true);
+    var xmlHttp = XmlHttp.create();
+    if (!xmlHttp) return;
+    prettydump('URL ' + url, LG_INFO);
+    xmlHttp.open('GET', url, true);
 
+    xmlHttp.onreadystatechange = function() {
+        if (xmlHttp.readyState != 4) return;
+        prettydump('Response XML ' + xmlHttp.responseText, LG_INFO);
+        parseXML(xmlHttp.responseXML, node);
+    };
 
-                xmlHttp.onreadystatechange = function () {
-                    if (xmlHttp.readyState == 4) {
-                                prettydump('Response XML ' + xmlHttp.responseText, LG_INFO);
-                                parseXML(xmlHttp.responseXML, node);
-                            }
-                            };
+    // call in new thread to allow ui to update
+    window.setTimeout(function() { xmlHttp.send(null); }, 10);
+}
 
-                // call in new thread to allow ui to update
-                window.setTimeout(function () {
-                        xmlHttp.send(null);
-                        }, 10);
-                }
-        else {
-                }
-        }
-
 function loadtree (rooturl, thisbaseurl) {
-        baseurl = rooturl;  // Global baseurl
-        docNavTree = document.getElementById('navtreecontents');
+    baseurl = rooturl;  // Global baseurl
+    docNavTree = document.getElementById('navtreecontents');
 
-        var url = thisbaseurl + SINGLE_BRANCH_TREE_VIEW;
-        loadtreexml(url, null);
-        }
+    var url = thisbaseurl + SINGLE_BRANCH_TREE_VIEW;
+    loadtreexml(url, null);
+}
 
 
 function removeChildren(node) {
-        var items = node.childNodes;
-        var numitems = items.length;
-        for (var i = 0; i < numitems; i++) {
-                node.removeChild(items[i]);
-                }
-        }
+    var items = node.childNodes;
+    var numitems = items.length;
+    for (var i=0; i<numitems; i++) {
+        node.removeChild(items[i]);
+    }
+}
 
 
 function parseXML(responseXML, node) {
-        if (responseXML) {
-                var data = responseXML.documentElement;
-                if (node == null) {
-                        //[top] node
-                        removeChildren(docNavTree);
-                        titleTemplate = data.getAttribute('title_tpl');
-                        loadingMsg = data.getAttribute('loading_msg');
-                        addNavigationTreeNodes(data, null, 1);
-//                        docNavTree.appendChild(navigationTree.domNode);
-                        }
-                else {
-                        //expanding nodes
-                        addNavigationTreeNodes(data, node, 0);
-                        node.finishLoadingChildren();
-                        }
-                }
+    if (responseXML) {
+        var data = responseXML.documentElement;
+        if (node == null) {
+            //[top] node
+            removeChildren(docNavTree);
+            titleTemplate = data.getAttribute('title_tpl');
+            loadingMsg = data.getAttribute('loading_msg');
+            addNavigationTreeNodes(data, null, 1);
+        //      docNavTree.appendChild(navigationTree.domNode);
+        } else {
+            //expanding nodes
+            addNavigationTreeNodes(data, node, 0);
+            node.finishLoadingChildren();
         }
+    } else {
+        // no XML response, reset the loadingNode
+        if (node == null) {
+            //unable to retrieve [top] node
+            docNavTree.innerHTML = abortMsg;
+        } else {
+            //abort expanding nodes
+            node.abortLoadingChildren()
+        }
+    }
+}
 
 function addNavigationTreeNodes(sourceNode, targetNavTreeNode, deep) {
-        // create tree nodes from XML children nodes of sourceNode
-        // and add them to targetNode
-        // if deep, create all descendants of sourceNode
-        var basePath = "";
-        if (targetNavTreeNode) {
-                basePath = targetNavTreeNode.path;
-                }
-        var items = getCollectionChildNodes(sourceNode);
-        var numitems = items.length;
-        for (var i=0; i< numitems; i++) {
-                var navTreeChild = createNavigationTreeNode(items[i], basePath, deep);
-                if (targetNavTreeNode) {
-                        targetNavTreeNode.appendChild(navTreeChild);
-                        }
-                }
-        }
+    // create tree nodes from XML children nodes of sourceNode
+    // and add them to targetNode
+    // if deep, create all descendants of sourceNode
+    var basePath = "";
+    if (targetNavTreeNode) basePath = targetNavTreeNode.path;
+    var items = getCollectionChildNodes(sourceNode);
+    var numitems = items.length;
+    for (var i=0; i<numitems; i++) {
+        var navTreeChild = createNavigationTreeNode(items[i], basePath, deep);
+        if (targetNavTreeNode) targetNavTreeNode.appendChild(navTreeChild);
+    }
+}
 
 
 function createPresentationNodes(title, targetUrl, icon_url, length) {
-        // create nodes hierarchy for one collection (without children)
+    // create nodes hierarchy for one collection (without children)
 
-        // create elem for plus/minus icon
-        var expandElem = document.createElement('expand');
-        // create elem for item icon
-        var iconElem = document.createElement('icon');
-        expandElem.appendChild(iconElem);
-        // Mozilla tries to infer an URL if url is empty and reloads containing page
-        if (icon_url != '')  {
-                iconElem.style.backgroundImage = 'url("' + icon_url + '")';
-                }
-        // create link
-        var linkElem = document.createElement('a');
-        var titleTextNode = document.createTextNode(title);
+    // create elem for plus/minus icon
+    var expandElem = document.createElement('expand');
+    // create elem for item icon
+    var iconElem = document.createElement('icon');
+    expandElem.appendChild(iconElem);
+    // Mozilla tries to infer an URL if url is empty and reloads containing page
+    if (icon_url != '')  {
+        iconElem.style.backgroundImage = 'url("' + icon_url + '")';
+    }
+    // create link
+    var linkElem = document.createElement('a');
+    var titleTextNode = document.createTextNode(title);
 
-        linkElem.appendChild(titleTextNode);
-        var titleText = titleTemplate.split(NUM_TEMPLATE).join(length);
-        linkElem.setAttribute('title', titleText);
-        linkElem.setAttribute('href', targetUrl);
+    linkElem.appendChild(titleTextNode);
+    var titleText = titleTemplate.split(NUM_TEMPLATE).join(length);
+    linkElem.setAttribute('title', titleText);
+    linkElem.setAttribute('href', targetUrl);
 
-        iconElem.appendChild(linkElem);
+    iconElem.appendChild(linkElem);
 
-        return expandElem;
-        }
+    return expandElem;
+}
 
 function createLoadingNode() {
-        var loadingElem = document.createElement('loading');
-        var titleTextNode = document.createTextNode(loadingMsg);
+    var loadingElem = document.createElement('loading');
+    var titleTextNode = document.createTextNode(loadingMsg);
 
-        loadingElem.appendChild(titleTextNode);
+    loadingElem.appendChild(titleTextNode);
 
-        return loadingElem;
-        }
+    return loadingElem;
+}
 
 function createNavigationTreeNode(source, basePath, deep) {
-        var newelem = document.createElement(source.tagName);
+    var newelem = document.createElement(source.tagName);
 
-        var navTreeNode = new navigationTreeNode(newelem);
-        var elemPath;
-        var elemTitle;
-        if (source.getAttribute('isroot') != null) {
-                elemTitle = source.getAttribute('name');
-                //elemPath = basePath;
-                // set base url for virtual host support
-                baseurl = source.getAttribute('baseURL');
-                elemPath = source.getAttribute('baseURL');
-                newelem.style.marginLeft = '0px';
-                navigationTree = navTreeNode;
-                docNavTree.appendChild(newelem);
-                }
-        else {
-                elemTitle = source.getAttribute('name');
-                elemPath = basePath + elemTitle + '/';
-                }
-        navTreeNode.setPath(elemPath);
+    var navTreeNode = new navigationTreeNode(newelem);
+    var elemPath;
+    var elemTitle;
+    if (source.getAttribute('isroot') != null) {
+        elemTitle = source.getAttribute('name');
+        //elemPath = basePath;
+        // set base url for virtual host support
+        baseurl = source.getAttribute('baseURL');
+        elemPath = source.getAttribute('baseURL');
+        newelem.style.marginLeft = '0px';
+        navigationTree = navTreeNode;
+        docNavTree.appendChild(newelem);
+    } else {
+        elemTitle = source.getAttribute('name');
+        elemPath = basePath + elemTitle + '/';
+    }
+    navTreeNode.setPath(elemPath);
 
-        //could show number of child items
-        var length = source.getAttribute('length');
+    //could show number of child items
+    var length = source.getAttribute('length');
 
-        var icon_url = source.getAttribute('icon_url');
+    var icon_url = source.getAttribute('icon_url');
 
-        var targetUrl = elemPath + CONTENT_VIEW;
+    var targetUrl = elemPath + CONTENT_VIEW;
 
-        var expandElem = createPresentationNodes(elemTitle, targetUrl, icon_url, length);
-        newelem.appendChild(expandElem);
+    var expandElem = createPresentationNodes(elemTitle, targetUrl, icon_url, length);
+    newelem.appendChild(expandElem);
 
+    // If no child element, we can disable the tree expansion
+    if (length == '0') expandElem.setAttribute('disabled','1');
 
-        if (deep) {
-                var children = getCollectionChildNodes(source);
-                var numchildren = children.length;
-                for (var i=0; i< numchildren; i++) {
-                        var navTreeNodeChild =  createNavigationTreeNode(children[i], navTreeNode.path, deep);
-                        navTreeNode.appendChild(navTreeNodeChild);
-                        }
-                if (numchildren) {
-                        navTreeNode.isEmpty = 0;
-                        navTreeNode.expand();
-                        }
-                else {
-                        navTreeNode.isEmpty = 1;
-                        navTreeNode.collapse();
-                        }
-                }
-        else {
-                navTreeNode.isEmpty = 1;
-                navTreeNode.collapse();
-                }
-        return navTreeNode;
+    // If this is the selected node, we want to highlight it with CSS
+    if (source.firstChild && source.firstChild.nodeValue == 'selected')
+        navTreeNode.setSelected();
+
+    if (deep) {
+        var children = getCollectionChildNodes(source);
+        var numchildren = children.length;
+        for (var i=0; i<numchildren; i++) {
+            var navTreeNodeChild = createNavigationTreeNode(children[i], navTreeNode.path, deep);
+            navTreeNode.appendChild(navTreeNodeChild);
         }
+        if (numchildren) {
+            navTreeNode.isEmpty = 0;
+            navTreeNode.expand();
+        } else {
+            navTreeNode.isEmpty = 1;
+            // if no child, we do not display icon '+'
+            if (length != '0') navTreeNode.collapse();
+        }
+    } else {
+        navTreeNode.isEmpty = 1;
+        // if no child, we do not display icon '+'
+        if (length != '0') navTreeNode.collapse();
+    }
+    return navTreeNode;
+}

Modified: Zope3/trunk/src/zope/app/rotterdam/zope3.css
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/zope3.css	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/zope3.css	2006-10-08 11:09:13 UTC (rev 70571)
@@ -217,39 +217,42 @@
 }
 
 
-/*  Styles for xmltree
-*/
+/* Styles for xmltree */
 
 #navtreecontents a {
-       cursor: pointer;
-       height: 20px;
+    cursor: pointer;
+    height: 20px;
 }
 
 #navtreecontents loading {
-       display: block;
-       padding-left: 31px;
-       height: 18px;
+    display: block;
+    padding-left: 31px;
+    height: 18px;
 }
 
 #navtreecontents expand {
-       background-repeat: no-repeat;
-       padding-left: 14px;
-       display: inline;
-       cursor: pointer;
-                }
+    background-repeat: no-repeat;
+    padding-left: 14px;
+    display: inline;
+    cursor: pointer;
+}
 
 #navtreecontents icon {
-       background-repeat: no-repeat;
-       padding-left: 20px;
-       display: inline;
-       cursor: auto;
-                }
+    background-repeat: no-repeat;
+    padding-left: 20px;
+    display: inline;
+    cursor: auto;
+}
 
+#navtreecontents icon.selected {
+    background-color: #ffa;
+}
+
 #navtreecontents collection {
-       display: block;
-       margin-left: 10px;
-/*     border: red solid 1pt;  */
-       height: auto;
+    display: block;
+    margin-left: 10px;
+/*  border: red solid 1pt; */
+    height: auto;
 }
 
 
@@ -369,7 +372,7 @@
     color: #fff;
     padding: 0.1em 0.5em 0.1em 0.5em; /* Same as .itemViews */
     border: 1px solid #369; /* Same as .itemViews */
-	margin: 0;
+    margin: 0;
     float: left;
     clear: both;
 }
@@ -379,7 +382,7 @@
     color: white;
     padding: 0.1em 0.5em 0.1em 0.5em; /* Same as .itemViews */
     border: 1px solid red; /* Same as .itemViews */
-	margin: 0;
+    margin: 0;
     float: left;
     clear: both;
 }
@@ -477,7 +480,7 @@
     border-left: 1px solid #CCCCCC;
     border-bottom: 1px solid #CCCCCC;
     margin: 1em 0em 1em 0em;
-/*    clear: both; */
+/*  clear: both; */
 }
 
 table.listingdescription {

Modified: Zope3/trunk/src/zope/app/rotterdam/zope3_tablelayout.css
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/zope3_tablelayout.css	2006-10-08 10:55:03 UTC (rev 70570)
+++ Zope3/trunk/src/zope/app/rotterdam/zope3_tablelayout.css	2006-10-08 11:09:13 UTC (rev 70571)
@@ -242,40 +242,44 @@
 /*  Styles for xmltree
 */
 
-#navtreecontents {  
+#navtreecontents {
     padding-right: 35px;
 }
 
 #navtreecontents a {
-       cursor: pointer;
-       height: 20px;
+    cursor: pointer;
+    height: 20px;
 }
 
 #navtreecontents loading {
-       display: block;
-       padding-left: 31px;
-       height: 18px;
+    display: block;
+    padding-left: 31px;
+    height: 18px;
 }
 
 #navtreecontents expand {
-       background-repeat: no-repeat;
-       padding-left: 14px;
-       display: inline;
-       cursor: pointer;
+    background-repeat: no-repeat;
+    padding-left: 14px;
+    display: inline;
+    cursor: pointer;
 }
 
 #navtreecontents icon {
-       background-repeat: no-repeat;
-       padding-left: 20px;
-       display: inline;
-       cursor: auto;
+    background-repeat: no-repeat;
+    padding-left: 20px;
+    display: inline;
+    cursor: auto;
 }
 
+#navtreecontents icon.selected {
+    background-color: #ffa;
+}
+
 #navtreecontents collection {
-       display: block;
-       margin-left: 10px;
-/*     border: red solid 1pt;  */
-       height: auto;
+    display: block;
+    margin-left: 10px;
+/*  border: red solid 1pt; */
+    height: auto;
 }
 
 
@@ -539,7 +543,7 @@
     border-left: 1px solid #CCCCCC;
     border-bottom: 1px solid #CCCCCC;
     margin: 1em 0em 1em 0em;
-/*    clear: both; */
+/*  clear: both; */
 }
 
 table.listingdescription {
@@ -658,4 +662,3 @@
     padding: 0.5em 1em;
     vertical-align: middle;
 }
-



More information about the Zope3-Checkins mailing list