There is a common and reasonable need for longer lines in tests.
The nudge for shorter lines doesn't seem valuable here. The natural
breaks will likely still fall in 80-100 given the enforced practice
for non-test code, e.g. whether through habit, or 80-100 column markers
in text editors, or the finite width of diff and code review
interfaces.
Change-Id: I879479e13551789a67624ce66f0946d2f185e6ee
The new module retains the name .ui name so that existing
skin style overrides continue to work. We can consider renaming it
to just "mediawiki.rcfilters.filters" in a future patch.
This does not handle file reorganization, since both of the
modules used package files - instead, in the main script we also
require() the old main script for the .dm module so that its
setup code runs. But, we did need to rename the virtual
config file from the .dm module to not clash with the
virtual config file from the .ui module, since the
latter uses a callback instead of retrieving configuration
variables directly. These can be merged later as well.
Bug: T256836
Change-Id: I5ec0af8b8e6bcdba6b7881f946f777b854a33739
The new functions `lcFirst` and `ucFirst` lowercases/uppercases the
first character of a JavaScript string with support of UTF-16
surrogates for characters out of the Unicode BMP.
Use these new functions at jqueryMsg.
Change-Id: I007b63bfbcc9e4bc7e89f48df9687111bc4db715
* Move to separate file.
* Remove most of the verbose assert messages in favour of just
a few words that label the asserted value or the call that it
checks the value of. The actual/expected values are already in
the UI, and the class/method are already in the formatted test
name (which includes the module name).
Change-Id: I43ec038abd0946a92f222a859807e252696c33d4
This change renames the existing method `codePointAt` to `charAt` and
make it public. This method is similar to `String.prototype.charAt()`
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt
but supports Unicode characters outside of the BMP.
The name `codePointAt` would be irritating because the method
`String.prototype.codePointAt()`
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt
returns the code point number of the character instead of the character
as string.
Use this method to fix in the module 'mediawiki.jqueryMsg' the
functions `int`, `ucfirst` and `lcfirst` for strings with a character
outside of the Unicode BMP as first character.
Also add tests and use the usual Unicode syntax in the tests.
Bug: T285174
Change-Id: I4343e628e846de44cfdf0405261fa1a8d7ffbed3
The distinction between the two was lost several years years ago
when the "position top" queue ceased to be a thing. Since then,
the two have been loaded and executed together in the same batch,
and are doing similar things.
mediawiki.page.ready is publicly used in several places
as dependendency, but mediawiki.page.startup is entirely internal
to core, which makes it the easier one of the two to dissolve.
Keep an alias for two weeks for cache compat to avoid console
warnings about unknown modules. Although even some cache still
refers to it, this is harmless since the errors are recoverable
and the correct module was also loaded by the cached pages
already.
Bug: T260210
Change-Id: Ic418c23a7400abba22fd07b17f173d3c5f1d1d10
Upstream TableWidget, TableWidgetModel, RowWidget, RowWidgetModel,
and their related styles and messages from the Graph extension.
The table widget was used in the Graph extension's visual editor
module, but does not actually depend on visual editor. Reassign
the widgets to the mw.widgets namespace, and rename CSS classes
and messages accordingly. Also use mw.msg instead of ve.msg.
Bug: T251611
Change-Id: I3ccabc1473dd56570afddf93f5e3a928f0835b9c
This test was an awful, awful, mess. (And I take full responsibility.)
Changing the global user language mid-way into execution is in no way
supported by ResourceLoader and this test was going through great
lengths to fool mw.loader about what's really going on.
Basically, all we're doing is get a list of instructions on what tests
to run, get comparison values based how the PHP side proceses these
(for parity comparison), and then run the assertions.
The mw.language singleton already has support for multiple languages,
and mediawiki.jqueryMsg already supports injecting data and constructing
new instances for each test case. Make use of that :)
Instead of calling ResourceLoaderLanguageDataModule::getData by
trying to hot load the same module repeatedly from load.php,
just export this data using 'packageFiles'.
The mediawiki.jqueryMsg QUnit suite previously took 4s to run locally
and now only 0.1s (145ms). This is not only significant for this
particular module, but also for QUnit in general as Headless Chrome
only took about 7s to run all of MediaWiki core's test suites prior
to this change, which is now down to ~3s. (MacBook Pro)
For WMF CI:
* Before (master commit):
- mediawiki.jqueryMsg.test: ~2.1s (2135ms)
- MediaWiki core total: ~4.8s
* After (this patch):
- mediawiki.jqueryMsg.test: ~0.015s (15ms)
- MediaWiki core total: ~3.6s
Bug: T250045
Bug: T225730
Change-Id: I5f1067feb0a43d63bfc5e7fff5110285a5e433c8
Much less indirection this way, making the test runner a bit easier
to reason about (maintenance-wise) and easier to debug for developers.
Minification doesn't help here anyway (quite the opposite).
This also means the legacy option to load a module synchronously
from ResourceLoader\ClientHtml can be removed. This option existed
solely to bootstrap the QUnit test runner, and can be removed in a
subsequent commit.
Bug: T250045
Change-Id: I73985048382e9cc754753ed84f04d25214c07599
This will make it easy to later allow the user to select which
component's specs to load and run (via CLI and GUI), e.g. for
an entire extension. We currently only have very narrow or very
wide selection mechanisms ('module' param for 1 module,
'rerun' for 1 test case, 'filter' param for global pattern match).
Bug: T250045
Depends-On: I55fe27e1c74972fcb3cdafefdc78e10e24f95b80
Change-Id: I5c01f720d787c3847228de511ce913284786ad66
When something loaded the module 'mediawiki.diff.styles' on
Special:JavaScriptTest (this happens e.g. with VisualEditor),
the diffs generated for failing tests were grotesquely stretched
and useless. Add some style overrides to restore sanity.
Change-Id: I8ac6a2c6e86c6e982fad5d628d3b2c96efc4fbc2
I split this out of it back in 2011 with 83a7822df7.
I don't remember why. I think it had something to do with
Special:JavaScriptTest where I wanted to do something with colors.
Having those functions is useful in theory, but that doesn't require
its own module.
Change-Id: I8815d32c7072da83ddb9fbf955534d1f954692ba
Deprecated in 1.32 and has no further purpose in its current
form as a jQuery plugin for <img srcset>, which we now use
natively without fallback.
The remaining logic for bracketed window.devicePixelRatio is
simple enough to inline as needed without the cruft and overhead
that comes with a centralised approach.
Bug: T202154
Change-Id: I729dfabcbb40a0a794d6b166a584f45a64ac0338
Upstream Sinon.JS no longer supports the pre-2.x v1.17 branch
anymore but there have been a few post-2.0 releases to address
bugs in v1.17 that we can still benefit from.
https://github.com/sinonjs/sinon/blob/v1.17.7/Changelog.txt
Notable changes include:
* Fix Blob feature test to support running tests on Safari 9.
* Avoid calls to object-local 'hasOwnProperty'.
* Improve error messages and stricter signature/type checks so
that debugging code is easier when things go wrong.
* Fix various gaps in the XHR mock.
* Misc fixes for Node.js support.
Also remove outdated comment about ie-hacks from Sinon 1.15.
Change-Id: I66d1b461465b92798ad7eb2efcf4df2731cc78a4
Follows-up 3801e54c29.
Also:
* Split the test into smaller more dedicated tests.
* Make minor changes so as to only assert values in the tests'
outer scope. Assertions within callbacks are an anti-pattern
that is fragile and can easily miss or mask problems. Using a
single state observer that is modified by the callbacks makes
for strict assertions with no implied or untested behaviour.
Callbacks running in a different order or a different number of
times now cause assertion failures - instead of causing the
assertion to not be run, or to be run multiple times, which
would pass.
Bug: T192623
Change-Id: Ice1560b754f8df29ca583eea19f559020fafaf12
These are all quite tiny and not worth providing separately
to the system as deliverable file bundles.
Mark the other mediawiki.api.* modules as alias to 'mediawiki.api'
for back-compat, with deprecation warning.
Highlights:
* Change mediawiki.api.edit.js to not use mw.user, because that
causes a circular dependency, given mw.user also depends on
mediawiki.api.
Bug: T192623
Change-Id: I0afdc8ab50bc1354bb5099bf39923c07eab0b665
In change Ia1269fd898dabbcf1582618eab46cef97e10a3b1 I want to add
functions that deal with codepoints instead of bytes to these modules,
after which the names wouldn't make sense. Doing this in a separate
commit to make the diffs clearer.
Change-Id: Ia554eb2265248e72b04fce69a662a9db1a5f1275
These methods do not belong on the jQuery object. And to resolve
T185948, we need to also add codePointLength and trimCodePointLength,
and this new module seems like a good place to put them.
There is no `mw.String` global, this module has to be used via `require()`.
Deprecations:
* Function `$.byteLength` (from module 'jquery.byteLength') is
deprecated, use `require( 'mediawiki.String' ).byteLength` instead.
* Function `$.trimByteLength` (from module 'jquery.byteLimit') is
deprecated, use `require( 'mediawiki.String' ).trimByteLength` instead.
* Module 'jquery.byteLength' is deprecated, use 'mediawiki.String' instead.
Note that `$.fn.byteLimit` and the 'jquery.byteLimit' module are not
deprecated.
Change-Id: I2501a79efee644e5f4a9f5c977fe49c8c05c6eb3
This parameter is a no-op for these tests, as such, nothing was being
tested by specifying it in tests. The behaviour 'test' and 'test.top'
was identical.
Bug: T184257
Change-Id: Ia2bb731f00d4b4175f7b75174aeafaca9412329e
On supported browsers handle the auto hide timeout with a
count of cumulative time the page has been visible to the
user. Old functionality can still be accessed, if desired,
by setting the visibleTimeout notification option to false.
On browsers without support for this visibilitychange event
wall clock time (the old behaviour) is used.
Adds a library function functionally similar to setTimeout that
only considers time when the page is visible. This is useful
both for analytics purposes, and when you want to temporarily
put something on screen and be reasonably certain it doesn't
go away until a user has seen it.
Bug: T42322
Change-Id: I7d8ea85602cae9cfc72e0155bc3092049ecafd43
This will allow us to load them in the backend, and to keep
consistency between RecentChanges and Watchlist if needed.
Added also a 'backup' preference to keep the previous version
before the conversion, in case of mangling of the queries.
Bug: T166908
Change-Id: I8e26b66e43bd16282b7bdb52abc152f92a9c877d
* Deprecated since MediaWiki 1.26.
* Not used anywhere in Wikimedia Git.
* Grafana mw-js-deprecate dashboard shows < 1 hit per day on average
for any of the jquery.mwExtension properties, during the past 3 weeks.
Most days 0, some days 18 individual hits.
By comparison, legacy wikibits before we removed it in May 2017 was down
to about 6,000/24h (combined), so removal is quite overdue.
Change-Id: Ib66d1844b4fb8d7185b0e6607b9f98c1be632bb5
The backend always merges the query with wiki/user defaults before
it gives us data. The frontend, though, initially assumed that the
state is given strictly by the URL parameters (especially after the
URL shorening commit). This made it so that the frontend state is
incompatible with backend state.
However, always merging frontend state with user/wiki defaults can
produce inconsistencies between URLs in the same wiki, preventing
users from sharing them -- and making it potentially break if ever
a wiki default changes.
The solution is to add 'urlversion=2' to all RCFilters-generated
URLs and have the backend recognize this parameter as 'do not
merge with defaults'.
When RCFilters frontend loads, it checks whether the parameter
exists; if it doesn't, it merges whatever it sees with the defaults
just like the backend, then it transforms the URL to represent the
correct full state, and adds 'urlversion=2' to the URL parameters,
making it consistent across accounts and through time for the
next time it will load.
This means several new behaviors over the 'short url' commit:
- Accessing Special:RecentChanges directly (no query) will result
in one of two things:
-- If there is a saved query that's set to default:
The system will load that saved query "straight forward" (as
if the user clicked that option from the menu) causing, also,
an ajax re-request from the server (since the server does not
yet know about saved queries or their potential for being
the default state.)
-- If there is no saved query default: The system will load
user/wiki defaults (like the backend does) and then fix the
url to represent this state fully (with parameters showing the
actual state of the filters.
-- Both cases will also result in adding 'urlversion=2' to
the end result URL.
- Accessing Special:RecentChanges?urlversion=2 (without any other
parameters) will result in loading a completely empty filter set
in RCFilters. We assume that 'urlversion=2' does not load defaults
even if it is the only parameter in the URL.
- Accessing Special:RecentChanges?hideX=1 (parameter set without
urlversion=2) will result in the front end taking the requested
parameters, merging them with user/wiki default (reproducing what
the backend does) and then adding urlversion=2 to the URL.
In all cases except for the default-saved-query-load case, the initial
load will **not** re-request data from the backend. The backend needs
to adjust to respect urlversion=2 as well (will come in an upcoming
commit) so the state and expectation of both the front- and back-end
are the same.
This commit also factors out URL handing to a separate class (UriProcessor)
and adds unit tests for it.
Bug: T166907
Bug: T166972
Bug: T166974
Change-Id: I0eed3bc0d4fa4810b6301b535c75b6bfbc8b4a5b
It's not very useful and needlessly emits deprecation warnings
which unfortunately cannot be surpressed at runtime.
The test just asserts that a no-op function exists.
Change-Id: I2768ba40191a3c0cc7be6202ffa5bed529eabfee
In practice, this means nothing, as the main browsers affected
were Internet Explorer 8 and early versions of Android (before
1.6), which are already Grade C.
Change-Id: I4488402686c8b9fefa0af5fed3c9a4b83cbff798
Create 'dm' / 'ui' and 'controller' modules for ResourceLoader,
make sure that Special:RecentChanges loads 'ui' module (that
depends on the other two) and yet the qunit tests only load
the dm module.
Bug: T156532
Change-Id: If53a735458703f0bd2c094349edf86f38f05ccd7
Add a new filter experience to Special:RecentChanges with
a drop-down filter menu. Put it behind the rcenhancedfilters
preference, which is hidden for now.
Bug: T149435
Bug: T149452
Bug: T144448
Change-Id: Ic545ff1462998b610d7edae59472ecce2e7d51ea
Doing edits "The Right Way" is non-trivial due there being mulitple strict options that
need to be known and enabled. By default, the API encourages bad behaviour:
* Edit is unexpectedly saved as anon after session becomes invalid.
* Other edits are silently overwritten.
* Accidentally re-creates a deleted page.
* Accidentally creates a new page when an edit was intended (eg. if title was wrong).
Implement abstraction methods for edit and create that handle all this.
Thus guarding JS edits with the same protections as EditPage.
Change-Id: Ic6a35902cbae262971c704b9b8127e54733dac79
* Send 'module' and 'require' parameters to module closures.
This depends on Ia925844cc22f143 being deployed one cycle earlier.
* Patch Moment and OOjs to ensure these libraries continue to expose
their module as globals as well. AMD/UMD-compatible libraries
only expose a global *OR* an export, not both. We need both
for back-compat.
* Update pluralRuleParser to make use of module export to allow
usage via require().
To test, check out the patch and run:
> mw.loader.load('moment');
> mw.loader.require('moment')()
> mw.loader.require('moment')('2011-04-01').fromNow()
Bug: T108655
Change-Id: Idbd054880ee70d659ec760aef8fcb38d0704a394
No major changes for us other than a bugfix that makes the
following work as expected:
var clock = this.sandbox.useFakeTimers();
setTimeout(function () {
clock.tick(10);
});
click.tick(1);
// Expected: 11ms is recorded
// Actual: 1ms is record
This was broken up until Sinon 1.16.0 (Lolex 1.3.0) because it saved the
"clock.now" value before running any pending timeout callbacks. Then it
unconditionally assigned the "clock.now" value to 'oldNow + ticked', which
discarded ticks made by a callback.
Change-Id: I2775f4c6353aef12ced6dc45e73fe8d4e49c2b68
As a useful utility function, we've copied this method several times
across multiple extensions, which is a pretty good sign it should
actually live in core.
Changes:
* Add `mediawiki.viewport` module
* Rewrite method to be more robust and accept any viewport
* Add `mw.viewport` to jsduck categories file
* Add method for checking if an element is close to the viewport
* Add unit tests
Bug: T124317
Change-Id: I38eec4f1e568f51e7e212b2b3f10b8da8d36f316
* Add template partial support which matches the server-side implementation
and means that we have full mustache support.
https://mustache.github.io/mustache.5.html#Partials
Bug: T97188
Change-Id: Ic752f52669dbffa21c4a514509c3ea1da8ac5d9c
We often use the idiom "window.onload" or "$(window).on('load')".
Since code loads asynchronous, this is problematic because the event won't
always be observed as it may fire before the event handler is attached.
Most tasks also don't really want to wait until the page is loaded (in which
case it would run immediately if the page is already loaded). Rather their intent
is just to defer it to a later point in time – to avoid disrupting user events.
Bug: T111456
Change-Id: Ieba0440c6d83086762c777dfbbc167f1c314a751