mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Poem
synced 2024-11-14 18:44:44 +00:00
All extension DOM processors should extend Ext\DOMProcessor
Change-Id: Ide9700747b3ecea9da59911c6eb342569be4c9b8
This commit is contained in:
parent
ded8bd5d74
commit
4f16aee1b5
|
@ -4,12 +4,10 @@ declare( strict_types = 1 );
|
|||
namespace Wikimedia\Parsoid\Ext\Poem;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use Wikimedia\Parsoid\Ext\ExtensionModule;
|
||||
use Wikimedia\Parsoid\Ext\ExtensionTagHandler;
|
||||
use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
|
||||
use Wikimedia\Parsoid\Utils\DOMCompat;
|
||||
use Wikimedia\Parsoid\Utils\DOMUtils;
|
||||
|
||||
class Poem extends ExtensionTagHandler implements ExtensionModule {
|
||||
|
||||
|
@ -18,7 +16,7 @@ class Poem extends ExtensionTagHandler implements ExtensionModule {
|
|||
return [
|
||||
'name' => 'Poem',
|
||||
'domProcessors' => [
|
||||
'wt2htmlPostProcessor' => self::class
|
||||
PoemProcessor::class,
|
||||
],
|
||||
'tags' => [
|
||||
[
|
||||
|
@ -129,86 +127,4 @@ class Poem extends ExtensionTagHandler implements ExtensionModule {
|
|||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
*/
|
||||
private function processNowikis( DOMElement $node ): void {
|
||||
$doc = $node->ownerDocument;
|
||||
$c = $node->firstChild;
|
||||
while ( $c ) {
|
||||
if ( !$c instanceof DOMElement ) {
|
||||
$c = $c->nextSibling;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !preg_match( '/\bmw:Nowiki\b/', $c->getAttribute( 'typeof' ) ?? '' ) ) {
|
||||
self::processNowikis( $c );
|
||||
$c = $c->nextSibling;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Replace the nowiki's text node with a combination
|
||||
// of content and <br/>s. Take care to deal with
|
||||
// entities that are still entity-wrapped (!!).
|
||||
$cc = $c->firstChild;
|
||||
while ( $cc ) {
|
||||
$next = $cc->nextSibling;
|
||||
if ( DOMUtils::isText( $cc ) ) {
|
||||
$pieces = preg_split( '/\n/', $cc->nodeValue );
|
||||
$n = count( $pieces );
|
||||
$nl = '';
|
||||
for ( $i = 0; $i < $n; $i++ ) {
|
||||
$p = $pieces[$i];
|
||||
$c->insertBefore( $doc->createTextNode( $nl . $p ), $cc );
|
||||
if ( $i < $n - 1 ) {
|
||||
$c->insertBefore( $doc->createElement( 'br' ), $cc );
|
||||
$nl = "\n";
|
||||
}
|
||||
}
|
||||
$c->removeChild( $cc );
|
||||
}
|
||||
$cc = $next;
|
||||
}
|
||||
$c = $c->nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
private function doPostProcessDOM(
|
||||
DOMElement $node, array $options, bool $atTopLevel
|
||||
): void {
|
||||
if ( !$atTopLevel ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$c = $node->firstChild;
|
||||
while ( $c ) {
|
||||
if ( $c instanceof DOMElement ) {
|
||||
if ( preg_match( '#\bmw:Extension/poem\b#', $c->getAttribute( 'typeof' ) ?? '' ) ) {
|
||||
// Replace newlines found in <nowiki> fragment with <br/>s
|
||||
self::processNowikis( $c );
|
||||
} else {
|
||||
$this->doPostProcessDOM( $c, $options, $atTopLevel );
|
||||
}
|
||||
}
|
||||
$c = $c->nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All DOM PostProcessors are expected to implement the run method.
|
||||
* Eventually, we will probably have an interface with a better name for this
|
||||
* entry method. But, for now, run() method it is.
|
||||
*
|
||||
* @param ParsoidExtensionAPI $extApi
|
||||
* @param DOMElement $body
|
||||
* @param array $options
|
||||
* @param bool $atTopLevel
|
||||
*/
|
||||
public function run(
|
||||
ParsoidExtensionAPI $extApi, DOMElement $body, array $options, bool $atTopLevel
|
||||
): void {
|
||||
$this->doPostProcessDOM( $body, $options, $atTopLevel );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
81
src/Parsoid/PoemProcessor.php
Normal file
81
src/Parsoid/PoemProcessor.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
declare( strict_types = 1 );
|
||||
|
||||
namespace Wikimedia\Parsoid\Ext\Poem;
|
||||
|
||||
use DOMElement;
|
||||
use Wikimedia\Parsoid\Ext\DOMDataUtils;
|
||||
use Wikimedia\Parsoid\Ext\DOMProcessor;
|
||||
use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
|
||||
use Wikimedia\Parsoid\Utils\DOMUtils;
|
||||
|
||||
class PoemProcessor extends DOMProcessor {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function wtPostprocess(
|
||||
ParsoidExtensionAPI $extApi, DOMElement $node, array $options, bool $atTopLevel
|
||||
): void {
|
||||
if ( !$atTopLevel ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$c = $node->firstChild;
|
||||
while ( $c ) {
|
||||
if ( $c instanceof DOMElement ) {
|
||||
if ( DOMDataUtils::hasTypeOf( $c, 'mw:Extension/poem' ) ) {
|
||||
// Replace newlines found in <nowiki> fragment with <br/>s
|
||||
self::processNowikis( $c );
|
||||
} else {
|
||||
$this->wtPostprocess( $extApi, $c, $options, $atTopLevel );
|
||||
}
|
||||
}
|
||||
$c = $c->nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
*/
|
||||
private function processNowikis( DOMElement $node ): void {
|
||||
$doc = $node->ownerDocument;
|
||||
$c = $node->firstChild;
|
||||
while ( $c ) {
|
||||
if ( !$c instanceof DOMElement ) {
|
||||
$c = $c->nextSibling;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !DOMDataUtils::hasTypeOf( $c, 'mw:Nowiki' ) ) {
|
||||
self::processNowikis( $c );
|
||||
$c = $c->nextSibling;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Replace the nowiki's text node with a combination
|
||||
// of content and <br/>s. Take care to deal with
|
||||
// entities that are still entity-wrapped (!!).
|
||||
$cc = $c->firstChild;
|
||||
while ( $cc ) {
|
||||
$next = $cc->nextSibling;
|
||||
if ( DOMUtils::isText( $cc ) ) {
|
||||
$pieces = preg_split( '/\n/', $cc->nodeValue );
|
||||
$n = count( $pieces );
|
||||
$nl = '';
|
||||
for ( $i = 0; $i < $n; $i++ ) {
|
||||
$p = $pieces[$i];
|
||||
$c->insertBefore( $doc->createTextNode( $nl . $p ), $cc );
|
||||
if ( $i < $n - 1 ) {
|
||||
$c->insertBefore( $doc->createElement( 'br' ), $cc );
|
||||
$nl = "\n";
|
||||
}
|
||||
}
|
||||
$c->removeChild( $cc );
|
||||
}
|
||||
$cc = $next;
|
||||
}
|
||||
$c = $c->nextSibling;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue