FLUID-4353 branch work

Antranig Basman antranig.basman at colorado.edu
Wed Jul 27 07:44:57 UTC 2011

Hi Cindy - I have had a look over the "options munging" branch and things are certainly going the right way. 
It looks like you are partway through unifying the (more complex) munging operation for the Fat Panel 
configuration with the (simpler) one you have written which goes in UIOptions, used in FullPreview and 
NoPreview - so do continue with that today. Some suggestions to tidy up the work:

i) What do people think of having a general namespacing sweep for UIOptions? Lots of things are irregularly 
dumped into the top-level fluid.* namespace but it might be clearer to reorganise things under 
fluid.uiOptions - and so for example

fluid.fatPanelUIOptions -> fluid.uiOptions.fatPanel
fluid.renderIframe -> fluid.uiOptions.renderIframe
fluid.uiOptionsBridge -> fluid.uiOptions.bridge
fluid.fullNoPreviewUIOptions -> fluid.uiOptions.fullNoPreview

ii) Make a new "grade" to account for the commonality between fluid.uiOptions.fullNoPreview and 
fluid.uiOptions.fullPreview - perhaps called something like

fluid.defaults("fluid.uiOptions.inline", {
     gradeNames: ["fluid.viewComponent"],
         components: {
             uiOptionsLoader: {
                 type: "fluid.uiOptions.loader",
                 //  container: "{fullPreviewUIOptions}.container" // treat this specially - see below
             templateLoader: {
                 priority: "first",
                 type: "fluid.uiOptions.templateLoader"

Then you can just write
fluid.defaults("fluid.uiOptions.fullPreview", {
     gradeNames: ["fluid.uiOptions.inline"]
); etc.

iii) Put the configuration for the munger into a declarative structure in the defaults for the component. I 
suggest something like this, in the component's defaults:

fluid.defaults("fluid.uiOptions.inline", {
all the standard material
     uiOptionsTransform: {
         transformer: "fluid.uiOptions.mapOptions",
         config: {
                 "*.templateLoader":                                 "templateLoader",
                 "*.uiOptionsLoader.container":                       "container", // special, see below
                 "*.uiOptionsLoader.*.uiOptions":                     "uiOptions",
                 "*.uiOptionsLoader.*.uiOptions.*.textControls":       "textControls",
                 "*.uiOptionsLoader.*.uiOptions.*.layoutControls":     "layoutControls",
                 "*.uiOptionsLoader.*.uiOptions.*.linksControls":      "linksControls",
                 "*.uiOptionsLoader.*.uiOptions.*.preview":            "preview",
                 "*.uiOptionsLoader.*.uiOptions.*.settingStore":       "settingStore",
                 "*.uiOptionsLoader.*.uiOptions.*.preview.*.enhancer": "previewEnhancer"

Note the abbreviated "*" notation for the noisy paths, you might like to choose a different character or 
convention but it is much less error-prone and more readable to condense the repeated stuff this way since 
it is perfectly easy for fluid.uiOptions.mapOptions to work out the path. e.g. 
"*.uiOptionsLoader.*.uiOptions" can expand using a utility named fluid.uiOptions.expandShortPath to 

Note I have written these backwards from the way you might first choose, i.e. as "destinationPath": 
"sourcePath" - this is for reasons that might be clearer later

iv) fluid.uiOptions.mapOptions then has the following signature and suggested sketch implementation:

fluid.uiOptions.mapOptions(options, config) {
     var applier = fluid.makeChangeApplier(options);
     fluid.each(config, function(source, dest) {
         dest = fluid.uiOptions.expandShortPath(dest); // to expand the .*. type paths
         var value = fluid.get(options, source);
         applier.requestChange(dest, value, "ADD");
         applier.requestChange(source, value, "DELETE");

Continue with manual wrappers for now - manually fish out the defaults by just calling 
fluid.defaults("fluid.uiOptions.fullPreview").uiOptionsTransform etc., and stick "container" into the 
options structure in the wrapper to make that piece of chewing work.


     fluid.uiOptions.fullPreview = function (container, options) {
         var mapping = fluid.defaults("fluid.uiOptions.fullPreview").uiOptionsTransform;
         options.container = container;
         var mappedOptions = fluid.uiOptions.mapOptions(options, mapping);
         var that = fluid.initView("fluid.uiOptions.fullPreview", container, mappedOptions);
         return that;

[[v) If you are REALLY LUCKY, then all the wrapper functions can just go away magically by renaming 
"uiOptionsTransform" to "transformOptions", since this is exactly the configuration expected by the "options 
chewing code" already written for the uploader in the 1.3.1 framework release. If you are not REALLY LUCKY 
and something strange and uncorrectable goes wrong (probably to do with the container), then you can just 
carry on with the manual wrapper functions.

vi) Some final wrinkles -

So, the fatPanel version looks like it could be driven by a config something like this:

     config: {
         "*.uiOptionsBridge.options.uiOptionsOptions": "uiOptions",
         "*.uiOptionsBridge.options.uiOptionsOptions.*.textControls": "textControls",
         "*.uiEnhancer": "previewEnhancer",  etc.

the wrinkle here is getting the (possibly two) uiEnhancers straight ... although looking at the code quickly 
by eye I don't seem to actually find the 2nd one, they all seem to be injected from this one at top level?

vii) We should be able to get rid of the demands blocks at the head of FullNoPreviewUIOptions.js dealing 
with the template paths by just adding more configuration into these files - the one in the middle can be 
left as the remaining "blot on the landscape" - although I see no reason why we couldn't just deal with this 
by means of GRADES and a slight extension to mapOptions - here is a proposed IDEAL TOTAL contents of 
FullPreviewUIOptions.js (we don't need to get all the way there for the release):

fluid.defaults("fluid.uiOptions.fullPreview", {
     gradeNames: ["fluid.uiOptions.inline"],
     transformOptions: {
         config: {
             "templates.uiOptions", "%prefixFullNoPreviewUIOptions.html", // need to recognise literal value
             "*.templateLoader.*.templatePrefix.*": "prefix", // This one could just go in the shared grade
             "*.uiOptionsLoader.container": "container", // similarly
             "*.uiOptionsLoader.*.uiOptions.*.preview": {
                 type: "fluid.emptySubcomponent"

It could be as little as that! We'll do this properly in 1.5.

More information about the fluid-work mailing list