Giter VIP home page Giter VIP logo

Comments (13)

getify avatar getify commented on June 27, 2024

Unfortunately, you can't split up the $LAB.script() calls and the $LAB.wait() call like that, because that will act as two independent LAB chains and won't get your desired effect.

You could do it like this:

<script type="text/javascript" src="http://d7.ttcn/sites/all/libraries/labjs/LAB.min.js?lekatr"></script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
var _lab = $LAB
.setOptions({AlwaysPreserveOrder:true})
.script("/misc/jquery.js")
.script("/misc/jquery.once.js")
.script("/misc/drupal.js")
.script("/misc/ui/jquery.ui.core.min.js")
.script("/misc/jquery.ba-bbq.js")
.script("/modules/overlay/overlay-parent.js")
.script("/modules/contextual/contextual.js")
.script("/misc/jquery.cookie.js")
.script("/modules/toolbar/toolbar.js");
//--><!]]>
</script>

<script type="text/javascript">
<!--//--><![CDATA[//><!--
_lab.wait(function() {
    jQuery.extend(Drupal.settings, {"basePath":"\/"},"overlay":{"... strip..."});
});
//--><!]]>
</script>

The difference here is we "continue" the original $LAB chain by saving the ultimate return value (technically the return value from the last .script() call) int _lab variable, and we then chain the .wait() off it later.

However, I would say in general, it's not a good idea to split the chains up like this, as there's a possibility that you can create race conditions (not really a case I've tested extensively). So if you do it that way, be careful and test thoroughly.

Another approach, which should be a little more solid, but is based on a very similar concept (simulated chaining) is found here:

https://gist.github.com/704226

-OR-

https://gist.github.com/475431

from labjs.

jcisio avatar jcisio commented on June 27, 2024

Thanks, Kyle, that works.

About the queuing, I can't use it. Developers put inline JS everywhere. I can grab all JS files and put in one chain without side effect, but for inline JS blocks, it's more difficult. However, I'll do more test about merging all inline JS blocks.

from labjs.

jcisio avatar jcisio commented on June 27, 2024

Anyway, is it better to have an event callback like this?
$LAB.ready(function() {
// code will be executed when all scripts are executed
// ...
});
It is like _lab.wait() but we can have many $LAB.script().script()... chains.

from labjs.

getify avatar getify commented on June 27, 2024

Initially, it was an important design decision for LABjs to have each $LAB chain completely independent. This is still currently my philosophy and it precludes features which deliberately tie the chains together, even for a single callback.

Syntactically, it introduces an API complexity/confusion that is undesirable. If $LAB.ready() fires when all current chains are done, what happens if you start another $LAB chain after it (or inside it)... will it clear out that event? Lots of issues arise in this line of questioning.

Basically, I'm not convinced that the use-case for multiple chains is all that strong (except in a few scenarios), and so I encourage people to consolidate their code into as few chains as possible. Really, you shouldn't have any code in separate chains if that code has any relationship to code being loaded in another chain. There's "simulated chaining" (with a for-loop) if you have the need to build up parts of a chain in contextually separate blocks of code and run the chain all at once once the chains parts are all known.

So, while I've thought about a $LAB.ready() thing before, I think it's counter to the philosophy, API design, and best-practices that are put forth from LABjs.

I'm not aware of any use-case that would be a strong argument for such a thing... can you explain why you think it's necessary?

from labjs.

jcisio avatar jcisio commented on June 27, 2024

When I think about $LAB.ready(), I suppose that there is no $LAB.script() inside it. I didn't thought about the case when there is a $LAB.script() after a $LAB.ready(). Indeed, I thought that the browser is fast enough (or there is a small delay before $LAB.ready()) so that all $LAB.script() are called (that mean LABjs knows all scripts in the page) before $LAB.ready().

When you ask about this case, I know that I'm wrong ;-) because your decision is "as fast as the browser will allow", then there is no delay... But I wonder if a few ms delay for $LAB.ready() could be enough so that all $LAB.script() are called before .ready()?

In a page there are many JS: some is in header, some is in footer, some is in the content for inline ads (the availability of JS depends on content, not on page, not all content have ads). But in fact I can postprocess to consolidate all JS file in one call, reorder JS (normally ads JS does not depend on other JS, thus it is placed 1st). So, currently I don't have any use case for multiple chain, it's just for convenient.

Thanks for your help. FYI I've created a new project page to enable LABjs in Drupal automatically http://drupal.org/project/labjs . Version for Drupal 7 was out, for Drupal 6 is coming soon. Maybe there will be more use cases.

from labjs.

getify avatar getify commented on June 27, 2024

I saw the Drupal LABjs project! Thanks so much for doing that!

I understand that it's common (especially in CMS's) for people to strewn their <script> tags (both inline script blocks and external script references) about the entire HTML.

That's why I gave you the link on the "queuing"... basically, you could have the drupal find all the different script blocks (inline and external src) and replace that with the appropriate call to $LAB.queue() as shown, just like you do with $LAB.script() or $LAB.wait() right now.

Then, in the master footer of the page, you have one call to $LAB.executeQueue() which causes the entire set of all scripts from across all the different snippets to start loading and executing, just like if you'd done a single $LAB chain at the end manually.

In my opinion, this is the best of both worlds for CMS's, because plugins and content authors get to keep leaving their scripts inline strewn about their content as makes sense to them, and the CMS takes care of re-writing all <script>...</script> and <script src="..."></script> blocks to calls to the $LAB.queue() manager, and the content/plugin authors never know the difference.

from labjs.

jcisio avatar jcisio commented on June 27, 2024

The following code doesnot work:


<title>TTCN D7 test</title>
<script type="text/javascript" src="http://d7.ttcn/sites/all/libraries/labjs/LAB.min.js?lenopg"></script>
<script type="text/javascript">
var _lab = $LAB
.setOptions({AlwaysPreserveOrder:true})
.script("http://d7.ttcn/file1.js");
</script>
<script type="text/javascript" src="http://partner.googleadservices.com/gampad/google_service.js"></script>
<script type="text/javascript">
_lab.wait(function() {
alert(0);
});
</script>

Test

I load all scripts with LABjs, but not google_server.js (I want it to be blocking one, and there are ads block with document.write() that requires this file that I can't put in .wait()). If all files are in cache, the code "alert(0)" is not executed.

from labjs.

getify avatar getify commented on June 27, 2024

yeah, like i said, it's not particularly a supported use-case to have significant delays in the middle of a chain's operation. That's why queuing up all your script and inline scripts (into .wait()) and then firing off the chain all at once at the end is the preferred route. The two links I've sent you above show exactly how to do that.

from labjs.

jcisio avatar jcisio commented on June 27, 2024

I've reread the queuing code snipset, but sorry I can't figure how to use it in my case.

I don't want (or it is impossible) to load all scripts with LABjs. There is an inline JS block that I can't put in .wait() because of document.write(). This inline block requires an external script. Thus I have to load this external script in the traditional way.

from labjs.

getify avatar getify commented on June 27, 2024

i undersstand that you only want to load some scripts with LABjs. as far as i'm concerned, if you have to, that's fine. if there's a script that has a document.write in it, you should definitely only load that with a regular script tag. (hint: you shold also pressure the creator of that script to stop using document.write()... it's terrible for performance!)

if you're wanting is to have a regular script block in the markup have some waiting affect on the code you're loading with LABjs, this is not possible. the definition of a dynamic script loader is that it makes script loading independent from the page's other resource loading (including manual script tags).

if you're just wanting to sometimes use the queueing (for LABjs loadable scripts) and other times not, do something like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>TTCN D7 test</title>
<script src="http://d7.ttcn/sites/all/libraries/labjs/LAB.min.js?lenopg"></script>
<script type="text/javascript">$LAB.setGlobalDefaults({AlwaysPreserveOrder:true});</script>
...
<script>$LAB.queue("http://d7.ttcn/file1.js");</script>
...
<script src="http://partner.googleadservices.com/gampad/google_service.js"></script>
...
<script>$LAB.queue(function() {
  alert(0);
});</script>
...
</head>
<body>Test</body>
...
<script>$LAB.executeQueue();</script>
</html>

As for how, in your original markup, to distinguish what code should be queued for LABjs and what should be left alone, have it be something like this as the original markup before you alter it with your Drupal module:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>TTCN D7 test</title>
...
<script rel="LABjs" src="http://d7.ttcn/file1.js"></script>
...
<script src="http://partner.googleadservices.com/gampad/google_service.js"></script>
...
<script rel="LABjs">
  alert(0);
</script>
...
</head>
<body>Test</body>
</html>

So, your original markup just starts off with script blocks strewn throughout, like shown. For the script blocks where you want LABjs to attach and queue (either for an external src loading, or for an inline snippet), you just mark the tag with something like rel="LABjs", that way your Drupal module knows it should rewrite that tag. And you inject the LABjs loading at the beginning, including the setting of global defaults, and you inject the executeQueue() call at the very bottom of the page.

I dunno if this helps or not, but that's how I'd approach a CMS module for LABjs.

from labjs.

jcisio avatar jcisio commented on June 27, 2024

That helps much! I try with queuing and it works. The conclusion could be we shouldn't use var _lab = $LAB... because it is not stable. About the document.write(), that's Google and I don't bother to tell...

The working code is as follow, I try to make it more comprehensive:


<title>TTCN D7 test</title>
<script type="text/javascript" src="http://d7.ttcn/LAB.min.js"></script>
<script type="text/javascript">$LAB.setGlobalDefaults({AlwaysPreserveOrder:true});</script>
<script>
$LAB.queue("http://d7.ttcn/file1.js");
$LAB.queue("http://d7.ttcn/file2.js");
</script>
<script type="text/javascript" src="http://partner.googleadservices.com/gampad/google_service.js"></script>
<script type="text/javascript">
$LAB.queue(function() {
// do some good thing
});
</script>


Test
<script type="text/javascript">
// this is evil, and it requires google_service.js
// it calls a function to add more JS file and do some document.write()
</script>
<script type="text/javascript">$LAB.executeQueue();</script>


My approach to rewrite a JavaScript is to verify if there is a comment // LABjs exclude at the begin, that way it get a great penetration with zero conf for mostly other modules.

Then when will the queuing functionality officially get in? ;-)

from labjs.

getify avatar getify commented on June 27, 2024

At the moment, I don't have specific plans to include it "officially". It's not a lot of extra size, but it is only a functionality that's actually useful if people are using it inside CMS's like you are, and in that case, I think them adding in the little extra snippet is probably the best idea.

Previously, before I released v1.1.12 (actually, v1.1.11), we didn't have "conditional chaining", and there was a lot more of a use-case for this queuing. But now that conditoinal chaining is directly supported, this queuing is only necessary if you need to spread out the building of your chain across the entire HTML block. I don't generally recommend that approach, but in the specific case of CMS's, it's the best (or only) option.

from labjs.

getify avatar getify commented on June 27, 2024

queueing was added in 2.0

from labjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.