Author: bree
Date: Mon Apr 17 16:57:53 2006
New Revision: 2860

Added:
   azax/branches/plugin/plugins/json/
   azax/branches/plugin/plugins/json/__init__.py
   azax/branches/plugin/plugins/json/browser/
   azax/branches/plugin/plugins/json/browser/jsonkukit.js
   azax/branches/plugin/plugins/json/config.py
   azax/branches/plugin/plugins/json/configure.zcml
   azax/branches/plugin/plugins/json/interfaces.py
   azax/branches/plugin/plugins/json/utils.py
Modified:
   azax/branches/plugin/plugins/configure.zcml
   azax/branches/plugin/plugins/registry.py
Log:
Added JSON plugin support

- it is loaded only as an option
- tested with demo1 (change tag contents) and two_select on:
   Mozilla, IE6, Konqueror3.5.2, Opera8

- tested With and Without the presence of Json

 * only problem: IE breaks two_select in any way, that's
   an IE bug, http://support.microsoft.com/default.aspx?scid=kb;en-us;276228


Modified: azax/branches/plugin/plugins/configure.zcml
==============================================================================
--- azax/branches/plugin/plugins/configure.zcml (original)
+++ azax/branches/plugin/plugins/configure.zcml Mon Apr 17 16:57:53 2006
@@ -6,6 +6,8 @@
     <!-- XXX concatresource is now included locally. -->
     <include package=".concatresource" />
 
+    <include package=".json" />
+    
      <!-- example plugin registration
      
      <azax:registerCommand

Added: azax/branches/plugin/plugins/json/__init__.py
==============================================================================
--- (empty file)
+++ azax/branches/plugin/plugins/json/__init__.py       Mon Apr 17 16:57:53 2006
@@ -0,0 +1,5 @@
+'''\
+Module init
+'''
+
+from utils import getJsonAddonFiles

Added: azax/branches/plugin/plugins/json/browser/jsonkukit.js
==============================================================================
--- (empty file)
+++ azax/branches/plugin/plugins/json/browser/jsonkukit.js      Mon Apr 17 
16:57:53 2006
@@ -0,0 +1,93 @@
+
+/*
+* Supplemental script for json
+*
+* This gets included when json plugins are registered.
+*
+* We overwrite notifyServer and at one point we return to the
+* normal execution chain (after results are received)
+*/
+
+kukit.makeJsonMethod = function(url, callback, error, timeout) {
+    // Constructing a json method call handler.
+    // It is more steps because the input is not in the form
+    // how the JSON-RPC logic would require it.
+    var pieces = url.split('/');
+    var methodName = pieces.pop();
+    var base = pieces.join('/');
+    var proxy = new JSONRPC(base);
+    proxy.addMethod(methodName, callback, error, timeout);
+    return proxy[methodName];
+}
+
+kukit.notifyServer = function(url, target) {
+    // sending form
+    var form_data = kukit.extractFormQuery(target).toDict();
+    // XXX set a standard 4 sec timeout... a sane choice
+    var method = kukit.makeJsonMethod(url, jsonCallback, jsonError, 4000);
+       var method_with_parms = partial(method, PythonKw(form_data));
+    kukit.requestManager.notifyServer(method_with_parms, url);
+}
+
+function jsonCallback(result) {
+    kukit.requestManager.receivedResult();
+    var command_processor = new kukit.CommandProcessor();
+    command_processor.parseCommands(result);
+    command_processor.executeCommands();
+}
+
+function jsonError(result) {
+    kukit.requestManager.receivedResult();
+    alert('ERROR ' + result); 
+}
+
+/* Command execution */
+
+kukit.CommandProcessor.prototype.parseCommand = function(command) {
+    // For the sake of old commands compatibility, we need to convert
+    // all the commands to DOM.
+    var new_params = {};
+    for (var name in command.params) {
+        var param = command.params[name];
+
+               //
+        // now convert to dom
+               //
+               
+               //param = 
"<option>test_xmlentity</option><option>tic</option><option>tac&#32;toe</option>";
+               // ***BROKEN*** param = 
"<option>test_htmlentity</option><option>tic</option><option>tac&nbsp;toe</option>";
+               //param = 
"<option>test_utf8</option><option>tic</option><option>tacűtoe</option>";
+
+               // This is a good solution since it does not do magic to
+               // our html - BUT html is parsed as xml
+               // so we currently preprocess it to remove html entities
+               // from it.
+               //
+               var root_txt = '<html 
xmlns="http://www.w3.org/1999/xhtml";><div>' + param + '</div></html>';
+       var doc = (new DOMParser()).parseFromString(root_txt, "text/xml");
+               var root = doc.getElementsByTagName('div')[0];
+
+               // This would be the perfect solution: insert our stuff
+               // into the main document that is, since it is html,
+               // will parse html in correctly. But the problem is
+               // that is also sensitive to context which we have not
+               // at this point yet. So: <option> will not work since
+               // we have no embedding select, etc...
+               // -->> gets broken with both MOZILLA and IE
+               //
+               //var root = document.createElement('html');
+               //root.innerHTML = param;
+               //
+               // XXX Sarissa bug; html docs would not have a
+               // working serialize, and so importNodes would fail on them.
+               // XXX Fixed in: Revision 1.23  - Sun Jul 10 18:53:53 2005 UTC
+               // use at least 0.9.6.1
+               
+        new_params[name] = root;
+               //alert(Sarissa.serialize(root));
+    }
+    command.params = new_params;
+    // Add the command.
+    this.addCommand(command);
+} 
+

Added: azax/branches/plugin/plugins/json/config.py
==============================================================================
--- (empty file)
+++ azax/branches/plugin/plugins/json/config.py Mon Apr 17 16:57:53 2006
@@ -0,0 +1,7 @@
+     
+try:
+    import Products.jsonserver
+except ImportError:
+    HAS_JSON = False
+else:
+    HAS_JSON = True

Added: azax/branches/plugin/plugins/json/configure.zcml
==============================================================================
--- (empty file)
+++ azax/branches/plugin/plugins/json/configure.zcml    Mon Apr 17 16:57:53 2006
@@ -0,0 +1,31 @@
+<configure xmlns="http://namespaces.zope.org/zope";
+           xmlns:browser="http://namespaces.zope.org/browser";
+           xmlns:five="http://namespaces.zope.org/five";>
+ 
+    <!-- We do not import things directly from jsonserver, as
+         its presence is optional. We import these locally
+         and if the import fails, blind stubs are provided
+         for the necessary interfaces and factories. This
+         ensures that this zcml will always execute.
+         XXX But this should actually be done via
+         features / conditionals from here.
+    -->
+
+    <!-- View that renders the command -->
+    <adapter
+        for="Products.azax.interfaces.IAzaxCommands
+             .interfaces.IJsonRequest"
+        provides="zope.interface.Interface"
+        factory=".utils.JsonCommandView"
+        name="render"
+    />
+ 
+    <!-- Json representation of commands -->
+    <adapter
+        for="Products.azax.interfaces.IAzaxCommand
+             .interfaces.IJSONWriter"
+        provides=".interfaces.IJSONStreamWriteable"
+        factory=".utils.AzaxCommandWriter"
+    />
+    
+</configure>

Added: azax/branches/plugin/plugins/json/interfaces.py
==============================================================================
--- (empty file)
+++ azax/branches/plugin/plugins/json/interfaces.py     Mon Apr 17 16:57:53 2006
@@ -0,0 +1,42 @@
+# -*- coding: ISO-8859-15 -*-
+# Copyright (c) 2005
+# Authors:
+#   Godefroid Chapelle <[EMAIL PROTECTED]>
+#   Tarek Ziad� <[EMAIL PROTECTED]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+
+from config import HAS_JSON
+from zope.interface import Interface
+
+if HAS_JSON:
+    from Products.jsonserver.interfaces import IJsonRequest
+    from Products.jsonserver.minjson.interfaces import IJSONStreamWriteable, 
IJSONWriter
+else:
+    # If jsonserver is not present, we just define interfaces
+    # that noone implements so the adapters will never be looked up.
+    # This is because the zcml will try to import these.
+    # XXX occasionally this should be done from the zcml, 
+    # via features/conditionals!
+    
+    class IJsonRequest(Interface):
+        'Interface never to be implemented'
+
+    class IJSONStreamWriteable(Interface):
+        'Interface never to be implemented'
+        
+    class IJsonWriter(Interface):
+        'Interface never to be implemented'

Added: azax/branches/plugin/plugins/json/utils.py
==============================================================================
--- (empty file)
+++ azax/branches/plugin/plugins/json/utils.py  Mon Apr 17 16:57:53 2006
@@ -0,0 +1,56 @@
+'''\
+Supplemental support for json plugins
+'''
+
+import os.path
+import zope.component
+from zope.interface import implements
+from zope.publisher.browser import TestRequest
+from config import HAS_JSON
+from interfaces import IJSONStreamWriteable
+
+def getJsonAddonFiles():
+    'Gets the addon javascript files for json'
+    files = []
+    if HAS_JSON:
+        # Add the jsonserver files
+        request = TestRequest()
+        # use the files already registered to that concat resource
+        jsonrpc = zope.component.getResource('jsonrpc.js', request)
+        files.extend(jsonrpc.context.context.getPathList())
+        # add the json kukit support file
+        plugins_dir = os.path.split(globals()['__file__'])[0]
+        files.append(os.path.join(plugins_dir, 'browser', 'jsonkukit.js'))
+    return files
+
+class JsonCommandView(object):
+    '''View of a command for JSON requests.
+    
+    We siply return the commands since they
+    will be transparently rendered for JSON,
+    via the writer adapter hooks.
+    '''
+    
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def render(self):
+        return self.context
+
+class AzaxCommandWriter(object):
+    'Writes a command to JSON'
+    implements(IJSONStreamWriteable)
+
+    def __init__(self, context, writer):
+        self.context = context
+        self.writer = writer
+        
+    def __jsonwrite__(self):
+        writer = self.writer
+        # All is written as a dict
+        d = dict(self.context.__dict__)
+        # params are converted to a dict from a list.
+        # Also get rid of "none" params that were only a hack for xml
+        d['params'] = dict([(param.name, param.content) for param in 
d['params'] if param.name != 'none'])
+        writer.write_repr(d)

Modified: azax/branches/plugin/plugins/registry.py
==============================================================================
--- azax/branches/plugin/plugins/registry.py    (original)
+++ azax/branches/plugin/plugins/registry.py    Mon Apr 17 16:57:53 2006
@@ -5,6 +5,7 @@
 # concatresource is an embedded product but interface is aliased to Products
 import concatresource
 from Products.concatresource.interfaces import IConcatResourceAddon
+from json import getJsonAddonFiles
 
 def getRegistry(context=None):
     'Convenience method to get or create the registry.'
@@ -75,4 +76,10 @@
         self.getRegistered(plugintype, name)
 
     def getAddonFiles(self):
-        return self.jsfiles.keys()
+        try:
+            files = self._addon_files
+        except AttributeError:
+            # Lazy setup of addon files
+            self._addon_files = files = getJsonAddonFiles()
+        files.extend(self.jsfiles.keys())
+        return files
-- 
http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins

Reply via email to