2020-04-21 23:22:30 +00:00
|
|
|
<?php
|
|
|
|
declare( strict_types = 1 );
|
|
|
|
|
2024-02-26 23:45:38 +00:00
|
|
|
namespace MediaWiki\Extension\Poem\Parsoid;
|
2020-04-21 23:22:30 +00:00
|
|
|
|
2021-07-04 21:06:37 +00:00
|
|
|
use Wikimedia\Parsoid\DOM\Element;
|
|
|
|
use Wikimedia\Parsoid\DOM\Node;
|
2021-09-17 17:02:39 +00:00
|
|
|
use Wikimedia\Parsoid\DOM\Text;
|
2020-04-21 23:22:30 +00:00
|
|
|
use Wikimedia\Parsoid\Ext\DOMProcessor;
|
2020-04-22 01:31:02 +00:00
|
|
|
use Wikimedia\Parsoid\Ext\DOMUtils;
|
2020-04-21 23:22:30 +00:00
|
|
|
use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
|
|
|
|
|
|
|
|
class PoemProcessor extends DOMProcessor {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public function wtPostprocess(
|
2023-07-21 20:32:28 +00:00
|
|
|
ParsoidExtensionAPI $extApi, Node $node, array $options
|
2020-04-21 23:22:30 +00:00
|
|
|
): void {
|
|
|
|
$c = $node->firstChild;
|
|
|
|
while ( $c ) {
|
2021-07-04 21:06:37 +00:00
|
|
|
if ( $c instanceof Element ) {
|
2020-04-22 01:31:02 +00:00
|
|
|
if ( DOMUtils::hasTypeOf( $c, 'mw:Extension/poem' ) ) {
|
2020-04-21 23:22:30 +00:00
|
|
|
// Replace newlines found in <nowiki> fragment with <br/>s
|
|
|
|
self::processNowikis( $c );
|
|
|
|
} else {
|
2023-07-21 20:32:28 +00:00
|
|
|
$this->wtPostprocess( $extApi, $c, $options );
|
2020-04-21 23:22:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$c = $c->nextSibling;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-04 21:06:37 +00:00
|
|
|
private function processNowikis( Element $node ): void {
|
2020-04-21 23:22:30 +00:00
|
|
|
$doc = $node->ownerDocument;
|
|
|
|
$c = $node->firstChild;
|
|
|
|
while ( $c ) {
|
2021-07-04 21:06:37 +00:00
|
|
|
if ( !$c instanceof Element ) {
|
2020-04-21 23:22:30 +00:00
|
|
|
$c = $c->nextSibling;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-04-22 01:31:02 +00:00
|
|
|
if ( !DOMUtils::hasTypeOf( $c, 'mw:Nowiki' ) ) {
|
2020-04-21 23:22:30 +00:00
|
|
|
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;
|
2021-09-17 17:02:39 +00:00
|
|
|
if ( $cc instanceof Text ) {
|
2024-02-26 21:38:57 +00:00
|
|
|
$pieces = preg_split( '/\n/', $cc->nodeValue ?? '' );
|
2020-04-21 23:22:30 +00:00
|
|
|
$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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|