Instead of monkey-patching mw.log from a conditionally loaded file,
patch it in-place using a $CODE substitution, as we already do for
other things.
Per <https://caniuse.com/console-basic>, conditional use of console is
no longer needed. Basically, only in IE 6-9 was it needed to check
whether window.console exists. The API exists in all Grade A browsers
now. It may still be a no-op in certain cases (like Mobile Safari
unless developer mode is enabled), but that's fine and was already
the case before since it satisfied the conditional.
For production mode, use of console.warn and console.error remain
conditional on their existence as before, though I've renamed the
local variable 'console' to 'con' to avoid shadowing the global,
and we now only check for the specific method, the object must exist.
Change-Id: Ied4d08c554936b0d86ff4a5fae749c9a2110badf
Modules that set "es6": true in their module definition will error when
a non-ES6 client tries to load them.
To detect ES6 support, this looks for native Promise support,
RegExp.prototype.flags, and non-BMP characters in variable names. All
browsers that lack full ES6 support fail at least one of those checks.
To flag modules as requiring ES6, this adds a ! to the end of their
version string. This takes up much less space than adding another
register() parameter (which would have to be at the end). It's hacky,
but we expect this feature to be relatively temporary, until we require
ES6 for running any JS at all (probably in about a year).
For distinguishing different types of errors thrown from
sortDependencies(), use e.name. We can't subclass Error properly because
that requires ES6.
Bug: T272104
Change-Id: I45670c910ff12eb422ae54c9fcf372e45c7b2bf1
* Add a void return hint to methods that are not meant to return
anything. This helps catch accidental return statements in the
future, lets Phan better understand how methods are meant to be
used, and might also allow PHP to better optimise the compiled
code form (speculation).
I did not, however, add it to publicly extended methods as that
might mess with strict mode.
* Remove the internal getResourceLoader() method from MessageBlobStore.
This has been redundant since 3edaa0b37c.
The method was protected, and not considered stable to subclass
for extensions. Hence not a breaking change.
* Add Throwable typehint to formatException() and friends.
This is the narrowest one I could add given that the methods
called from here already enforce the same typehint.
Update the doc to match for now. There isn't a reason right now
to limit this only to Exception, and given this is the method
and not the catch statement itself, does not change behaviour.
* Remove unused ResourceLoader->getHookContainer().
Added within 1.35 cycle, safe to remove.
* Remove unexpected `@since` for `@internal` getHookRunner().
* Remove redundant `@internal` from ResourceLoaderMwUrlModule
methods, which itself is already `@internal`.
Change-Id: I68d33ff6feca7ef95282a7ff03eb9332adfde31c
Follows-up 3ac385a0c3. This was generated by the installer at some
point and we've received two user reports of someone being caught by
this. We don't need to support "unlimited" anymore, but at least make it
do something more sensible, like using the default of 2000.
Previously, it was effectively treating the -1 like 0,
which was causing "debug mode"-like behaviour for end users.
Bug: T251789
Change-Id: I483d5312e6fa25a0b00bb6173ed01eeb99ad42aa
=== Observe the bug
1. Run Special:JavaScriptTest
(add ?module=mediawiki.loader to run only the relevant tests)
2. In the Network panel, check the JS requests to load.mock.php?…
3. Without this patch, they are like:
"load.mock.php?1234?lang=en&modules=…&…"
With this patch, they are like:
"load.mock.php?lang=en&modules=…&…"
The question mark is only valid as the start of the query string,
not as divider between them. This means without this patch, the
"lang" parameter is simply ignored because it becomes part
of the key "1234?lang" with value "en".
=== What
The mock server doesn't do anything with "lang". And given that
RL sorts its query parameters for optimum cache-hit rate, the
corrupted parameter is always "lang", as its sorts before
"module" or "version", which our mock server does utilize.
As part of server-side compression of the startup module (d13e5b75),
we filter redundant base parameters that match the default. For
RLContext, this is `{ debug: false, lang: qqx, skin: fallback }`.
As such, if one were to mock the localisation backend with
uselang=qqx internally, the "lang" parameter will not need to be
sent, and thus the above bug will start corrupting the "modules"
paramater instead, which our test suite correctly detects as being
very badly broken.
=== Why
mediawiki.loader.test.js used QUnit.fixurl() as paranoid way to
avoid accidental caching. This blindly adds "?<random>" to the
url. Upstream QUnit assumes the URL will be a simple file on disk,
not expecting existing query parameters.
=== Fix
* Removing the call to QUnit.fixurl(). It was set by me years ago.
But, there is no reason to believe a browser would cache this
anyway. Plus, the file hardly ever changes. Just in case,
set a no-cache header on the server side instead.
* Relatedly, the export of $VARS.reqBase is an associative array in
PHP and becomes an object in JSON. Make sure this works even if
the PHP array is empty, by casting to an object. Otherwise, it
becomes `[]` instead of `{}` given an PHP php array is ambiguous
in terms of whether it is meant as hashtable or list.
Bug: T250045
Change-Id: I3b8ff427577af9df3f1c26500ecf3646973ad34c
This data isn't needed for startup, and we can shave off a few K from
startup by moving it to mediawiki.base instead.
It was requested that this be done as a "package file", which
necessitated some other minor structural changes to mediawiki.base as
well.
Bug: T235350
Change-Id: I525a5203533089d5a542f83a847be58a10cb6319
It's only=scripts, not only=script. As written, following the
instructions in the comment that StartUpModule returns when you're using
it wrong doesn't work, this fixes that.
Change-Id: Ib0cb2ce18dbc446dc3c5f3c670b4c29064d000d9
This change allows to use the context in the functions.
The following internal static functions from ResourceLoader get now a
reference to the ResourceLoaderContext object:
* makeLoaderImplementScript
* makeLoaderStateScript
* makeLoaderRegisterScript
* makeLoaderSourcesScript
ResouceLoader::encodeJsonForScript is duplicated to
ResourceLoaderContext::encodeJson loading the debug mode from context.
ResourceLoader::encodeJsonForScript is kept for other usages without
context.
The debug mode is loaded from $context->getDebug() instead of from
ResourceLoader::inDebugMode(). This does not support to enable the debug
mode by setting the cookie 'resourceLoaderDebug' or the configuration
variable wgResourceLoaderDebug. Only the URL parameter debug=true
enables the debug mode. This should be sufficient for the subsequent
ResourceLoader requests. The tests don't need the global variable
wgResourceLoaderDebug anymore. The initial ResourceLoader context in
OutputPage still uses ResourceLoader::inDebugMode() with cookie and
global configuration variable.
This change adds the parameter $context with a ResourceLoaderContext
object to ResourceLoaderModule::getDeprecationInformation and deprecates
omitting the parameter. Ifa1a3bb56b731b83864022a358916c6aca5d7c10
updates this in extension ExtJSBase.
Bug: T229311
Change-Id: I5341f18625209446a6d006f60244990f65530319
* Add license header where missing.
* Add missing `@since` (1.17 for most classes), except
ResourceLoaderLessVarFileModule since 1.32 (1bc62c548c).
* Remove duplicate file-level description for class-only files,
merge with the class description instead.
* Remove my own `@author` annotation from one file.
* Mark core's own FileModule subclasses as `@internal`, except
for the following which we support use of in extensions:
ResourceLoaderLessVarFileModule,
ResourceLoaderOOUIIconPackModule, and
ResourceLoaderWikiModule.
Change-Id: I336af2e4ccdbe2512594e8861b72628d24194e41
This was previously just added by Echo, but it's generally useful.
We should probably deprecate wgDBname, because wgWikiID is a better wiki
identifier that also works when two wikis have different table prefixes
in the same database, but that'll take some work because a number of
things rely on it right now (including ResourceLoader itself, for its
localStorage keys).
Change-Id: I4d289267991f1f9a8e0710ec6ee5a2131306c510
In a nut shell:
* We very often (52% of modules on enwiki) pad the hash with a zero,
which means the amount of bits we currently compute already fit in
6 characters already for most modules. For some modules (3%) we
even padded two zeroes.
* For the (now documented) use cases, the space of 78 Giga
(78 billion, or 78 milliard) seems more than we need. The space of
60 million should be enough.
This follows-up dfd046412f from 2016, which previously shortened the hash
down from 8 chars of base 64 (or 12 chars of hex) to 7 chars of base 32.
Before that change, the space was 281 Tera (64^8, or 16^12).
For more details see the added inline comment for ResourceLoader::makeHash,
and also the data at <https://phabricator.wikimedia.org/T229245>.
Bug: T229245
Change-Id: I9ad11772a33b3a44cb625275b1d7353e1393ee49
I added this as wrapper for the private 'getBaseModules' method
in commit dec800968e for "use by SpecialJavaScriptTest", but
I never did. And it doesn't need it so.. let's remove that.
Change-Id: Ia301bd1c1f3a15098b9e6cd2934dd8e80879dd50
This isn't needed because the startup module validates this already.
The vast majority of modules are FileModule instances which can't be invalid,
because a separate test asserts that class already. This test existed for
validating the format of version hashes returned by a theoretical Module
sub class in an extension that (badly) overrides the getVersionHash method.
As of writing, no extension overrides that method. And more importantly,
the startup module already validates this at run-time, and logs a warning.
This commit turns that into an exception, which would get logged in a way
that Jenkins will fail the build if encountered.
This structure test, which computed the response for all registered modules,
previously took 3-5 seconds in CI.
Bug: T225730
Change-Id: Id2e37434b0ccd95dd2279f04e2230e9c06b09ccb
Before this change, the startup module responds as follows:
```lang=js
... contents of startup/mediawiki.js:
...... mw.config = null;
...
... contents of startup/startup.js:
...... mw.config = new mw.Map( bool );
```
After this change:
```lang=js
... contents of startup/mediawiki.js:
...... mw.config = new mw.Map( bool );
...
... contents of startup/startup.js:
......
```
Change-Id: I97fea20f17c4865aa4740482f3054532038531f0
Only needed internally by the startup module, which can export it
through private means instead.
Follows 0a8e37f042 and 30ddfc8a77.
Change-Id: I5e54bd51d9b47146e1ef9a64b14c1a00697bd6a9
This change makes ResourceLoaderStorageVersion a private variable.
The JavaScript global variable wgResourceLoaderStorageVersion is now
removed.
This change makes the JavaScript code smaller.
Change-Id: I8e31b95d4c44ba653bedb6be500011a39bc6abd8
Use
mw.util.wikiScript( 'load' )
instead of
mw.config.get( 'wgLoadScript' )
The module 'mediawiki.util' now gets the value from a private config
variable.
Change-Id: Iae4f4754f40999ba9d7c7161e9a37820c4b5931c
Being a raw module means that when it is requested from load.php with
"only=scripts" set, then the output is *not* wrapped in an
'mw.loader.implement' closure *and* there no 'mw.loader.state()' appendix.
Instead, it is served "raw".
Before 2018, the modules 'mediawiki' and 'jquery' were raw modules.
They were needed before the client could define 'mw.loader.implement', and
could never be valid dependencies. Module 'mediawiki' merged to 'startup',
and 'jquery' became a regular module (T192623). Based on the architecture
of modules being deliverable bundles, it doesn't make sense for there to
ever be raw modules again. Anything that 'startup' needs should be bundled
with it. Anything else is a regular module.
On top of that, we never actually needed this feature because specifying
the 'only=scripts' and 'raw=1' parameters does the same thing.
The only special bit about marking modules (not requests) as "raw" was that
it allowed the client to forget to specify "raw=1" and the server would
automatically omit the 'mw.loader.state()' appendix based on whether the
module is marked as raw. As of Ie4564ec8e26ad53f2, the two remaining use
cases for raw responses now specify the 'raw=1' request parameter, and we
can get rid of the "raw module" feature and all the complexity around it.
== Startup module
In the startup module there was an interesting use of isRaw() that has
little to do with the above. The "ATTENTION" warning there applies to the
startup module only, not raw modules in general. This is now fixed by
explicitly checking for StartupModule.
Above that warning, it talked about saving bytes, which was an optimisation
given that "raw" modules don't communicate with mw.loader, they also don't
need to be registered there because even if mw.loader would try to load
them, the server would never inform mw.loader about the module having
arrived. There are now no longer any such modules.
Bug: T201483
Change-Id: I8839036e7b2b76919b6cd3aa42ccfde4d1247899
This change also removes the defaults from the URL parameter:
* lang=qqx
* skin=fallback
* debug=false
Bug: T225899
Change-Id: I4cbc42e39ebc56c3d29f773a275afe2b1a44c913
This feaure exists for controlling cache fragmentation of modules
that are queued for loading. However, the startup module is never
"queued" for loading.
It's loading is hardwired into ResourceLoaderClientHtml and doesn't
use any batching and couldn't logically, given that by design it
has to be the first thing that loads and cannot be combined with
other code (because we need to be able to return early and control
what else gets loaded from there).
[0] https://www.mediawiki.org/wiki/ResourceLoader/Architecture#Balance
Change-Id: If8900c538ce623f6a9a68a3bbef0927b4b6ae346
Either the server needs to omit these from the registry with
state=error output to the client (and server-side error logging),
or it needs to detect them, and transport them unchanged, so that
the existing client-side logic can handle it.
This patch does the latter.
Without the source code change in this patch, the added test case
fails due to "top" and "middle1" then being registered with
an empty array as dependencies.
Bug: T223402
Change-Id: I57502d7c4e434de4737759aed325dd4200ca89bf
The methods existed for two use cases.
1. Inside ResourceLoaderContext, usage was removed with I4e4ee758cd22.
2. In Module class methods that get $context, already have their own
Config and Logger instances injected from ResourceLoader::getModule(),
which should be used instead.
Deprecating these opens the paths for making ResourceLoaderContext
a purer value object with no ResourceLoader, Config, or Logger objects
needing to be passed (in the future).
Bug: T32956
Change-Id: I74a9535918ea43b2c00073c5d4469f864d1eeb41
The only remaining use of 'new ResourceLoader' is in tests, which have
been migrated in this commit to either passing the real config explicitly
(for integration tests), or by passing a HashConfig from a new
'getMinimalConfig' method which has only the keys required for the tests
to pass (e.g. avoid any ConfigExeption for unknown keys).
Also clean up some related code quality issues:
* Migrate wfScript() to $conf->get() so that the local Config is used,
instead of implicitly using global variables. This isn't deprecated for
MediaWiki generally, but done here to prepare ResourceLoader for becoming
a standalone library.
* Remove mocking of 'CacheEpoch' config, this is no longer used anywhere
in ResourceLoader.
* Change EmptyResourceLoader to use the minimal config by default and
remove code duplication by calling the parent.
Update the small number of uses that are integration tests, to explicitly
pass in the live config as needed. And for the one case that tests the
'startup' module, it no longer needs to register it manually given this
is part of ResourceLoader::__construct() by default.
Bug: T32956
Change-Id: I127346fd530fa66f205156e545758b1c29d0fac0
This was added in 2009 with cf75bdf4ba (r54384) and moved to the
startup module in 2010 with a99f9ec28b (r72772).
It is no longer used by any extension in Wikimedia Git, nor
elsewhere indexed by MediaWiki Codesearch. It also no longer has
any uses in mwgrep from public WMF wikis.
Bug: T220926
Depends-On: Ifdedccb513f5dd4636a37badc329ac5f1c4dd943
Change-Id: Id2729653cd450d31c1d903358ccf5e4fac564228
The method could not be used in session-less endpoints. This was
worked around once in the Startup module.
I plan to use this method in an extension module as well,
and would prefer not to duplicate core's logic for determining
the main page, outside this repository.
As general dependency-injection pattern, it seems desirable
to allow injecting a MessageLocalizer here.
Change-Id: I76cd02b2f489882e9404b93270f76aad9f0a4d9d
Added in 2011 for use in QUnit tests (r80790, r80792).
That was a terrible idea in hindsight, which I removed again in
2015 with 6b758fc982, and 0f9e4ca0fb.
If a need for it were to arise in the future, we'd export it
within the file module that needs it, or via addJsConfigVars()
on only the pages that need it – not globally.
Bug: T217772
Change-Id: I3885cacaa9b33e6947dbaf26f9b6839e19588603