Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Indicator
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 3
110
0.00% covered (danger)
0.00%
0 / 1
 getConfig
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 processAttributeEmbeddedDom
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 sourceToDom
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Ext\Indicator;
5
6use Wikimedia\Parsoid\DOM\DocumentFragment;
7use Wikimedia\Parsoid\DOM\Element;
8use Wikimedia\Parsoid\Ext\DiffDOMUtils;
9use Wikimedia\Parsoid\Ext\DOMDataUtils;
10use Wikimedia\Parsoid\Ext\DOMUtils;
11use Wikimedia\Parsoid\Ext\ExtensionModule;
12use Wikimedia\Parsoid\Ext\ExtensionTagHandler;
13use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
14use Wikimedia\Parsoid\Utils\DOMCompat;
15
16/**
17 * Implements the php parser's `indicator` hook natively.
18 */
19class Indicator extends ExtensionTagHandler implements ExtensionModule {
20    /** @inheritDoc */
21    public function getConfig(): array {
22        return [
23            'name' => 'Indicator',
24            'tags' => [
25                [
26                    'name' => 'indicator',
27                    'handler' => self::class,
28                    'options' => [
29                        'wt2html' => [
30                            'embedsDomInAttributes' => true,
31                            'customizesDataMw' => true,
32                        ],
33                        'outputHasCoreMwDomSpecMarkup' => true
34                    ],
35                ]
36            ],
37        ];
38    }
39
40    /** @inheritDoc */
41    public function processAttributeEmbeddedDom(
42        ParsoidExtensionAPI $extApi, Element $elt, callable $proc
43    ): void {
44        $dmw = DOMDataUtils::getDataMw( $elt );
45        if ( isset( $dmw->html ) ) {
46            $proc( $dmw->html );
47        }
48    }
49
50    /** @inheritDoc */
51    public function sourceToDom(
52        ParsoidExtensionAPI $extApi, string $content, array $args
53    ): DocumentFragment {
54        $dataMw = $extApi->extTag->getDefaultDataMw();
55        $kvArgs = $extApi->extArgsToArray( $args );
56        $name = $kvArgs['name'] ?? '';
57        if ( trim( $name ) === '' ) {
58            $out = $extApi->pushError( 'invalid-indicator-name' );
59            DOMDataUtils::setDataMw( $out->firstChild, $dataMw );
60            return $out;
61        }
62
63        // Convert indicator wikitext to DOM
64        $domFragment = $extApi->extTagToDOM( [] /* No args to apply */, $content, [
65            'parseOpts' => [ 'extTag' => 'indicator' ],
66        ] );
67
68        // Strip an outer paragraph if it is the sole paragraph without additional attributes
69        $content = DiffDOMUtils::firstNonSepChild( $domFragment );
70        if ( $content &&
71            DOMCompat::nodeName( $content ) === 'p' &&
72            DiffDOMUtils::nextNonSepSibling( $content ) === null &&
73            $content instanceof Element && // Needed to mollify Phan
74            DOMDataUtils::noAttrs( $content )
75        ) {
76            DOMUtils::migrateChildren( $content, $domFragment, $content->nextSibling );
77            $domFragment->removeChild( $content );
78        }
79
80        $dataMw->html = $domFragment;
81
82        // Use a meta tag whose data-mw we will stuff this HTML into later.
83        // NOTE: Till T214994 is resolved, this HTML will not get processed
84        // by all the top-level DOM passes that may need to process this (ex: linting)
85        $meta = $domFragment->ownerDocument->createElement( 'meta' );
86        DOMDataUtils::setDataMw( $meta, $dataMw );
87
88        $domFragment = $meta->ownerDocument->createDocumentFragment();
89        $domFragment->appendChild( $meta );
90        return $domFragment;
91    }
92}