cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeremy Quinn <>
Subject RFC: Changes to CForms in 2.1.11-dev
Date Wed, 27 Dec 2006 16:37:41 GMT
Hi All

I hope you all had a good Christmas.
Santa's little helpers have been busy working on CForms over the  
holiday break :)

Below is a list of changes I have in my local repo, ready to commit.  
I would like to get feedback on these changes, in case of dissent, or  
usecases I have not fully understood.

1. Updated to use Dojo 0.4.1 -- brings lots of improvements, bug  
fixes and broader browser support.

2. Introduction of widget namespaces, allows lazy loading of widgets  
via lookup from a manifest.

3. Dojo debugging is now turned on and off via an optional sitemap  

4. The contents of the optional <fi:init/> tag is now inserted after  
the scripts to load dojo etc.

5. TODO: cocoon.forms.* to take over from forms_* in forms_lib.js.


The upgrade to Dojo 0.4.1 brings us many advantages, but may break  
some user's custom widgets due to changes in some of the APIs. The  
work required to adapt the existing forms and ajax widgets was pretty  

The widgets that come with 0.4.1 are much improved. This will make it  
far easier to replace the legacy javascripts like htmlarea and the  
mattkruse-libs with their dojo equivalents, while supporting a wider  
range of browsers.

The main rationale for these changes has been to reduce the amount of  
javascript that gets loaded by a CForms page. Currently everything  
possible gets loaded, regardless of whether it gets used or not.

One of the big changes in 0.4.1 is the introduction of Widget  
Namespaces, with it's auto-load mechanism, using a manifest and  
namespace resolver to load the Widget's resources. This removes the  
need to dojo.require Widgets before they are used :

Before :
<script type="text/javascript">dojo.require 
. . .
<div dojoType="FormUploadProgress"><div>Upload Progress Sample</div></


After :
<div dojoType="ajax:FormUploadProgress"><div>Upload Progress Sample</ 

NB. Unfortunately @class="namespace-WidgetName" is not currently  
supported by 0.4.1.

The default namespace (does not need declaring) is 'dojo:'.
I have introduced 2 new namespaces for Cocoon, 'forms:' is for  
widgets in cocoon.forms.* and 'ajax:' is for widgets in  
cocoon.ajax.*. There is a manifest file for each new namespace that  
registers the name of each Widget and provides a mapping between a  
widget name and it's module and path. i.e.

	cformsform --> cocoon.forms.CFormsForm which can be found in : ../ 

Unfortunately, because dojo.ns does it's resolution in lower case and  
we have CamelCase widget names, we need an actual map. New widgets  
must be registered there for auto-discovery to work.

The manifest for the forms namespace looks like this :

   var map = {
     html: {
       "cformsdraganddroprepeater" :  
       "cformsform"                : "cocoon.forms.CFormsForm",
       "cformsrepeater"            : "cocoon.forms.CFormsRepeater",
       "cformssuggest"             : "cocoon.forms.CFormsSuggest"
       // register new Widgets in the cocoon.forms namespace here
     }, svg: {
       // register svg widgets here
     }, vml: {
       // register vml widgets here
   function formsNamespaceResolver(name, domain){
     if(!domain){ domain="html"; }
     if(!map[domain]){ return null; }
     return map[domain][name];
   // cocoon.forms module has a dependency on the cocoon.ajax module  
   dojo.registerModulePath("cocoon.ajax", "../ajax/js");
   dojo.registerModulePath("cocoon.forms", "../forms/js");
   dojo.registerNamespace("forms", "cocoon.forms",  

The path is wide open for users to add their own auto-loading widget  
namespaces via their own manifests. Converting existing custom  
widgets to use a custom namespace is pretty trivial.

The big plus we get from this switch, is that is will be far easier  
to write the CForms XSLT in a way that allows only used code to be  
loaded by the browser. When we have managed to replace all legacy  
widgets with dojo equivalents, the browser will only load code that  
is actually used.

That pretty much covers points 1 and 2.

The next issues regard points 3 and 4: debugging and the use of  

The <fi:init/> tag, introduced in 2.1.9, was being used to add  
<script/> tags into the html/head of pages *before* dojo was loaded.  
It was being used in a couple of samples for turning on dojo debug  
mode on the browser.

Debugging can now be turned on from the sitemap :

   <map:transform src="resources/forms-samples-styling.xsl">
     <map:parameter name="resources-uri" value="{request:contextPath}/ 
     <map:parameter name="dojo-debug" value="true"/>

Leave the param out or set it to false, to turn off debugging.

Debug messages now should go to the Browser's console (tested in  
Safari, FireFox ± FireBug) instead of being written into the end of  
the page. You can get navigable tree-views of your Objects even on  
browsers that do not support FireBug.

The contents of <fi:init/> are now inserted *after* dojo is loaded,  
so may be used for custom initialisation code required for custom  
dojo widgets and other custom functions. eg.

   <fi:init><!-- load my custom non-widget library module -->
     <script type="text/javascript">
       dojo.registerModulePath("myns.stuff", "../path/to/my/ 
stuff"); // relative to dojo.js
       ... do something with the lib now, or later in the page ...

NB. dojo.registerModulePath is now used instead of the dojo.require  
hack we used to have in ajax/cocoon.js.

I think this is far more useful but the change could possibly break  
some user's forms.

Which leads us to point 5.

We have a complicated mixture of legacy global forms_* functions (in  
forms_lib.js) and the cocoon.forms.* namespace.

I would like to make the following changes :
Deprecate forms_onloadHandlers, forms_onsubmitHandlers,  
forms_getForm, forms_submitForm and forms_onsubmit. (Leave an alias  
to those functions for now, but print a deprecation warning if they  
are called directly, remove after the next release). Move all of that  
functionality into cocoon.forms.*.

Also forms should always use a CFormsForm Widget, regardless of  
whether Ajax behaviour is wanted or not. There would be two versions  
of the CFormsForm Widget, one SimpleForm (@ajax='false') which is  
extended by AjaxForm(@ajax='true'). CForms XSLT would choose the  
right one depending on form-template/@ajax. Since dojo is always  
loaded, this decision is inevitable imho.

To get closer to allowing more than one form per page, the  
cocoon.forms library should manage onsubmit handlers for each  
CFormsForm Widget by storing them in a global hash instead of an  
Array, with the CFormsForm Widget id as the key (I'd have to change  
the API). The onload handlers can remain in a global Array.

The trouble here is that this will have a far greater impact on  
existing user projects.

So that's it, a lot of changes, some that may break user's projects  
(but AFAICS all of the samples are still working).

Apart from general feedback, I'd like to ask for feedback on possible  
widget name changes.

Firstly, are you happy with the names of the two new namespaces,  
'forms:' and 'ajax:' they are named after the blocks that contain them.

Secondly, I find stuff like @dojoType="forms:CFormsRepeater" a bit  
redundant now.
To me, the forms block and cforms are synonymous.

I would suggest removing the 'CForms' from the beginning of all of  
the forms widget names :

	@dojoType="forms:CFormsSuggest" --> @dojoType="forms:Suggest"
	@dojoType="forms:CFormsDragAndDropRepeater" -->  

WDYT ? Or is this change for changes sake ?

What's next ? Make dojo replacements for all legacy code (forms_lib,  
mattkruse, htmlarea etc.),

Thanks for any feedback

regards Jeremy

PS. All the samples seem to be working :)

View raw message