[Checkins] SVN: jquery.jsontree/trunk/src/jquery/jsontree/ Added
initial version of json tree
Roger Ineichen
roger at projekt01.ch
Mon Jun 11 16:15:26 EDT 2007
Log message for revision 76625:
Added initial version of json tree
Added minimal tests
TODO:
- Add more tests
- Implement better way for render HTML based on JSON callback
- Implement a sample for z3c.website
Changed:
A jquery.jsontree/trunk/src/jquery/jsontree/README.txt
A jquery.jsontree/trunk/src/jquery/jsontree/SETUP.cfg
A jquery.jsontree/trunk/src/jquery/jsontree/__init__.py
A jquery.jsontree/trunk/src/jquery/jsontree/base.py
A jquery.jsontree/trunk/src/jquery/jsontree/browser/
A jquery.jsontree/trunk/src/jquery/jsontree/browser/__init__.py
A jquery.jsontree/trunk/src/jquery/jsontree/browser/configure.zcml
A jquery.jsontree/trunk/src/jquery/jsontree/browser/img/
A jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeCollapsed.gif
A jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeExpanded.gif
A jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeStatic.gif
A jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.css
A jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.js
A jquery.jsontree/trunk/src/jquery/jsontree/browser/li.pt
A jquery.jsontree/trunk/src/jquery/jsontree/browser/tests.py
A jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.pt
A jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.py
A jquery.jsontree/trunk/src/jquery/jsontree/browser/ul.pt
A jquery.jsontree/trunk/src/jquery/jsontree/configure.zcml
A jquery.jsontree/trunk/src/jquery/jsontree/interfaces.py
A jquery.jsontree/trunk/src/jquery/jsontree/jquery.jsontree-configure.zcml
A jquery.jsontree/trunk/src/jquery/jsontree/json.py
A jquery.jsontree/trunk/src/jquery/jsontree/tests/
A jquery.jsontree/trunk/src/jquery/jsontree/tests/__init__.py
A jquery.jsontree/trunk/src/jquery/jsontree/tests/output/
A jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_1.xml
A jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_2.xml
A jquery.jsontree/trunk/src/jquery/jsontree/tests/util.py
A jquery.jsontree/trunk/src/jquery/jsontree/util.py
-=-
Added: jquery.jsontree/trunk/src/jquery/jsontree/README.txt
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/README.txt (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/README.txt 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,28 @@
+======
+README
+======
+
+Version: Alpha
+
+
+Description
+-----------
+
+The jsontree is a <ul> tag tree loading child items via JSON form a context.
+
+NOTE:
+
+Description will follow after I changed the JOSN loader method. See TODO.txt
+
+
+TODO
+----
+
+- Improve rendering of JSON loader result. Allow to render HTML content and
+ skip default.
+
+- write tests
+
+- write documentation
+
+- add a sampe for z3c.website
Added: jquery.jsontree/trunk/src/jquery/jsontree/SETUP.cfg
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/SETUP.cfg (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/SETUP.cfg 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ jquery.jsontree-*.zcml
+</data-files>
Added: jquery.jsontree/trunk/src/jquery/jsontree/__init__.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/__init__.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/__init__.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
Added: jquery.jsontree/trunk/src/jquery/jsontree/base.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/base.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/base.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,449 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import string
+import zope.interface
+import zope.component
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.traversing import api
+from zope.traversing.interfaces import TraversalError
+from zope.security.interfaces import Unauthorized
+from zope.security.interfaces import Forbidden
+from zope.traversing.browser import absoluteURL
+from zope.traversing.namespace import getResource
+from zope.viewlet.interfaces import IViewlet
+from zope.contentprovider.interfaces import IContentProvider
+from zope.app.container.interfaces import IReadContainer
+from zope.app.component import hooks
+from z3c.template.template import getPageTemplate
+
+from jquery.jsontree import interfaces
+from jquery.jsontree.interfaces import JSON_TREE_ID
+from jquery.jsontree.interfaces import JSON_TREE_VIEW_NAME
+from jquery.jsontree.interfaces import JSON_TOGGLE_ICON_COLLAPSED
+from jquery.jsontree.interfaces import JSON_TOGGLE_ICON_EXPANDED
+from jquery.jsontree.interfaces import JSON_TOGGLE_ICON_STATIC
+from jquery.jsontree.interfaces import JSON_LI_CSS_EXPANDED
+from jquery.jsontree.interfaces import JSON_LI_CSS_COLLAPSED
+from jquery.jsontree.interfaces import JSON_LI_CSS_STATIC
+from jquery.jsontree.interfaces import STATE_EXPANDED
+from jquery.jsontree.interfaces import STATE_COLLAPSED
+from jquery.jsontree.interfaces import STATE_STATIC
+from jquery.jsontree import util
+
+
+class TreeBase(object):
+ """Tree iterator base implementation."""
+
+ root = None
+ childTags = None
+ rootChilds = None
+ items = []
+
+ jsonTreeId = JSON_TREE_ID
+ jsonTreeName = JSON_TREE_ID
+ jsonTreeClass = JSON_TREE_ID
+
+ viewName = JSON_TREE_VIEW_NAME
+
+ # LI tag CSS names
+ expandedCSSName = JSON_LI_CSS_EXPANDED
+ collapsedCSSName = JSON_LI_CSS_COLLAPSED
+ staticCSSName = JSON_LI_CSS_STATIC
+
+ # toggle icon names
+ collapsedIconName = JSON_TOGGLE_ICON_COLLAPSED
+ expandedIconNamen = JSON_TOGGLE_ICON_EXPANDED
+ staticIconName = JSON_TOGGLE_ICON_STATIC
+
+ def getRoot(self):
+ if not self.root:
+ self.root = hooks.getSite()
+ return self.root
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def getSubItems(self, item):
+ items = []
+ append = items.append
+ if IReadContainer.providedBy(item):
+ keys = list(item.keys())
+ else:
+ keys = []
+ for name in keys:
+ # Only include items we can traverse to
+ subItem = api.traverse(item, name, None)
+ if subItem is not None:
+ append(subItem)
+ return items
+
+ def getIconURL(self, item, request, name='icon'):
+ return util.getIconURL(item, request, name=name)
+
+ def getParents(self):
+ root = self.getRoot()
+ return util.getParentsFromContextToObject(self.context, root)
+
+ def hasSubItems(self, item):
+ res = False
+ if IReadContainer.providedBy(item):
+ try:
+ if len(item) > 0:
+ res = True
+ except(Unauthorized, Forbidden):
+ pass
+ return res
+
+ def update(self):
+ """Returns HTML code for representing a <ul> tag tree with the
+ siblings and parents of an object.
+
+ There is only one branch expanded, in other words, the tree is
+ filled with the object, its siblings and its parents with
+ their respective siblings. This tree is stateless.
+
+ If we access the tree via a virtual host, the root is adjusted to
+ the right root object.
+
+ """
+ childTags = None
+ stackItem = self.context
+ parents = self.getParents()
+
+ for item in parents:
+ tagList = []
+ append = tagList.append
+
+ for subItem in self.getSubItems(item):
+ if self.hasSubItems(subItem):
+
+ if subItem == stackItem:
+ append(self.renderUL(subItem, childTags))
+ else:
+ append(self.renderUL(subItem))
+
+ else:
+ append(self.renderLI(subItem))
+
+ childTags = ' '.join(tagList)
+ stackItem = item
+
+ self.childTags = childTags
+
+
+class PythonRendererMixin(object):
+ """Mixin class for template less tree generation.
+
+ This renderer is responsible for rendering all HTML elements for the items
+ found in the tree. This means evrey item will be presented in the same way.
+ Use this renderer only if you like to get the same representation for each
+ item. If you need custom representation for each item, use the template
+ based renderer which allows you to define for each item a custom class and
+ template.
+ """
+
+ def getRootName(self):
+ root = self.getRoot()
+ name = api.getName(self.root)
+ if name is None:
+ name = u'[top]'
+ return name
+
+ def getToggleIcon(self, item, state):
+ """Returns a toggle icon including settings for json url."""
+ if state == STATE_COLLAPSED:
+ iconName = self.collapsedIconName
+ elif state == STATE_EXPANDED:
+ iconName = self.expandedIconNamen
+ else:
+ iconName = self.staticIconName
+ icon = zope.component.getMultiAdapter((item, self.request),
+ name=iconName)
+ resource = getResource(icon.context, icon.rname, self.request)
+ src = resource()
+ longDescURL = absoluteURL(item, self.request)
+ return ('<img src="%s" alt="toggle icon" width="%s" height="%s" '
+ 'border="0" longDesc="%s" />' % (src, icon.width,
+ icon.height, longDescURL))
+
+ def renderLI(self, item):
+ name = api.getName(item)
+ url = absoluteURL(item, self.request) +'/'+ self.viewName
+ iconURL = self.getIconURL(item, self.request)
+ id = self.getId(item)
+
+ res = u''
+ toggleIcon = self.getToggleIcon(item, STATE_STATIC)
+ res += '<li id="%s" class="jsonTreeItem">%s' % (id, toggleIcon)
+ if iconURL != '':
+ res += '<img src="%s" width="16" height="16" />' % iconURL
+ res += '<a href="%s">%s</a>' % (url, name)
+ res += '</li>'
+ return res
+
+ def renderUL(self, item, childTags=None):
+ """Renders <li> tag with already rendered child tags."""
+ name = api.getName(item)
+ url = absoluteURL(item, self.request) +'/'+ self.viewName
+ iconURL = self.getIconURL(item, self.request)
+ id = self.getId(item)
+
+ if item == self.context:
+ state = STATE_COLLAPSED
+ liClass = self.collapsedCSSName
+ else:
+ state = STATE_EXPANDED
+ liClass = self.expandedCSSName
+
+ if childTags is None:
+ state = STATE_COLLAPSED
+ liClass = self.collapsedCSSName
+
+ toggleIcon = self.getToggleIcon(item, state)
+
+ res = u''
+ res += '<li id="%s" class="%s">%s' % (id, liClass, toggleIcon)
+ if iconURL != '':
+ res += '<img src="%s" class="" width="16" height="16" />' % iconURL
+ res += '<a href="%s">%s</a>' % (url, name)
+ res += ' <ul>'
+ if childTags is not None:
+ res += ' %s' % childTags
+ res += ' </ul>'
+ res += '</li>'
+ return res
+
+ @property
+ def tree(self):
+ root = self.getRoot()
+ if root is None:
+ raise ValueError("Missing tree root object.")
+ id = self.getId(root)
+ rootName = self.getRootName()
+ url = absoluteURL(root, self.request) +'/'+ self.viewName
+
+ # setup root item
+ if self.childTags is None:
+ rootChilds = ''
+ liClass = self.collapsedCSSName
+ state = STATE_COLLAPSED
+ else:
+ rootChilds = '<ul>%s</ul>' % self.childTags
+ liClass = self.expandedCSSName
+ state = STATE_EXPANDED
+
+ # setup root toggle icon
+ toggleIcon = self.getToggleIcon(self.context, state)
+
+ # setup root link
+ rootLink = '<a href="%s">%s</a>' % (url, rootName)
+ rootItem = '<li id="%s" class="%s">%s%s%s</li>' % \
+ (id, liClass, toggleIcon, rootLink, rootChilds)
+
+ # render the <ul> tag tree
+ jsonTree = u''
+ jsonTree += '<ul class="%s" id="%s" name="%s">%s</ul>' % (
+ self.jsonTreeClass, self.jsonTreeId, self.jsonTreeName, rootItem)
+ return jsonTree
+
+
+class TemplateRendererMixin(object):
+ """Mixin class for template based tree generation.
+
+ This implementation uses IContentProvider for element tag rendering. This
+ makes it very flexible.
+
+ Note: Don't forget to define custom JSONTreeItems methods which reflect the
+ custom rendering. Or you will get the default rendering behavior for JSON
+ loaded items.
+ """
+
+ zope.interface.implements(interfaces.ITemplateRenderer)
+
+ def renderLI(self, item):
+ provider = zope.component.getMultiAdapter(
+ (item, self.request, self), IContentProvider,
+ self.liProviderName)
+ provider.state = STATE_STATIC
+ provider.update()
+ return provider.render()
+
+ def renderUL(self, item, childTags=None):
+ """Renders <li> tag with already rendered child tags."""
+ if item == self.context:
+ state = STATE_COLLAPSED
+ else:
+ state = STATE_EXPANDED
+
+ if childTags is None:
+ state = STATE_COLLAPSED
+
+ provider = zope.component.getMultiAdapter(
+ (item, self.request, self), IContentProvider,
+ self.ulProviderName)
+ provider.childTags = childTags
+ provider.state = state
+ provider.update()
+ return provider.render()
+
+ @property
+ def tree(self):
+ root = self.getRoot()
+ if root is None:
+ raise ValueError("Missing tree root object.")
+
+ if self.childTags is None:
+ state = STATE_COLLAPSED
+ else:
+ state = STATE_EXPANDED
+
+ provider = zope.component.getMultiAdapter(
+ (root, self.request, self), IContentProvider,
+ self.treeProviderName)
+ provider.childTags = self.childTags
+ provider.state = state
+ provider.update()
+ return provider.render()
+
+
+class IdGeneratorMixin(object):
+ """This mixin class generates Object Ids based on the the objects path.
+
+ Note: The objects must be traversable by it's path. You can implement a
+ a custom path traverse concept in the getObjectByPath it you need to use
+ another traverse concept.
+
+ This ids must conform the w3c recommendation described in:
+ http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-name
+ """
+
+ def getId(self, item):
+ """Returns the DOM id for a given object.
+
+ Note: we encode the upper case letters because the Dom element id are
+ not case sensitive in HTML. We prefix each upper case letter with ':'.
+ """
+ path = api.getPath(item)
+ newPath = u''
+ for letter in path:
+ if letter in string.uppercase:
+ newPath += ':' + letter
+ else:
+ newPath += letter
+
+ # we use a dot as a root representation, this also avoids to get the
+ # same id for the ul and the first li tag
+ if newPath == '/':
+ newPath = '.'
+ # add additinal dot which separates the tree id and the path, this is
+ # used for get the tree id out of the string in the javascript using
+ # ids = id.split("."); treeId = ids[0];
+ id = self.jsonTreeId +'.'+ newPath
+ # convert '/' path separator to marker '::', because the path '/'' is
+ # not allowed as DOM id. See also:
+ # http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-name
+ return id.replace('/', '::')
+
+ def id(self):
+ """Returns the DOM id for a given context."""
+ return self.getId(self.context)
+
+
+class ProviderBase(object):
+ """Base class for element provider."""
+
+ template = getPageTemplate()
+
+ state = None
+ childTags = None
+ viewName = u'@@SelectedManagementView.html'
+ iconName = 'icon'
+
+ # LI tag CSS names
+ collapsedCSSName = JSON_LI_CSS_COLLAPSED
+ expandedCSSName = JSON_LI_CSS_EXPANDED
+ staticCSSName = JSON_LI_CSS_STATIC
+
+ # toggle icon names
+ collapsedIconName = JSON_TOGGLE_ICON_COLLAPSED
+ expandedIconNamen = JSON_TOGGLE_ICON_EXPANDED
+ staticIconName = JSON_TOGGLE_ICON_STATIC
+
+ def __init__(self, context, request, view):
+ self.context = context
+ self.request = request
+ self.view = view
+
+ @property
+ def className(self):
+ if self.state == STATE_COLLAPSED:
+ return self.collapsedCSSName
+ elif self.state == STATE_EXPANDED:
+ return self.expandedCSSName
+ else:
+ return self.staticCSSName
+
+ @property
+ def toggleIcon(self):
+ """Returns a toggle icon including settings for json url."""
+ if self.state == STATE_COLLAPSED:
+ iconName = self.collapsedIconName
+ elif self.state == STATE_EXPANDED:
+ iconName = self.expandedIconNamen
+ else:
+ iconName = self.staticIconName
+ icon = zope.component.getMultiAdapter((self.context, self.request),
+ name=iconName)
+ resource = getResource(icon.context, icon.rname, self.request)
+ src = resource()
+ longDescURL = absoluteURL(self.context, self.request)
+ return ('<img src="%s" alt="toggle icon" width="%s" height="%s" '
+ 'border="0" longDesc="%s" />' % (src, icon.width,
+ icon.height, longDescURL))
+
+ def icon(self):
+ """Returns a toggle icon including settings for json url."""
+ icon = zope.component.queryMultiAdapter((self.context, self.request),
+ name=self.iconName)
+ if icon is not None:
+ resource = getResource(icon.context, icon.rname, self.request)
+ src = resource()
+ longDescURL = absoluteURL(self.context, self.request)
+ return ('<img src="%s" alt="toggle icon" width="%s" height="%s" '
+ 'border="0" />' % (src, icon.width, icon.height))
+ return u''
+
+ @property
+ def name(self):
+ return api.getName(self.context)
+
+ @property
+ def url(self):
+ return absoluteURL(self.context, self.request) +'/'+ self.viewName
+
+ def update(self):
+ pass
+
+ def render(self):
+ template = zope.component.getMultiAdapter((self, self.request),
+ IPageTemplate)
+ return template(self)
+
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/__init__.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/__init__.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/__init__.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,22 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+
+from zope.viewlet import viewlet
+
+
+JSONTreeCSSViewlet = viewlet.CSSViewlet('jsontree.css')
+JSONTreeJavaScriptViewlet = viewlet.JavaScriptViewlet('jsontree.js')
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/configure.zcml
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/configure.zcml (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/configure.zcml 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,62 @@
+<configure
+ xmlns:zope="http://namespaces.zope.org/zope"
+ xmlns="http://namespaces.zope.org/browser"
+ xmlns:z3c="http://namespaces.zope.org/z3c"
+ i18n_domain="jquery">
+
+ <!-- provider and template for content providers -->
+ <zope:adapter
+ name="tree"
+ factory=".tree.TreeProvider"
+ />
+ <z3c:template
+ template="tree.pt"
+ for="jquery.jsontree.interfaces.ITreeProvider"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+ <zope:adapter
+ name="li"
+ factory=".tree.LITagProvider"
+ />
+ <z3c:template
+ template="li.pt"
+ for="jquery.jsontree.interfaces.ILITagProvider"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+ <zope:adapter
+ name="ul"
+ factory=".tree.ULTagProvider"
+ />
+ <z3c:template
+ template="ul.pt"
+ for="jquery.jsontree.interfaces.IULTagProvider"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+
+ <!-- default icons -->
+ <icon
+ name="jsonTreeCollapsedIcon"
+ for="zope.interface.Interface"
+ file="img/jsonTreeCollapsed.gif"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+ <icon
+ name="jsonTreeExpandedIcon"
+ for="zope.interface.Interface"
+ file="img/jsonTreeExpanded.gif"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+ <icon
+ name="jsonTreeStaticIcon"
+ for="zope.interface.Interface"
+ file="img/jsonTreeStatic.gif"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+
+</configure>
\ No newline at end of file
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeCollapsed.gif
===================================================================
(Binary files differ)
Property changes on: jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeCollapsed.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeExpanded.gif
===================================================================
(Binary files differ)
Property changes on: jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeExpanded.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeStatic.gif
===================================================================
(Binary files differ)
Property changes on: jquery.jsontree/trunk/src/jquery/jsontree/browser/img/jsonTreeStatic.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.css
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.css (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.css 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,42 @@
+
+ul.jsonTree {
+ list-style-type: none;
+ margin: 0px;
+ padding: 0px;
+}
+
+ul.jsonTree ul {
+ margin-left: 12px;
+ padding: 0px;
+}
+
+ul.jsonTree li {
+ list-style: none;
+ white-space: nowrap;
+ margin: 0px;
+ padding: 0px;
+}
+
+ul.jsonTree img {
+ height: 16px;
+}
+
+ul.jsonTree a {
+ text-decoration: none;
+}
+
+ul.jsonTree .jsonTreeIcon {
+ cursor: pointer;
+}
+
+ul.jsonTree li.jsonTreeItem .jsonTreeIcon {
+ cursor: default;
+}
+
+ul.jsonTree li.jsonTreeExpanded ul {
+ display: block;
+}
+
+ul.jsonTree li.jsonTreeCollapsed ul {
+ display: none;
+}
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.js
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.js (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/jsontree.js 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,159 @@
+//----------------------------------------------------------------------------
+/**
+ * @fileoverview JSON supported unordered list based tree
+ *
+ * @author Roger Ineichen dev at projekt01 dot org.
+ * @version Initial, not documented
+ */
+//----------------------------------------------------------------------------
+/* zrt-replace: "./jsonTreeIMG" tal"string:${context/++resource++jsonTreeIMG}" */
+
+/* TODO: use metadata plugin for get/set the json loader uri */
+
+//----------------------------------------------------------------------------
+// public API
+//----------------------------------------------------------------------------
+
+
+(function($) {
+$.fn.jsonTree = function (settings) {
+ settings = $.extend({
+ jsonTreeCollapsedGif: './jsonTreeIMG/jsonTreeCollapsed.gif',
+ jsonTreeExpandedGif: './jsonTreeIMG/jsonTreeExpanded.gif',
+ jsonTreeStaticGif: './jsonTreeIMG/jsonTreeStatic.gif',
+ jsonTreeCollapsedClass: 'jsonTreeCollapsed',
+ jsonTreeExpandedClass: 'jsonTreeExpanded',
+ jsonTreeStaticClass: 'jsonTreeItem',
+ jsonTreeIconClass: 'jsonTreeIcon',
+ loadItemsMethodName: 'loadJSONTreeItems'
+ }, settings);
+
+ function jsonTreeToggleItem(img) {
+ ele = img.parentNode;
+ var uri = $(img).attr('longDesc');
+ if ($.className.has(ele, settings.jsonTreeExpandedClass)) {
+ ele.className = settings.jsonTreeCollapsedClass;
+ $(img).attr("src", settings.jsonTreeCollapsedGif);
+ }
+ else {
+ /* check for sub items */
+ if ($(ele).find('li').length == 0){
+ /* load childs from server via JSON */
+ id = $(ele).attr('id');
+ jsonTreeLoadItems(uri, id);
+ }
+ ele.className = settings.jsonTreeExpandedClass;
+ $(img).attr("src", settings.jsonTreeExpandedGif);
+ }
+ return false;
+ }
+
+ function jsonTreeLoadItems(uri, id) {
+ /* each different json tree uses a own function for calling the childs */
+ loader = settings.loadItemsMethodName;
+ var jsonProxy = new JSONRPC(uri);
+ jsonProxy.addMethod(loader, jsonTreeAddItems, id);
+ /* call the child loader method */
+ var loaderMethod = jsonProxy[loader];
+ loaderMethod(id);
+ }
+
+ function jsonTreeAddItems(response, requestId) {
+ var res = response['treeChilds'];
+ var childs = res['childs'];
+ ele = document.getElementById(res['id']);
+ var ele = $(ele);
+ var ul = null;
+
+ /* find ul tag which will contain the new childs */
+ var ul = ele.find('ul')[0]
+ if (!ul){
+ ele.append('<ul></ul>')
+ }
+ var ul = ele.find('ul')[0]
+
+ /* render and append the new childs to the existing empty <ul> tag */
+ for (var i=0; i<childs.length; i++) {
+ var itemInfo = childs[i];
+ var iconSrc = itemInfo['iconURL'];
+ var hasChilds = itemInfo['hasChilds'];
+ var linkHandler = itemInfo['linkHandler'];
+ var contextURL = itemInfo['contextURL'];
+
+ /* create toggle icon */
+ if (iconSrc != '') {
+ var icon = $('<img></img>');
+ icon.attr("src", iconSrc);
+ }
+ /* create li tag */
+ var li = $('<li></li>');
+ li.attr("id", itemInfo['id']);
+
+ /* create toggle image */
+ var img = $('<img></img>');;
+ img.attr("width", "16");
+ img.attr("height", "16");
+ if (hasChilds) {
+ img.className = settings.jsonTreeIconClass;
+ img.attr('longDesc', contextURL);
+ img.click(function(){
+ jsonTreeToggleItem(this)
+ });
+ img.attr("src", settings.jsonTreeCollapsedGif);
+ li.className = settings.jsonTreeCollapsedClass;
+ }
+ else{
+ li.className = settings.jsonTreeStaticClass;
+ img.attr("src", settings.jsonTreeStaticGif);
+ }
+ /* create link or handler */
+ var a = $('<a href=""></a>');
+ if (linkHandler != '') {
+ a.click(eval(linkHandler));
+ a.attr("href", '#');
+ }else {
+ a.attr("href", itemInfo['url']);
+ }
+ /* append content to link */
+ a.html(itemInfo['content']);
+ li.append(a);
+ /* append link to to link */
+ if (iconSrc != '') {
+ icon.insertBefore(a);
+ img.insertBefore(icon);
+ }
+ else {
+ img.insertBefore(a);
+ }
+ $(ul).append(li);
+ }
+ }
+
+ // render tree
+ function renderTree(ul) {
+ if ($(ul).length == 0) {
+ return;
+ }
+ for (var i=0; i<ul.childNodes.length; i++) {
+ var item = ul.childNodes[i];
+ if (item.nodeName == "LI") {
+ for (var si=0; si<item.childNodes.length; si++) {
+ var subitem = item.childNodes[si];
+ if (subitem.nodeName == "UL") {
+ renderTree(subitem, false);
+ }
+ }
+ img = $(item.firstChild);
+ img.click(function(){
+ jsonTreeToggleItem(this)
+ });
+ }
+ }
+ }
+
+ // initialize json trees
+ return $(this).each(function(){
+ renderTree(this);
+ });
+};
+})(jQuery);
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/li.pt
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/li.pt (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/li.pt 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,11 @@
+<li id="" class=""
+ tal:attributes="id view/id;
+ class view/className"
+ ><img src="" width="16" height="16"
+ tal:replace="structure view/toggleIcon"
+ /><img src="" width="16" height="16"
+ tal:replace="structure view/icon"
+ /><a href=""
+ tal:attributes="href view/url"
+ tal:content="structure view/name"></a>
+</li>
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/tests.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/tests.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/tests.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,85 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+
+import zope.component
+import zope.app.security
+from zope.app.component import hooks
+from zope.configuration.xmlconfig import XMLConfig
+from zope.pagetemplate.tests.util import check_xml
+from zope.publisher.browser import TestRequest
+from zope.app.component import testing
+
+from z3c.testing import TestCase
+from jquery.jsontree.tests import util
+from jquery.jsontree.browser import tree
+
+
+class TestView(tree.SimpleJSONTree):
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+
+class TestJSONTreeView(testing.PlacefulSetup, TestCase):
+
+ def setUp(self):
+ testing.PlacefulSetup.setUp(self, site=True)
+ self.rootFolder.__name__ = 'rootFolder'
+ hooks.setSite(self.rootFolder)
+ import zope.app.publication
+ import zope.app.publisher.browser
+ import z3c.template
+ import jquery.jsontree
+ import zif.jsonserver
+ XMLConfig('meta.zcml', zope.component)()
+ XMLConfig('meta.zcml', zope.app.security)()
+ XMLConfig('meta.zcml', zope.app.publication)()
+ XMLConfig('meta.zcml', zope.app.publisher.browser)()
+ XMLConfig('meta.zcml', z3c.template)()
+ XMLConfig('meta.zcml', zif.jsonserver)()
+ XMLConfig('configure.zcml', jquery.jsontree)()
+
+ def test_getTree_folder1(self):
+ context = self.rootFolder['folder1']
+ request = TestRequest()
+ view = TestView(context, request)
+ view.update()
+ ultree = view.tree
+ check_xml(ultree, util.read_output('tree_1.xml'))
+
+ def test_getTree_folder2_1_1(self):
+ """This test includes cyrillic letters."""
+ context = self.rootFolder['folder2']['folder2_1']['folder2_1_1']
+ request = TestRequest()
+ view = TestView(context, request)
+ view.update()
+ ultree = view.tree
+ check_xml(ultree, util.read_output('tree_2.xml'))
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(TestJSONTreeView),
+ ))
+
+
+if __name__=='__main__':
+ unittest.main(defaultTest='test_suite')
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.pt
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.pt (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.pt 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,20 @@
+<ul class="" id="" name=""
+ tal:attributes="id view/jsonTreeId;
+ class view/jsonTreeClass;
+ name view/jsonTreeName">
+ <li id="" class=""
+ tal:define="childTags view/childTags"
+ tal:attributes="id view/id;
+ class view/className"
+ ><img src="" width="16" height="16"
+ tal:replace="structure view/toggleIcon"
+ /><img src="" width="16" height="16"
+ tal:replace="structure view/icon"
+ /><a href=""
+ tal:attributes="href view/url"
+ tal:content="structure view/name"></a>
+ <ul tal:condition="childTags"
+ tal:content="structure childTags">
+ </ul>
+ </li>
+</ul>
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/tree.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,131 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.interface
+import zope.component
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.traversing import api
+from zope.traversing.browser import absoluteURL
+from zope.viewlet.interfaces import IViewlet
+from zope.contentprovider.interfaces import IContentProvider
+from zope.app.container.interfaces import IReadContainer
+from zope.app.intid.interfaces import IIntIds
+from z3c.template.template import getPageTemplate
+
+from jquery.jsontree import interfaces
+from jquery.jsontree.interfaces import JSON_TREE_ID
+from jquery.jsontree import base
+
+
+# simple trees
+class SimpleJSONTree(base.TreeBase, base.PythonRendererMixin,
+ base.IdGeneratorMixin):
+ """Simple JSON tree using inline methods for rendering elements and
+ using traversable path for item lookup.
+ """
+
+ zope.interface.implements(interfaces.ISimpleJSONTree)
+
+ def update(self):
+ super(SimpleJSONTree, self).update()
+
+
+# simple tree viewlet
+class SimpleJSONTreeViewlet(SimpleJSONTree):
+ """Simple JSON tree viewlet."""
+
+ zope.interface.implements(IViewlet)
+
+ def __init__(self, context, request, view, manager):
+ super(SimpleJSONTreeViewlet, self).__init__(context, request)
+ self.__parent__ = view
+ self.context = context
+ self.request = request
+ self.manager = manager
+
+
+# generic template based tree
+class LITagProvider(base.ProviderBase, base.IdGeneratorMixin):
+ """LI tag content provider."""
+
+ zope.interface.implements(interfaces.ILITagProvider)
+ zope.component.adapts(zope.interface.Interface, IBrowserRequest,
+ interfaces.ITemplateRenderer)
+
+ jsonTreeId = JSON_TREE_ID
+
+
+class ULTagProvider(base.ProviderBase, base.IdGeneratorMixin):
+ """UL tag contet provider."""
+
+ zope.interface.implements(interfaces.IULTagProvider)
+ zope.component.adapts(zope.interface.Interface, IBrowserRequest,
+ interfaces.ITemplateRenderer)
+
+ childTags = None
+
+ jsonTreeId = JSON_TREE_ID
+
+
+class TreeProvider(base.ProviderBase, base.IdGeneratorMixin):
+ """UL tag contet provider."""
+
+ zope.interface.implements(interfaces.ITreeProvider)
+ zope.component.adapts(zope.interface.Interface, IBrowserRequest,
+ interfaces.ITemplateRenderer)
+
+ # provider id, class and name
+ jsonTreeId = JSON_TREE_ID
+ jsonTreeClass = JSON_TREE_ID
+ jsonTreeName = JSON_TREE_ID
+ childTags = None
+
+
+class GenericJSONTree(base.TreeBase, base.TemplateRendererMixin,
+ base.IdGeneratorMixin):
+ """IntId base object lookup and template base rendering.
+
+ This implementation uses IContentProvider for element tag rendering.
+ This content provider are resonsible for represent a node. This allows us
+ to embed html or javascript calls in the html representation in a smart
+ way.
+ """
+
+ zope.interface.implements(interfaces.IGenericJSONTree)
+
+ liProviderName = 'li'
+ ulProviderName = 'ul'
+ treeProviderName = 'tree'
+
+ def update(self):
+ super(GenericJSONTree, self).update()
+
+
+# generic tree viewlet
+class GenericJSONTreeViewlet(GenericJSONTree):
+ """Generic JSON tree viewlet."""
+
+ zope.interface.implements(IViewlet)
+
+ def __init__(self, context, request, view, manager):
+ super(GenericJSONTreeViewlet, self).__init__(context, request)
+ self.__parent__ = view
+ self.context = context
+ self.request = request
+ self.manager = manager
Added: jquery.jsontree/trunk/src/jquery/jsontree/browser/ul.pt
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/browser/ul.pt (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/browser/ul.pt 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,15 @@
+<li id="" class=""
+ tal:define="childTags view/childTags"
+ tal:attributes="id view/id;
+ class view/className"
+ ><img src="" width="16" height="16"
+ tal:replace="structure view/toggleIcon"
+ /><img src="" width="16" height="16"
+ tal:replace="structure view/icon"
+ /><a href=""
+ tal:attributes="href view/url"
+ tal:content="structure view/name"></a>
+ <ul tal:condition="childTags"
+ tal:content="structure childTags">
+ </ul>
+</li>
Added: jquery.jsontree/trunk/src/jquery/jsontree/configure.zcml
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/configure.zcml (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/configure.zcml 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,16 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:jsonrpc="http://namespaces.zope.org/jsonrpc"
+ i18n_domain="jquery">
+
+ <include package=".browser" />
+
+ <!-- this method only returns what the user has permission for -->
+ <jsonrpc:view
+ for="*"
+ class="jquery.jsontree.json.JSONTreeItems"
+ permission="zope.Public"
+ methods="loadJSONTreeItems"
+ />
+
+</configure>
\ No newline at end of file
Added: jquery.jsontree/trunk/src/jquery/jsontree/interfaces.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/interfaces.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/interfaces.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,164 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.interface
+from zope.contentprovider.interfaces import IContentProvider
+
+# DOM id and name for json tree ``<UL>`` tag
+JSON_TREE_ID = u'jsonTree'
+JSON_TREE_VIEW_NAME = u'@@SelectedManagementView.html'
+
+JSON_TOGGLE_ICON_COLLAPSED = 'jsonTreeCollapsedIcon'
+JSON_TOGGLE_ICON_EXPANDED = 'jsonTreeExpandedIcon'
+JSON_TOGGLE_ICON_STATIC = 'jsonTreeStaticIcon'
+
+JSON_LI_CSS_EXPANDED = u'jsonTreeExpanded'
+JSON_LI_CSS_COLLAPSED = u'jsonTreeCollapsed'
+JSON_LI_CSS_STATIC = u'jsonTreeStatic'
+
+STATE_EXPANDED = 'expanded'
+STATE_COLLAPSED = 'collapsed'
+STATE_STATIC = 'static'
+
+
+class IDOMContentProvider(IContentProvider):
+
+ state = zope.interface.Attribute(
+ """The collapsed, expanded or static state .""")
+
+ childTags = zope.interface.Attribute(
+ """A list of rendered child tags.""")
+
+ viewName = zope.interface.Attribute(
+ """The view name which get called on the context.""")
+
+ collapsedCSSName = zope.interface.Attribute(
+ """Class name for the collapsed <LI> tag.""")
+ expandedCSSName = zope.interface.Attribute(
+ """Class name for the expanded <LI> tag.""")
+ staticCSSName = zope.interface.Attribute(
+ """Class name for the static <LI> tag.""")
+
+ # context icon
+ iconName = zope.interface.Attribute(
+ """The icon name for the context icon.""")
+
+ # toggle icon
+ collapsedIconName = zope.interface.Attribute(
+ """The icon name for the collapsed icon.""")
+ expandedIconNamen = zope.interface.Attribute(
+ """The icon name for the expanded icon.""")
+ staticIconName = zope.interface.Attribute(
+ """The icon name for the static icon.""")
+
+ # properties
+ className = zope.interface.Attribute(
+ """The CSS class name for the rendered <LI> tag.""")
+
+ toggleIcon = zope.interface.Attribute(
+ """The toggle icon including settings for json url.""")
+
+ icon = zope.interface.Attribute("""The icon for the given context.""")
+
+ name = zope.interface.Attribute("""The context name""")
+
+ url = zope.interface.Attribute("""The context url""")
+
+ def update():
+ """Must get called before render."""
+
+ def render():
+ """Render the template."""
+
+
+# content provider using templates
+class ILITagProvider(IDOMContentProvider):
+ """Content provider for ``LI`` tag."""
+
+
+class IULTagProvider(IDOMContentProvider):
+ """Content provider for ``UL`` tag."""
+
+
+class ITreeProvider(IDOMContentProvider):
+ """Content provider for tree (main) ``UL`` tag."""
+
+
+# tree renderer interfaces
+class ITreeRenderer(zope.interface.Interface):
+ """Knows how to render elements fo the tree items."""
+
+ def renderLI(item):
+ """Renders <LI> tags."""
+
+ def renderUL(item, childTags=None):
+ """Renders <li> tag including rendered child tags."""
+
+ tree = zope.interface.Attribute(
+ """Renders <ul> tree tag including rendered child tags.""")
+
+
+class IPythonRenderer(ITreeRenderer):
+ """Uses python methods for rendering the tree items."""
+
+
+class ITemplateRenderer(ITreeRenderer):
+ """Uses IContentProvider classes within templates for rendereing the items.
+ """
+
+
+class IIdGenerator(zope.interface.Interface):
+ """Knows how to get ids for the tree items."""
+
+ def getId(item):
+ """Returns the DOM id for a given object.
+
+ Note: we encode the upper case letters because the Dom element id are
+ not case sensitive in HTML. We prefix each upper case letter with ':'.
+ """
+
+ def id():
+ """Returns the DOM id for a given context."""
+
+
+class IJSONTree(ITreeRenderer, IIdGenerator):
+ """Complete JSON tree definition.
+
+ Don't care about the javascript part, just implement all methods define in
+ this interfaces.
+ """
+
+
+class ISimpleJSONTree(IJSONTree):
+ """Simple JSON tree implementation.
+
+ Simple JSON tree using inline methods for rendering elements and
+ traversable path for item lookup.
+ """
+
+
+class IGenericJSONTree(IJSONTree):
+ """Generic JSON tree implementation.
+
+ IntId base object lookup and template base rendering.
+
+ This implementation uses IContentProvider for element tag rendering.
+ This content provider are resonsible for represent a node. This allows us
+ to embed html or javascript calls in the html representation in a smart
+ way.
+ """
Added: jquery.jsontree/trunk/src/jquery/jsontree/jquery.jsontree-configure.zcml
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/jquery.jsontree-configure.zcml (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/jquery.jsontree-configure.zcml 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1 @@
+<include package="jquery.jsontree" />
Added: jquery.jsontree/trunk/src/jquery/jsontree/json.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/json.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/json.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,107 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.component
+from zope.traversing import api
+from zope.traversing.browser import absoluteURL
+from zope.app.container.interfaces import IReadContainer
+from zope.app.intid.interfaces import IIntIds
+
+from zif.jsonserver.jsonrpc import MethodPublisher
+
+from jquery.jsontree import interfaces
+from jquery.jsontree.interfaces import JSON_TREE_ID
+from jquery.jsontree.interfaces import JSON_TREE_VIEW_NAME
+from jquery.jsontree import base
+from jquery.jsontree import util
+
+
+class JSONTreeItems(MethodPublisher, base.IdGeneratorMixin):
+ """Returns the data of the childs from the path for the json tree.
+
+ This is a simple implementation which uses the traversal concept.
+ If you need to lookup items for other conponents then ocntianers,
+ e.g. for a widget, you need to implement your own child loader class.
+ """
+
+ viewName = JSON_TREE_VIEW_NAME
+ jsonTreeId = JSON_TREE_ID
+ linkHandler = ''
+
+ @property
+ def subItems(self):
+ """Returns a list of items for the given context."""
+ items = []
+ keys = []
+ append = items.append
+ if IReadContainer.providedBy(self.context):
+ try:
+ keys = list(self.context.keys())
+ except(Unauthorized, Forbidden):
+ return items
+ for name in keys:
+ # Only include items we can traverse to
+ subItem = api.traverse(self.context, name, None)
+ if subItem is not None:
+ append(subItem)
+ return items
+
+ def hasSubItems(self, item):
+ """Returns a True or False if the sub item has subitems."""
+ res = False
+ if IReadContainer.providedBy(item):
+ try:
+ if len(item) > 0:
+ res = True
+ except(Unauthorized, Forbidden):
+ pass
+ return res
+
+ def getIconURL(self, item, request, name='icon'):
+ return util.getIconURL(item, request, name=name)
+
+ def loadJSONTreeItems(self, id):
+ """Returns child information for the object with the given path in a
+ JSON format.
+
+ """
+ res = {}
+ childs = []
+ append = childs.append
+
+ for subItem in self.subItems:
+
+ if self.hasSubItems(subItem):
+ hasChilds = True
+ else:
+ hasChilds = False
+
+ info = {}
+ url = absoluteURL(subItem, self.request)
+ info['id'] = self.getId(subItem)
+ info['content'] = api.getName(subItem)
+ info['url'] = url +'/'+ self.viewName
+ info['iconURL'] = util.getIconURL(subItem, self.request)
+ info['linkHandler'] = self.linkHandler
+ info['hasChilds'] = hasChilds
+ info['contextURL'] = url
+ append(info)
+
+ res['treeChilds'] = {'id':id, 'childs':childs}
+
+ return res
Added: jquery.jsontree/trunk/src/jquery/jsontree/tests/__init__.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/tests/__init__.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/tests/__init__.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
Added: jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_1.xml
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_1.xml (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_1.xml 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1 @@
+<ul class="jsonTree" id="jsonTree" name="jsonTree"><li id="jsonTree.." class="jsonTreeExpanded"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeExpandedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder1" /><a href="http://127.0.0.1/rootFolder/@@SelectedManagementView.html"></a><ul><li id="jsonTree.::folder1" class="jsonTreeCollapsed"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeCollapsedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder1" /><a href="http://127.0.0.1/rootFolder/folder1/@@SelectedManagementView.html">folder1</a><ul></ul></li><li id="jsonTree.::folder2" class="jsonTreeCollapsed"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeCollapsedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder2" /><a href="http://127.0.0.1/rootFolder/folder2/@@SelectedManagementView.html">folder2</a><ul></ul></li><li id="jsonTree.::папка3" class="jsonTreeCollapsed"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeCollapsedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/%D0%BF%D0%B0%D0%BF%D0%BA%D0%B03" /><a href="http://127.0.0.1/rootFolder/%D0%BF%D0%B0%D0%BF%D0%BA%D0%B03/@@SelectedManagementView.html">папка3</a><ul></ul></li></ul></li></ul>
Added: jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_2.xml
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_2.xml (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/tests/output/tree_2.xml 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1 @@
+<ul class="jsonTree" id="jsonTree" name="jsonTree"><li id="jsonTree.." class="jsonTreeExpanded"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeExpandedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder2/folder2_1/folder2_1_1" /><a href="http://127.0.0.1/rootFolder/@@SelectedManagementView.html"></a><ul><li id="jsonTree.::folder1" class="jsonTreeCollapsed"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeCollapsedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder1" /><a href="http://127.0.0.1/rootFolder/folder1/@@SelectedManagementView.html">folder1</a><ul></ul></li><li id="jsonTree.::folder2" class="jsonTreeExpanded"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeExpandedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder2" /><a href="http://127.0.0.1/rootFolder/folder2/@@SelectedManagementView.html">folder2</a><ul><li id="jsonTree.::folder2::folder2_1" class="jsonTreeExpanded"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeExpandedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder2/folder2_1" /><a href="http://127.0.0.1/rootFolder/folder2/folder2_1/@@SelectedManagementView.html">folder2_1</a><ul><li id="jsonTree.::folder2::folder2_1::folder2_1_1" class="jsonTreeItem"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeStaticIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/folder2/folder2_1/folder2_1_1" /><a href="http://127.0.0.1/rootFolder/folder2/folder2_1/folder2_1_1/@@SelectedManagementView.html">folder2_1_1</a></li></ul></li></ul></li><li id="jsonTree.::папка3" class="jsonTreeCollapsed"><img src="http://127.0.0.1/rootFolder/@@/zope-interface-Interface-jsonTreeCollapsedIcon.gif" alt="toggle icon" width="16" height="16" border="0" longDesc="http://127.0.0.1/rootFolder/%D0%BF%D0%B0%D0%BF%D0%BA%D0%B03" /><a href="http://127.0.0.1/rootFolder/%D0%BF%D0%B0%D0%BF%D0%BA%D0%B03/@@SelectedManagementView.html">папка3</a><ul></ul></li></ul></li></ul>
\ No newline at end of file
Added: jquery.jsontree/trunk/src/jquery/jsontree/tests/util.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/tests/util.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/tests/util.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import os
+
+def read_output(filename):
+ import jquery.jsontree.tests
+ dir = os.path.dirname(jquery.jsontree.tests.__file__)
+ output_dir = os.path.join(dir, 'output')
+ filename = os.path.join(output_dir, filename)
+ return open(filename, 'r').read().decode("utf-8")
Added: jquery.jsontree/trunk/src/jquery/jsontree/util.py
===================================================================
--- jquery.jsontree/trunk/src/jquery/jsontree/util.py (rev 0)
+++ jquery.jsontree/trunk/src/jquery/jsontree/util.py 2007-06-11 20:15:25 UTC (rev 76625)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.component
+from zope.traversing import api
+from zope.proxy import sameProxiedObjects
+from zope.traversing.interfaces import TraversalError
+
+
+def getIconURL(item, request, name='icon'):
+ url = ''
+ icon = zope.component.queryMultiAdapter((item, request), name=name)
+ if icon is not None:
+ try:
+ url = icon.url()
+ except TraversalError:
+ return url
+ return url
+
+
+def isChildOf(child, parent):
+ """Check if object is a child of the parent."""
+ if parent in api.getParents(child):
+ return True
+ else:
+ return False
+
+
+def getParentsFromContextToObject(context, obj):
+ """Returns a list starting with the given context's parent followed by
+ each of its parents till we reach the object.
+
+ If the child object is not a child of the parent a empty list
+ will return.
+ """
+ if not isChildOf(context, obj):
+ return []
+
+ if sameProxiedObjects(context, obj):
+ return []
+
+ parents = []
+ w = context
+
+ while 1:
+ w = w.__parent__
+ if sameProxiedObjects(w, obj):
+ parents.append(w)
+ break
+ if w is None:
+ break
+
+ parents.append(w)
+
+ return parents
More information about the Checkins
mailing list