Rob Berens wrote:
In 2.1.6. explicit declaration of variables in global scope was enforced
(fix 25951).
This was implemented by locking the scope after the main part of the main
script has been loaded and processed.
In our situation we have one generic script loaded form the sitemap once,
that determines the name of the script to be loaded based on the request and
than loads that script. Simplified it's like this.
The sitemap loads the script main.js:

main.js:

function loadScript() {
    var scriptURI = "determineScriptURIFromRequest";
    cocoon.load(scriptURI);
}


When a request comes in, the sitemap calls the function loadScript(). Let's
say loadScript determines that it needs to load myScript.js.


myScript.js:

var myVar = "myValue"; // This results in an error when loaded from main.js.

"doSomething";


In this way we have a mechanism to load scripts dynamically without knowing
their names before hand.
The problem is that after loading the initial main.js the global scope is
locked, which results in an error on "var myVar = .....".

I solved by changing the jsFunction_Load method in
org.apache.cocoon.components.flow.javascript.fom.FOM_Cocoon.java into:

    public Object jsFunction_load( String filename )
        throws Exception {
        org.mozilla.javascript.Context cx =
            org.mozilla.javascript.Context.getCurrentContext();
        FOM_JavaScriptInterpreter.ThreadScope scope =
            (FOM_JavaScriptInterpreter.ThreadScope)getParentScope();
        Script script = getInterpreter().compileScript(cx, filename);
        Object obj;
        synchronized(scope) {
            scope.setLock(false);
            obj = script.exec( cx, scope );
            scope.setLock(true);
        }
        return obj;
    }


In this way the scope is temporarily unlocked during the load of the script.
This works fine. There is however one problem. The scope in FOM_Cocoon will
always be an instance of FOM_JavaScriptInterpreter.ThreadScope, but this is
not explicitly known in FOM_Cocoon. I just made this assumption to get
things working. So we might need a better solution..

Is there any GURU who can help? Can this be solved in 2.1.8?

There's a big problem with this approach: since the actual script to load is defined by the currently executing request, what happens when different scripts are loaded? You fill the global (and session-bound) scope with request-dependent items.

To solve your issue, what we need is to extend cocoon.load() so that it accepts a second parameter, which will be the scope used to load the script.

That way, you can write:

function foo() {
   var scriptURI = "determineScriptURIFromRequest";
   var scope = {}; // new empty object
   cocoon.load(scriptURI, scope);
   // use something in the loaded script
   print(scope.myVar);
}

Sylvain

--
Sylvain Wallez                        Anyware Technologies
http://people.apache.org/~sylvain     http://www.anyware-tech.com
Apache Software Foundation Member     Research & Technology Director

Reply via email to