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 parameter.
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. Notes: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 minor.
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 ("cocoon.ajax.FormUploadProgress");</script>
. . .<div dojoType="FormUploadProgress"><div>Upload Progress Sample</div></ div>
After :<div dojoType="ajax:FormUploadProgress"><div>Upload Progress Sample</ div></div>
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 : ../ forms/js/
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 :
dojo.provide("cocoon.forms.manifest");
(function(){
var map = {
html: {
"cformsdraganddroprepeater" :
"cocoon.forms.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
libraries
dojo.registerModulePath("cocoon.ajax", "../ajax/js");
dojo.registerModulePath("cocoon.forms", "../forms/js");
dojo.registerNamespace("forms", "cocoon.forms",
formsNamespaceResolver);
})();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 <fi:init/>.
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}/ _cocoon/resources"/>
<map:parameter name="dojo-debug" value="true"/>
</map:transform>
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
dojo.require("myns.stuff.somelibrary");
... do something with the lib now, or later in the page ...
</script>
</fi:init>
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" -->
@dojoType="forms:DragAndDropRepeater"
etc.
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 :)
smime.p7s
Description: S/MIME cryptographic signature
