- Remove min-height so menu items are a little smaller and
their content is vertically-aligned.
- Force `vertical-align: middle;` for checkboxes by overriding
OOUI with extreme specificity.
Bug: T200364
Change-Id: If0b2b5c1b749f913badbd0c02a85852ec0007020
Currently, these separators are unnecessarily hardcoded in HTML.
This is problematic, as it limits the extent to which skins such
as Minerva and Timeless can skin these pages.
If the pseudo selector is not available (e.g. legacy browsers)
this degrades nicely to whitespace and the page is still useable.
Right now, these changes are scoped to pages uses the ContribsPager
(used by Special:Contributions)
but we can adopt them in other pages once we have this approach set in
stone (CSS)
Bug: T205581
Change-Id: Ia2c485e6058ebf4282ed2f7eb7b046b2deb03f57
This header can be injected into api responses that include
search results to provide a link between the backend logs
and any frontend logging. Associating autocomplete tracking
with backend logs will allow us to determine autocomplete
examination probabilities, and more generally be able to
evaluate autocomplete effectiveness.
Bug: T205348
Change-Id: I1663906e2fd71f7df215e563b09a0b4fb8948ab8
Upstream commit 'd9aa703' is the commit right before the tagging
of v1.0.0. The only difference is the version string.
Change-Id: Icf7b7abacac583984977183da6f93f5fd02404fa
Since OOUI v0.24.4, menus/popups of infused PHP widgets are placed
into the default overlay, so this workaround is not needed.
Change-Id: I4f8a76cb258e44ed4f2fbba41425100d2e0e9b45
The border choice for `#a2a9b1` was intended to provide AA conforming
contrast for widgets. In case of framed PanelLayout it is not necessary
due to it's different use case and the additional high padding.
Change-Id: Ia425594c1795d1d8668cd62daff32ff9b97d67c2
* Function#bind is a given per the explicit feature test for Grade A.
* Object.defineProperty is part of ES5 which is also tested for.
This code is from before we required ES5 and is now redundant.
Also remove the unused eslint-disable rule for global 'console' use,
the code in question does not use console as global unconditionally.
Change-Id: I6c77b25856da8b7717aeba8298b17a9231540d58
In course of icon overhaul we've also unified base widget font-size
to `14px` in I693d168d2ccf2. DateInputWidget has been left behind.
Let's amend it and also align other variables like
`transition-medium`.
Change-Id: I033bfa17b665d7e36f6d18c3adfa0315c4b26cb0
* Use prop() instead of attr().
- Avoids extra overhead from attr() relating to XML/SVG compat.
- Makes the code consistent with jquery.accessKeyLabel, which,
reads the node.accessKey value as property already, and we now
set it the same way.
* Use append() instead of wrap().parent().
Most use of adding portlets is as links in the sidebar or
as menu items for the page actions menu. For this, simply
assign the <li> directly, and append the link. Instead of
wrapping it in the DOM and then unwrapping the jQuery
collection. This also saves a bunch of clone operations
internally due to how jQuery objects keep a stack of
mutations.
* Set 'textContent' directly instead of text().
* Use $('<li>') instead of $().wrap('<li></li>') which allows jQuery
to take a fast path for element creation. Also consistent with
MW code conventions which say to avoid <tag></tag>.
* Use node.querySelector(str) instead of $(node).find(str).eq(0).
The latter does a lot more, including querySelectorAll(),
and twice a clone/push/merge of the jQuery collection.
* Use createElement() for the anchor tag, given that none of the
remaining code needed the jQuery object anymore. The return
value was already the DOM Node directly as well.
Bug: T204625
Change-Id: I9070f63a4c75411c0eff7757bd2d8aed46c182e9
Follows-up e5912535ae, and removes the last use of
Object.prototype-inheriting objects for map-like objects, in
mediawiki.js.
I'd like to consider using ES6 Map as well, with a partial shim
like we do for StringSet/Set, but that'll require some more
refactoring. It's also not clear whether it will improve
execution speed and/or memory use. Worth trying at a later time,
though.
The current change simply removes the inheritance and simplifies
the code. Apart from slightly smaller code, I could not find any
notable/reproducible improvement in either NavTiming metrics or
CPU time spent in 'Scripting'. The metrics are in the same range
as before this changes.
Change-Id: Ie0016667d9291dcfafde61289d5444817be3447d
* Remove redundant registry check in the internal
queueModuleScript function. Like most internal methods,
it can only be inside the mw.loader closure, and is only
called with extant module name.
* Remove redundant registry check from execute().
* Rename local variable in mw.loader.state() from 'modules'
to 'states' to avoid confusion.
* Shorten exception messages in mw.html to not prefix the method
names, because we don't do that anywhere else in RL JS.
Change-Id: Idf1a49fd98445477f2d940624ca0d079325bd15b
Follows-up Id6d13bbea6:
- '$': mw.loader.implement does this already.
- 'mw': Use the canonical name directly.
This replaces the following patterns:
File closures (common):
- `( function ( $, mw ) {` => `( function () {`
- `( function ( $ ) {` => `( function () {`
- `( function ( mw ) {` => `( function () {`
- `( function ( mw, $ ) {` => `( function () {`
File closures (rare):
- `( function ( mw, $, OO ) {` => `( function () {`
- `( function ( mw, OO, $ ) {` => `( function () {`
- `( function ( mw, document ) {` => `( function () {`
Combined dom-ready and file closure (rare):
- `jQuery( function ( $ ) {` => `$( function () {
- `jQuery( function () {` => `$( function () {
Remaining references in files without a closure, as found by
the new ESLint setting (rare):
- `jQuery` => `$`
- `mediaWiki` => `mw`
Change-Id: I7cf2426cde597259e8c6f3f6f615a1a81a0ca82b
aka "handlePending 2.0",
aka "don't recurse 300x before executing a module",
aka "don't break DevTools flame graphs".
== Impact
Comparison based on viewing the default Main page on Chrome stable.
The local MediaWiki has a few extensions installed (EventLogging,
ULS, Navigation Timing).
Measured by alternating between before/after and logging 'mediaWikiLoadEnd'
from ext.navigationTiming.js, and evaluating the following on the console:
```
({ responseStart: performance.timing.responseStart - performance.timing.navigationStart,
domInteractive: performance.timing.domInteractive - performance.timing.navigationStart,
domComplete: performance.timing.domComplete - performance.timing.navigationStart,
loadEventEnd: performance.timing.loadEventEnd - performance.timing.navigationStart });
```
This was repeated five times, and I picked three results based on similar
responseStart values. This provides a fairer comparison by avoiding bias of
fluctuation from the network/server. The actual values ended up slightly
favouring the older code.
| -------------- | ---------------- | ---------------- | -------- |
| | Before | After | Avg diff |
| -------------- | ---------------- | ---------------- | -------- |
| responseStart | 1044, 1001, 1016 | 1025, 1023, 1024 | +3ms |
| domInteractive | 2080, 2069, 2059 | 1872, 2101, 2050 | -61ms |
| domComplete | 4361, 4239, 3927 | 3691, 4023, 3981 | -227ms |
| loadEventEnd | 4366, 4244, 3932 | 3691, 4023, 3982 | -282ms |
| mwLoadEnd | 4524, 4416, 4113 | 3994, 4320, 4297 | -147ms |
| -------------- | ---------------- | ---------------- | -------- |
== Implementation
While technically a single logical change, this commit does
resolve multiple long-standing issues and inefficiencies.
* handlePending (now called doPropagation) was called way more
often than needed. When a load.php response arrived with calls
to mw.loader.implement(), each one could execute and immediately
call handlePending().
Now, the first implementation in a batch schedule one call
doPropagation(), and the later ones ride along that one call.
* Most calls to handlePending were only able to execute one
pending module, which in turn created its own handlePending
call that started all over again. This meant that by the time
control returned to an outer call, there was nothing left to
do, except it still needed to continue its iteration over the
whole registry before knowing there was nothing left to dos.
* Due to recursive calls to handlePending() from execute(), and
due to immediate execution from implement() - as called from
load.php or asyncEval - the stack was often already 100s of
level deep before *starting* the execution of a module.
Such deep stacks caused:
- a larger memory footprint (for the stacks themselves).
- confusing flame graphs. It was impossible to analyze
performance of module initialisation, I typically could only
look at code from dom-ready handlers or other events.
The stacks were so big, they actually caused rendering
bugs inside Chrome where higher parts of the stack would be
trimmed, and thus related code would no longer be visually
grouped by the same parent.
- confusing error messages (long stack traces).
* The eager execution from mw.loader.implement() calls meant
that it was not possible to separate the parsing/loading of
code (by load.php and asyncEval), from the execution of code.
Now, this is separated by a 1ms yield (in practice it's
larger than 1ms, but it has high priority). This means that the
batch of localStorage eval() and the batch response from
load.php can now first do one type of work (allocating of functions
and objects, stashing them in the registry), and then later the
other type of work (execution of the module code) - with some
breathing room allowed for rendering.
Bug: T127328
Bug: T202703
Change-Id: I499ae3f095545abcc03e8989f54422b1997738d3
This is using the non-standard value of word-break, instead of
overflow-wrap/word-wrap, since the latter doesn't produce the desired
effect. That may be due to figure being displayed as a table, without
the layout being "fixed".
Unfortunately, non-Webkit based browsers don't implement this and
break-all is a little heavy handed for the few cases this turns up in
practice.
Bug: T171761
Change-Id: If123d30addb4c707ebed63bafd18dccba9afe158