FLUID-4353 UIOptions

Antranig Basman antranig.basman at colorado.edu
Thu Aug 4 05:08:23 UTC 2011

Cindy asked a very cogent question in the channel earlier -

[13:29] <cindyli> Bosmon2: i was looking at kettle url rebasing code and thinking how to calculate the 
actual prefix in fat panel
[13:29] <cindyli> the integrator will provide us 2 relative urls
[13:30] <cindyli> one is from the main html to iframe html, the other is from the main to templates
[13:30] <cindyli> both of them could be from anywhere
[13:31] <cindyli> for instance, if iframe html is at "../../a/b/iframe.html", templates prefix is "c/"
[13:32] <cindyli> first, we need to reverse the relative from main to iframe, which is into - the relative 
from iframe to main
[13:32] <cindyli>  "../../a/b/iframe.html" needs to turn into "../../components/uiOptions"
[13:33] <cindyli> then, concat it with the 2nd relative path "c/"
[13:33] <cindyli> my problem is at the first conversion, how to find out where my main html is located
[13:34] <cindyli> in other words, comes up with the part of "....components/uiOptions"
[13:36] <cindyli> Bosmon2: any idea?

This relates to our final piece of work on UIOptions configuration, trying to harmonise the URLs used in the 
FatPanel configuration so that they are not unexpectedly different from the non-iframe versions.

Looking into this in more detail, this is a more serious problem that requires much more than the "1 hour" I 
ludicrously hoped for :P

As a quick worked example, let's just make a minor adjustment to the above so that the path depths are not 
exactly equal to avoid an "accidental solution" and say that the iframe relative URL is in fact

Say that in some sense that the "main page" was indeed "../../components/uiOptions/main.html". In combining
with the relative iframe path this would lead to "../../components/uiOptions/../../a/b/g/iframe.html" as a
rendition of the iframe's base URL. Let's say that in the a very simple case, we have actually stored the 
uiOptions templates in exactly the same directory as the main page and so merely require to get back to it ..
this requires us to "unthread" the added portion of the URL to the iframe which then forms the added 
relative path "../../components/uiOptions/../../a/b/g/../../components/uiOptions" which as Cindy rightly 
observes above requires us to "miraculously resurrect" the segments components/uiOptions which were 
previously further back on the path. This is only "accidentally" possible here and is clearly not possible 
if, for example, the iframe relative URL were to begin "../../../", consuming parts of the URL which had not 
been seen in this relative construction.

This shows that it is impossible to resolve this situation simply working with relative URLs. Really we need 
to discover the complete document.location for the original page and use this to drive the unthreading - 
since without this the information destroyed by "../../" segments in the iframe relative URL cannot be 
recovered. This requires slightly more URL parsing machinery than we have to hand and so I propose a 
compromise solution for now of setting up the component to be correctly configured in the case where the 
templates and the iframe markup are held in the same directory - and supplying an extra configuration 
"relativePrefix" just for FatPanel to allow users to fix up the anomaly themselves if they are not. This now 
defaults to "./" expressing the fact that the iframe and template markup are in the same directory.

This meets at least some of our goals of letting the top-level configuration of the 3 UIOptions use the same 
URLs semantics, as well as dealing with the most common case where all the user requires to configure is a 
single prefix which configures the common location of all the framework markup needed to drive the 
component. This should allow the vast majority of ours users to configure the component in an expected way - 
we/I can spend some time tomorrow looking at the full solution and grubbing out what "full URL parsing 
machinery" we have lying around but given we are timeboxed for this release I propose that we also consider 
leaving things as they are.

I've committed a version like this to my FLUID-4353 branch - some URL utilities have been rescued but are 
currently unused.

Code review for cindy's FLUID-4353 branch in general:

Generally looking very good except for some of the options mapping machinery which is a bit ropy:

In UIOptions.js:

     fluid.uiOptions.expandShortPath = function (path) {
         var strToreplaceFirst = "components";
         var strToreplaceRest = "options.components";

         // replace the first "*"
         var re = fluid.stringToRegExp("*");
         var newPath = path.replace(re, strToreplaceFirst);

The use of the new framework utility fluid.stringToRegExp is enterprising here but not necessary since the 
text to form the regexp is known in advance. Also the use of the expression here is incorrect since it will 
match the first * in the string wherever it appears, whereas it should only match a * occuring as the first 
character. I suggest the use of a regExp is entirely unnecessary here and can be replaced by a 
path.charAt(0) check. The use of the 2nd regExp is ok but it will be fine to just write 
newPath.replace(/\*/g, strToReplace).

in FatPanelUIOptions.js:

         fluid.each(bridgeMapping, function (to, from) {
             fluid.each(that.options, function (value, key) {
                 // the mapping belongs to FatPanelOtherWorldLoader
                 if (from.indexOf("bridge") !== -1 && key === to) {
                     overallOptions[key] = value;

The matching here is also over-broad and should probably read from.indexOf("*.bridge") === 0 - however the 
nested loop is rather inefficient and it would be much quicker to simply invert the "bridgeMapping" 
structure by swapping the keys and the values first into a temporary structure - and then just iterating 
over these keys when routing the bridged options.

Other than this I think the implementation is ready to commit, although I'd like to see a lot more tests (at 
least some) showing that this options routing system is actually working - for example a demonstration of 
anastasia's requirement that the classnameMap, for example, can correctly reach the required components, 
etc. - both in FatPanel and FullNoPreview versions.


More information about the fluid-work mailing list