determining the location of a script on the server? Firefox bug won't let me

Discussion in 'Javascript' started by petermichaux@gmail.com, Mar 21, 2006.

  1. Guest

    Hi,

    I'm hoping for a reason I'm wrong or an alternate solution...

    I'd like to be able to dynamically include some javascript files. This
    is like scriptaculous.js library but their solution is broken in
    Firefox 1.5.0.1 on OS X. What happens with the Scriptaculous library is
    this

    In the html document the author only has to include one line

    <script type="text/javascript"
    src="/javascripts/scriptaculous.js"></script>

    but scriptaculous.js determines where scriptaculous.js was from and
    then add other lines to the html doc to src other JavaScript files. By
    the end of scriptaculous.js the html doc has something like

    <script type="text/javascript"
    src="/javascripts/scriptaculous.js"></script>
    <script type="text/javascript" src="/javascripts/effects.js"></script>
    <script type="text/javascript" src="/javascripts/dragdrop.js"></script>

    (All the scripts are in the same server directory.)

    This is a good idea in scriptaculous because it insures that the
    JavaScript files are src'ed in the correct order. Also, if the
    implementation of scriptaculous library changes then the html docs that
    use it are not broken. This may lead to too much javascript being
    src'ed by the html doc but I'm not worried about that right now.

    The problem with the method of determining from what domain and which
    directory scriptaculous.js came from in the first place cannot be used
    twice in Firefox (ie for two separate libraries). I tried to play the
    same trick but document.getElementsByTagName('script') will not let me
    do it. I have tried to trim down the following example to show what I
    want to do. It works in Safari. The divs backgrounds are green and red.
    In Firefox only one has a background color. No errors or exceptions.
    Firefox can never find the <script src="grof.js"> tag.

    If you want to see the problem I found with Firefox more isolated
    please see bugzilla
    (https://bugzilla.mozilla.org/show_bug.cgi?id=331174). What I found was
    the problem is that in firefox you cannot ask for the length of the
    scriptTags variable below twice (grof.js, burp.js). Changing the
    variable name (scriptTags) in only grof.js did not make a difference.

    So what is another way to determine the location (url) of grof.js (and
    burp.js) in the following example (or scriptaculous.js in that library)
    so that I can dynamically src the other js files in the libraries
    (grof2.js)? I don't want to hardcode any locations.

    Thanks for reading this far and I hope someone has a suggestion.

    Peter


    ------------------- test.html -------------------

    <html>
    <head>

    <script type="text/javascript" src="grof.js"></script>

    <script type="text/javascript" src="burp.js"></script>


    </head>
    <body>
    <div id="grof">Grof</div>
    <div id="burp">Burp</div>
    </body>
    </html>


    ------------------- grof.js -------------------

    var scriptTags = document.getElementsByTagName("script");
    for(var i=0;i<scriptTags.length;i++) {
    if(scriptTags.src && scriptTags.src.match(/grof\.js(\?.*)?$/))
    {
    var path = scriptTags.src.replace(/grof\.js(\?.*)?$/,'');
    document.write('<script type="text/javascript"
    src="'+path+'grof2.js"></script>');
    }
    }

    ------------------- grof2.js -------------------
    function g(){
    var burp = document.getElementById("grof");
    burp.style.background="green";
    }

    window.addEventListener("load", g, false);


    ------------------- burp.js -------------------

    var scriptTags = document.getElementsByTagName("script");
    for(var i=0;i<scriptTags.length;i++) {
    if(scriptTags.src && scriptTags.src.match(/burp\.js(\?.*)?$/))
    {
    // Firefox will never get in here because the if condition will
    never be true.
    var path = scriptTags.src.replace(/burp\.js(\?.*)?$/,'');
    document.write('<script type="text/javascript"
    src="'+path+'burp2.js"></script>');
    }
    }

    ------------------- burp2.js -------------------

    function b(){
    var burp = document.getElementById("burp");
    burp.style.background="red";
    }

    window.addEventListener("load", b, false);
    , Mar 21, 2006
    #1
    1. Advertising

  2. Csaba Gabor Guest

    wrote:
    > So what is another way to determine the location (url) of grof.js (and
    > burp.js) in the following example (or scriptaculous.js in that library)
    > so that I can dynamically src the other js files in the libraries
    > (grof2.js)? I don't want to hardcode any locations.
    >
    > Thanks for reading this far and I hope someone has a suggestion.


    I don't quite follow all of what your are thinking to do. In
    particular, if you call on your first js file to be loaded, why can't
    it presume that the rest haven't been loaded, given that you are
    defining one "gateway" to access all the files. In other words, all
    anybody is ever supposed to write is <script
    src="firstJSfileToCall.js"> and that takes care of loading the rest,
    which the HTML author is not supposed to care about.

    But, if you argue some schizophrenia on the part of the file
    identifications, you could test for the existence of a function or
    variable you know to exist. For example, each script that you are
    interested in could set itself (that is, its name) on
    window.aIAmLoaded.

    Also, you could assign an id to each script as well as an onload so
    that is perhaps another way to get to the script element you are
    looking for. For example, you could put in properties
    id="currentScriptFileName" and
    onload='bootstrapIterator("nextScriptFileName")', which function you'd
    define in your first script file.

    Could it be that the script loading has not settled? Perhaps you could
    put in a
    window.setTimeout(
    function(){
    var st = document.getElementsByTagName("script");
    alert(st.length)},100);

    Does it make a difference whether you use document.write or DOM methods
    (document.createElement...)?

    Good luck,
    Csaba Gabor from Vienna
    Csaba Gabor, Mar 21, 2006
    #2
    1. Advertising

  3. Guest

    Hi Csaba,

    Thanks for taking the time to read all of my problem. And thanks for
    the ideas. I still think there is a fundamental problem left unsolved.
    I've inserted comments below.

    Peter

    Csaba Gabor wrote:
    > wrote:
    > > So what is another way to determine the location (url) of grof.js (and
    > > burp.js) in the following example (or scriptaculous.js in that library)
    > > so that I can dynamically src the other js files in the libraries
    > > (grof2.js)? I don't want to hardcode any locations.
    > >
    > > Thanks for reading this far and I hope someone has a suggestion.

    >
    > I don't quite follow all of what your are thinking to do. In
    > particular, if you call on your first js file to be loaded, why can't
    > it presume that the rest haven't been loaded, given that you are
    > defining one "gateway" to access all the files.


    I could but there is a bigger plan behind my example. This may be
    wasteful if the two gateway scripts are subsets of one big library.
    This isn't my big problem now anyway.

    > In other words, all
    > anybody is ever supposed to write is <script
    > src="firstJSfileToCall.js"> and that takes care of loading the rest,
    > which the HTML author is not supposed to care about.


    Yes, but where are the rest of the scripts? This is my big problem.
    Determining the location of the other scripts. I have the library
    installed in a top level directory ("/javascripts/") on my web app but
    I give the library to someone else they may install the library further
    down the directory tree. The gateway file for the library needs a way
    to locate all of the rest of the scripts.

    > For example, you could put in properties
    > id="currentScriptFileName" and
    > onload='bootstrapIterator("nextScriptFileName")', which function you'd
    > define in your first script file.


    I can't chain the files together in this case. But even if I could I
    don't know the URL of the next script. I'm hoping I don't have to force
    the library user into writing the whole URL in the initial script src
    tag for their installation of the library. That would feel like
    failure. There should be some workaround so the gateway script can
    identify it's own URL and use this as a basis to determine the other
    files' URLs.

    > Could it be that the script loading has not settled? Perhaps you could
    > put in a
    > window.setTimeout(
    > function(){
    > var st = document.getElementsByTagName("script");
    > alert(st.length)},100);
    >
    > Does it make a difference whether you use document.write or DOM methods
    > (document.createElement...)?


    scriptaculous.js says that document.createElement method doesn't work
    in Safari. I haven't tried this yet but either way i still need to know
    the locations of all the script files in the library.

    Any other ideas about getting the script locations?

    thanks again,
    Peter
    , Mar 21, 2006
    #3
  4. Csaba Gabor Guest

    wrote:
    > Csaba Gabor wrote:
    > > wrote:
    > > > So what is another way to determine the location (url) of grof.js (and
    > > > burp.js) in the following example (or scriptaculous.js in that library)
    > > > so that I can dynamically src the other js files in the libraries
    > > > (grof2.js)? I don't want to hardcode any locations.


    > Yes, but where are the rest of the scripts? This is my big problem.
    > Determining the location of the other scripts. I have the library
    > installed in a top level directory ("/javascripts/") on my web app but
    > I give the library to someone else they may install the library further
    > down the directory tree. The gateway file for the library needs a way
    > to locate all of the rest of the scripts.
    >
    > > For example, you could put in properties
    > > id="currentScriptFileName" and
    > > onload='bootstrapIterator("nextScriptFileName")', which function you'd
    > > define in your first script file.

    >
    > I can't chain the files together in this case. But even if I could I
    > don't know the URL of the next script. I'm hoping I don't have to force


    I think I'm missing something here. Who does know the URL (or more
    rather, file name) of the next script(s). In other words, once the
    first file in your library is loaded, either that file should know the
    rest of the scripts involved, or it should know the next one only and
    the next one is responsible for knowing the 3rd one's name and so on.
    Or is there something else going on? I assumed it was the second of
    the two possibilities I mentioned since you were mentioning that you
    were ensured sequential loading. If this is off, please correct me.
    Not that it really would have changed my responses, I think.

    > the library user into writing the whole URL in the initial script src
    > tag for their installation of the library. That would feel like


    So let me paraphrase what I think I read. I imagined that you had a
    library (of several javascript files full of lots of fun code). And
    that this library winds up on other people's servers - that is to say
    that the javascript files wind up on someone's server who is intending
    to use the library. Only it could be in an arbitrary location relative
    to the HTML documents they are serving up. So you want them to be able
    to have a minimally long src="..." in order to specify the location of
    the first javascript file in the library. And that javascript file is
    responsible for loading all the rest. But to do that, it needs to know
    where it itself is, so that it can write a complete src for the
    remaining SCRIPTS that it writes out. And it intends to do this by
    finding the src for its own SCRIPT tag (and also window.location.href).

    > failure. There should be some workaround so the gateway script can
    > identify it's own URL and use this as a basis to determine the other
    > files' URLs.
    >
    > > Could it be that the script loading has not settled? Perhaps you could
    > > put in a
    > > window.setTimeout(
    > > function(){
    > > var st = document.getElementsByTagName("script");
    > > alert(st.length)},100);
    > >
    > > Does it make a difference whether you use document.write or DOM methods
    > > (document.createElement...)?

    >
    > scriptaculous.js says that document.createElement method doesn't work
    > in Safari. I haven't tried this yet but either way i still need to know
    > the locations of all the script files in the library.
    >
    > Any other ideas about getting the script locations?


    So is it not the case, that you only ever need to fish out one script
    tag, really, that first one that the user/developer must code because
    that will allow subsequent scripts to determine the location of all the
    remaining script files?

    In this case, won't placing an id=... allow that script element to be
    recovered? I still think this is the one that bears most careful
    examination.
    <script type='text/javascript' id='PetersFunkyLibrary'
    onLoad="alert(document.getElementById('PetersFunkyLibrary').id)"
    src="..."></script>

    Up to some months (a year?) ago, it was the case that in FF the SCRIPT
    elements sat in the HEAD element off the HTML element
    (=document.documentElement). But that is evidently no longer the case,
    as I am now finding the SCRIPT elements under document.body, and not
    necessarily directly under (if you wrap the SCRIPT in a DIV). It seems
    to me that they were happy where they used to live and I don't see the
    reason for their eviction. Nevertheless, perhaps directly walking all
    the elements of document.body.childNodes and checking for
    ..nodeName=="SCRIPT" might have a shot at finding all the script
    elements in the problem browser (though I don't give it good chances if
    document.body.getElementsByTagName('SCRIPT') is failing).

    Csaba
    Csaba Gabor, Mar 21, 2006
    #4
  5. Guest

    Casab,

    > So you want them to be able
    > to have a minimally long src="..." in order to specify the location of
    > the first javascript file in the library. And that javascript file is
    > responsible for loading all the rest. But to do that, it needs to know
    > where it itself is, so that it can write a complete src for the
    > remaining SCRIPTS that it writes out. And it intends to do this by
    > finding the src for its own SCRIPT tag (and also window.location.href).


    Yes, exactly.

    > So is it not the case, that you only ever need to fish out one script
    > tag, really, that first one that the user/developer must code because
    > that will allow subsequent scripts to determine the location of all the
    > remaining script files?


    Yes that is true. If two libraries are included then I need to do this
    once for each library. That is where the scriptaculous idea fails in
    firefox. Once the trick is used once then it can't be used again due to
    a bug. It might be breaking other things too.


    > In this case, won't placing an id=... allow that script element to be
    > recovered? I still think this is the one that bears most careful
    > examination.
    > <script type='text/javascript' id='PetersFunkyLibrary'
    > onLoad="alert(document.getElementById('PetersFunkyLibrary').id)"
    > src="..."></script>


    I was hoping to avoid adding anything on the part of the library user
    but maybe it is necessary for now. If I can't find a cross browser
    solution then I will try this.


    > Up to some months (a year?) ago, it was the case that in FF the SCRIPT
    > elements sat in the HEAD element off the HTML element
    > (=document.documentElement). But that is evidently no longer the case,
    > as I am now finding the SCRIPT elements under document.body, and not
    > necessarily directly under (if you wrap the SCRIPT in a DIV). It seems
    > to me that they were happy where they used to live and I don't see the
    > reason for their eviction. Nevertheless, perhaps directly walking all
    > the elements of document.body.childNodes and checking for
    > .nodeName=="SCRIPT" might have a shot at finding all the script
    > elements in the problem browser (though I don't give it good chances if
    > document.body.getElementsByTagName('SCRIPT') is failing).


    I didn't know that there were such problems with the SCRIPT elements in
    Firefox. Thanks for this suggestion. I tried direct walking
    document.childNodes and it worked in Firefox!!! Now I don't even have
    to check for script tags. I just look for any tag with a src with a
    regular string match. This is great! Now I have to try on IE. Nail
    biting time.

    Below is my new burp.js which needs some clean up (and the old one for
    reference).

    Many thanks! I really appreciate your patients in helping me.

    :D

    Peter


    ------------------------------ new burp.js
    -------------------------------------

    function check_is_script(element){
    if(element.src && element.src.match(/burp\.js(\?.*)?$/)){
    return element;
    }

    var children = element.childNodes;
    for(var i=0;i<children.length;i++) {
    var found = check_is_script(children);
    if (found != null) {
    return found;
    }
    }

    return null;
    }

    var asdf = check_is_script(document);
    if(asdf != null) {
    var path = asdf.src.replace(/burp\.js(\?.*)?$/,'');
    document.write('<script type="text/javascript"
    src="'+path+'burp2.js"></script>');
    }


    ------------------------------ old burp.js
    -------------------------------------

    var scriptTags = document.getElementsByTagName("script");
    for(var i=0;i<scriptTags.length;i++) {
    if(scriptTags.src && scriptTags.src.match(/burp\.js(\?.*)?$/))
    {
    var path = scriptTags.src.replace(/burp\.js(\?.*)?$/,'');
    document.write('<script type="text/javascript"
    src="'+path+'burp2.js"></script>');
    }
    }
    , Mar 21, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dot net work
    Replies:
    4
    Views:
    526
    Dot net work
    Jun 16, 2004
  2. Luigi Donatello Asero

    Let or not let the text float

    Luigi Donatello Asero, Jan 15, 2004, in forum: HTML
    Replies:
    6
    Views:
    458
    Steve R.
    Jan 15, 2004
  3. Alan Silver
    Replies:
    1
    Views:
    3,035
    Alan Silver
    Jul 20, 2006
  4. Aaron
    Replies:
    11
    Views:
    15,734
    Aaron
    Sep 13, 2006
  5. Nathan Sokalski
    Replies:
    2
    Views:
    369
    Nathan Sokalski
    Sep 22, 2006
Loading...

Share This Page