Compare commits

..

31 commits

Author SHA1 Message Date
OfficialCRUGG 4ca967ff4d chore: add readme 2024-02-02 15:08:31 +01:00
OfficialCRUGG 1499b9aa3c feat: remove style tags 2024-02-02 15:08:26 +01:00
Translation updater bot cdb35a545d Localisation updates from https://translatewiki.net.
Change-Id: I77d92242f931574eb50615a66f351baba4c2ab99
2024-01-30 09:38:55 +01:00
Translation updater bot 43a4771737 Localisation updates from https://translatewiki.net.
Change-Id: I6a044c5e55e485253e2e9b64d5d9266b7394c2eb
2024-01-28 16:06:10 +01:00
alex4401 050086dd6e Do not try to derive descriptions if one has been specified already
Skip running the generator on interface messages and if a description has already been set. This resolves some annoyances ranging from performance (relevant if the algorithm becomes more expensive to run) to multiple description meta tags being spawned.

This is part of my RemexHtml patch chain, which I've split up to avoid having a single commit alter the majority of the codebase. If it ends up being rejected, I can rebase this change to rid of dependencies on the rest of the chain.

Depends-On: I97fd065c9554837747021ba9fff26005e33270f4
Change-Id: I585f2c0046571310aad67f3ba148c4f22aaae49f
2024-01-12 08:28:31 +00:00
alex4401 b73fe26c29 Extract description algorithm into a new class
Separating the extract algorithm from integration code. This results in a slightly cleaner code structure (at least in my opinion) and enables adding alternate algorithms without devolving into spaghetti.

The DescriptionProvider (name of the new base interface) is exposed as a service through dependency injection to avoid factories. The implementation can be swapped at service instantiation time.

Depends-On: I73c61ce045dcf31ac1ca5888f1548de8fd8b56ff
Change-Id: I97fd065c9554837747021ba9fff26005e33270f4
2024-01-12 08:24:19 +00:00
alex4401 43eb47183e Switch to hook handlers and inject ConfigFactory
Moving hooks into a separate class, and using dependency injection for configuration. Due to hook interfaces being added in MW 1.35, this change also raises the MediaWiki requirement to >1.35.0.

This patch is a part of my RemexHtml deriver chain (split into multiple patches to avoid a single commit altering almost the entirety of the codebase), which raises the floor to 1.38 later. There's not really a point in merging this if the rest of the patch chain is declined.

Depends-On: I484feeb51beab0c2e06c9f958a1c15c40853b967
Change-Id: I73c61ce045dcf31ac1ca5888f1548de8fd8b56ff
2024-01-11 22:44:02 +00:00
alex4401 15f2edbaee Use namespace autoloading instead of manually tracking classes
This extension's classes have already been namespaced. Perhaps wrongly, but I don't see any showstoppers against using PSR-4 autoloading here.

Change-Id: I484feeb51beab0c2e06c9f958a1c15c40853b967
2023-12-07 15:37:32 +00:00
Translation updater bot 323c797f28 Localisation updates from https://translatewiki.net.
Change-Id: I2d4a3bc2a96f98c22d115c5a721a2a40ba8d5af6
2023-09-13 08:31:48 +02:00
Translation updater bot 1f10d667fe Localisation updates from https://translatewiki.net.
Change-Id: Id6bd7d7432289c887e6144f02c330d00b747048f
2023-07-31 08:57:09 +02:00
libraryupgrader 2d68312307 build: Updating grunt-banana-checker to 0.11.0
Change-Id: Ieaa8314b65d77e77367af692476a0bb03bd4a9ca
2023-06-01 04:19:12 +00:00
libraryupgrader 6cbe68fa54 build: Updating npm dependencies
* eslint-config-wikimedia: 0.24.0 → 0.25.0
* grunt-eslint: 24.0.0 → 24.0.1

Change-Id: Ia12348aa1098e03ee65fcffc3c7bde2d208a40bd
2023-05-04 01:54:14 +00:00
libraryupgrader cab185a2a6 build: Updating npm dependencies
* eslint-config-wikimedia: 0.22.1 → 0.24.0
* grunt: 1.5.3 → 1.6.1

Change-Id: I8240834199bd51f76664026759e27903b718fec5
2023-03-15 04:47:13 +00:00
libraryupgrader 4cd70b8e7e build: Updating mediawiki/mediawiki-codesniffer to 41.0.0
Change-Id: If0f4df5a40f2c5fbd63535b5d895d4a7934f265b
2023-03-12 00:41:07 +00:00
Translation updater bot 655b11d7ea Localisation updates from https://translatewiki.net.
Change-Id: I550012a6b7562a647cc3a87bc86ba19ef2199e67
2023-01-05 09:07:56 +01:00
Translation updater bot 4ba5e24b71 Localisation updates from https://translatewiki.net.
Change-Id: I41b7a5e2b0855b79da83eb4852398587f768603a
2022-12-21 09:14:56 +01:00
libraryupgrader dbc034f125 build: Updating mediawiki/mediawiki-codesniffer to 40.0.1
Change-Id: I8a3d0295a57e7cbb8776e637e3b191b3bc0ce60e
2022-11-16 04:50:22 +00:00
libraryupgrader e83256f305 build: Updating minimatch to 3.0.8
* https://github.com/advisories/GHSA-f8q6-p94x-37v3

Change-Id: Ie10e39d694879722b03e824626eed6494486aa74
2022-10-21 04:25:30 +00:00
libraryupgrader 6b4777721f build: Updating grunt-banana-checker to 0.10.0
Change-Id: I9488e108b555de13447db3a9e339f250330c2d09
2022-10-06 01:59:41 +00:00
libraryupgrader d2a5322a44 build: Updating grunt to 1.5.3
Change-Id: Ic14500ab823ac82074ca6eed50ea1abea65af98e
2022-05-26 10:07:42 +00:00
libraryupgrader 6eca5a303c build: Updating dependencies
composer:
* mediawiki/mediawiki-codesniffer: 38.0.0 → 39.0.0
* php-parallel-lint/php-console-highlighter: 0.5.0 → 1.0.0
* php-parallel-lint/php-parallel-lint: 1.3.1 → 1.3.2

npm:
* grunt-eslint: 23.0.0 → 24.0.0

Change-Id: Ic5c5cb36ad85238dbc5a1cbaec3f3ea0e3eda707
2022-05-21 02:41:53 +00:00
libraryupgrader bd9bc72317 build: Updating grunt to 1.5.2
Change-Id: I50c0ad5627d769697a5ff1d9e5b93511ad2177b9
2022-04-27 09:39:11 +00:00
libraryupgrader d53638e642 build: Updating npm dependencies
* eslint-config-wikimedia: 0.21.0 → 0.22.1
* async: 3.2.0 → 3.2.3
  * https://github.com/advisories/GHSA-fwr7-v2mv-hh25

Change-Id: I92726e9b0cd4bec2839c03366bd1b9a450028917
2022-04-15 02:51:41 +00:00
Translation updater bot 23e0582f58 Localisation updates from https://translatewiki.net.
Change-Id: I331d9b42ca98f0fea2f9598b89450f93b0d9cf95
2022-02-25 09:43:17 +01:00
C. Scott Ananian b269304773 ParserOutput::getPageProperty() now returns null when key is missing.
The return value of ParserOutput::getPageProperty() has transitioned
to returning `null` instead of `false` when the page property is missing.

Bug: T301915
Depends-On: Iaa25c390118d2db2b6578cdd558f2defd5351d15
Change-Id: I31d4115d75e080bb0177f30b2acf55ca2525a19d
2022-02-16 19:33:00 -05:00
C. Scott Ananian 84276905bc Update uses of ParserOutput::getPageProperty() to handle new return value
The return value of ParserOutput::getPageProperty() will transition to
returning `null` instead of `false` when the page property is missing.

Bug: T301915
Change-Id: Id95dbdd427310e4e1cf40330b149adfe2b68f848
2022-02-16 19:31:35 -05:00
libraryupgrader adc340542c build: Updating npm dependencies
* eslint-config-wikimedia: 0.20.0 → 0.21.0
* grunt: 1.4.0 → 1.4.1

Additional changes:
* Set `name` in package.json.

Change-Id: I80cb9a1386e4217c3d1721c1a76c556b31c9d3b1
2022-02-06 12:13:42 +00:00
Umherirrender 6d3b7ce782 Replace deprecated ParserOutput::getProperty
Change-Id: I9278120212bcd0c003af899ce9602c292edac947
2022-02-06 13:11:38 +01:00
Umherirrender 838ef90fe0 Set MediaWiki 1.31 as minimum requirement in extension.json
Added an old, but not to-outdated required version to keep a minimum
requirement

Change-Id: I7ffdf9c3246614521853c70fef6a2f0c105d7d3c
2021-12-10 13:18:23 +01:00
libraryupgrader 0c238dce47 build: Updating mediawiki/mediawiki-codesniffer to 38.0.0
Change-Id: Ic4ca68f9346bcf13083564704f183cf2e5168b3c
2021-10-24 02:10:21 +00:00
libraryupgrader f6c96a869c build: Updating dependencies
composer:
* php-parallel-lint/php-parallel-lint: 1.3.0 → 1.3.1

npm:
* ansi-regex: 5.0.0 → 5.0.1
  * https://npmjs.com/advisories/5197 (CVE-2021-3807)

Additional changes:
* composer.json: Updated phpcs command in composer test (T280592).
* composer.json: Added phpcs command to scripts (T280592).

Change-Id: I63b73115ccd5bc7539fbaa70dc60173eb827eb24
2021-10-04 17:36:49 +00:00
17 changed files with 2487 additions and 1222 deletions

14
README.md Normal file
View file

@ -0,0 +1,14 @@
# fanwikis/Description2
This is a fork of the MediaWiki Description2 extension maintained by the fanwikis.org Team with tweaks and improvements for use on fanwikis.org's MediaWiki installation.
## Changes
### Removing <style> tags
When using the TemplateStyles extension at the top of an article, the Description may end up being just CSS. This is not what we want, so we remove the <style> tags from the description.
```diff
- $pattern = '%<table\b[^>]*+>(?:(?R)|[^<]*+(?:(?!</?table\b)<[^<]*+)*+)*+</table>%i';
+ $pattern = '%<(table|style)\b[^>]*+>(?:(?R)|[^<]*+(?:(?!</?(table|style)\b)<[^<]*+)*+)*+</(table|style)>%i';
```

View file

@ -1,9 +1,9 @@
{
"require-dev": {
"mediawiki/mediawiki-codesniffer": "37.0.0",
"mediawiki/mediawiki-codesniffer": "41.0.0",
"mediawiki/minus-x": "1.1.1",
"php-parallel-lint/php-console-highlighter": "0.5.0",
"php-parallel-lint/php-parallel-lint": "1.3.0"
"php-parallel-lint/php-console-highlighter": "1.0.0",
"php-parallel-lint/php-parallel-lint": "1.3.2"
},
"scripts": {
"test": [

View file

@ -8,14 +8,20 @@
"descriptionmsg": "description2-desc",
"license-name": "GPL-2.0-or-later",
"type": "other",
"requires": {
"MediaWiki": ">= 1.35.0"
},
"config": {
"EnableMetaDescriptionFunctions": false
},
"ConfigRegistry": {
"Description2": "GlobalVarConfig::newInstance"
},
"AutoloadClasses": {
"MediaWiki\\Extension\\Description2\\Description2": "includes/Description2.php"
"ServiceWiringFiles": [
"includes/ServiceWiring.php"
],
"AutoloadNamespaces": {
"MediaWiki\\Extension\\Description2\\": "includes/"
},
"ExtensionMessagesFiles": {
"Description2Magic": "Description2.i18n.magic.php"
@ -25,10 +31,19 @@
"i18n"
]
},
"HookHandlers": {
"Description2": {
"class": "MediaWiki\\Extension\\Description2\\Hooks",
"services": [
"ConfigFactory",
"Description2.DescriptionProvider"
]
}
},
"Hooks": {
"OutputPageParserOutput": "MediaWiki\\Extension\\Description2\\Description2::onOutputPageParserOutput",
"ParserAfterTidy": "MediaWiki\\Extension\\Description2\\Description2::onParserAfterTidy",
"ParserFirstCallInit": "MediaWiki\\Extension\\Description2\\Description2::onParserFirstCallInit"
"OutputPageParserOutput": "Description2",
"ParserAfterTidy": "Description2",
"ParserFirstCallInit": "Description2"
},
"manifest_version": 1
}

View file

@ -1,8 +1,9 @@
{
"@metadata": {
"authors": [
"З. ӘЙЛЕ",
"Мухамадеева"
]
},
"description2-desc": " Башҡа киңлектәрҙә файҙаланыу өсөн MediaWiki һәм ParserOutput битенә һүрәтләү мета-тег - ын өҫтәй"
"description2-desc": "Башҡа киңәйтеүҙәрҙә файҙаланыу өсөн MediaWiki һәм ParserOutput битенә тасуирлау мета-тамғаһын өҫтәй"
}

View file

@ -1,8 +1,9 @@
{
"@metadata": {
"authors": [
"Cedric31"
"Cedric31",
"Lhanars"
]
},
"description2-desc": "Apond una metaetiqueta de descripcion a las paginas de MediaWiki e a ParserOutput per las autras extensions d'utilizar"
"description2-desc": "Apond una meta-etiqueta de descripcion a las paginas de MediaWiki e a ParserOutput per las autras extensions d'utilizar"
}

8
i18n/scn.json Normal file
View file

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Ajeje Brazorf"
]
},
"description2-desc": "Agghiunci nu meta-tag pâ discrizzioni dê pàggini MediaWiki e ntâ ParserOutput pi putiri èssiri usata d'àutri stinzioni"
}

View file

@ -1,7 +1,7 @@
{
"@metadata": {
"authors": [
"Vlad5250"
"Winston Sung"
]
},
"description2-desc": "Dodaje metaoznaku za opis u MediaWiki stranice i u parserski izlaz (ParserOutput) za uporabu od strane drugih dodataka"

8
i18n/sl.json Normal file
View file

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Eleassar"
]
},
"description2-desc": "Stranem MediaWiki in v ParserOutput doda opisno metaoznako, ki jo lahko uporabljajo druge razširitve"
}

6
i18n/sr-el.json Normal file
View file

@ -0,0 +1,6 @@
{
"@metadata": {
"authors": []
},
"description2-desc": "Dodaje metaoznaku opisa na Medijaviki stranice i u ParserOutput za upotrebu od strane drugih proširenja"
}

View file

@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"Base",
"DDPAT"
"DDPAT",
"Ice bulldog"
]
},
"description2-desc": "Додає мета-тег опису для сторінок MediaWiki і ParserOutput, для використання в інших розширеннях"

View file

@ -2,10 +2,7 @@
namespace MediaWiki\Extension\Description2;
use MediaWiki\MediaWikiServices;
use OutputPage;
use Parser;
use ParserOutput;
use PPFrame;
/**
@ -20,68 +17,24 @@ use PPFrame;
*/
class Description2 {
/**
* @param Parser $parser The parser.
* @param string $desc The description text.
*/
public static function setDescription( Parser $parser, $desc ) {
$parserOutput = $parser->getOutput();
if ( method_exists( $parserOutput, 'getPageProperty' ) ) {
// MW 1.38+
if ( $parserOutput->getPageProperty( 'description' ) !== null ) {
return;
}
$parserOutput->setPageProperty( 'description', $desc );
} else {
if ( $parserOutput->getProperty( 'description' ) !== false ) {
return;
}
$parserOutput->setProperty( 'description', $desc );
}
/**
* @link https://www.mediawiki.org/wiki/Manual:Hooks/ParserAfterTidy
* @param Parser &$parser The parser.
* @param string &$text The page text.
* @return bool
*/
public static function onParserAfterTidy( Parser &$parser, &$text ) {
$desc = '';
$pattern = '%<table\b[^>]*+>(?:(?R)|[^<]*+(?:(?!</?table\b)<[^<]*+)*+)*+</table>%i';
$myText = preg_replace( $pattern, '', $text );
$paragraphs = [];
if ( preg_match_all( '#<p>.*?</p>#is', $myText, $paragraphs ) ) {
foreach ( $paragraphs[0] as $paragraph ) {
$paragraph = trim( strip_tags( $paragraph ) );
if ( !$paragraph ) {
continue;
}
$desc = $paragraph;
break;
}
}
if ( $desc ) {
self::setDescription( $parser, $desc );
}
return true;
}
/**
* @param Parser &$parser The parser.
* @return bool
*/
public static function onParserFirstCallInit( Parser &$parser ) {
$config = MediaWikiServices::getInstance()
->getConfigFactory()
->makeConfig( 'Description2' );
if ( !$config->get( 'EnableMetaDescriptionFunctions' ) ) {
// Functions and tags are disabled
return true;
}
$parser->setFunctionHook(
'description2',
[ static::class, 'parserFunctionCallback' ],
Parser::SFH_OBJECT_ARGS
);
return true;
}
/**
@ -95,16 +48,4 @@ class Description2 {
self::setDescription( $parser, $desc );
return '';
}
/**
* @param OutputPage &$out The output page to add the meta element to.
* @param ParserOutput $parserOutput The parser output to get the description from.
*/
public static function onOutputPageParserOutput( OutputPage &$out, ParserOutput $parserOutput ) {
// Export the description from the main parser output into the OutputPage
$description = $parserOutput->getProperty( 'description' );
if ( $description !== false ) {
$out->addMeta( 'description', $description );
}
}
}

View file

@ -0,0 +1,13 @@
<?php
namespace MediaWiki\Extension\Description2;
interface DescriptionProvider {
/**
* Extracts description from the HTML representation of a page.
*
* @param string $text HTML to extract the description from.
* @return ?string
*/
public function derive( string $text ): ?string;
}

116
includes/Hooks.php Normal file
View file

@ -0,0 +1,116 @@
<?php
namespace MediaWiki\Extension\Description2;
use Config;
use ConfigFactory;
use OutputPage;
use Parser;
use ParserOutput;
/**
* Description2 Adds meaningful description <meta> tag to MW pages and into the parser output
*
* @file
* @ingroup Extensions
* @author Daniel Friesen (http://danf.ca/mw/)
* @copyright Copyright 2010 Daniel Friesen
* @license GPL-2.0-or-later
* @link https://www.mediawiki.org/wiki/Extension:Description2 Documentation
*/
class Hooks implements
\MediaWiki\Hook\ParserAfterTidyHook,
\MediaWiki\Hook\ParserFirstCallInitHook,
\MediaWiki\Hook\OutputPageParserOutputHook
{
/** @var Config */
private Config $config;
/** @var DescriptionProvider */
private DescriptionProvider $descriptionProvider;
/**
* @param ConfigFactory $configFactory
*/
public function __construct(
ConfigFactory $configFactory,
DescriptionProvider $descriptionProvider
) {
$this->config = $configFactory->makeConfig( 'Description2' );
$this->descriptionProvider = $descriptionProvider;
}
/**
* @link https://www.mediawiki.org/wiki/Manual:Hooks/ParserAfterTidy
* @param Parser $parser The parser.
* @param string &$text The page text.
* @return bool
*/
public function onParserAfterTidy( $parser, &$text ) {
$parserOutput = $parser->getOutput();
// Avoid running the algorithm on interface messages which may waste time
if ( $parser->getOptions()->getInterfaceMessage() ) {
return true;
}
// Avoid running the algorithm multiple times if we already have determined the description. This may happen
// on file pages.
if ( method_exists( $parserOutput, 'getPageProperty' ) ) {
// MW 1.38+
$description = $parserOutput->getPageProperty( 'description' );
} else {
$description = $parserOutput->getProperty( 'description' );
}
if ( $description ) {
return true;
}
$desc = $this->descriptionProvider->derive( $text );
if ( $desc ) {
Description2::setDescription( $parser, $desc );
}
return true;
}
/**
* @param Parser $parser The parser.
* @return bool
*/
public function onParserFirstCallInit( $parser ) {
if ( !$this->config->get( 'EnableMetaDescriptionFunctions' ) ) {
// Functions and tags are disabled
return true;
}
$parser->setFunctionHook(
'description2',
[ Description2::class, 'parserFunctionCallback' ],
Parser::SFH_OBJECT_ARGS
);
return true;
}
/**
* @param OutputPage $out The output page to add the meta element to.
* @param ParserOutput $parserOutput The parser output to get the description from.
*/
public function onOutputPageParserOutput( $out, $parserOutput ): void {
// Export the description from the main parser output into the OutputPage
if ( method_exists( $parserOutput, 'getPageProperty' ) ) {
// MW 1.38+
$description = $parserOutput->getPageProperty( 'description' );
} else {
$description = $parserOutput->getProperty( 'description' );
if ( $description === false ) {
$description = null;
}
}
if ( $description !== null ) {
$out->addMeta( 'description', $description );
}
}
}

View file

@ -0,0 +1,13 @@
<?php
use MediaWiki\Extension\Description2\DescriptionProvider;
use MediaWiki\Extension\Description2\SimpleDescriptionProvider;
use MediaWiki\MediaWikiServices;
return [
'Description2.DescriptionProvider' => static function (
MediaWikiServices $services
): DescriptionProvider {
return new SimpleDescriptionProvider();
},
];

View file

@ -0,0 +1,36 @@
<?php
namespace MediaWiki\Extension\Description2;
class SimpleDescriptionProvider implements DescriptionProvider {
/**
* Extracts description from the HTML representation of a page.
*
* The algorithm:
* 1. Removes all <table> and <style> elements and their contents.
* 2. Selects all <p> elements.
* 3. Iterates over those paragraphs, strips out all HTML tags and trims white-space around.
* 4. Then the first non-empty paragraph is picked as the result.
*
* @param string $text
* @return string
*/
public function derive( string $text ): ?string {
$pattern = '%<(table|style)\b[^>]*+>(?:(?R)|[^<]*+(?:(?!</?(table|style)\b)<[^<]*+)*+)*+</(table|style)>%i';
$myText = preg_replace( $pattern, '', $text );
$paragraphs = [];
if ( preg_match_all( '#<p>.*?</p>#is', $myText, $paragraphs ) ) {
foreach ( $paragraphs[0] as $paragraph ) {
$paragraph = trim( strip_tags( $paragraph ) );
if ( !$paragraph ) {
continue;
}
return $paragraph;
}
}
return null;
}
}

3354
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -5,9 +5,9 @@
"test": "grunt test"
},
"devDependencies": {
"eslint-config-wikimedia": "0.20.0",
"grunt": "1.5.3",
"grunt-banana-checker": "0.9.0",
"grunt-eslint": "23.0.0"
"eslint-config-wikimedia": "0.25.0",
"grunt": "1.6.1",
"grunt-banana-checker": "0.11.0",
"grunt-eslint": "24.0.1"
}
}