SCRIPTING:

Kitana Jade
Kitana Jade stop swap»
HOW TO CRAFT YOUR OWN ULMA FUNCTIONS

In this file you can learn the procedures by which you can build your own ULMA Dhtml functions such that then you can add (ULMA term is: enable) them to a given layerManager as one of the valid managerMethods belonging to its pool.
ULMA is probably one of the most interesting complete and intriguing approaches to Dynamic Html, and behaves as a reciprocate/inverse of Java.
So if you're interested in using it and custom your method, this file is for you. A ULMA method is suitable to be shared with whoever uses ULMA as his/her Dhtml methods library of choice.
There is an ample test form to help you out.

August 2002
{ @ }

The model above is Kitana Jade
LOADS OF KITANA JADE ON THE NET


CUSTOM YOUR ULMA
How to custom and the main things you may or should use

A long belated promise is still and none the less a promise. A valid promise.
I told you I would have issued a file on some main advice about crafting your own ULMA functions. Perhaps it is going to be, for some aspects, the most boring file of the site. But a promise even to bore you to death is still a promise you see bud...
 
Obviously, this file is of actual interest to you only if you've decided to elect ULMA (for its documentation click this link) as your preferred Dhtml approach and Dhtml powerhouse.
You know:
«Life's but a walking shadow: a poor player
That struts and frets his hour upon the stage
And then is heard no more; it is a tale
Told by an idiot, full of sound and fury
Signifying nothing.» [ Shakespeare, Macbeth ]
Therefore frequently I have taken my chance in my own hour to strut about ULMA Dhtml. Wouldn't I be persuaded ULMA is a Dhtml approach which has few comparisons, I would probably have made much less fuss about it. After all, I don't champion other scripts this way. But ULMA, ULMA is another lot. As far as Dhtml is concerned, well still Louis XIV's way, still Carlito's way: «Nec Pluribus Impar»: not inferior to a few, baby: not inferior to just a few. And that's all, and that's the story. I gracefully bow to the distinguished public that threw tomatoes at me and I withdraw from the stage which has been lent to me for my 5 minutes of void ness.
 
As you should already know, since this file implies you already got a glimpse at ULMA at least, as soon as you initialize a new layerManager, you can the add to it a whole lot of methods (you define your method once, then you can borrow it to whichever ULMA layerManager: each would hold its own independent copy from the template) even defined by yourself, and you achieve it by simply:
  1. You obviously have loaded all the ULMA libraries (about 23Kb, which can be downloaded in two seconds, especially when you consider that a gif is often more heavy and that a script has not to be painted on the screen canvas: therefore the browser is three times as fast to download those bytes for its rendering engine has no job to do at all).
  2. You have obviously included your layer and initialized some variables as new layerManager() and you have abilitated them:
    var foo= new layerManager("foo", "layerID");
    foo,abilitate();
    .
  3. You now define/craft your own ULMA function and to add it as a new managerMethod to your pet layer managers, you just do:
    yourLayerManagerName.enable("yourCraftedFunctionName");
So, let's see step by step:
  1. Let's device a shell for a function:
    function crafted(){}
  2. Since such function called crafted (or whatever name), now empty, is going to be enabled as a new managerMethod on a layerManager, it is going to be an Object (everything in javaScript which is initialized by the agency of keyword new is gonna be a full fledged, full blown Object).
    And since such function is going to perform as an Object, as such it will be able to hold its own properties with their chosen given names, and could even hold more functions on its own; actually, and in fact, upon enabling as a new managerMethod of a give layerManager, the function we just named crafted would inherit (precisely as a class would) all the ULMA built in methods assigned to each instance of a managerMethod (a few among many: setAttributes, run, execute, setAmount, reset, setDefaults).
     
    Therefore, such function (Object) is now suitable to host, along with the bundled ones, even property names initialized by yourself for your own purposes, and of course you can populate with values the properties names already available in ULMA as built in attributes: the function named crafted would own its own set, and the function itself can be borrowed as an independent Object to other layerManagers. For instance: even in the empty shell of crafted we devised, if it gets enabled as a managerMethod, you could invoke on it (imaging foo our usual placeholder for a layerManager variable name):
    foo.crafted.setAttributes("speed", 500)
    In fact each enabled function holds and owns all the built in ULMA methods, and can use them instantaneously; such move (calling setAttributes with such arguments, that is) would for instance automatically give to the foo.crafted's property named speed the value of 500 [that is: now foo.crafted.speed=500].
    Not only but such function once enabled can also from within its body manipulate the properties belonging to the layerManager which owns it (in our case: foo, for remember: layerManager and its enabled managerMethods are two different Objects, full fledged, and that can be interwined).
    So from within crafted you can address the foo properties/methods by the following syntaxes, all ULMA "keyword" aliases of each other:
    • function crafted(){
    • this.variable
    • this.owner
    • this.manager
    • this.layer
    • this.layerManager
    • If after such calls you append by a dot a layerManager property name and you assign to it a value, there you go: it will update (from within the enabled method called crafted!) with such value the current value of the given property in the layerManager that owns crafted (on which it has been enabled, that is; keep in mind, the layerManager name's still foo in our case), or if a property with such name didn't exist, it would create it and append it to the layerManager pool immediately: instance:
      this.owner.APROPERTY="hallo"
      Now foo has a property named APROPERTY, and a call from whatever section of the scripts to foo.APROPERTY would read/manipulate such value on... foo!
    • }
    If on the other hand what you want to do (by far the most common case, actually) isn't to manipulate the pool of data held by the layerManager but the pool of data held by this crafted managerMethod itself (and by pool of data we mean the pool of data of the instance of crafted which has been enabled on foo; for if you enable another instance of crafted on, say, foo2, each of them will be an independently enabled instance!), whatever call from within it (crafted function in our example case) must just resort to keyword this, without further reference to neither variable or owner or any of the above aliases; so:
    • function crafted(){
    • this.speed
      it affects a property named speed which belongs to the pool of properties of the managerMethod; and, more precisely, to the instance of this managerMethod borrowed to the given layerManager.
    • this.APROPERTY
      would create from scratch a property named APROPERTY. Note that since a layerManager is a different thing from managerMethod, a property whose name is APROPERTY and which might belong to a layerManager is completely different a thing, fully independent of, from whatever analogous property with the very same name but this time bestowed as an attribute of a managerMethod: it's a full containment what's being enacted.
      • Each layerManager instance is independent from any other layerManager instance: they may all hold properties with the same names, but a call to foo1.top would affect top only on foo1, and not on foo2, although foo2 has its own property named top.
      • The same as above applies to each managerMethod initialized instance for a given layerManager from the managerMethod template called crafted.
      • Then, which was our point, if in a managerMethod enabled on a layerManager exists a property whose name is identical to the name of a property existing in the layerManager which owns such method, the two property names won't interfere with each other at all.
    • }
  3. Therefore the only thing you have to look after, is to be sure that if you initialize for your crafted method a property name, such property is not already one of the property names belonging to the bundled pack of property names built in either in the layerManager constructor or in the managerMethod constructor. Here is a snippet that can help you find out:

CHECK IF A PROPERTY NAME
is available
This snippet checks if a property name for your own crafted ULMA object properties is available. Checks on layerManager constructor and on managerMethod constructor, so you can avoid conflicting names.
It is Case SeNsItIvE.

[ NOT case sensitive? » ]


ULMA BUILTIN/BUNDLED NAMES
within constructors and DOM setup
On the other hand, ULMA also has some global variable names you'd be sure not to interfere with (aside from other possible ULMA power function from this site you may have added):

CUSTOMIZED PROPERTY/VALUES
for crafted managerMethod
Caravaggio
Add properties to foo.crafted: it has already been enabled as a new managerMethod for the already abilitated layerManager foo in the background by:
foo.enable("crafted");
Keep in mind two things:
  1. From within the crafted function you can even influence (set/update/read) properties not stored in the crafted managerMethod but even properties stored in the layerManager (foo) by using one of the keywords:
    variable, owner, manager, layer, layerManager
    such as:
    this.owner.property_Name
    It is up to you to pre pend such ULMA keywords by selecting them in the menu.
  2. For the value do include quotes if it is meant as a string

foo.crafted. =
Syntax for last added properties if initialized from within the method:

Section for managerMethod crafted specific properties [that is: the list does not include the managerMethod properties that anyway crafted possesses, but only the ones you've added/created yourself]:

Section for layerManager foo specific properties set/updated by managerMethod crafted [that is: the list does not include the layerManager properties that foo possesses anyway, but only the ones you've added/created yourself by using expressions like: this.crafted.variable.PROPERTY_here]:



INSIDE YOUR CUSTOM FUNCTION
The main tricks

Actually that's easy.
First thing you keep in mind, conceptually we can divide each ULMA function in 3 main sectors/tasks:
  1. BEGIN: populate with default values, change values, add properties if needed. It's the doorway.
  2. RUN: the main (arguably repetitive) tasks. It's the kitchen.
  3. STOP: conditions upon which exiting the function and possible final steps like resetting the variables at step #1 to their defaults in order to guarantee a smooth fresh restart if you wanna re-execute the crafted function on the same layerManager again. It's the doorway in the other direction: say bye Jimmy.
Here it is how simple it is: for each point:
function crafted(){
  1. BEGIN:
    MY suggestion is to begin like this:
    if(this.isRunning==0){
    this.isRunning=1;
    /* now main preliminary stuff...*/
    }

    In fact each managerMethod has a property named isRunning set to zero. Checking this allows you to store in within one single conditional statement which would be executed only once (provided immediatly after the check you update such isRunning property to 1, or to something else than zero!) even a huge amount of code: it won't affect the performance for with such trick it is executed just once!
    You can then initialize in within there your new variables. You can assign to them default values (maybe by this.setDefaults(), see the ULMA documentation for details on the built in functions).
    A crafted ULMA function doesn't even need you pass parameters to it if you initialize in within such preliminary check your properties in a savvy way.
    None the less, if you want your user to set properties for what you want to achieve can't rely on default values anyway (that is, you need passing/setting arguments), well it is done prior to calls by:
    foo.crafted.setAttributes(/*args, values*/)
    foo.crafted.run()
    //go!
  2. RUN:
    It is the main repetitive tasks corehouse (if run by a call to run and therefore triggering a setInterval; if you just call foo.crafted.execute() would "run" just once).
    Arguably, it is in this arena that you may nest runtime updates of the previously initialized variables/properties, and it is certainly in this area that you set the calls to the ULMA bundled functions which are ULMA main engines, such as dispatcher or clipper etc...: trivial example:
    this.clipSide1+=30;
    this.clipper.execute(this.x1,this.clipSide1,this.uhm,this.whoKnows)

    (Remember: ULMA wants you to append keyword execute even to bundled methods. See the ULMA documentation for more.)
  3. END:
    YOu nest a conditional check which verifies whether what you consider/have calculated as the final condition has been met:
    if(this.someProperty=="dunno"){
    this.stop(); //stop is built in: no appending execute
    this.isRunning=0;
    //remember to reset variables. You may consider using this.reset()
    //if you have used this.setDefaults(args);
    }

    As you can see, this is the area where you may call a block of the running process. You can achieve by using the ULMA method called stop, and this is the area where you should also remember to reset your variables (and of course do remember to reset this.isRunning=0).
 }
  • You now enable your method for the given layerManager.
    foo.enable("crafted")
    You then trigger it either by:
    foo.crafted.run()
    or:
    foo.crafted.execute()

  • Remember that a NS4 bug prevents you from issuing such calls like inline statements from event handlers such as onClick: workaround: nest those calls in fake functions, and NS4 would work fine:
    function NS4WeLuvU(){foo.crafted.run()}
So, on the whole, it's darn simple and you won't face bigger difficulties than those you may face scripting your own scripts.
Last but not least, if you need accelerating or decelerating speeds, you just have to check the small section on the otherwise long official ULMA file; such section can be pinpointed by clicking here.
Difficult? Illogic?