From 3220bb8ef48523d1759d56f0051613201b097e32 Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Wed, 20 Apr 2022 17:21:49 -0400 Subject: [PATCH] feat: add initial Parsoid support for the tabber tag --- extension.json | 1 + includes/Hooks.php | 20 ++++++++- includes/TabberParsoid.php | 86 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 includes/TabberParsoid.php diff --git a/extension.json b/extension.json index 3ee2242..e65ffa0 100644 --- a/extension.json +++ b/extension.json @@ -87,5 +87,6 @@ "class": "TabberNeue\\Hooks" } }, + "ParsoidModules": [ "TabberNeue\\Hooks" ], "manifest_version": 2 } diff --git a/includes/Hooks.php b/includes/Hooks.php index 8306b5d..a0e9ee3 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -6,8 +6,9 @@ namespace TabberNeue; use MediaWiki\Hook\ParserFirstCallInitHook; use Parser; +use Wikimedia\Parsoid\Ext\ExtensionModule; -class Hooks implements ParserFirstCallInitHook { +class Hooks implements ExtensionModule, ParserFirstCallInitHook { /** * @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserFirstCallInit * @@ -17,4 +18,21 @@ class Hooks implements ParserFirstCallInitHook { $parser->setHook( 'tabber', Tabber::class . '::parserHook' ); $parser->setHook( 'tabbertransclude', TabberTransclude::class . '::parserHook' ); } + + /** + * Return information about this Parsoid extension module + * + * @return array + */ + public function getConfig(): array { + return [ + 'name' => 'TabberNeue', + 'tags' => [ + [ + 'name' => 'tabber', + 'handler' => TabberParsoid::class + ] + ] + ]; + } } diff --git a/includes/TabberParsoid.php b/includes/TabberParsoid.php new file mode 100644 index 0000000..7f386cd --- /dev/null +++ b/includes/TabberParsoid.php @@ -0,0 +1,86 @@ + tag in Parsoid + * + * @package TabberNeue + * @author alistair3149, Eric Fortin, Alexia E. Smith, Ciencia Al Poder + * @license GPL-3.0-or-later + * @link https://www.mediawiki.org/wiki/Extension:TabberNeue + */ + +declare( strict_types=1 ); + +namespace TabberNeue; + +use Wikimedia\Parsoid\Ext\ExtensionTagHandler; +use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI; + +class TabberParsoid extends ExtensionTagHandler { + /** @inheritDoc */ + public function sourceToDom( ParsoidExtensionAPI $extApi, string $src, array $extArgs ) { + $extApi->addModuleStyles( [ 'ext.tabberNeue' ] ); + $html = self::render( $extApi, $src ); + return $extApi->htmlToDom( $html ); + } + + /** + * Renders the necessary HTML for a tag. + * + * @param PParsoidExtensionAPI $extApi + * @param string $src The input URL between the beginning and ending tags. + * + * @return string HTML + */ + public static function render( ParsoidExtensionAPI $extApi, string $src ) { + $arr = explode( "|-|", $src ); + $htmlTabs = ''; + foreach ( $arr as $tab ) { + $htmlTabs .= self::buildTab( $extApi, $tab ); + } + + $html = '
' . + '
' . $htmlTabs . "
"; + + return $html; + } + + /** + * Build individual tab. + * + * @param PParsoidExtensionAPI $extApi + * @param string $tab Tab information + * + * @return string HTML + */ + private static function buildTab( ParsoidExtensionAPI $extApi, string $tab ) { + $tab = trim( $tab ); + if ( empty( $tab ) ) { + return $tab; + } + + // Use array_pad to make sure at least 2 array values are always returned + list( $tabName, $tabBody ) = array_pad( array_map( 'trim', explode( '=', $tab, 2 ) ), 2, '' ); + + // $tabBody = $extApi->wikitextToDOM( $tabBody ); + + $tabBody = $extApi->domToHTML( + $extApi->wikitextToDOM( + $tabBody, + [ + 'parseOpts' => [ + 'extTag' => 'tabber', + 'context' => 'inline', + ] + ], + true // sol + ) + ); + + $tab = '
' . $tabBody . '
'; + + return $tab; + } +}