Commit graph

47 commits

Author SHA1 Message Date
Siddharth VP 72cbb64069 Add support for content models in definitions
Adds a contentModels option to gadget definitions to restrict gadgets to
run in pages of the given content models only.

Use-cases include gadgets for tabular data[1] (for Tabular
.JsonConfig model), for editing map data[2] (for Map.JsonConfig model),
and for showing links in code pages[3] (restricted to javascript, css,
json, and scribunto models), as well as common gadgets like ProveIt[4]
which can be restricted to wikitext model.

[1]: https://commons.wikimedia.org/wiki/MediaWiki:Gadget-TabularImportExport.js
[2]: https://fr.wikipedia.org/wiki/MediaWiki:Gadget-KartoEditor.js
[3]: https://en.wiktionary.org/wiki/MediaWiki:Gadget-CodeLinks.js
[4]: https://commons.wikimedia.org/wiki/Help:Gadget-ProveIt

Bug: T204201
Bug: T63007
Change-Id: I7dcfc21d674ead8d710e7f77d13bf18bcad15079
2023-09-21 22:27:22 +05:30
brandonxlf ec69cea0e3 Add support for namespaces in definitions
Adds a "namespaces" option to the gadget definition, which takes a
list of namespace IDs. Enabled gadgets will only load when the
viewed page is in one of the required namespaces.

Bug: T204201
Bug: T63007
Change-Id: I7f797e35352b242ad78704074e98c6569a1adf91
2023-09-20 14:50:33 -07:00
Timo Tijhof 5aaa843a28 tests: Enforce parity between Gadget::serializeDefinition and toArray
Follows-up 087ab65e24 (Ieae6706537). To avoid silent mistakes such
as during development of T63007 (I7f797e35352b242).

Bug: T303194
Change-Id: If675f8d02ed3fee768af3d2b4912249319ae9ef4
2023-09-20 14:41:33 -07:00
jsn 929bfc6404 Preserve Gadget prefs when they can't be enabled
- Always define gadget enable/disable preferences
- Show a gadget's preference when it can be enabled

Bug: T341421
Change-Id: If32eecebccf2c9b557d7dde273b7faf7118a7ac3
2023-09-06 19:32:31 -05:00
Daimona Eaytoy b6e76eeb3a Add GadgetHooksTest to the Database group
The test uses black magic to override the behaviour of
MediaWikiGadgetsDefinitionRepo. However, this magic doesn't work well
with I2ac659a4, which disabled gadget loading in non-database tests.
This test is the only one that needs that code to be run, although it
won't actually make any queries because of said black magic.

Add the test to the Database group as a temporary (TM) workaround to
replacing the TestingAccessWrapper magic with something else.

Change-Id: I7d9fd612dd685a5728d3a7a9ced97fd5ac45f491
2023-08-06 22:55:00 +02:00
Daimona Eaytoy b1b7bfefa3 Avoid using TestUser in non-database test
TestUser needs a database connection to create the User, but this test
doesn't need a real user, so just use a mock instead.

Ideally we'd use Authority, but the hook still takes a User object.

Change-Id: If6cb7e3756036fc458a4308b06499c4bc0d3d9b0
2023-07-17 23:12:13 +02:00
Jon Robson 8af75aa6e5 Gadget maintains its own version of targets system
The ResourceLoader module associated with the gadget will have
mobile and desktop targets, but this allows gadgets to disable
themselves on the mobile site if necessary by not adding the gadget
to the page if it's been marked as such.

This also has the benefit of not showing the gadget on the preferences
page if it's not relevant.

Bug: T328610
Change-Id: I4f2b57d1d22f641ff7520358a46cd0e6b2103aa9
2023-06-29 16:20:29 -07:00
Siddharth VP 087ab65e24 Avoid caching serialized PHP object
Cache array representation of the Gadget object instead of the
php-serialized representation. Gadget::toArray() is an inverse of the
constructor which already constructs an object from an array of config
values.

Also, the static Gadget::newFromDefinitionContent method which accesses
the service container is replaced with the dependency-less
serializeDefinition() method.

Bug: T303194
Change-Id: Ieae6706537143d766777b2299c31726e2a1dfd29
2023-06-22 06:01:28 +00:00
Jon Robson 58463ce97c Gadgets should default to mobile and desktop targets
The targets system is being deprecated.

Bug: T127268
Bug: T340046
Change-Id: I69d11d52238ac852534cb9a4555208a0b0bb5fd7
2023-06-21 15:36:39 +00:00
Siddharth VP 7793a9475f Add support for ES6 gadgets, but with validation disabled
Gadgets can mark themselves as ES6-only by specifying the requiresES6
boolean attribute. Syntax validation is disabled for them (as the
validator doesn't support ES6 yet), and they are loaded together in a
separate request.

The minifier doesn't reject syntax errors, and thus these would
be passed through to web clients. Hence, communities using this feature
are encouraged to use ESLint or another linter to make sure only
valid ES <= 6 code is being used.

Because of the above, this feature is only made available for
non-default gadgets.

Bug: T75714
Change-Id: Ib98ac0700471554d5721d7ab858d4660e1e0e980
2022-10-20 22:03:18 +00:00
Fomafix b504a6f496 Use HookHandlers and implement hook interfaces
Bug: T271014
Change-Id: I50d42df04038d1214fd9835c3d3b0f602037ac62
2022-04-17 12:00:24 +00:00
Timo Tijhof db04e488b6 Rewrite and simplify MediaWikiGadgetsDefinitionRepo cache
* Remove most APCu logic, including the reverse checking of WANCache
  touch time to validate the APCu key
  The APCu expiry had a 7-15s blind TTL before this check took place.
  Keep the conservative part of this (blind TTL). This should be
  more than enough to debounce memcached traffic.

* Simplify WAN handling with plain key and delete (using the default
  holdoff tombstone, which should take care of edge cases like second
  DC warming up the WAN key shortly after a delete).

* Fix incorrect method doc about being by section. The returned
  list is not by section.

Change-Id: If14ff83a29367df58d1824615bcf0bcd2edc886f
2022-04-05 21:39:45 +01:00
Timo Tijhof 6f452d11b9 tests: Use setGroupPermissions() to fix flaky test
Locally these tests are failing for me on master every time.
In WMF CI, it seems they are passing right now, although they
too would start failing as of Ib27fd34fbfe7a7. My guess is that
my change there causes the service container to be initialised
earlier and thus causes the modified global to no longer be seen.

At the very least this should have been using setMwGlobals(), which
would have also avoided the issue by ensuring a service reset,
however use setGroupPermissions() since it's tailor made for this
purpose, and avoids potential problems later with default groups
not existing.

Change-Id: I8f02ffc996d6077ca6e7433229b1ea5d8fc6ce7c
2022-04-05 21:07:28 +01:00
Reedy 998f20994c GadgetHooksTest: Use namespaced GadgetRepo
Change-Id: I6a1ba1241bd0ada4bc024c6a3f48200d9c6ae6d9
2022-03-06 02:07:17 +00:00
Reedy 01f6a6c34e Namespace extension
Bug: T278278
Change-Id: I49b57e68079c998419e235b1727eea8c121c234b
2022-03-05 17:03:35 +00:00
Ammarpad 5d3a547c8b Restrict ?withgadget query parameter to opt-in gadgets.
?withgadget query parameters allows for ad-hoc loading of gadgets
(after passing all other basic checks). This was recently added in
I5b30d4e.

In T29766#7611796 Gergo raised concerns about how this can be
potentially abused.

This patch aims to restrict the feature by giving gadgets latitude
to either use it or not depending on the nature of the gadget.

The patch does so by adding `supportsUrlLoad` option that gadgets
(maybe those deemed safe) can use it to opt-in to the parameter.
By default gadgets don't support it, so it can be enabled for each
on a case-by-case basis.

Bug: T29766
Change-Id: Ie64174085e650579d76cc862774a4fe1b3d08396
2022-01-24 00:31:19 +00:00
Siddharth VP 7ead5dab61 Allow specifying page actions in definitions
Allow specifying page actions ('view', 'edit', 'history', etc) in
gadget definitions. If specified, the gadget is run only on the given
page action(s).

This is especially useful for default gadgets like RefToolbar[1] and
TextReactions[2] that only need to be loaded while editing.

[1]: https://en.wikipedia.org/wiki/WP:RefToolbar
[2]: https://en.wikipedia.org/wiki/WP:Text_reactions

Bug: T204201
Bug: T63007
Change-Id: Idde71b3f1f6c36cd21539a2312be8f12217a9acc
2022-01-01 00:41:08 +05:30
Siddharth VP 1f7b9d90df Support JSON files in gadgets
The parsed content of JSON files in the gadget is made available from the
gadget's JS files via require(). That is, MediaWiki:Gadget-data.json (or
Gadget:data.json) is available as `require('./data.json')`. This is
supported for both MediaWikiGadgetsDefinitionRepo and
GadgetDefinitionNamespaceRepo. The JSON parsing is done server-side.

JSON can only be used in "package" gadgets - in which the JS files can
also be invoked via require().

Also added a test for GadgetResourceLoaderModule.

Bug: T198758
Depends-On: Ib4556d09c4d393269e32771aab00f59a5f630e1b
Depends-On: Id4589a597ccfc4266b3e63d10f75b146aa7a287a
Change-Id: I21acb46cdd244a39b5cc6963aa763f0113bd1e38
2021-12-27 17:33:21 +00:00
Bartosz Dziewoński ea786ce9dc Re-apply "Make each gadget a separate preference, instead of one huge multiselect"
Previously attempted in 82281d82d0,
reverted in 7c4ac597e2.

This gives each section and each gadget's entry an `id` attribute,
which can be used for linking, as requested in T126962. Existing user
options still match the new preferences.

It also probably makes future improvements easier. No one understands
multiselects with subsections.

Bug: T126962
Change-Id: Ie96fd94c994d05ab8507920fa560c7ed9c1f9b69
2021-11-05 23:15:45 +01:00
Krinkle 7c4ac597e2 Revert "Make each gadget a separate preference, instead of one huge multiselect"
This reverts commit 82281d82d0.

Bug: T126962
Bug: T292777
Change-Id: I7c858b8c4bc12626ea1d53374ea4d75862f684ff
2021-10-07 19:52:18 +00:00
Bartosz Dziewoński 82281d82d0 Make each gadget a separate preference, instead of one huge multiselect
This gives each section and each gadget's entry an `id` attribute,
which can be used for linking, as requested in T126962. Existing user
options still match the new preferences.

It also probably makes future improvements easier. No one understands
multiselects with subsections.

Bug: T126962
Change-Id: Ifaca96e288c475017636c2408712d6a20aa77da9
2021-09-30 18:39:41 +02:00
libraryupgrader b5e7230698 build: Updating mediawiki/mediawiki-codesniffer to 37.0.0
Change-Id: Id55b598a81bd22cbe0f415f32fd28ba3825bf61e
2021-07-22 20:01:41 +00:00
Umherirrender e9f6ea3492 Reduce message parse in GadgetHooks::getPreferences (second time)
Multiselect can build by message keys only and allows to parse them.

This reverts fix for T32182, there is no way to handle the dir on each
item/checkbox at the moment

Reintroduce Iccd6202c443bd699aa3a911c8ba36a2b7bcdcfed (reverted by
I1cf3c7c61e9e90567587350639590691add1af34)

Bug: T58633
Bug: T278650
Depends-On: I8f52f21ae2641ddcad1aa85ce6bf14de1a09ab4b
Change-Id: If71008195f58faff9f302f7ea2bf9dbb1a527844
2021-05-28 20:52:58 +02:00
libraryupgrader c3c98c1146 build: Updating composer dependencies
* mediawiki/mediawiki-codesniffer: 35.0.0 → 36.0.0
* php-parallel-lint/php-parallel-lint: 1.2.0 → 1.3.0

Change-Id: I5e0b9e78f0436355cc21dc356fb78e96e59cb536
2021-05-04 18:43:54 +00:00
Jforrester b50309db2c Revert "Reduce message parse in GadgetHooks::getPreferences"
This reverts commit 662c63882c.

Reason for revert: plain() is too plain for our needs, sadly.

Change-Id: I1cf3c7c61e9e90567587350639590691add1af34
2021-04-21 21:55:32 +00:00
Umherirrender 662c63882c Reduce message parse in GadgetHooks::getPreferences
Multiselect can build by message keys only

This reverts fix for T32182, there is no way to handle the dir on each
item/checkbox at the moment

Bug: T58633
Bug: T278650
Depends-On: Ie983757081dc39f3685ba5b01b02bd124880e1af
Change-Id: Iccd6202c443bd699aa3a911c8ba36a2b7bcdcfed
2021-04-20 18:49:19 +00:00
libraryupgrader b95f062426 build: Updating dependencies
composer:
* mediawiki/mediawiki-codesniffer: 34.0.0 → 35.0.0
* mediawiki/minus-x: 1.1.0 → 1.1.1

npm:
* eslint-config-wikimedia: 0.17.0 → 0.18.1

Additional changes:
* Added the "composer phan" command to conveniently run phan.
* Removing manual extensions for eslint.

Change-Id: Ia5e47e750485b1499c9a0899407e24bfdfddacd4
2021-01-29 13:35:14 +00:00
libraryupgrader d9afecbd84 build: Updating mediawiki/mediawiki-codesniffer to 29.0.0
The following sniffs are failing and were disabled:
* MediaWiki.Commenting.FunctionComment.MissingDocumentationPrivate

Additional changes:
* Also sorted "composer fix" command to run phpcbf last.

Change-Id: I5fa8001a2ea7fdab2dbf9ce8cba9d1764f7a4562
2020-01-14 05:38:11 +00:00
James D. Forrester ed181c2db0 build: Upgrade mediawiki-codesniffer to v28.0.0
Change-Id: I61896470e0dc9cffd3e8fff8b45e2231ef4265f3
2019-10-09 16:24:09 -07:00
Derk-Jan Hartman 2008def806 Only queue gadget module if relevant on the current target
Bug: T171180
Depends-On: Ibe693bb6a84bdf56fd22d1ea1f0b798094b91c62
Change-Id: Ibce4d642c87651880f3c981dfa0d68def3bddd3a
2019-10-02 19:43:15 +00:00
Max Semenik 7d1b74d8c7 Split tests to unit and integration
Change-Id: Ib703086c38b6b1ca13f37504c5b6eab6834694b8
2019-07-23 02:23:41 -07:00
Max Semenik 2470a59218 Hook handlers don't always need to return something
And other minor fixes to hook signatures.

Change-Id: Ib6d8c9dff5bb79386ac88828ba2a57a9bf81ee71
2019-07-23 02:23:27 -07:00
jenkins-bot ef4c537d9e Merge "Fix skins option to use currently displayed skin, rather than user preference" 2018-08-03 18:53:39 +00:00
Matt Russell b340532c52 Fix skins option to use currently displayed skin, rather than user preference
The user's preference usually reflects the displayed skin, however this isn't
true if the `useskin` URL query is set, or MobileFrontend is being used.

This fixes gadgets being displayed on the wrong skin when using `useskin`,
and allows mobile-specific gadgets (using `skins=minerva`).

Testing if the gadget is allowed in the current skin is split out from
`isAllowed` to `isSkinSupported` to enable a future patch showing gadgets
on preferences regardless of if they are allowed on the current skin.
Test coverage is added for both functions.

Also fixed another test which wasn't working, presumably because the placeholder
user didn't have the "read" right, so the section wasn't being kept.

Bug: T199478
Change-Id: I21febe92d54d6d0b89925f902581cc2739d824fb
2018-08-01 11:06:17 +10:00
Thiemo Kreuz bede1c0178 More loose @covers annotations in GadgetTest
This is more an integration test than anything. The @covers tags I found
are to strict, in my opinion. These test cases cover more code.

Change-Id: I6cef7ce0c612ac3dfbb855c495032df1fe96f4af
2018-07-31 18:38:26 +02:00
Kunal Mehta 677d4e932c Move classes into includes/
Change-Id: I10bc5234ad2ebeed2514aafc3dbe2a0afa983bd8
2018-02-25 11:19:23 +00:00
Timo Tijhof eabfab52e0 tests: Add @covers tags
Change-Id: Ia3e18e7149292cd23765636111acc846564bf6cc
2018-01-05 00:11:10 +00:00
Umherirrender f102194baf Add phpcs and make pass
Change-Id: I02b7f85f54ffaf8a1c9d5bed6fa20abb1627afe5
2017-05-31 16:36:45 +02:00
Thiemo Mättig 6b22f1089e Use …->assertArrayHasKey() instead of isset()
… as well as update a line of documentation I had stashed. I think this
does not need it's own patch, or does it?

Change-Id: I99eee1f7b5ec96c1c75e73d66200bc41807452fa
2017-05-31 07:52:18 +00:00
Timo Tijhof 3dd92c6f76 Remove duplicate loading of styles (assume type=general if content is mixed)
Follows-up dc834f3, dc4ea6c.

Bug: T92459
Bug: T42284
Change-Id: I94dbdb052a78bbbc3c1b7b8bb8805a5f327670d9
2017-05-12 21:44:42 +00:00
Gergő Tisza b5befcbbe2 Switch TestingAccessWrapper to librarized version
Bug: T163434
Change-Id: I493d9b28d2c0d265e003a9851746eb07c7d15770
Depends-On: I52cc257e593da3d6c3b01a909e554a950225aec8
2017-04-20 11:35:09 +00:00
Fomafix 1a569b590b Convert PHP syntax from array() to []
Performed using:
find . -name \*.php -exec php ~/convert.php -w "{}" \;

Script from:
https://github.com/thomasbachem/php-short-array-syntax-converter

And convert syntax in comments manually.

Change-Id: I7ea9e57f9ab1250c8687885ad9e010771603bf78
2016-12-28 13:51:30 +01:00
Timo Tijhof 27a0ca6568 Implement support for 'hidden' feature in MediaWikiGadgetsDefinitionRepo
Follows-up 152484566, which added support for it in Gadgets 2.0, but
it's easy enough to make it work in existing definitions as well.

That way, people can stop using 'rights=hidden' hacks.

Bug: T33150
Change-Id: Idd6944a9ad38279e117c1a02a4b5fd0343455ba0
2016-11-22 23:46:38 +00:00
Timo Tijhof 846b979578 Remove redundant 'position', 'top', and getPosition() code
Unused as of bc374082fa in MediaWiki core (T109837).

Change-Id: Idcec3c4fa2bc3bc05ac417062139794880040a6d
2016-11-18 13:55:30 -08:00
Timo Tijhof 906aaeeb82 Default to type=general for styles-only gadgets having dependencies
Bug: T147726
Change-Id: I4153851b0e2f5cc067b1f31a7cd80f73d0620d7c
2016-11-16 17:53:10 -08:00
Timo Tijhof dc834f3933 Implement support for specifying type=styles
T87871 formally introduced the concept of a styles module,
which sets mw.loader.state to "ready" when loaded through addModuleStyles().

Previously, addModuleStyles couldn't safely do that because a module may
contain scripts also, in which case mw.loader must still load the (rest)
of the module (causes styles to load twice).

In MediaWiki core or extensions this is easily avoided by calling not
calling both addModules() and addModuleStyles().

For Gadgets we call both as a workaround to allow users to provide styles
(without a FOUC), but also to provide scripts+styles. Since we don't declare
which one is intended (and some gadgets do both), we loaded them both ways.
This will no longer be allowed in the future (see T92459).

The new 'type=styles' Gadget attribute promises to ResourceLoader that a
gadget only contains styles.

Impact:

* [Bug fix] When mw.loader requires a styles module that already loaded,
            it will not load again.

* [Feature] It is possible for a general scripts+styles gadget to depend on
            a styles gadget. Previously this caused the styles to load twice.

* Specifying type=styles will load the module through addModuleStyles() only.

  Use this for modules that contain styles that relate to elements already
  on the page (e.g. when customising the skin, layout, or article content).

* Specifying type=general will load the module through addModules() only.

  Use this if your module contains both scripts and styles and the styles
  only relate to elements created by the script. This means the styles do not
  need to be loaded separately through addModuleStyles() and will not apply
  to noscript mode.

Effective difference:

* Gadgets with only styles: We assume type=styles.

  This fixes the main bug (styles loading twice) and requires no migration!

* Gadgets with only scripts: We assume type=general.

  This requires no migration! (And: No more empty stylesheet request)

* Gadgets with scripts (with or without styles): We assume type=general, but
  unless type=general was explicitly set we'll still load it both ways so
  that the styles apply directly on page load.

  If this is not needed, set type=general.

  If this is needed, it should become two separate modules. We do not support
  a single module having two purposes (1: apply styles to the page,
  2: provide scripts+styles). The styles module should be separate.
  It can be made hidden, and listed as dependency of the other module.

The latter case is detected on page load and results in a console warning
with a link to T42284.

Bug: T42284
Bug: T92459
Change-Id: Ia3c9ddee243f710022144fc2884434350695699a
2016-09-30 10:43:29 +00:00
Reedy 34795a8803 Remove 'UnitTestList' hook
No longer needed now that extension unittests are autodiscovered.

Bug: T142120
Bug: T142121
Change-Id: I89cfc1ea3e652ebec1cd67f62810586c4ef49574
2016-08-06 01:14:53 -07:00