2015-08-03 06:37:32 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
*/
|
|
|
|
|
2022-02-06 18:54:47 +00:00
|
|
|
namespace MediaWiki\Extension\Gadgets\Content;
|
|
|
|
|
2024-10-19 23:15:50 +00:00
|
|
|
use MediaWiki\Content\Content;
|
|
|
|
use MediaWiki\Content\JsonContentHandler;
|
2021-10-07 10:09:05 +00:00
|
|
|
use MediaWiki\Content\Renderer\ContentParseParams;
|
Replace EditFilterMergedContent hook with ContentHandler override
The reason for this hook is not the validation itself, because that
is already done by `GadgetDefinitionContent->isValid` which is part
of the core Content interface, already enforced by ContentHandler.
Instead, the hook was here to provide the custom interface message
GadgetDefinitionValidator, because the core Content interface is
limited to boolean isValid(), which provides a very generic error
message.
However, nowadays ContentHandler exposes this mechanism directly
such that we can directly attach a custom message to it without
needing to wait for the stack to reach the EditPage and then override
it after the fact from a global hook.
Also:
* Simplify validation logic towards "is" checks with only an
expected description.
* Move schema.json file to top-level file.
It has been unused for as long as it has been in the repo, despite
appearing (due to its placement) to be used as part of the source.
It was added, I believe, with the intent to be used by the validator,
but it isn't. It also isn't validated or checked for correctness
by anything right now.
For now, keep it as informal schema in the top-level location for
easy discovery where perhaps others can find a use for it.
SD0001 mentions gadget developers may want to start using it for
Git-maintained gadgets to help with validation in their IDE, after
Gadgets 2.0 is launched.
Test Plan:
* Set `$wgGadgetsRepo = 'json+definition';`
* Create `MediaWiki:Gadgets/example.json`
* Attempt to save "x" in settings.namespaces item.
* Attempt to save "x.zip" in module.pages item.
* Fails with this patch, similar as on master.
Bug: T31272
Change-Id: I61bc3e40348a0aeb3bd3fa9ca86ccb7b93304095
2024-03-26 21:06:26 +00:00
|
|
|
use MediaWiki\Content\ValidationParams;
|
2024-02-09 19:03:36 +00:00
|
|
|
use MediaWiki\Extension\Gadgets\GadgetRepo;
|
Goodbye Gadget/Gadget_definition namespaces!
== What ==
* Remove the empty Gadget and Gadget_definition namespaces.
* Remove the "gadgets-definition-edit" user right.
* Remove need for custom namespace permissions that previously
had to extend editsitejs to apply to NS_GADGET.
== Why ==
Simplify the (unused) "GadgetDefinitionNamespaceRepo" backend for
Gadgets 2.0 by making it less radically different from the status quo.
The experimental 2.0 branch will now make use of the "gadget definition"
content model via "MediaWiki:Gadgets/<id>.json" pages, instead of
through a dedicated namespace.
When I first worked the Gadgets 2.0 branch, content models
were not a thing in MediaWiki, and interface-admin wasn't a thing yet
either. Now that we have per-page permissions and per-page content
models, we don't really need a separate namespace.
This follows the principle of least surprise, and fits well with other
interface admin and site configuration tools such as:
- Citoid, MediaWiki:Citoid-template-type-map.json,
- VisualEditor, MediaWiki:Visualeditor-template-tools-definition.json,
- AbuseFilter, MediaWiki:BlockedExternalDomains.json,
- the upcoming "Community Config" initiative.
If/when we develop the SpecialPage GUI for editing gadget definitions,
this can save its data to these pages the same as it would in
any other namespace. Similar to how Special:BlockedExternalDomains
operates on MediaWiki:BlockedExternalDomains.json.
See also bf1d6b3e93 (I6ffd5e9467), which recently removed the
gadgets-edit user right in favour of the editsite{css,js,json} rights.
Change-Id: I5b04ab251552e839087d0a8a6923d205adc7f771
2023-12-05 23:28:45 +00:00
|
|
|
use MediaWiki\Extension\Gadgets\MediaWikiGadgetsJsonRepo;
|
2024-10-19 23:15:50 +00:00
|
|
|
use MediaWiki\Json\FormatJson;
|
2024-01-06 16:45:07 +00:00
|
|
|
use MediaWiki\Linker\Linker;
|
|
|
|
use MediaWiki\Parser\ParserOutput;
|
2023-08-19 04:15:51 +00:00
|
|
|
use MediaWiki\Title\Title;
|
Replace EditFilterMergedContent hook with ContentHandler override
The reason for this hook is not the validation itself, because that
is already done by `GadgetDefinitionContent->isValid` which is part
of the core Content interface, already enforced by ContentHandler.
Instead, the hook was here to provide the custom interface message
GadgetDefinitionValidator, because the core Content interface is
limited to boolean isValid(), which provides a very generic error
message.
However, nowadays ContentHandler exposes this mechanism directly
such that we can directly attach a custom message to it without
needing to wait for the stack to reach the EditPage and then override
it after the fact from a global hook.
Also:
* Simplify validation logic towards "is" checks with only an
expected description.
* Move schema.json file to top-level file.
It has been unused for as long as it has been in the repo, despite
appearing (due to its placement) to be used as part of the source.
It was added, I believe, with the intent to be used by the validator,
but it isn't. It also isn't validated or checked for correctness
by anything right now.
For now, keep it as informal schema in the top-level location for
easy discovery where perhaps others can find a use for it.
SD0001 mentions gadget developers may want to start using it for
Git-maintained gadgets to help with validation in their IDE, after
Gadgets 2.0 is launched.
Test Plan:
* Set `$wgGadgetsRepo = 'json+definition';`
* Create `MediaWiki:Gadgets/example.json`
* Attempt to save "x" in settings.namespaces item.
* Attempt to save "x.zip" in module.pages item.
* Fails with this patch, similar as on master.
Bug: T31272
Change-Id: I61bc3e40348a0aeb3bd3fa9ca86ccb7b93304095
2024-03-26 21:06:26 +00:00
|
|
|
use StatusValue;
|
2021-07-15 14:40:45 +00:00
|
|
|
|
2015-08-03 06:37:32 +00:00
|
|
|
class GadgetDefinitionContentHandler extends JsonContentHandler {
|
2024-02-09 19:03:36 +00:00
|
|
|
private GadgetRepo $gadgetRepo;
|
|
|
|
|
|
|
|
public function __construct( string $modelId, GadgetRepo $gadgetRepo ) {
|
|
|
|
parent::__construct( $modelId );
|
|
|
|
$this->gadgetRepo = $gadgetRepo;
|
2015-08-03 06:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Title $title
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function canBeUsedOn( Title $title ) {
|
Goodbye Gadget/Gadget_definition namespaces!
== What ==
* Remove the empty Gadget and Gadget_definition namespaces.
* Remove the "gadgets-definition-edit" user right.
* Remove need for custom namespace permissions that previously
had to extend editsitejs to apply to NS_GADGET.
== Why ==
Simplify the (unused) "GadgetDefinitionNamespaceRepo" backend for
Gadgets 2.0 by making it less radically different from the status quo.
The experimental 2.0 branch will now make use of the "gadget definition"
content model via "MediaWiki:Gadgets/<id>.json" pages, instead of
through a dedicated namespace.
When I first worked the Gadgets 2.0 branch, content models
were not a thing in MediaWiki, and interface-admin wasn't a thing yet
either. Now that we have per-page permissions and per-page content
models, we don't really need a separate namespace.
This follows the principle of least surprise, and fits well with other
interface admin and site configuration tools such as:
- Citoid, MediaWiki:Citoid-template-type-map.json,
- VisualEditor, MediaWiki:Visualeditor-template-tools-definition.json,
- AbuseFilter, MediaWiki:BlockedExternalDomains.json,
- the upcoming "Community Config" initiative.
If/when we develop the SpecialPage GUI for editing gadget definitions,
this can save its data to these pages the same as it would in
any other namespace. Similar to how Special:BlockedExternalDomains
operates on MediaWiki:BlockedExternalDomains.json.
See also bf1d6b3e93 (I6ffd5e9467), which recently removed the
gadgets-edit user right in favour of the editsite{css,js,json} rights.
Change-Id: I5b04ab251552e839087d0a8a6923d205adc7f771
2023-12-05 23:28:45 +00:00
|
|
|
return MediaWikiGadgetsJsonRepo::isGadgetDefinitionTitle( $title );
|
2015-08-03 06:37:32 +00:00
|
|
|
}
|
|
|
|
|
2023-11-20 13:06:57 +00:00
|
|
|
/** @inheritDoc */
|
2015-08-03 06:37:32 +00:00
|
|
|
protected function getContentClass() {
|
2021-04-08 18:34:17 +00:00
|
|
|
return GadgetDefinitionContent::class;
|
2015-08-03 06:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function makeEmptyContent() {
|
|
|
|
$class = $this->getContentClass();
|
2023-12-13 10:08:16 +00:00
|
|
|
return new $class( FormatJson::encode( $this->getEmptyDefinition(), "\t" ) );
|
|
|
|
}
|
|
|
|
|
Replace EditFilterMergedContent hook with ContentHandler override
The reason for this hook is not the validation itself, because that
is already done by `GadgetDefinitionContent->isValid` which is part
of the core Content interface, already enforced by ContentHandler.
Instead, the hook was here to provide the custom interface message
GadgetDefinitionValidator, because the core Content interface is
limited to boolean isValid(), which provides a very generic error
message.
However, nowadays ContentHandler exposes this mechanism directly
such that we can directly attach a custom message to it without
needing to wait for the stack to reach the EditPage and then override
it after the fact from a global hook.
Also:
* Simplify validation logic towards "is" checks with only an
expected description.
* Move schema.json file to top-level file.
It has been unused for as long as it has been in the repo, despite
appearing (due to its placement) to be used as part of the source.
It was added, I believe, with the intent to be used by the validator,
but it isn't. It also isn't validated or checked for correctness
by anything right now.
For now, keep it as informal schema in the top-level location for
easy discovery where perhaps others can find a use for it.
SD0001 mentions gadget developers may want to start using it for
Git-maintained gadgets to help with validation in their IDE, after
Gadgets 2.0 is launched.
Test Plan:
* Set `$wgGadgetsRepo = 'json+definition';`
* Create `MediaWiki:Gadgets/example.json`
* Attempt to save "x" in settings.namespaces item.
* Attempt to save "x.zip" in module.pages item.
* Fails with this patch, similar as on master.
Bug: T31272
Change-Id: I61bc3e40348a0aeb3bd3fa9ca86ccb7b93304095
2024-03-26 21:06:26 +00:00
|
|
|
/**
|
|
|
|
* @param Content $content
|
|
|
|
* @param ValidationParams $validationParams
|
|
|
|
* @return StatusValue
|
|
|
|
*/
|
|
|
|
public function validateSave( Content $content, ValidationParams $validationParams ) {
|
|
|
|
$status = parent::validateSave( $content, $validationParams );
|
|
|
|
'@phan-var GadgetDefinitionContent $content';
|
|
|
|
if ( !$status->isOK() ) {
|
|
|
|
return $content->validate();
|
|
|
|
}
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
|
2023-12-13 10:08:16 +00:00
|
|
|
public function getEmptyDefinition() {
|
|
|
|
return [
|
|
|
|
'settings' => [
|
|
|
|
'category' => '',
|
|
|
|
],
|
|
|
|
'module' => [
|
|
|
|
'pages' => [],
|
|
|
|
'dependencies' => [],
|
|
|
|
]
|
|
|
|
];
|
2015-08-03 06:37:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getDefaultMetadata() {
|
2016-12-28 10:25:47 +00:00
|
|
|
return [
|
|
|
|
'settings' => [
|
|
|
|
'rights' => [],
|
2015-08-03 06:37:32 +00:00
|
|
|
'default' => false,
|
2021-10-17 13:05:15 +00:00
|
|
|
'package' => false,
|
2022-01-30 13:15:25 +00:00
|
|
|
'requiresES6' => false,
|
2015-08-03 06:37:32 +00:00
|
|
|
'hidden' => false,
|
2016-12-28 10:25:47 +00:00
|
|
|
'skins' => [],
|
2021-12-14 13:10:22 +00:00
|
|
|
'actions' => [],
|
2020-09-04 03:42:31 +00:00
|
|
|
'namespaces' => [],
|
2024-02-20 13:55:52 +00:00
|
|
|
'categories' => [],
|
2023-05-22 08:41:15 +00:00
|
|
|
'contentModels' => [],
|
2022-01-11 09:03:44 +00:00
|
|
|
'category' => '',
|
|
|
|
'supportsUrlLoad' => false,
|
2016-12-28 10:25:47 +00:00
|
|
|
],
|
|
|
|
'module' => [
|
2023-12-11 17:16:30 +00:00
|
|
|
'pages' => [],
|
2016-11-18 04:54:17 +00:00
|
|
|
'peers' => [],
|
2016-12-28 10:25:47 +00:00
|
|
|
'dependencies' => [],
|
|
|
|
'messages' => [],
|
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-01 23:31:14 +00:00
|
|
|
'type' => '',
|
2016-12-28 10:25:47 +00:00
|
|
|
],
|
|
|
|
];
|
2015-08-03 06:37:32 +00:00
|
|
|
}
|
2021-07-15 14:40:45 +00:00
|
|
|
|
2021-10-07 10:09:05 +00:00
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function fillParserOutput(
|
|
|
|
Content $content,
|
|
|
|
ContentParseParams $cpoParams,
|
2022-01-20 18:12:33 +00:00
|
|
|
ParserOutput &$parserOutput
|
2021-10-07 10:09:05 +00:00
|
|
|
) {
|
|
|
|
'@phan-var GadgetDefinitionContent $content';
|
2016-02-16 19:38:44 +00:00
|
|
|
// Create a deep clone. FIXME: unserialize(serialize()) is hacky.
|
|
|
|
$data = unserialize( serialize( $content->getData()->getValue() ) );
|
|
|
|
if ( $data !== null ) {
|
2023-12-11 17:16:30 +00:00
|
|
|
if ( isset( $data->module->pages ) ) {
|
|
|
|
foreach ( $data->module->pages as &$page ) {
|
Goodbye Gadget/Gadget_definition namespaces!
== What ==
* Remove the empty Gadget and Gadget_definition namespaces.
* Remove the "gadgets-definition-edit" user right.
* Remove need for custom namespace permissions that previously
had to extend editsitejs to apply to NS_GADGET.
== Why ==
Simplify the (unused) "GadgetDefinitionNamespaceRepo" backend for
Gadgets 2.0 by making it less radically different from the status quo.
The experimental 2.0 branch will now make use of the "gadget definition"
content model via "MediaWiki:Gadgets/<id>.json" pages, instead of
through a dedicated namespace.
When I first worked the Gadgets 2.0 branch, content models
were not a thing in MediaWiki, and interface-admin wasn't a thing yet
either. Now that we have per-page permissions and per-page content
models, we don't really need a separate namespace.
This follows the principle of least surprise, and fits well with other
interface admin and site configuration tools such as:
- Citoid, MediaWiki:Citoid-template-type-map.json,
- VisualEditor, MediaWiki:Visualeditor-template-tools-definition.json,
- AbuseFilter, MediaWiki:BlockedExternalDomains.json,
- the upcoming "Community Config" initiative.
If/when we develop the SpecialPage GUI for editing gadget definitions,
this can save its data to these pages the same as it would in
any other namespace. Similar to how Special:BlockedExternalDomains
operates on MediaWiki:BlockedExternalDomains.json.
See also bf1d6b3e93 (I6ffd5e9467), which recently removed the
gadgets-edit user right in favour of the editsite{css,js,json} rights.
Change-Id: I5b04ab251552e839087d0a8a6923d205adc7f771
2023-12-05 23:28:45 +00:00
|
|
|
$title = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-$page" );
|
2023-12-11 17:16:30 +00:00
|
|
|
$this->makeLink( $parserOutput, $page, $title );
|
2021-10-07 10:09:05 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-13 10:08:16 +00:00
|
|
|
if ( isset( $data->module->dependencies ) ) {
|
|
|
|
foreach ( $data->module->dependencies as &$dep ) {
|
|
|
|
if ( str_starts_with( $dep, 'ext.gadget.' ) ) {
|
|
|
|
$gadgetId = explode( 'ext.gadget.', $dep )[ 1 ];
|
2024-02-09 19:03:36 +00:00
|
|
|
$title = $this->gadgetRepo->getGadgetDefinitionTitle( $gadgetId );
|
Goodbye Gadget/Gadget_definition namespaces!
== What ==
* Remove the empty Gadget and Gadget_definition namespaces.
* Remove the "gadgets-definition-edit" user right.
* Remove need for custom namespace permissions that previously
had to extend editsitejs to apply to NS_GADGET.
== Why ==
Simplify the (unused) "GadgetDefinitionNamespaceRepo" backend for
Gadgets 2.0 by making it less radically different from the status quo.
The experimental 2.0 branch will now make use of the "gadget definition"
content model via "MediaWiki:Gadgets/<id>.json" pages, instead of
through a dedicated namespace.
When I first worked the Gadgets 2.0 branch, content models
were not a thing in MediaWiki, and interface-admin wasn't a thing yet
either. Now that we have per-page permissions and per-page content
models, we don't really need a separate namespace.
This follows the principle of least surprise, and fits well with other
interface admin and site configuration tools such as:
- Citoid, MediaWiki:Citoid-template-type-map.json,
- VisualEditor, MediaWiki:Visualeditor-template-tools-definition.json,
- AbuseFilter, MediaWiki:BlockedExternalDomains.json,
- the upcoming "Community Config" initiative.
If/when we develop the SpecialPage GUI for editing gadget definitions,
this can save its data to these pages the same as it would in
any other namespace. Similar to how Special:BlockedExternalDomains
operates on MediaWiki:BlockedExternalDomains.json.
See also bf1d6b3e93 (I6ffd5e9467), which recently removed the
gadgets-edit user right in favour of the editsite{css,js,json} rights.
Change-Id: I5b04ab251552e839087d0a8a6923d205adc7f771
2023-12-05 23:28:45 +00:00
|
|
|
if ( $title ) {
|
|
|
|
$this->makeLink( $parserOutput, $dep, $title );
|
|
|
|
}
|
2023-12-13 10:08:16 +00:00
|
|
|
}
|
2016-02-16 19:38:44 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-13 10:08:16 +00:00
|
|
|
if ( isset( $data->module->peers ) ) {
|
|
|
|
foreach ( $data->module->peers as &$peer ) {
|
2024-02-09 19:03:36 +00:00
|
|
|
$title = $this->gadgetRepo->getGadgetDefinitionTitle( $peer );
|
Goodbye Gadget/Gadget_definition namespaces!
== What ==
* Remove the empty Gadget and Gadget_definition namespaces.
* Remove the "gadgets-definition-edit" user right.
* Remove need for custom namespace permissions that previously
had to extend editsitejs to apply to NS_GADGET.
== Why ==
Simplify the (unused) "GadgetDefinitionNamespaceRepo" backend for
Gadgets 2.0 by making it less radically different from the status quo.
The experimental 2.0 branch will now make use of the "gadget definition"
content model via "MediaWiki:Gadgets/<id>.json" pages, instead of
through a dedicated namespace.
When I first worked the Gadgets 2.0 branch, content models
were not a thing in MediaWiki, and interface-admin wasn't a thing yet
either. Now that we have per-page permissions and per-page content
models, we don't really need a separate namespace.
This follows the principle of least surprise, and fits well with other
interface admin and site configuration tools such as:
- Citoid, MediaWiki:Citoid-template-type-map.json,
- VisualEditor, MediaWiki:Visualeditor-template-tools-definition.json,
- AbuseFilter, MediaWiki:BlockedExternalDomains.json,
- the upcoming "Community Config" initiative.
If/when we develop the SpecialPage GUI for editing gadget definitions,
this can save its data to these pages the same as it would in
any other namespace. Similar to how Special:BlockedExternalDomains
operates on MediaWiki:BlockedExternalDomains.json.
See also bf1d6b3e93 (I6ffd5e9467), which recently removed the
gadgets-edit user right in favour of the editsite{css,js,json} rights.
Change-Id: I5b04ab251552e839087d0a8a6923d205adc7f771
2023-12-05 23:28:45 +00:00
|
|
|
if ( $title ) {
|
|
|
|
$this->makeLink( $parserOutput, $peer, $title );
|
|
|
|
}
|
2023-12-13 10:08:16 +00:00
|
|
|
}
|
2016-02-16 19:38:44 +00:00
|
|
|
}
|
2023-12-13 10:08:16 +00:00
|
|
|
if ( isset( $data->module->messages ) ) {
|
|
|
|
foreach ( $data->module->messages as &$msg ) {
|
|
|
|
$title = Title::makeTitleSafe( NS_MEDIAWIKI, $msg );
|
|
|
|
$this->makeLink( $parserOutput, $msg, $title );
|
|
|
|
}
|
2016-02-16 19:38:44 +00:00
|
|
|
}
|
2023-12-13 10:08:16 +00:00
|
|
|
if ( isset( $data->settings->category ) && $data->settings->category ) {
|
2016-02-16 19:38:44 +00:00
|
|
|
$this->makeLink(
|
2022-01-20 18:12:33 +00:00
|
|
|
$parserOutput,
|
2016-02-16 19:38:44 +00:00
|
|
|
$data->settings->category,
|
|
|
|
Title::makeTitleSafe( NS_MEDIAWIKI, "gadget-section-" . $data->settings->category )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !$cpoParams->getGenerateHtml() || !$content->isValid() ) {
|
2022-01-20 18:12:33 +00:00
|
|
|
$parserOutput->setText( '' );
|
2016-02-16 19:38:44 +00:00
|
|
|
} else {
|
2022-01-20 18:12:33 +00:00
|
|
|
$parserOutput->setText( $content->rootValueTable( $data ) );
|
|
|
|
$parserOutput->addModuleStyles( [ 'mediawiki.content.json' ] );
|
2016-02-16 19:38:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a link on the page
|
2022-01-20 18:12:33 +00:00
|
|
|
* @param ParserOutput $parserOutput
|
2016-02-16 19:38:44 +00:00
|
|
|
* @param string &$text The text to link
|
|
|
|
* @param Title|null $title Link target title
|
|
|
|
* @return void
|
|
|
|
*/
|
2022-01-20 18:12:33 +00:00
|
|
|
private function makeLink( ParserOutput $parserOutput, string &$text, ?Title $title ) {
|
2016-02-16 19:38:44 +00:00
|
|
|
if ( $title ) {
|
2022-01-20 18:12:33 +00:00
|
|
|
$parserOutput->addLink( $title );
|
2016-02-16 19:38:44 +00:00
|
|
|
$text = new GadgetDefinitionContentArmor(
|
|
|
|
Linker::link( $title, htmlspecialchars( '"' . $text . '"' ) )
|
|
|
|
);
|
2021-10-07 10:09:05 +00:00
|
|
|
}
|
|
|
|
}
|
2015-08-03 06:37:32 +00:00
|
|
|
}
|