Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
CRAP | |
0.00% |
0 / 1 |
UpdateTemplateOutput | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
72 | |
0.00% |
0 / 1 |
run | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
72 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace Wikimedia\Parsoid\Wt2Html\DOM\Processors; |
5 | |
6 | use Wikimedia\Parsoid\Config\Env; |
7 | use Wikimedia\Parsoid\DOM\DocumentFragment; |
8 | use Wikimedia\Parsoid\DOM\Element; |
9 | use Wikimedia\Parsoid\DOM\Node; |
10 | use Wikimedia\Parsoid\Utils\DOMCompat; |
11 | use Wikimedia\Parsoid\Utils\DOMDataUtils; |
12 | use Wikimedia\Parsoid\Utils\DOMUtils; |
13 | use Wikimedia\Parsoid\Utils\PipelineUtils; |
14 | use Wikimedia\Parsoid\Wt2Html\Wt2HtmlDOMProcessor; |
15 | |
16 | class UpdateTemplateOutput implements Wt2HtmlDOMProcessor { |
17 | /** |
18 | * FIXME: |
19 | * -- We have hardcoded check for Template: in English |
20 | * -- We aren't checking for other instances (ex: template args) |
21 | * -- We aren't checking for indirect dependencies (ex: nested templates) |
22 | * -- In the core repo, we also need to figure out what OutputTransformPipeline |
23 | * stages need to run in this case. |
24 | * |
25 | * @inheritDoc |
26 | */ |
27 | public function run( |
28 | Env $env, Node $root, array $options = [], bool $atTopLevel = false |
29 | ): void { |
30 | '@phan-var Element|DocumentFragment $root'; // @var Element|DocumentFragment $root |
31 | |
32 | $selparData = $options['selparData'] ?? null; |
33 | if ( !$selparData ) { |
34 | error_log( "Missing selpar data" ); |
35 | return; |
36 | } |
37 | |
38 | // FIXME: Hardcoded for English |
39 | $tplTitle = "./Template:" . $selparData->templateTitle; |
40 | // FIXME: Insufficient - missing check for template args, indirect dependencies |
41 | $tplNodes = DOMCompat::querySelectorAll( $root, '[typeof~="mw:Transclusion"]' ); |
42 | foreach ( $tplNodes as $tplNode ) { |
43 | $dataMw = DOMDataUtils::getDataMW( $tplNode ); |
44 | $ti = $dataMw->parts[0] ?? null; |
45 | if ( !is_string( $ti ) && $ti->href === $tplTitle ) { |
46 | $dp = DOMDataUtils::getDataParsoid( $tplNode ); |
47 | $wt = $dp->dsr->substr( $selparData->revText ); |
48 | $opts = [ |
49 | 'pipelineType' => 'selective-update-fragment-wikitext-to-dom', |
50 | 'sol' => false, // FIXME: Not strictly correct |
51 | 'srcText' => $selparData->revText, |
52 | 'pipelineOpts' => [], |
53 | 'srcOffsets' => $dp->dsr, |
54 | ]; |
55 | |
56 | // Process template string in new pipeline |
57 | $frag = PipelineUtils::processContentInPipeline( |
58 | $env, $options['frame'], $wt, $opts |
59 | ); |
60 | |
61 | // Pull out only the transclusion marked portion of $frag & strip p-wrapper |
62 | $newContent = $frag->firstChild; |
63 | if ( |
64 | DOMCompat::nodeName( $tplNode ) !== 'p' && |
65 | DOMCompat::nodeName( $newContent ) === 'p' |
66 | ) { |
67 | $newContent = $newContent->firstChild; |
68 | } |
69 | DOMDataUtils::getDataParsoid( $newContent )->dsr = $dp->dsr; |
70 | |
71 | // Delete template from DOM + add new content to DOM |
72 | // Note that $tplNode and $frag may have more than one child in the general case |
73 | $tplParent = $tplNode->parentNode; |
74 | $about = DOMCompat::getAttribute( $tplNode, 'about' ); |
75 | do { |
76 | $next = $tplNode->nextSibling; |
77 | $tplParent->removeChild( $tplNode ); |
78 | $tplNode = $next; |
79 | } while ( |
80 | $tplNode instanceof Element && |
81 | DOMCompat::getAttribute( $tplNode, 'about' ) === $about |
82 | ); |
83 | |
84 | DOMUtils::migrateChildren( $newContent->parentNode, $tplParent, $tplNode ); |
85 | } |
86 | } |
87 | } |
88 | } |