Use of JavaScript in Moodle

Use of JavaScript in Moodle

Tim Hunt -
Erantzun kopurua: 83
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I naively started to clean up some of the places we include JavaScript code in Moodle (MDL-16583), and found some real mess*. We really need to clean it up a bit. However, rather than just starting to hack around with the code, I realised that we should have some sort of consensus about how things should work, before we can fix it.

So, I wrote Development:JavaScript_guidelines, which is my proposal for what the Moodle JavaScript coding guidelines should say. However, I am not the most experienced JavaScript developer here - most of what is written in that document I learned from working with sam and others, and looking at the YUI code example - so this definitely needs input from more knowledgable people. Hence this forum thread.

Let the discussion begin ...


* For example, we seem to have three mechanisms: the nice new require_js, the slighly hacky $CFG->javascript, and the truely horrific global $standard_javascript.
Puntuazioen batez bestekoa:Useful (2)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Adam Zapletal -
Thanks for including the "Getting more variables from PHP to JavaScript" section. My team was looking for a nice way to localize strings that are provided by javascript, and this is a great starting point.

We have a lot of javascript in some places, but I think the only code that is run on import is adding event listeners. I'm not a huge javascript guy either, but I am worried that wrapping these in an init() would cause any problems with certain events.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Nigel McNie -
FWIW, Mahara puts a small dictionary at the top of every page with really commonly used things like wwwroot in it. Maybe you could do that with some common things to save people having to pass them around?
Nigel McNie(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I was wondering about that, but I did not want to commit myself to what should be included in such a dictionary. I would be happy to hear specific suggestions.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Nigel McNie -
Mahara has (of things that are potentially relevant to Moodle):

session key (string)
wwwroot (string)
loggedin (1|0)
userid (int, ID of user viewing the page)

So far that's been all we've required. YMMV.
Nigel McNie(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I needed this, so I did it. MDL-16672. So far in Moodle, we just have

'wwwroot' => $CFG->httpswwwroot, // Yes, really.
'pixpath' => $CFG->pixpath,
'modpixpath' => $CFG->modpixpath,
 Tim Hunt - 25/Sep/08 11:12 AM Currently we just have 'wwwroot' => $CFG->httpswwwroot, // Yes, really. 'pixpath' => $CFG->pixpath, 'modpixpath' => $CFG->modpixpath,

which is all I have needed so far. Obviously the list is extensible in future.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Dongsheng Cai -
About "Activating your JavaScript" section

Another way to do this is to use javascript event, for example:
window.onload= function() {
init_my_script('perhaps_some_data', 'for_example', 'mything');
}
In this case, you can define this onload function in static javascript code, after the page loaded, this event will be fired.

In YUI, you can simply call:
YAHOO.util.Event.onDOMReady(init_my_script);
plus,
YAHOO.util.Event.onAvailable(html_id, this.ElementOnAvailable, this);
ElementonAvailable() will be fired when DOM element available.

See more: http://developer.yahoo.com/yui/event/#ondomready

About "print_js_config"
I noticed you didn't actually use that prefix in javscript class name, when developers use these function more than once in one page, qengine_config will be overwritten by latest call, also, qengine_config should declare as "var", when using it without "var" inside a javascript class, qengine_config will be declared as global object by default.

Last but not least, should we include JavaScript Object-Oriented Programming? It is quite useful.




Dongsheng Cai(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I have never had to use an event handler like window.onload, YAHOO.util.Event.onDOMReady or YAHOO.util.Event.onAvailable to initialise things. It has always been enough to output a simple function call script in the page - but perhaps I have only ever done simple things, and there are some subtleties that I don't understand. Do you have an example where it is necessary?

With print_js_config. I was thinking of using this just for fixed configuration data, so you would only call it once per page, probably around the time you do print_header. Any things that varied between different instances of the JavaScript on the page - for instance initialising different HTML editors - would be handled by parameters to an init function. But again, perhaps this is showing my lack of experience. Or you could make up a unique name for the config variable in PHP, and then pass that to the init code.

A tutorial about JavaScript OOP might be useful, but I think it should be a separate page from the coding guidelines. The coding guidelines should be just what someone who already knows how to program in JS needs to know to do things the right way in Moodle.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Dongsheng Cai -
> Do you have an example where it is necessary?
1) Sometimes, I don't have chance to modify the HTML code, I have to define the init code in a separated javascript file.

2) I use DOM to insert HTML element into HTML document, and trying to create a event handler for it, DOM element won't be available immediately, so I have to use onAvaialbe event to make sure the event handler is created safely.

Inline javascript works good in most time, but sometimes we need event hander to solve particular problem.
Dongsheng Cai(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Perhaps we should add an optional parameter to print_js_call to make it easy to do function calls after a particular event?
Dongsheng Cai(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
If you are using the DOM to create page elements, you can add the event handler to the element before its even written to the page.
How is this unsafe?
Inline javascript should be used sparingly (and only as a last resort).
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
And to answer my own question, I just wrote some JS that was causing something really weird to happen, so I changed the init to run only when the DOM was ready, and magically it started working.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Next question: Should we make a separate top level js folder in in the codebase to hold core JavaScript ?

At the moment, JavaScript for specific modules tends to live inside that module, either in a scrip.php file that is included from lib/javascript-mod.php, or in separate .js file that are included using require_js (for example mod/quiz/quiz.js). This is a good thing, and I am not proposing to change this.

And even for things that are part of core, and not separate plugins, I they that they should look after their own JavaScript. For example I recently created question/quengine.js, and again I think that this is good encapsulation. Similarly, the HTML editor encapsulages a lot of JavaScript, which is good.

So what I am really thinking about is all the code in lib. I can see three options:
  1. Continue to add all core JavaScript to lib/javascript-static.php, making it bigger and bigger. This will also mean that rarely used JavaScript is included on every page, whether it is needed or not.
  2. Put lots of different .js files in lib.This lets us only include rarely used JavaScript on relevant pages, but adds to the already long list of files in lib.
  3. Make a top level js folder to hold these scripts, and move the 7 .js files that are currently in lib to there. This is my preferred solution. I think it would be a bit like the pix folder, which holds images that are shared by the whole code, while modules can add their own icons too.
What to people think?
Puntuazioen batez bestekoa:Useful (1)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Martin Dougiamas -
Core developers-ren irudia Documentation writers-ren irudia Moodle HQ-ren irudia Particularly helpful Moodlers-ren irudia Plugin developers-ren irudia Testers-ren irudia
I do like the idea of option 3 from a "make it nice and tidy" standpoint, but ...

One pro for the big static JS file is it reduces hits on the server for the first time and then it caches very nicely after that (I guess the browser can also keep it precompiled too). Lots of files means lots of hits on httpd the first time at least. This may not be a huge issue but it is the number one thing that YSlow checks for (Minimise HTTP requests). Perhaps this is offset by less loading on pages that don't need it, I'm not sure.

Another small issue is that moving files around has the potential to break local customisations etc.

Overall, I think I'd vote conservatively for option 1. If that's not popular then do it properly with option 3.
Martin Dougiamas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Matt Gibson -
Would it be possible to add something to require_js() so that it concatenates the .js files temporarily and then sends that single file to the browser? I think Drupal does this and keeps a cache of the various combinations of js files (I assume named using a hash of the names of the constituent files) that can then be recylced.
Matt Gibson(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
It would certainly be possible once all the JavaScript usage in Moodle has been cleaned up to use require_js (only 15
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia
Tim you may check habari http://habariproject.org/en/.

They use Stack::add (system/classes/stack.php) to collect CSS and JS and Stack::out in the pure PHP templates.

habari is a new weblog software with a "Modular, object-oriented core for easy extensibility" based on a MVC (model-view-controler) architecture.

It's great irribarrea
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I guess you are talking about http://svn.habariproject.org/habari/trunk/htdocs/system/classes/stack.php. On a quick look at the code, it seems to do the same as the proposed page_resource_tracker class I posted recently, and which I think will go into Moodle 2.0. Still, nice to see how other projects do it. Thanks.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia

Because I work a lot with behavioural add-ons based on JavaScript in Moodle here my proposals:

  1. Moodle JavaScript handling needs to be flexible enough to handle YUI and other JS frameworks if needed. YUI is too complex for easy implementations - most the time I work with jQuery. Especially because jQuery and YUI play together nicely.
    From my point of view "modular" in Moodle's name needs to stand for a modular codebase too.

  2. Following the YAHOO optimization rules Moodle JavaScript handling needs to be able to load JS from the footer. My survey about theme and JavaScript handling speed have proven that pages load significantly better when behavioural add-ons (as JavaScript code) are loaded after page content.
    Seldom special functions need to load before the page loads. For example code that checks for onAvailable for DOM elements. Moodle needs to be able to load this JS before the page from header. All JS using "on DOM ready" can load from the footer. Therefore I load most JS from the footer in my themes.
    In this context it's also good to know that browsers load and process JS files one after the other.

  3. To keep the number of files sent to the browser small following the YAHOO speed rules Moodle should handle JS similar to the CSS in themes. Create granulated JS and collect it into one file when the page is build.
    Create JS as in Tim' proposal 3 and deliver as in proposal 1.

  4. To be able to include only the needed JS other systems use a JS stack - adding information about preload (from header) or normal load (from footer, default). Every part using JS adds their JS to the stack and Moodle builds two big JS files delivered to the browser - a small one loaded from header and the bigger one loaded from footer.
    As Tim mentioned some parts of Moodle may handle JS individually if needed.
    Many times JS code can be executed after the page has loaded. Code which needs to be executed immediately better uses individual optimized JavaScript than relying on huge and definitely slower JS frameworks like YUI (see topic 7).

  5. Replace the huge overlib.js with YUI functionality. It is only used for the calendar when I am right.

  6. Load the media script UFO only when needed.

  7. Write central core JS in optimized JavaScript which works faster without YUI overhead. Replace all the other functions with YUI.
    In my implementations I use optimized JS for core functionality (loaded from the footer). Afterwards jQuery is loaded form the footer preparing the pages for the behavioural add-ons. My speed researches proved that this way with separate optimized code plus standard framework code you get the best compromise concerning performance on one hand and ease of implementation on the other.

  8. The YAHOO rules very clearly describe the difference between first time page load and cached page load. They also describe the importance of the first time page impression.
    For a good first time page impression the amount of data sent to the browser needs to be as small as possible. Think about Moodle first contact sessions in training situations. These first time impressions are crucial for system acceptance.
    Therefore it is important to send only the needed JS to the browser and not all code on every page.

  9. Create documentation for the Moodle core JS. Then developers don't tend to create the same functionality again and again as it happens now every once in a while.

  10. To reach the round amount of ten topics: Moodle needs to integrate jQuery too begi-keinua

Puntuazioen batez bestekoa:Useful (3)
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Wow Urs, great contribution. Now I just need to think it all through begi-keinua

My initial reaction is to not change the clean-ups I am currently working on. I am removing a lot of cruft from the code base. If I can succeed, we wil be in a situation where all the JavaScript that each page requires is included by using the require_js function.

If we can get to that position, then it should become easier to analyse all of the places in Moodle where JavaScript is used; do things like list or log the number of js files used by each page with the other performance information; and experiment with moveing the place where most JS files are included to the footer; or automatically aggregating them.

Overlib is used in a few other places, e.g. the multianswer question type. I too would like to see it gone, but I don't know how much work that is.
Puntuazioen batez bestekoa:Useful (1)
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Dan Poltawski -

Create granulated JS and collect it into one file when the page is build.
Create JS as in Tim' proposal 3 and deliver as in proposal 1.


Hmm, i've not done any research into this, but this makes me a little uneasy. Surely that is making static content dynamic and thus uncachable?

I accept the point about reducing http requests, but if we slowly load layers of js as required then hopefully this will happen anyway as its cached? Especially as a lot of moodle use cases can really benefit from caching (many people at same institution loading same thing at same time).
Puntuazioen batez bestekoa:Useful (1)
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Jamie Robe -
I case others run across this thread, in regards to jquery, I would really like to see it as an option in moodle. I also added some comments to the tracker issue: http://tracker.moodle.org/browse/MDL-15727

Thanks,
Jamie

Jamie Robe(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
A lesson in logic:

"I have used jQuery a lot, and I know exactly how to use it, and it does everything I want, therefore it should be included in Moodle." Is not a convincing argument. (Of course, it is a butter argument for jQuery than "I have use jQuery and it sucks.")

A convincing argument would look like: "I have used and understand both jQuery and YUI for (insert quantification of level of expertise here). I think that jQuery is better because (insert technical arguments here). I think the advantages are big enough to justify Moodle switiching, even though Moodle has been using YUI for the last 18 months."

Of course, if you are making your own plugin, and are convinced of the benefits, there is nothing to stop you shipping your own copy of jQuery in the plugin folder if you want.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia

Hmm Tim - there is no need to rant.

Jamie wrote "I would really like to see it as an option in moodle"

He does nothing more than support my proposal that Moodle should support the choice of a JavaScript library. You answer to his posting as if he demanded to replace YUI with jQuery which he didn't do at all.

Following some very personal remarks which I need to make due to the experiences in discussions with you. I feel indirectly attacked by your answer.

You seam to react very sensible when somebody talks about flexibility. What makes you fear flexibility? Loose of control? I really don't understand your harsh reaction.

You mention logic.

I see you showing a very specific look on logic - I see your view on logic selective to those aspects that fit your view on Moodle and your view how Moodle has to be. Other approaches you try to goof on (that's the way I see your reactions).

I notice in the last few month that I make huge progress with Moodle related problem solving when I step out of the box and look at the issues from another point of view - like cleanly separating program logic from page view.

For your great engagement in the Moodle forums I highly regard you. You are sometimes the only one who engages in discussions. And you don't fear to engage in unpopular Moodle topics like templates.

Templates

A very old but nevertheless repeating discussion in the Moodle forums. Until now I have not read an argumentation that proves that the way Moodle is build is superior to clearly separating program logic and view and then use templates for the view. The answers look more like "What should templates be good for?" I read the logic behind such an argument as "The status quo is always better than a new approach."

In many Open Source projects the developers decided at some point of their way to switch from pure procedural or even "Spagetti" code to a consequently object oriented approach. Moodle uses objects in some parts. The fundamental switch seams not to be on the horizon. What are the reasons for this reluctance?

When you separate program logic from view there is no problem to add JavaScript or CSS to the header or footer at all. You first calculate and collect the page content. Then you know which page specific JS or CSS you need and you add it to the header or footer in the view. No programing acrobatic needed at all.

Hoping to make progress in our discussion how to make Moodle better.

Puntuazioen batez bestekoa:Useful (1)
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I am sorry, Urs, if you felt attacked by my response. That was not my intention.


Over the years, I have learned a lot while working on Moodle. In particular from discussions in these forums. I have learned, because other people have taken the time to explain why what they were proposing was right. What is frustrating me in these recent discussions is that no one seems to be explaining why.

I try to remember what Martin often says in his keynotes. The Moodle community is itself a learning community. We are not just building a course management system, we are all learning together how to build the best course management system. And one of the most powerful techniques to promote learning is to ask questions. So if I don't understand something I will ask questions. Sometimes they will be tough questions. That is not an attack. That is an attempt to promote learning. Sometimes, from my manner, that may not be clear. In which case I should be more careful, particularly if I post when I am tired.


To return to the technical issue under discussion: I, of course, would not say I am arguing against flexibility. I would say I am arguing in favour of consistency. In a large distributed project, consistency is important so that people who understand one part of the code can probably understand and work on other parts of the code. That is why most open source projects have extensive coding guidelines (e.g. Development:Coding]]). That is why it is better to standardise on just one javascript library, one forms library, and one database abstraction layer, etc.

At the moment, if anything, the Moodle code has too many inconsistencies. For example, the library that builds the admin tree is completely separate from the forms library, even though they do a similar job.

So, without a very good reason, we are better off with just one JavaScript library.

On the other hand, there are good reasons why people have to deploy Moodle on Windows or Linux, or use different databases, or have there Moodle look different. That is why we support different OSs (by using PHP), different databases (by using a database abstraction layer) and different appearances (by having a themes system).
Puntuazioen batez bestekoa:Useful (1)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Jamie Robe -
Hi Tim and Urs,
Holy Toledo!!!! Hope I didn't touch off anything serious here. I sure didn't mean to cause trouble...and I appreciate the open dialog and time spent discussing this issue...

...but I still want to use some jquery and I am sure there are others like me and I will try to make a short but logical case why:

1. I personally have way more experience using jquery on other non-moodle projects. I always use Aptana Studios as my editing/development environment, and it supports using and testing all the big names in javascript libraries. I guess I just took to jquery, and sure helped that there are several really great books out that you can buy at any big bookstore. Since I feel most comfortable in using it to get proven, reliable results in my other php-based applications, it is logical to me to have the option to use it... somehow... in the context of my moodle-based application.

2. I think YUI is absolutly probably one the most valid options for moodle developers to adopt as the single standard for core javascript and ajax or ajax-like functionality. I mean, you can't argue against YUI on any points like long-term viability, which I can see on such a big project as moodle is probably a big issue. However, as painful and improbable as it is, YUI could go south, just the same as any other programming language/ product/ technology. The same could be said for any of the others, including jquery of course. In this very unstable economy, which affects everyone from companies like Yahoo down to the lowly open source "volunteer", I think a very flexible approach would help with long-term viability at teh core level. Now at the site developer level, while we want long term viability too, we need results quickly and painlessly. I think this review done by Javier Rojas is very up-to-date and realistically shows some of the strengths and weaknesses of 5 of the top libraries: http://wiki.freaks-unidos.net/javascript-libraries The final score of jquery edging out YUI is not the important thing in his comparision chart begi-keinua but it shows how logical-based choices often turn out to be subject to human factors afterall. I submit that moodle site developers (or atleast some percentage) are not going to prefer working in YUI, so options for us is very helpful for us getting the job done using moodle.

3. And for my site, all I want are some tips on best pratices to sticking in the files I need to get jquery working in moodle. Logically or not, I (and undoubtly others stumbling upon this forum discussion in the year 2011 or something) will figure out a way, but there is probably a good way(s) and some very bad way(s) to acompish it. I hope some guidance will help me keep my moodle site steering away from the rocks...

Thanks,
Jamie

PS I feel moodle is really terrific to work with and it is because of the contributions of people like you.

Jamie Robe(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Thanks for the link to the comparison site, that looks interesting. Now I just need to find time to read it begi-keinua

For those who don't now the history. YUI was chosen to be the JavaScript library for Moodle about 18 months ago, during one of the Google Summer of Code projects. There was a thread in this forum where it was discussed, and the decision reached. I expect if you search you'll be able to find the thread.

I only really started to get into YUI about 6 months ago, because it is what we use in Moodle. I find it perfectly easy to use. It was easy to learn, and the docs are pretty good, so I don't see a strong case for switching. However, I have not tried anything else.


In terms of being able to use jQuery for your personal customisations. Well, if you use your own theme, it is easy, you can just add a script tag to the header to load jQuery. If you don't want to do it in your theme, then you just need to know that the normal way include a JavaScript file from any bit of Moodle PHP code is to call the require_js function.
Tim Hunt(e)ri erantzunda

JavaScript FAQ

Frank Ralf -
Hi,

I started a Javascript FAQ page for everyone who wants to keep track of this interesting discussion and anything else related to Moodle and JavaScript. Any additions are welcome.

There's also a Category:Javascript, so if you stumble across something in the documentation which should be included in this category just add this code [[Category:Javascript]] to the bottom of the page and it will automatically show up in that list.

Kind regards,
Frank

Frank Ralf(e)ri erantzunda

Comparison between JavaScript, YUI and jQuery

Frank Ralf -
JFTR

For an example, how a simple problem is solved using plain Javascript, YUI and jQuery see User:Frank Ralf/JavaScript1 - which IMHO is definitely in favor of jQuery.

Frank
Frank Ralf(e)ri erantzunda

Re: Comparison between JavaScript, YUI and jQuery

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I took the liberty of hacking your two examples to make it a fairer comparison. You had used significantly different JavaScript styles in the two examples.

I'll let you fix the bug in the JQuery one begi-keinua

While it is very cool to write jQuery-like code that uses implicit looping and other cool functional programming voodoo. However, my experience is that is is much less fun to maintain code like that. Admittedly my experience is that area is with XSLT, which is the ultimate write-only language, but still.
Tim Hunt(e)ri erantzunda

Re: Comparison between JavaScript, YUI and jQuery

Frank Ralf -
Thanks for your effort to clean up my code, Tim!

The two different coding styles are those advocated in the programming books on YUI and jQuery I consulted. And I admit, with all those very long class and function names of YUI I tend to use some intermediate steps (and more comments...).

I will look into the bug (which I think isn't one, but that's what they all say).

My interest in programming was spurred by regular expressions and Perl, inventor of the infamous Obfuscated Perl Contest (http://en.wikipedia.org/wiki/Obfuscated_Perl_Contest), which might explain my warped mindset begi-keinua (And yes, XSLT might be even worse.)

Cheers,
Frank
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Hugh Morrow -
> Of course, if you are making your own plugin, and are convinced of the benefits, there is nothing to stop you shipping your own copy of jQuery in the plugin folder if you want.

Tim, I totally support your comment/observation.

In a current moodle project I am making great use of the Mootools JS framework, simply by including it as part of the module codebase ... it adds lots of lovely bells and whistles and has integrated very smoothly.

And despite really enjoying the Mootools feature set, I respect and support the decision to use YUI as the core JS framework - it is robust, well architected and increasing in scope ... just like Moodle. I think it is a good fit for Moodle and is well placed to meet the needs of the broad Moodle community.
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

ryan sanders -
i don't like javascript being called within the body of documents. my big complaint is addon's/plugin's in CMS. will do an include of some sort to call javascript or there will be a php function that writes out javascript within the body of the page. and you are forced to download this extra javascript each and every time. more addon's you add the slower the site gets.... due to source file ends up being 20,000 plus lines just of javascript and some html mixed in.

it would be nice to have abilty, for creation of plugin/addon to give option of were and how the output should be displayed.

function func_code_were{"header,inline,footer,block,theme,course,etc...","type, JS,PHP,HTML,etc...","ID", "what is to be outputed";}

func_code_were{"header","javascript","bog_addon","var mousexy_y = 45;"}
func_code_were{"inline","javascript","bog_addon","onclick(bog_load_pic1)"}
func_code_were{"footer","javascript","bog_addon","function bog_load_pic1{var X=1; Y='abc';}"}

for me being on dial up. i don't mind taking a large hit on downloading. but multi large hits of source code do bother me.

if i click on something while page loads and it does nothing. it bugs me more. due to i will need to wait till page fully loads. and for me being on dial up. and alot of images. or other downloading happening. the page my never fully load. example some websites, there dynamic menus, will just load inital buttons but do nothing. and i know what i want to click on and goto, but i can't and forced to wait. normally i am forced to do this with each page of the site. because i never do let the page fully load up.

i would rather have layout theme images loaded up last, i don't care how the site looks i want to know if site has what i want.

another thing for me, is dynimacally loaded images. right now in firefox3, on a old 9 year old computer. winxp, 1.2ghz, 1.5gig ram and i get some major stallings. when current WYSIWYG HTML editors (like on this forum, and other websites) begins to load graphics for the toolbar. my browser window almost comes to a crawling stop. the same thing happens in Internet expleror 6. my resources cpu memory are reading low. but it is the proccessing of the images and inserting them into the correct place within the source code and displaying the images.

normally when i first see the box were i want to type something, i goto it asap, but then i get nailed by the editor buttons loading and have to wait 2 to 10 seconds (pending on page) or so for the buttons to load. before i can begin typing. due waiting for the browser to finish inserting/changing source code.

to me being able to prioritize code in such a way. that allows content and functionality to load first, then themes and images would be a major bonous for forums.
on other hand, for say ecommerce website, i would most likely want to priortize, content (things to sell images), buy now image buttons to show first, and then load additional functionality, and images and themes last.

because of the wide varity of content that does get displayed on bigger websites, it would be nice to be able to change priorty of how things change multi times throughout the life time of the website. so as community changes and complaints and performance problems come in. the adminsitoratrs can change it on the fly.

most CMS in current versions have databased role creation. IE adimn, course creator, teacher, non teacher, and then you are able to assign groups to the roles. but instead of that, it would be header,body start, body end, footer, block etc... and the users would be the sniplets of source code.

because of large amount of dynmiac content gets repeated, it would be nice of a cache like doing was implemented as well within the server side of moodle. so that certain parts of code do not get regenerated for each page load or each portion of the site.

or abilty for entire site files, (not content files) to go through a proccess, that removes all comments,white spaces, etc... out of source files. all the white spaces and comments can really add up quickly and do add to overall page file size of what needs to be download and then proccess by the browser, at times i am shocked to see that 1/4th of the source code from my browser is code comments, and half of it is white space (space bar and tab keys, return keys). if i do a edit on source code to remove white spaces and comments and hard returns in code. on this old computer it is like night and day. in how fast the page loads and responds.

high speed internet connections and new computer folks don't really take notice, the screen my go out of sync for a moment and everything is good. but for dial up folks and then older computers. you really do see a big difference. both in load times and broswer proccessing the page times.

remember we put in spaces and tabes and goto a new line as programers. to make code more easier to read and work with. end users could care less. and they don't need to, once a site is put together is stays like it is for some times. with only content changing. think of it this way, remove white spaces tabs, returns in code is like are compling of the code to make it faster exucting.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

François Marier -

Matt Clarkson and I have been thinking about this thread and the Javascript situation in Moodle for a little while now.

Basically, we think that the ideal solution would cover most of these goals:

  1. Ability to choose where (footer or header) to put the Javascript code with a default to the footer (as per the Yahoo guidelines).
  2. Each page has only the minimum amount of Javascript in it so that it's lighter for the browser to parse and execute.
  3. Ability to minify the Javascript code without having to maintain a readable development version and a minifed version separately.
  4. Includes a "version number" in the Javascript URL so that browsers/proxies can cache the javascript code forever (see Yahoo guidelines).
  5. Do as much work as possible at install/upgrade time rather than at runtime.
  6. Support the case where a filter's HTML output is cached but the filter needs to added a Javascript blurb in the footer of the page where it's included. So even if the filter code isn't executed (and require_js() doesn't get to run), the Javascript dependency will be picked up properly.

We sketched out a solution that would cover all of these. Without going into too much detail, our proposed solution would look like this:

  • A new "Server | Performance" option would be introduced: "Javascript caching". When turned on, a version number for each JS file would be generated by hashing the file at install/upgrade time and the output file would be stored in moodledata.
  • Another option, "Minify Javascript" (probably in "Experimental" at first) would minify these hashed files before putting them in moodledata.
  • Developers would leave "Javascript caching" turned off and would still be able to develop on Javascript files without having to regenerate these hashed copies.
  • Each plugin (module, filters, blocks etc) would register the JS files it requires.
  • A table of PHP pages and a serialised array of the JS includes would be re-generated each time it needs to (usually at install/upgrade time with some exceptions).
  • When printing the header and footer of each page Moodle would check that table to see what scripts the page needs to include.

This system would be fully backward-compatible with the way that Javascript is currently used in Moodle.

To take advantage of the new caching and to deal properly with javascript in filters and blocks, all a developer would have to do is define these Javascript dependencies like this:

In a file like /mod/scorm/js/register.php:

register_js(array('script' => 'YUI-events',
                  'scope' => '/mod/scorm/',
                  'location' => 'header'));
register_js(array('script' => 'player.js',
                  'scope' => '/mod/scorm/player.php',
                  'location' => 'footer'));
register_js(array('script' => 'player.js',
                  'scope' => '/mod/scorm/view.php'));

Any comments? As far as we can see, this would also address most of Urs' suggestions.

Puntuazioen batez bestekoa:Useful (1)
François Marier(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
First, note that MDL-16583 has evolved into a tracking bug for all the JavaScript cleaning up that I am doing.

I you and Urs have convinced me to that we need to defer the loading of most JS to the footer. All we need to do to enable that is to add an optional $loadimmediately argument to require_js that defaults to false to make this possible.

Also, since I am starting to introduce the print_js_call function for printing the scripts that initialise your JavaScript, I can again make it save all these up and put them in the footer.

Becuase this is all getting a more complicated, think I am going to move the implementation into a new single class page_resources_tracker or something. That will help with keeping track of lists of stylesheets and initialisation calls to me. However, I think I will keep the external api of require_js and print_js_call as simple functions in weblib.

This does not revent us from doing things making an admin option to combine all the filter/*/*.js files for all the filters that are currently enabled into a single, minified .js file in moodledata/cachedscripts/filters_1324d54be7f6.js. We just need to record which actual scripts went into that file, and then when require_js gets a request for filter/myfilter/flashy.js, it can actually load the minified .js instead, and ignore future requests for any of the libraries that went into it.

So, your proposal for a more declarative approach 'register.php' does not convince me. It feels a bit like over-engineering. I think we can do everything we need without substantially changing the require_js api, which we have had for a while, and which in my experience is nice to use.

Hopefully we can discuss this face-to-face soon when we meet at either the Australian or NZ Moot. However, that is no reason not to continue this excellent thread. I am learning a lot here. Thank you everyone who has contributed.
Puntuazioen batez bestekoa:Useful (1)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Matt Clarkson -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
The reason for taking a declarative approach is that it allows the output of functions to be cached as static HTML and for any javascript required in that static HTML to be included in the header of footer of the page.

A good example of this is the 'media filter' plugin - it has to use an inline include of the eolis fix javascript because using require_js wouldn't work due the filter only being called when the text cache has expired.

Knowing in advance what Javascript is required on a particualr page also allows us to be smarter when combining javascript files, i.e. we don't include javascript thats only required a handfull of page.
Puntuazioen batez bestekoa:Useful (1)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Putting javascript in the footer is a bad idea in my opinion.
Modern web design practices state that javascript should be always inserted in to the head of the document.
This way the javascript is unobtrusive to the actual page body.

In fact, we should be encouraging the development of moodle to completely dump in-line script attributes - e.g. onclick

http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

I'll give you an example of an area of improvement in Moodle - the administrator collapsible tree menu. This contains lots of in-line 'onclicks'. This is poor development practice. We should instead give the tree the class 'jstree' and then have a script in the document header convert all objects with this class to a collapsible tree. This way, it degrades gracefully and doesn't sit there in the mark-up of the page.

Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

François Marier -
Hi Guy,

I agree with you that we should minimize the amount of inline Javascript there is in Moodle. Tim is doing a lot of good work in that area at the moment.

As far as putting scripts in the footer, that's actually the recommended way to do things in other to get better performance.

See this page for example:
http://developer.yahoo.com/performance/rules.html#js_bottom

Francois
Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
If you read the document I link to at the start of this thread, you will see that unobtrusive JavaScript is the way Moodle is already heading. We are discussing the best way to support developers to make it easy for them to write JavaScript like that.

And have a look at the admin tree in Moodle 2.0 dev. It is already fixed.

And the latest writing strongly recommends JS in the footer, and it has convinced me.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Tim, we still need a mechanism to allow blocks and filters to insert css into the 'head' of the html document (as my proposed modification allows). Putting css into the document body breaks xhtml compliance.

I have to say that even Yahoo's recommendations on performance gains by putting javascript into the document body are a bitter pill for me to swallow.
Also, surely if the http1.1 spec prevents parallel downloads during javascript downloads, you wont get any performance downloads if you stick it in the footer. What you will get is the page popping up quicker (images, etc) but then it will have to do the non-parellel downloads at a different time. All you have done is delay the point at which the non-parellel download of javascript occurrs. If we stick all the javascript in the head, the page will just appear as a blank page longer than if we stick it all in the footer.

Users will perceive that the page has loaded (i.e. all images, links, css, etc..) but in actual fact the page hasn't really loaded yet - and this is dangerous - inline javascript will cause errors if it referrs to javascript in the footer and it is called before the footer js has been loaded. If you go down this road then inline javascript has to be strongly discouraged! Otherwise people are going to start clicking elements with inline 'onclick' and they will get javascript errors.

Nice to hear the tree has been fixed.

Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

sam marshall -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
As far as I'm aware, HTTP1.1 has nothing to say about JavaScript and parallel downloads? The issue with JS is that the browser will stop processing the page at the point where the JS occurs. There's nothing to stop it continuing to read network data relating to already-known resources.

So for instance if you have you have a page with 3 img statements then a <script> then another img, it ought to load - in parallel - the script and first 3 images. It will not start loading the final image until the script has completely loaded and run, because it hasn't processed that part of the html yet (pending possible document.write, etc).

At least that's my understanding - could be wrong.

--sam

PS I'm sure it's already been discussed here but in any case, JS loading network delays [as opposed to JS processing delays once it's loaded] are largely theoretical. Providing the JS file is served with the correct headers so that it doesn't expire more than every few hours, then this delay only applies to the first page you view in a session, since JS always loads from memory or disk.
François Marier(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia

@François and Mark - good points.

Topic 5 is important - "register.php" looks like a solution.

@Tim - the declarative approach demands more thinking beforehand. Afterwards Moodle doesn't need to search around hunting for files to include as it does now.

For example actually collecting module specific CSS is a search through all module directories on demand - again and again.

Other systems use the register approach and it's easy to work with. And Moodle is going to use events more in coming releases. Registering what you want or need will become self-evident in an event driven environment.

Puntuazioen batez bestekoa:Useful (1)
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Well, I am not yet convinced about the declarative approach, but I will go on listening to the arguments and thinking about it. The media filter with caching is a good example. I realise that to justify my approach, I need to cope with it.

The fact remains that there is still lots of work to do to convert everything to require_js from the previous horrible legacy mechanisms. And that work won't be wasted if we later decide to convert to a declarative approach. It will the just be a matter of searching the code for occurrences of require_js, which is easy.

Doing require_js throughout the page, and then deciding what to do in the footer lets us gather a lot of information about what each page actually requires, which gives us the possibility of doing a lot of automatic optimisations.

For example, we could imagine a development/testing option that logs to a file or a database how many times each .js file is included, and which .js are included at the same time as each other. Then we could analyse all that data, and decide which .js files it woud most be worth spending time merging. You could not do that with the declaritive approach.

I certainly agree about doing more at install time. That will be possible. (Also, for something like filters js, we should do things like automatically update the prebuilt stuff whenever the admin changes the list of enabled filters.) Anyway, I am only proposing doing searching around at config time, not on every page load, and the unit testing system shows that directory seraching is fast enough for that.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I a surge of inspiration (while waiting for my laptop to update all the installed macports - which still hasn't finished!) I wrote a page_resource_tracker class.

It is attached here for review by anyone who can be bothered.

Note that it is completely untested as yet.

I suppose the main benefit of someone reviewing it would be to check whether the API looks about right, and whether it does all the things we might want of it.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Matt Clarkson -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Your class looks good and addresses some of the things I think moodle should be doing, i.e. Loading Javascript and the footer of the page, adding a dictionary of useful in-line Javascript variables.

However I feel it doesn't address these issues:

1. Cached HTML including JavaScript in the footer
2. Using versioning to enable better caching.
3. Combining Javascript files.
4. Minifying Javascript and CSS files.

It would be possible to address many of these points by combing, minifying and versioning the standard Javascript that moodle bundles, however non-standard plugins wound't be included in the processed javascript and it would be nice for it to only include Javascript required by enabled plugins.
Matt Clarkson(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
You don't need to feel that it does not address those issues. It doesn't. Yet.

However, it would be easy to enhance this class to support most of these things. But, only after all of core Moodle has been changed to use this class or something like it, rather than scattering inline JavaScript throut the HTML in a million different HTML files. That is a bit, grim job that someone (me) has to do. Until that is done, there is virtually nothing that can be done.

I would tackle your points 2-4 as follows:

A. Make a new admin page "Compress JavaScript and CSS". This has one or more checkboxes for controlling what is done. Let us suppose that there is a single on/off switch for now, but we might want to give more sophisticated control. Underneath this control, it would probably be nice to show some status information to admins/developers about exactly what has beed done to the JS/CSS.

B. Whenever that option is turned on, or whenever a module/block/filter/... is turned on or off, we rebuild all the cached resources. That is, we crawl the code tree for just the enabled modules/blocks/filters/.., plus core JS and CSS files. Decide which to concatenate together, then minify (a quick Google shows JSMIN and minify as the two most promising PHP libraries for this) them into $CFG->dataroot/resourcecache, probably with filenames that are a SHA1 of the contents. Then, into $CFG->dataroot/resourcecache, write a file, probably a manifest.php that defines some arrays that say which original .js and .css files ended up in each compressed blob.

C. Change page_resource_tracker::resolve_script_url so that includes manifest.php, and if you ask for one of the libraries in a compressed blob, it actually includes the blob instead, and updates the lists of what has been included to say that both the blob, and all its content librarys, are already on the list.

D. Ensure that files from $CFG->dataroot/resourcecache are served with appropriate headers to get them cached well.

This means that all the coplicated decisions about what JS and CSS files are aggregated are in encapsulated in B. and can be changed at any time. This makes it possible to experiment with different strategies here. This is the area where we have least information, at the moment, about what the best design decisions are, so it is good that it is encapsulated.

I think C. should just be a few array lookups at runtime, so will not slow down ordinary array process. All the work in done from admin screen A., when it triggers B. It is OK if this takes a few seconds.

About your point 1. I think that the best that is achievable is just to include the JavaScript (if any) for all the currently active filters on each page. And ensure that each filter can be initialised with a single JS call that, say, does a getElementsByClassName on some suitably distinctive class name to find the elements to initialise. If this is done in the footer, then it should not hurt performace too much. My guess would be that any sheme that triest to track in detail which cached filtered strings use which resources would eat more in server processing time than it saves on the client side.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

François Marier -
Tim: that's a good point actually. We can generalize this Javascript system to handle CSS files as well. It would be advantageous on busy sites to both minify and cache CSS files.

In fact, I don't see anything that's JS-specific in the solution that Matt and I proposed.

Francois
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
I think I have a solution to CSS and javascript include issues with Moodle.

require_js simply doesn't cut the mustard because you end up with javascript linked after the head is written if you are developing blocks.

It is not good development practice to put any linked javascript into the body of the html document. Yes, you can do it but it is much neater to have all the linked javascript in the head of the document.

With CSS its even worse as it breaks w3 standards if you stick linked CSS into the document body.

How could a block, filter or module insert javascript or css into the document head?

Please see my proposal:

http://moodle.org/mod/forum/discuss.php?d=95743#p422799

Direct links to screencast:

High quality video (does not stream, you have to wait for it to load up):

http://www.ossett.wakefield.sch.uk/web/media/video/moodle_mod_screencast_hq/

Low quality video (streaming):

http://www.ossett.wakefield.sch.uk/web/media/video/moodle_mod_screencast


Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia

@Yes, you can do it but it is much neater to have all the linked javascript in the head of the document.

Please see the attached page loading chart (moodle.org startpage) showing how JS files in the header influence page load. 2 seconds between sec. 1.5 when JS #6 starts loading until sec 3.5 when JS #12 finishes loading the browser merely catches one single JS file after the other. For the user 2 valuable seconds long nothing visible happens. And parallel loading begins again after the last JS file is ready.

As Tim will handle JS most JS is loaded from the footer. Then the page and most visual elements are loaded and the page looks complete/nearly complete.

One JS file invoked from the header with JS that is needed while the page loads doesn't influence loading too much. It may be loading parallel to the CSS files as now.

And when CSS will be optimized and minified another advantage will be that while one or two CSS files load the browser can start fetching images. Page load will look much faster for the user.

When we estimate with the loading times shown here you can figure that the user get's the impression that the page is loaded about 2 seconds earlier. On the moodle.com start page for users visible page load will take roughly half the time.

Eranskina moodle.org_loading_timeline.png
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Hi Urls.

I totally agree with batching CSS together and minifying it to optimize page loading times- great idea. However, linked CSS will have to go in the head otherwise you are breaking the xhtml standard. Also linked css in the footer causes the page to appear unformatted and then suddenly formatted as the CSS is loaded.

Blocks and filters need to have a way to pass CSS to the header. The CSS resources a block or filter requires will have to be collected before any page rendering occurrs.

The key to sticking javascript in the footer of the page is that it will 'look' like its loaded faster but in actual fact it hasn't. Then your users start clicking things that call javascript functions and you get errors (because the javascript hasn't finished loading).
Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Blocks getting JS into the header will be dealt with. Stop worrying.

And JS should be used for progressive enhancement. If the page does not work without JavaScript, it is not accessible, and should be rethought. (To avoid JavaScript errors, you just add event handers using an initialisation function the moment the JS has loaded.)

And I am prepared to trust research that Yahoo and others have done and published that JS in the footer is best.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Hi Tim - OK I'll stop worrying- I also trust Yahoo's research.
You are right about scripts applying the event handlers via an init function - thats how all my scripts work already. This is the best way to get purely unobtrusive javascript that enhances the page. Your original links should have anchors that provide non-js functions and these should be disabled as your js click events are applied. Now, this is where I see a problem with sticking the javascript in the footer - your page and links will appear before the javascript has had a chance to remove anchors for enhanced links. So users will click on them and could get something that they are not necessarilly used to seeing if they have javascript switched on and the js in the footer hasn't loaded.
BTW - I'm not preaching here - I'm just trying to make people aware of some of the issues they will face with javascript in the footer.



Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia
Guy, may you have a special understanding of "unobtrusive JavaScript"?

You write about links not working when JS is loaded in the footer. What happens when you don't have JS at all?

The ALA article "Understanding Progressive Enhancement" http://www.alistapart.com/articles/understandingprogressiveenhancement explains the content/presentation/interaction layers nicely.

The interaction layer (JavaScript) enhances user experience but must not break the page when it's not present. The page works without JS.

@ JavaScript before the page is ready loaded.
When pages need JS before the page is ready loaded I propose to use highly optimized JavaScript and not use one of the huge JS libraries. And YUI is a really big one. This JS may either be included into the page or be loaded from the header.
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Urs, you have mis-understood my post.

The point I'm making is, if you use progressive enhancements then users clicking js enhanced links will get the un-enhanced version if the footer js hasn't loaded.
So they end up seeing something that they are not used to seeing (even though it still provides them with all the functionality they need without js).
I see this creating lots of support calls.

BTW - I really appreciate the effort that you have gone to in supporting the case for footer based javascript. Until I read your posts I would have never considered putting javascript in the footer but now I can see how it can benefit sites where you need the visual content to appear before all the page has loaded. I do think you have some really good points- I'm just trying to preempt some problems that might be caused by footer js.

P.S. Sorry for the typo on your name in my previous post.
Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia
Ok Guy. You always need to see the whole picture (needs for the special page) and decide if fast page load impression or enhanced functionality weights more.

Or create a solution in between when necessary. And therefore we need the most flexible way to make the best solution possible.
Urs Hunkler(e)ri erantzunda

Re: Use of JavaScript in Moodle

Sr. Miguel -

Hello hunkler,

Can you tell me with what tool did you generated that page loading chart?

thank you

Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Ensuring that all types plugins have the ability to get any CSS or JavaScript they need included in the page at the right time is one of the things I will have to solve, and it looks like you may have done a lot of the work for me.

At Moodle HQ, we are all about to jet off to Brisbane for the Australian Moodle Moot, so I don't have time to look in detail at what you have done right now, but I have just grabbed MDL-14542, and will take a look at it in due course. (May be a few weeks, I am going on from Brisbane to NZ for some holday and the NZ Moot.)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
OK, Tim I appreciate that you will take a look at it at some point.
If you want to test the code out then please be aware that it is a proof of concept. It will definitely need some tweaking to make it perfect.
If you are going to experiment with it, I suggest you do it with blocks first as that was where I really concentrated on the proof of concept.
The actual hacks I made where to an early version of Moodle 2 (as you can see, MDL-14542 was raised 24th April 2008). Hopefully they will still work, but if not please let me know and I will rework them for the latest dev version of Moodle 2.
Hope you enjoy your holiday in NZ.
Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

Olli Savolainen -
I welcome all work towards standardizing the usage of javascript in Moodle. I look forward to seeing you come to a conlusion about how to do inclusion of javascript as also Quiz UI redesign includes YUI, separate js file and variables that need to be passed to the js functions.

Also, I am interested in about if Moodle theming will be connected with YUI skins somehow, or will for example dialogs of different blocks/modules/etc. look different?
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Can I just say thank you to everyone who has participated in this thread. I have certainly learned a lot, and I think we have got to consensus. I would summarise the current position of the discussion as:

1. I need to continue my work to clean up the remaining ~150 hard-coded script tags throughout Moodle, using require_js etc instead.

2. We should change require_js to include most JS in the footer, and make it possible to implement various caching and minifying schemes later.

3. Once that is done, we should experiment with various caching and minifying schemes, to see what works best.

4. We need to review all the various plugin-types (filters and blocks are the two hardest) and ensure they can include the JS and CSS they need.
Puntuazioen batez bestekoa:Useful (1)
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Urs Hunkler -
Core developers-ren irudia
Marvellous Tim - looking forward to work with the comfortable and fast JS integration in Moodle.

And please don't forget to make it easy to integrate other JS libraries than YUI. Thank you.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Tim, thanks for pushing for a better javascript implementation in Moodle 2.0.
I've learnt a lot from this forum.

In response to point 4, for filters and blocks I can see 2 solutions (making css head insertions possible).
1) Include files within block folders to declare resources (that's how my hack worked). I think this is the easiest method and most backward compatible.
2) Enhance the block class to include a function (e.g. provide_css) for returning required js / css. Then convert filters to use a class instead of a function for returning required js /css. Blocks and filters would be instantiated before the output of the document head and the 'provide_css' function would be called at this point.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

sam marshall -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Sorry for not really contributing to this until now. I was really busy. Just wanted to add a couple of points:

1) The classic case for inline JS is if you need to hide something. E.g. you have something that is only revealed when a 'show answer' link is clicked. You don't want to have it hidden by default in CSS because then it won't be visible for non-JS users - so you need to hide it in JS. But if you wait for pageload there will be flicker, so add inline JS immediately after the start of the relevant DIV.

Obviously this should be easy enough to do cross-browser without need for YUI. Unfortunately there are also cases where you might want to do some quite serious page-rearranging in JS (dynamically adding whole sections or whatever) in order to add extra UI that is available for JS users without cluttering up the page with crap that doesn't work for non-JS users. For these cases it might be nice to have JS available immediately, again simply to avoid flicker/distracting motion.

Could we have a require_js_now() function [no parameters] that immediately - er, assuming you're after the header - flushes the cache to output all the required JS scripts so that if you do want to do major page surgery inline, you can do it using YUI functions. If you don't call that function you get it in the footer.

Also note that this might be useful even if it isn't necessary for uses of JS in core (I agree it's bad practice and should be avoided if possible) - third party features including some of ours might benefit from it. Better to provide this easily-detectable use of bad practice than let each developer hack it themselves with manually-written script tags...

2) Somebody made a point about 'slow' JS loading in footer meaning that people might see the non-JS version of something if they click a link too quickly. A few things about that:

i) Those public resources saying it's fine for things to be loaded in footer may not be anticipating Moodle-style performance (where some pages can load horrifically slowly - 2 seconds and up).
but
ii) I'm not sure how many of these slow-loading pages actually load progressively - ie more likely you get nothing, or only a header for 2 seconds then the rest of the page loads all at once, than that the page loads bit by bit. So you probably won't have long enough to click a not-working-yet link.
and
iii) How likely is it that one of these slow-loading pages, which loads progressively, also uses fancy JS?

If you are writing a page that does something very slow which happens progressively (eg some kind of log search), this would be a suitable case for something like the require_js_now() I mentioned above, and the relevant inline JS when needed.

In all other cases, JS in the footer should be fine...

--sam
sam marshall(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Hi Sam.

In response to point 1)

I think that Tim is going to push for the ability to insert javascript into the head or footer of the document.
That way, if you want to hide a page element via javascript, you could actually load the css via javascript in the head of the document. So you wouldn't have to use any inline javascript.

E.g. - this script in your header

function ImportStyleSheet(shtLoc){
// add style sheet via javascript
var link = document.createElement( 'link' );
link.setAttribute( 'href', shtLoc );
link.setAttribute( 'type', 'text/css' );
link.setAttribute( 'rel', 'stylesheet' );
var head = document.getElementsByTagName('head').item(0);
head.appendChild(link);
}

ImportStyleSheet('hidejsenhancedelements.css');

A user with javascript turned off will never get the 'hidejsenhancedelements.css'

A user with javascript turned on will never see the page elements because the css will be loaded from the head via javascript.
Guy Thomas(e)ri erantzunda

Re: Use of JavaScript in Moodle

sam marshall -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Yes this is possible (in fact it's the way I actually wrote our current stuff that works like this) and can be fairly neat, but I am leaning away from the approach personally. I don't like that it applies two different ways to express the 'hide' logic (which is done both in JS, if you click the 'hide' link after revealing it, but also in CSS for the default behaviour).

Anyway the point is you need to run JS before the footer in these cases. If this is going to happen very frequently then maybe we need a complex solution such as a way to place specific JS things in the header. If it's going to happen only on a limited range of pages then a simple solution like a way to flush the 'cache' of JS files to the page earlier should be good enough.

Incidentally if Moodle is going to encourage the technique above (fine by me) I would prefer that, rather than adding a separate stylesheet, an inline JS one-liner in/after the header adds a class="jsenabled" to the BODY tag. This means you can write CSS rules that only apply when JS is enabled, without needing separate stylesheets. You can keep the rules together with the related non-JS versions which makes maintenance easier.

Similarly I like the technique, applied in our local theme header serverside, of adding eg 'ie ie6' or 'gecko firefox2' classes to the body tag depending on user's browser, which mean you can apply browser tweaks without needing CSS hacks or the extra CSS files that are used in standard Moodle. Could be a .ajaxsupported class as well, so that a rule with .ajaxsupported.jsenabled applies only if AJAX stuff is going to run and not if, say, they have JS but are using Netscape 4...

--sam
sam marshall(e)ri erantzunda

Re: Use of JavaScript in Moodle

Guy Thomas -
Core developers-ren irudia Plugin developers-ren irudia
Using the class attribute on the body tag is a cool idea- it is certainly a more elegant approach to hiding styling the page differently for javascript enabled browsers.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Matt Gibson -
I've just tried to follow the guidelines and have put an inline javascript object into my block code to output some PHP variables, but I've got stuck because require_js() puts the main script files into the block header so that they run before the variables are available.

Any ideas on how to fix this apart from the old fashioned in-line inclusion of the .js file without using require_js()?
Matt Gibson(e)ri erantzunda

Re: Use of JavaScript in Moodle

Matt Gibson -
Aargh!

JSON notation seems to tank IE6. Firefox is fine, but the following source causes IE6 to refuse to load the page at all. What's going on?

<script type="text/javascript">
 am_variables = {wwwroot: 'http://moodle.plumsteadmanor.com', totalMessage: 'Total to mark', userid: '2', assignmentString: 'Assignment', workshopString: 'Workshop', forumString: 'Forum', configNothingString: 'You have no courses with graded assessments', nothingString: 'Hooray - nothing to mark!', collapseString: 'Collapse &amp; refresh', forumSaveString: 'Send in my latest ratings', quizString: 'Quiz', quizSaveString: 'Save changes', journalString: 'Journal', journalsavestring: 'Save all my feedback', connectFail: 'AJAX conncetion failed'}
</script>

Matt Gibson(e)ri erantzunda

Re: Use of JavaScript in Moodle

Matt Gibson -
Fixed it by adding defer="defer" to both the above snippet and the conventional .js file inclusion bit that came after it.
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

David Horat -

In the wiki it is said: "Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages."

I think that every piece of Javascript that is reused in several pages, must be in a separate .js file. This helps caching. Don't you think it should be enforced?

David Horat(e)ri erantzunda

Re: Use of JavaScript in Moodle

sam marshall -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
Don't you think that is the meaning of the wiki text? I.e. the only inline javascript should be things like

<script type="text/javascript">
strRemove='Remove';
initSomething(37,'xyzzy',4.2);
</script>

ie setting up necessary data such as language strings or other, or calling initialisation functions (esp those that need to happen at particular point in code) - the 'smallest possible amount'. Not things that are reused in several pages.

That's how I read it - but I could be wrong! And maybe the wiki isn't clear, even if I'm right...

--sam


Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

David Horat -
Moreover, Javascript files should be combined as much as possible if a set of Javascript files is always used together. This is done to reduce the number of HTTP requests that are done. Since HTTP messages are heavy and each HTTP header is on average around 1-2 KB, every extra HTTP request makes the page slightly slower.

PS: I am not a regular Javascript developer, so I would like to know more opinions.
David Horat(e)ri erantzunda

Re: Use of JavaScript in Moodle

sam marshall -
Core developers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
The HTTP request issue only affects first-load providing that the .js has a correctly-set Expires header etc. (Not sure this is the case...)

Even on first-load (in a session), if you've been to the site before, it should require the smaller 304 response. Most Moodle sites are likely to have many more repeat visitors than general sites.

In my opinion that would mean it's not a problem if moodle/mod/obscure/somepage.php requires a special mod/obscure.js because even a first-time visitor will only be loading that one .js by the time they get to that page. However there would be a minor problem if the first page people are likely to hit (the front page or a course page) loads a very large number of separate .js files.

In our local install the worst JS performance problem is caused by loading the TinyMCE JavaScript on every page (even where it's not needed). In Firefox, this causes about a 1 second delay to every page - more than you'd see from a handful of .js requests, and this happens every single time you load any page on the system. Ouch. It'll be fixed in our next update.

--sam
Tim Hunt(e)ri erantzunda

Re: Use of JavaScript in Moodle

Tim Hunt -
Core developers-ren irudia Documentation writers-ren irudia Particularly helpful Moodlers-ren irudia Peer reviewers-ren irudia Plugin developers-ren irudia
I've just seen this page about how they use JavaScript in Drupal 6. It looks quite nice. Shall we steal it?