Commit graph

21 commits

Author SHA1 Message Date
James D. Forrester
21d8d9863b Drop old ResourceLoader class aliases, deprecated since 1.39
Depends-On: Iff15a2e13a3507ef1ab5cfa504ca1a1c8d2b2a60
Depends-On: Icf8331e35acf6fe51a8303ee639921b9e4f3e6bb
Depends-On: I5a5af003026db69b279ddde0b0dedbfcfe7d70fd
Change-Id: I5929a2f760c8d21c1cb2542a19220a91ac7240e4
2024-01-31 18:24:37 -05:00
Timo Tijhof
c7ee0dbf96 ResourceLoader: Document the clientPrefs system and make Skin option
Move parts of implementation code comments into something that is
discoverable and understable to a general audience of MW core and skin
developers (not hidden in code mostly seen by maintainers
and contributors to ResourceLoader internals).

Most notably, that the system is turned off by default (and how to
turn it on), that it is limited to requests by unregistered users,
and that the class must follow a certain pattern.

$wgResourceLoaderClientPreferences is removed as part of this.

This is not considered a breaking change as the feature is now
automatically on in the skins needs it (via skin.json), and previously
it was marked experimental and off by default.

Skins are naturally required to have knowledge of this system, as they
need to call into it to persist classes for feature toggles. By removing
the need to also enable it at the site-level we get a few benefits:

1) make skins like Vector easier to correctly install and configure.
2) ease maintenance for skin devs by removing the need to manually
   export and check $wgResourceLoaderClientPreferences before calling
   mw.user.clientPrefs or otherwise hinting in UI or docs that the
   feature persists when it might not be turned on on a given MW site
   or WMF wiki.
3) ease browser testing in CI.

Bug: T344069
Depends-On: If9b83dd559cda2dac315afcb65a4761b9e97f319
Change-Id: Ib0b5ee29ec7accb7b291830d2ab6566fe4f4c0c5
2023-08-18 13:32:01 -07:00
Timo Tijhof
785dd9f89d ResourceLoader: Add unit test for clientprefs
Move the file to /resources/src/startup/, where it also benefits
from automatic enforcement by ESLint for ES3 syntax compliance
via the local .eslintrc.json file.

Bug: T344069
Change-Id: I95fbecbd10815a4ff0d5784c3820683ef1a41d2f
2023-08-17 21:44:02 +00:00
jenkins-bot
04b321a688 Merge "ResourceLoader: Simplify clientpref storage" 2023-08-11 18:00:25 +00:00
Timo Tijhof
fdb8daa966 ResourceLoader: Simplify clientpref storage
After this change, for the 99% case, all we do is:

* read local string variable (doc.cookie),
* match a regex that has no matches,
* 1 assignment to docEl.className.

This are the same three operations as before change I1e635f843ac.
Specifically, this avoids:
* build a data structure from the cookie.
* match and extract every feature class (even when unchanged),
* perform a no-op replacement for each one,

For the case where client prefs do exist, this reduces the logic to
a string replacement (not a DOM read-write), and doing so only N times
(for each customisation), instead of the maximum numer of times for
every feature that could be customised.

Bug: T339268
Change-Id: Ia85ef5c2be7bf759bc6041f8a999eeb584e554e8
2023-08-11 09:09:18 -07:00
Tim Starling
f2a5946375 ResourceLoader: wrap module definitions in functions
This is an intermediate step towards the linked bug, to help untangle
the performance impacts.

Bug: T343407
Change-Id: I086f173f811fb44683f4a67bf6bc415d7e27f593
2023-08-11 00:36:52 +00:00
jenkins-bot
267af890e1 Merge "ResourceLoader: Remove support for CSP nonce" 2023-08-10 23:25:21 +00:00
Timo Tijhof
b28faecb2b ResourceLoader: Remove support for CSP nonce
The "nonce" CSP feature has been never been properly tested and is not
on track to be enabled at WMF or in MW by default. The use of
nonce-protected eval is not particularly meaningful. It is trivially
bypassed by mw.loader.implement, mw.loader.store, or importScript();
all of which allow any code to be executed directly, or to be stored
and loaded from a first-party origin.

The "nonce" feature is not required for the T208188 roadmap, and with
change I51b8535b2b21a3 there is now also a (small) performance reason
to keep this disabled long-term.

Until and unless there is a plan for enabling this particular aspect
of CSP, we might as well remove it so that we don't waste time our
time building abstraction layers and satisfying dependency injection
through many years for something that might never be used.

Note that this does not remove CSP support from ResourceLoader, and
does not take away from the future of enabling CSP in MediaWiki to
e.g. strictly block third-party scripts, or to require domains to
opt-in by site config or user pref (T208188).

Change-Id: I5a176c41a06a484a11e64bdacdc42b40811fe72e
2023-08-09 02:30:39 +01:00
Moh'd Khier Abualruz
a9045f21f7 core - client side preferences inline script
Changes:
- Add/Modify client preference classes to documentElement,
- Only uses existing classes, for maintainability. For new feature,
the new class must be added a couple of weeks before the feature is deployed,
so that the feature class is already in the cache when the feature is deployed
- Add mw.user.clientPrefs as an API to manage Preferences. This exposes set and get methods
- When set method is called it saves to a cookie which saves key value pairs of
feature and its value. The value corresponds with a suffix on the class.
- get method always uses HTML to obtain result.
- Tests are defined for set and get methods to ensure that the API does not have unexpected
side effects and caters for the case where two tabs are open and the cookie may not reflect
the classes on the HTML element
- A prefix "-clientpref-" is required on any class managed by this capability.
The purpose of this is to aid discoverability and to act as an allow list for which classes
can be modified by the API
- Using '~' instead of '=' and '!' instead of ',' for separators as they require no url encoding
and do not interfere with the delimiters and special characters
- This is a breaking change for Vector 2022's existing limited width feature. For this
reason this patch should be merged around the same time as the Vector 2022 patch to ensure
backwards compatibility.
- No backwards compatibility is provided by core given the previous capability was Vector
specific. Backwards compatibility will be handled in the skin. Please see:
I120f8f7114b33d2cfbd1c3c57ebf41f8b2d7fec4

Note:
This patch doesn't provide tests for the inline script because
* It is not possible to add this to this patch at the current time since we need to determine
whether or not it is okay to call file_get_contents at such a critical time
* the tests are written in Jest due to limitations with our QUnit test framework.

For development purposes a standalone test patch was added I6ad496bb25a4bd523fa69f2e6d936d7eb643793e
A task will be created on merge to explore incorporating these tests in the codebase.

Bug: T339268
Bug: T341720
Change-Id: I1e635f843ac9b2f248b1f7618134598e80291b38
2023-08-07 21:29:10 +00:00
Tim Starling
8a4134ed21 ResourceLoader: deliver deprecation warnings as strings
It's awkward to construct a source map when the file contents is
modified after loading. Delivering deprecation warnings as JS code
seems like an odd convention anyway.

So, send the module deprecation warning as an additional parameter to
mediawiki.loader.implement().

Deprecation warnings are no longer displayed in only=scripts mode.

Remove deprecation tests from FileModuleTest since FileModule no longer
has any relevant deprecation code. Add tests to ModuleTest.

Deprecate Module::getDeprecationInformation().

Bug: T47514
Change-Id: I20938cf4ab78afc9a2d72fbd163a7c5f21755820
2023-08-03 14:10:16 +10:00
DannyS712
9c30021328 ResourceLoader: Simplify and clean up ClientHtml nonce passing
remove $nonce parameter from ::getLoad(), access
the option directly in that method; unhoist variables
and reduce duplication.

Change-Id: If0aef56fa123105e5c98568cb95c09368d55b68e
2023-07-18 15:35:50 +01:00
Amir Sarabadani
7d8768e931 Reorg: Move HTML-related classes out of includes/ to Html/
Bug: T321882
Change-Id: I5dc1f7e9c303cd3f5b9dd7010d6bb470d8400a18
2023-02-16 20:40:01 +01:00
Reedy
ed1771bf58 ClientHtml: Fix use of ${var} string interpolation
Bug: T314096
Follows-Up: Ic3b6eec19953932c697ab5bf48c33a4ac1841b07
Follows-Up: I07f471b815ffadfca9eb4f7bd228cb72dfd1ec9b
Change-Id: I1635081720b983340a19d5ee93b748e6b3616fbf
2023-01-28 00:35:04 +00:00
Timo Tijhof
190598d10f ResourceLoader: Follow-up to adding ResourceLoaderClientPreferences
Minor clean up:
* Fix broken `@see` in MainConfigSchema.
* Add missing `@since`.
* Doc experimental nature, as per the Ic3b6eec1995393 msg.
* Doc anonymous scope, and mention general strategy for elsewhere.

* Dependency inject, to separate concerns and keep ClientHtml
  decoupled from MediaWiki settings like wgCookiePrefix, which
  otherwise break testing this class with only RL-specific config.

* Apply JS conventions. Made easier by using "JS" as the heredoc
  identifier, which IDEs recognise as for highlighting.

* Move code together with the other documentElement.className
  statement. This helps both with understanding the PHP side in terms
  of related logic and how it interacts, as well as the frontend as
  it literally brings <html script>, client-js, and clientpref all
  next to each other.

HTML weight of default Main_Page on localhost, logged-out:

* vector                              : 23.21 kB / 140.48 kB
* vector-2022                         : 24.17 kB / 146.43 kB +6.0 kB
* vector-2022 ClientPref=true before  : 24.28 kB / 146.70 kB +6.3 kB
* vector-2022 ClientPref=true after   : 24.27 kB / 146.68 kB +6.2 kB

Given:
* $wgResourceLoaderClientPreferences = true;

Test plan:
1. View /wiki/Main_Page?useskin=vector-2022 while logged-out,
   confirm the inline script is there, and
   "vector-feature-limited-width-content" is set on <html class>,
   layout width appears fixed.
2. Run mw.cookie.set('mwclientprefs', 'vector-feature-limited-width-content');
3. Refresh and confirm the class is changed at runtime and layout
   width is fluid.

Use mw.cookie.set('mwclientprefs', null) to undo.

Bug: T321498
Change-Id: I07f471b815ffadfca9eb4f7bd228cb72dfd1ec9b
2023-01-25 04:24:38 +00:00
Jon Robson
d4d6156c3b ResourceLoader: Basic client side user preferences
This allows the body classes of skins to be customized for anonymous
users. Enable using $wgResourceLoaderClientPreferences = true;

* Only classes of the form <prefix>-(disabled|enabled)
  can be toggled.
* For now no client side API is provided as this should not be
  considered stable.
* Storage mechanism is cookie, stored under "mwclientprefs"
* Preferences apply to all skins. This means setting a preference
  in Vector 2022  would also lead to class manipulation in Minerva.
  This is by design to allow for skin-agnostic preferences. Up to
  caller to make sure the class being manipulated is limited to the
  skin if required ie. don't use generic classes.
* Avoids try/catch and JSON parsing by storaging as a string
* Places inline script before body tag before first stylesheet to
  avoid breaking the article's ability to parse the article
  concurrently with stylesheet download.

Usage:
Given a document with classes
"client-js vector-feature-limited-width-enabled ext-feature-enabled"

Set:
    document.cookie = 'mwclientprefs=vector-feature-limited-width'

Will result in toggling off the limited width.

Bug: T321498
Change-Id: Ic3b6eec19953932c697ab5bf48c33a4ac1841b07
2023-01-25 02:24:35 +00:00
jenkins-bot
a85966542d Merge "Use short array destructuring instead of list()" 2022-10-21 11:11:06 +00:00
Tim Starling
0077c5da15 Use short array destructuring instead of list()
Introduced in PHP 7.1. Because it's shorter and looks nice.

I used regex replacement.

Change-Id: I0555e199d126cd44501f859cb4589f8bd49694da
2022-10-21 15:33:37 +11:00
Tim Starling
43a93d9782 Use the null coalescing assignment operator
Available since PHP 7.4.

Automated search, manual replacement.

Change-Id: Ibb163141526e799bff08cfeb4037b52144bb39fa
2022-10-21 13:26:49 +11:00
Tim Starling
3e2653f83b ResourceLoader namespace (attempt 2)
Move ResourceLoader classes to their own namespace. Strip the
"ResourceLoader" prefix from all except ResourceLoader itself.

Move the tests by analogy.

I used a namespace alias "RL" in some callers since RL\Module is less
ambiguous at the call site than just "Module".

I did not address DependencyStore which continues to have a non-standard
location and namespace.

Revert of a241d83e0a.

Bug: T308718
Change-Id: Id08a220e1d6085e2b33f3f6c9d0e3935a4204659
2022-05-24 15:41:46 +00:00
Lucas Werkmeister (WMDE)
a241d83e0a Revert "ResourceLoader namespace"
This reverts commit e08ea8ccb9.

Reason for revert: Breaks Phan in extensions, and as far as I’m aware,
this change isn’t urgently needed for anything, so the simplest fix is
to revert it again for now. After PHP 7.4 it should be safer to try this
again (we hopefully won’t need the two “hack” classes by then).

Bug: T308443
Change-Id: Iff3318cbf97a67f821f78e60da62a583f63e389e
2022-05-16 14:43:33 +00:00
Tim Starling
e08ea8ccb9 ResourceLoader namespace
Move ResourceLoader classes to their own namespace. Strip the
"ResourceLoader" prefix from all except ResourceLoader and
ResourceLoaderContext.

Move the tests by analogy.

I used a namespace alias "RL" in some callers since RL\Module is less
ambiguous at the call site than just "Module".

I did not address DependencyStore which continues to have a non-standard
location and namespace.

Change-Id: I92998ae6a82e0b935c13e02a183e7c324fa410a3
2022-05-16 14:41:27 +10:00
Renamed from includes/resourceloader/ResourceLoaderClientHtml.php (Browse further)