5,693,062 members and growing! (17,356 online)
Email Password   helpLost your password?
Web Development » Client side scripting » General     Advanced License: The Code Project Open License (CPOL)

Challenge-Me: Javascript Including Engine - Part III

By Alexandru Lungu

Implementing JavaScript’s missing functionality of including in js files other js files.
Javascript, Windows, Visual Studio, IE 6.0, IE 5.5, IE, Dev, QA

Posted: 22 Jan 2007
Updated: 10 Jul 2008
Views: 22,341
Bookmarked: 9 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
21 votes for this Article.
Popularity: 5.37 Rating: 4.06 out of 5
1 vote, 4.8%
1
0 votes, 0.0%
2
1 vote, 4.8%
3
0 votes, 0.0%
4
19 votes, 90.5%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article
  • Download source files - 10.4 Kb

    Foreword

    This is the third and final part of the article, and for better understanding of this part, I recommend reading the first and second parts first.

    Part III

    From Previous Parts

    The challenge - To create an engine that will implement the JavaScript’s missing functionality of including in js files other js files.

    The solutions - A solution that works only if the external files contain functions, or declarations that don't depend on other files and another solution that works in every situation but has one small disadvantage: having to create header files for the source files.

    The second isn’t far from meeting the challenge, but not there yet. Can we push further?

    Solution 3

    The Logic

    One of the problems identified back then was that when the execution of a script starts, it goes all the way and from that we have the restriction: all files should contain only function declarations and object declarations (but only if they're not related to objects from other files).

    Ideally, only the part with the $include function of the file should be executed – and will name this part header, and then, when the time is right, the rest – body, but as I stated above, it cannot be done.

    Let’s think again; how do we stop the execution of a script? For a function you use return, but for the entire script?

    Error is the answer!!! When an error occurs the script’s execution is halted! So we throw an error on purpose! The next question will be: But the browser won’t display the error? It will, unless we override window.onerror so that nothing will be shown to the user.

    Our code should look like this

    $include = function ()

    {

    //code …

    throw new Error(“Special Error”);

    }

    Window.onerror = function ()

    {

    //we can check here to see if the message of the error is not “Special Error” //and then show it to the user

    }

    But 2 problems arise:

    1. The execution of the script can be resumed when needed? NO! (But we can execute it all again)

    2. Also, what happens when a legitimate error occurs? Can it be shown? (Yes, because we can differentiate through an error from the parser and a personalized error thrown by us).

    However there is a more elegant approach: using an iframe.

    But how? A solution would be as text file. Next we read the header (that now does not necessarily have to be a function) and then use eval to execute the body. As stated in the first part eval handles badly resources and this makes it totally inappropriate for executing large portion of code as in our case.

    The other problem is that IE doesn't load the js file like text, but asks you to download it.

    So we will have a html file that will load the script normally and will execute only the $include function that will pass to the parent document the filenames that are dependencies for the file currently loaded in the iframe, and after that we will throw the error.

    Also when a file is loaded is cached so, when needed for the main document, isn’t loaded from the server again.

    But what happens if the script has no dependencies, therefore no $include function?

    Can we force the user to use $include() with no parameters? Yes we can, but also we can wait till the script.onload event is fired and then tell the parent document that this file has no dependencies.

    Of course another problem: the script will be executed twice: first in the iframe and second in the main document; and that’s the least of our problems; the code can contain alert, confirm, open etc. that will screw up our work badly by executing in the iframe.

    And yet another artifice: overriding window.alert, window.open, window.confirm etc. and not just setting them to do nothing but to stop the execution of the script also.

    And that seems to be it!

    Let’s recap a bit:

    The main page will contain a tree of files that will be created by recursively passing a filename (filepath) to the iframe’s document that will return the dependencies for that file. Here we’ll need an algorithm to check for circular dependencies. And of course the $include function will do nothing in the main page.

    After that all files can be added to the main document’s head in the correct order.

    Of course we will keep from the first solution we’ll keep the code that lets us specify path relative to the IncludingEngine.js file and not to the current html document, and from the second solution the way the application starts with the Main function.

    The Implementation

    Unlike the implementations from the previous 2 parts, this one is much larger, therefore not suited for pasting it here.

    But the most important thing was already presented above: general idea together with the little ideas on how to overcome different barriers.

    However you can download this implementation and then examine it. (Don’t forget: there are 2 files: IncludingEngine.js and LoadFile.htm that toghether do the job)


    Next diagram expresses the power of the product that resulted from this solution:

     

    Things that this diagram doesn't show about the resulted product:
    - it works online and offline.
    - doesn't use eval
    - detects and shows the files that form circular dependencies.

    Now we can say that the challenges established in the first part were finally met.

    Notes:
    - the latest version of this implementation can be found at IncludingEngine.jsFramework.com

    Here are all the parts of "Javascript Including Engine" article: Part I, Part II, Part III.
    Also you may want to visit the IncludingEngine website for more info.



  • License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    About the Author

    Alexandru Lungu


    Alexandru Lungu graduated in 2004, first in his class, Cybernetics, Statistics and Computer Science faculty from A.S.E. Bucharest, and two years later finished his master in project management.

    His motto: “Challenge is Life!”

    Now, he works as project manager, developer, consultant depending on the “Challenge”.

    You can reach him at allex4project@yahoo.com.

    Occupation: Web Developer
    Location: Romania Romania

    Other popular Client side scripting articles:

    Article Top
    Sign Up to vote for this article
    You must Sign In to use this message board.
    FAQ FAQ Noise ToleranceSearch Search Messages 
     Layout  Per page   
     Msgs 1 to 5 of 5 (Total in Forum: 5) (Refresh)FirstPrevNext
    GeneralImpossible? Seems not!memberbobyThorn19:01 29 Jul '07  
    GeneralRe: Impossible? Seems not!memberAlexandru Lungu10:58 30 Jul '07  
    GeneralSee my post in Part ImemberSBJ11:54 29 Jan '07  
    GeneralLicensememberSceptic Mole6:18 24 Jan '07  
    GeneralRe: LicensememberAlexandru Lungu13:00 24 Jan '07  

    General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    PermaLink | Privacy | Terms of Use
    Last Updated: 10 Jul 2008
    Editor:
    Copyright 2007 by Alexandru Lungu
    Everything else Copyright © CodeProject, 1999-2008
    Web18 | Advertise on the Code Project