Ok a third mail finally exposing our internal features.
Short introduction:

By designing our javascripts it was up for discussion whether we should use an existing lib or rolling our own. The + side of an existing lib would be already existing code, the downside, you drag along a lot of code which will never be used. But on the other hand I did not want the pure lets do only the spec approach but I wanted to get something solid a base for other complibs also to be used sort of as shared core which easily can be extended and merged into existing libraries.

For maintainance reasons I always opted for a pure oo approach (although the scripts in 2.0.0 were not entirely there) with a beak binding between the layers.

Also I wanted to have a clear boundary between api and impl.

Have in mind I hate reinventing the wheels, so I took the liberty to rip out foreign code wherever it suited (we have some dojo code in some parts came from j4fry, also some small part is from YUI) But sometimes it is better to reinvent the wheels a little bit to prevent a lot of useless code to be dragged in.

One of the cornerstones of all this which was late introduced was the _Runtime.js. The _Runtime.js is a small file which is the base for all
scripts.

It provides following functionality:

Core Patterns:
 Namespaceing
 Inheritance
 Singletons
 Delegation

Dom Core functionality:
 Global Evaluation of scripts
 Dynamic script loading via xhr get
 Dynamic scoping of functions via hitch
 Advanced Exists checking of elements
 Browser Detection


Everything else in our scripts is based upon this functionality.

I will give a few examples:

Namespacing:
var _RT = myfaces._impl.core._Runtime

_RT.reserveNamespace("myfaces.hello.world")

after that a global namespace map under
myfaces.hello.world should be present

_RT.reserveNamespace("myfaces.hello.world", "myhello")

after that a global namespace map under
myfaces.hello.world should be present
with myhello being assigned to it as value


_RT.fetchNamespace("myfaces.hello.world")

resolves the namespace in a speed optimized manner and returns its value

Inheritance:

http://www.pastebin.org/432772


This is an example, the inheritance is pretty much the same as dojo, the main differences come later.

One thing, the super call must be performed via
this._callSuper('<functionName>', hello1, hello2);

I might introduce a real inherited without the function name later.
Multiple inheritance is not implemented for now, it was not necessary for what we are doing and would have only introduced more code.


Delegation:

myfaces._impl.core._Runtime.singletonDelegateObj("myfaces._impl._util._Lang", myfaces._impl.core._Runtime, {
    fetchNamespace : function(namespace) {
        if (!namespace || !this.isString(namespace)) {
throw Error("_Lang.fetchNamespace namespace must be of type String");
        }
        return this._callDelegate("fetchNamespace", namespace);
    },
});

That produces a new singleton which delegates from runtime.
Without producing a singleton you could use following:

Also as you can see the delegation methods are added automatically if you want to overwrite a certain behavior then use _callDelegate.
(like it is done here by adding additional type checking)

myfaces._impl.core._Runtime.delegateObj("myfaces._impl._util._Lang", myfaces._impl.core._Runtime, {

...
});

Besides that there is some nifty stuff like browser detection
this is straight from dojo with _RT.browser.isIE carrying a number if it is IE etc... (you can look up the details in the code)

Hitch also from dojo. With it you can enforce a certain scope on a function passed down, no matter what the runtime system downs with the function afterwards.

Usage _RT.hitch(newScope, function() { this.hello(); });
this pushes the internal this of the anonymous function to newScope.

A classical addOnLoadWrapper

_RT.addOnLoad(window, function() {alert("loaded");});
_RT.addOnLoad(document.body, function() {alert("loaded");});

etc... pretty self explanatory

loadScript loads and evals a script:


myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.util:_Lang.js']}", null, null, "UTF-8");

There are other smaller things in there which I have not yet listed, and some of the code might change in detail, but not too much anymore, I will try to keep the _Runtime from now on as stable as possible, I do not want to have too much in there anymore to keep it small.




Werner

Reply via email to