Topic on Talk:ResourceLoader/Core modules

Can't tell what is a module name and what not

7
TMg (talkcontribs)

From this documentation I can't tell if I should write

  • mw.loader.using('mediawiki.user.options', fn),
  • mw.loader.using('mediaWiki.user.options', fn),
  • mw.loader.using('mw.user.options', fn),
  • mw.loader.using('user.options', fn), maybe
  • mw.loader.using('mediawiki.user', fn) or possibly
  • mw.loader.using('options', fn) (I'm pretty sure I saw this somewhere).

In short, the list is a mess. I can't tell the difference between module names and function names that are part of a module. Or is this the same? Can I use 'mediawiki.util.addCSS' as a module name even if it is a function? I can't tell. My proposed solution is to mark function calls with mediaWiki.a.b() and module names with 'mediawiki.a.b' (without the color, of course).

Also from what I know mw is a shortcut for mediaWiki and shouldn't be used in this list except for a single hint in the introduction. Or the other way around. But don't mix it, please.

Also I'm confused because it seems many of these mw.loader.using() calls are pointless. Things like mw.user.options.get() or mw.config.get() work anyway, everywhere. Under what circumstances do they not work? How to replicate these circumstances?

Mattflaschen (talkcontribs)

Bottom line, if it's a level three heading, it's a module. In the TOC, that's every heading like "d.dd some.module" (example: "1.4 mediawiki.api"). The number (1.4) is generated by the TOC, and doesn't matter except to tell you the heading depth. In the wikitext source, these have three equals signs on each side.

user.options is a little bit of an odd man odd in terms of the naming convention. However, you can see there is such a heading (currently "1.2 user.options"), and "user.options" is the module.

You can only use using with a module name, so you can not do things like using('mediawiki.util.addCSS'). Also, 'user.options' only works everywhere because something else on the page is depending on it. You get lucky like this sometimes. However, I try to explicitly depend on everything I need except two modules, 'mediawiki' and 'jquery'. Those two are always present.

The module names do look as you proposed in the TOC (except for quotes). I'm fine with adding () to the method headings. However, I don't want to invest too much work into this, since the goal is to replace it with auto-generated documentation relatively soon.

This post was posted by Mattflaschen, but signed as Superm401.

TMg (talkcontribs)

It would be very helpful to make the headings something like "Module <code>"mediawiki.api"</code>" to make things clear. Currently I can't tell the difference between the heading levels. They all look the same except for a slightly different font size. Even worse, things like "mediaWiki.config" are neither a module nor a function. "mediaWiki.config()" would be wrong. Please remove such stuff if it's neither an usable function name nor an usable module name. It doesn't add anything. It's just confusing. Also an overview of the dependencies would be helpful.

I'm not a friend of the resource loader stuff. It makes things so insanely complicated without adding much use. (It worked for years. Why change it? Do our Internet connections get slower?) Sometimes I consider the resource loader "broken by design". If no average user is able to write valid user scripts any more something must be broken.

Mattflaschen (talkcontribs)

That heading would break existing links, but you could do it if you add {{anchor}} with the old values. You kind of have a point about mediaWiki.config, but it is an object and needs to be documented somewhere.

The dependencies are in Resources.php, but generally you don't need to worry about that. You just depend on what you need. If you need to add stuff to the watchlist, you depend on mediawiki.api.watch. You don't need to worry about what it depends on.

I think the ResourceLoader is quite useful. There are two big reasons:

  • It handles minification and concatenation quite well, and some MediaWiki message (for i18n) cases (I am working on improving this).
  • It handles dependencies properly, and if you're writing an extension, or in MW core, the dependency interface is nice (you just specify an array of dependencies in a module definition). It is currently a bit of a pain for user scripts, though you can still pass an array of dependencies to using if there's more than one you need at the same time. Improving the user script and gadget experience is an important goal.

Since the good ol' days, MW has added a lot of useful scripts with various dependency chains. Further, other major sites have gotten faster through techniques like minification, and we need to do the same. RL also has other useful side features like flipping CSS automatically for right-to-left languages.

This post was posted by Mattflaschen, but signed as Superm401.

TMg (talkcontribs)

Thank you very much for the nice answer. After fighting every possible problem while maintaining my user script (which is also used by many other users) I think I understand most parts of that crazy nesting hell. (Except for the ready() stuff. I would really like to understand that.) Everything there is required for some reason: Make sure the options are loaded. Check one of the options. If it's enabled make sure an other module is loaded. Wait for it (I think that's what the ready() does but I don't understand how). Apply the button.

However, to make this usable for an average user there needs to be a simplified way to write it like this without loosing any functionality:

import('user.options');
if (mw.user.options.get('usebetatoolbar'))
{
    import('ext.wikiEditor.toolbar');
    $('#wpTextbox1').wikiEditor('addToToolbar', /* … */);
}
קיפודנחש (talkcontribs)

first, you don't import "user.options", but rather the module: "mediawiki.user", which, in turn, makes the *object* mw.user.options available to you.

second, because these resources are pulled from the web, it is usually not such a great idea to serialize it the way you suggest. in principle it *is* possible to do it the way you outlined (one would have to write a "synchronized import" function, which is totally possible), but it would mean that the browser will "freeze", and do nothing else (it might be responsive to user input, but it won't be able to execute any other JS stuff) while the browser goes and pulls the module off the server, however long that takes.

in the current mode (using the "using" method), the browser sends a request to the server to pull the module "mediawiki.user", and while the server prepares and sends the module, the browser is free to go and play elsewhere and do other stuff, such as figuring out what *else* is needed, and ask for it. once the module arrives from the server, the "using" triggers execution of the inside function.

think about it like this: javascript is single-threaded. the "using" and similar methods (such as "ready") allow it to pretend to be multithreaded, in the sense that while waiting for something to happen, it can go and do other stuff instead of wait idly.

peace.

TMg (talkcontribs)

I'm sorry but I do not care. All I want to do is to add a damn button to a toolbar. It has to wait anyway no matter how this stuff is loaded. This was a single (!) line of code with the old toolbar. Add button. Done. The current copy and paste garbage required to do the same is simply insane. It's not my job to put code that clearly belongs to the MediaWiki core into my user script.

Reply to "Can't tell what is a module name and what not"