LA.NET [EN]

Dec 04

Though i really don”t like Britney Spears, I must say that this is a good time for singing “oopss, i”ve did it again…”. This post is the result of another thread in the AJAX extensions forum. GQAdonis was really sure about the problem: ScriptLoader (the class used for loading script files) wasn”t working properly. I”m not an expert, but after looking at the class, I really didn”t see how it could be causing the problem he was having.

After several complaints, we finally got a sample: it was time to run it and see what”s going on. Guess what: the ScriptLoaded didn”t had any fault in what was happening. His only fault was loading the files in the specified order (and, in this case, it ended up loading the file 2 times). Let me give you a small example which shows how things can go wrong when you don”t pay attention to the loading of the jscript files and end up loading the same file two times. We”ll demonstrate this with a simple example. Let”s suppose that we have class A in file A.js:

//A.js
Type.registerNamespace( “Test” );
Test.A = function(){
 ….
}
Test.A.registerClass( “Test.A” );

Now, let”s suppose that you redefine the class (yes, no need to change the internals; copying and pasting the contents to another file is more than enough for our purposes) in B.js:

//B.js
Type.registerNamespace( “Test” );
Test.A = function(){
 ….
}
Test.A.registerClass( “Test.A” );

Now the big question: what happens when you load both files sequentially?

<asp:ScriptManager runat=”server” id=”manager”>
  <Scripts>
    <asp:ScriptReference path=”A.js” />
    <asp:ScriptReference path=”B.js” />
  </Scripts>
</asp:ScriptManager>

After A.js is loaded, you”ll end up having a Test.A object (well, if you want to be more specific,you”ll have a subproperty A of the object Test) which points to the function that is used as a constructor to the object. Loading B.js will result in the creation of a new function and your global Test.A will point to this new function. Normally,this isn”t a big deal. Problems might happen when you create a new class which inherits from A. Suppose you have a C.js file with the following code:

//C.js
Type.registerNamespace( “Test” );
Test.C = function(){
 ….
}
Test.C.registerClass( “Test.C”, Test.A );

And what do you think will happen when you load the following sequence:

<asp:ScriptManager runat=”server” id=”manager”>
  <Scripts>
    <asp:ScriptReference path=”A.js” />
    <asp:ScriptReference path=”C.js” />
    <asp:ScriptReference path=”B.js” />
  </Scripts>
</asp:ScriptManager>

I”d say that you might be in trouble now! Why might that happen? let”s jump to the C.js loading. When that happens, you have a new C class which inherits from A. What you might not know is that C has an internal field called _baseType which points to the base class type (ie, to the function which is used as a constructor for A). Now, when you B (which redefines the base A class), you”ll “redirect” Test.A to that new function which is created. Start to see the problem? no? ok, let me show it to you in one line:

Test.A === Test.C.__baseType is ALWAYS false now!

why? well, if you compare the values of each property of Test.A to Test.C.__baseType, you”ll see that those values are the same. however, we”re talking about different objects! though most of you never saw the previous line, i can assure you that there”s a similar one to that and it”s used when you initialize the base class (ie, when you execute the initializeBase method). btw, if it fails you”ll get an exception…

Yes, you”d have to be crazy to reload code but you should keep in mind that getting in this trap is easier than it seems: for instance, the only thing you need is a scenario like GQAdonis”: you add a reference to a script file and you”re also injecting that file in the page through a server control.

In GQAdonis defense, one might say that script controls should be integrated with the scripts added to the ScriptManager control (unfortunatelly, that doesn”t happen).

5 comments so far

  1. Bertrand Le Roy
    4:40 am - 12-4-2006

    You”ll be glad to know that in the RC release, you can”t redefine a class at all. So in this case you”d get an error message telling you that the class is already defined.

  2. Luis Abreu
    9:32 am - 12-4-2006

    that”s is good, though we still need to solve the double insertion issue which happens when you register a file on a script control (IScriptControl) and also in the scriptmanager control (currently, you get both files inserted on the page and even though i”ll get an exception in rc1, what i need is to download only a file).

  3. Luis Abreu
    10:46 am - 12-4-2006

    just to be more explicit: can you tell me why the scripts registered by script controls aren”t “persisted” in the same list as the ones you add through the scripts property of the scriptmanager control? though i may be wrong, i think that not doing this will let me add two times the same file (as happened in the link i”ve provided above).

  4. trhmayhoe
    4:05 am - 10-31-2009

    woyXye kzmwrolfyood, [url=http://cmbchafkxrra.com/]cmbchafkxrra[/url], [link=http://oqjbzusjpcmn.com/]oqjbzusjpcmn[/link], http://xkrzeqooebui.com/

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>