Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
WikiLinkText
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 3
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 escape
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 fromSelSerImpl
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Html2Wt\ConstrainedText;
5
6use Wikimedia\Parsoid\Config\Env;
7use Wikimedia\Parsoid\Config\SiteConfig;
8use Wikimedia\Parsoid\DOM\Element;
9use Wikimedia\Parsoid\NodeData\DataParsoid;
10use Wikimedia\Parsoid\Utils\DOMCompat;
11use Wikimedia\Parsoid\Utils\DOMUtils;
12use Wikimedia\Parsoid\Utils\PHPUtils;
13
14/**
15 * An internal wiki link, like `[[Foo]]`.
16 */
17class WikiLinkText extends RegExpConstrainedText {
18    /** @var bool */
19    private $greedy = false;
20
21    /**
22     * @param string $text
23     * @param Element $node
24     * @param SiteConfig $siteConfig
25     * @param string $type
26     *   The type of the link, as described by the `rel` attribute.
27     */
28    public function __construct(
29        string $text, Element $node,
30        SiteConfig $siteConfig, string $type
31    ) {
32        // category links/external links/images don't use link trails or prefixes
33        $noTrails = preg_match( '#^mw:WikiLink(/Interwiki)?$#D', $type ) === 0;
34        $badPrefix = '/(^|[^\[])(\[\[)*\[$/D';
35        $linkPrefixRegex = $siteConfig->linkPrefixRegex();
36        if ( !$noTrails && $linkPrefixRegex ) {
37            $badPrefix =
38                '/(' . PHPUtils::reStrip( $linkPrefixRegex, '/' ) . ')' .
39                '|(' . PHPUtils::reStrip( $badPrefix, '/' ) . ')/uD';
40        }
41        parent::__construct( [
42            'text' => $text,
43            'node' => $node,
44            'badPrefix' => $badPrefix,
45            'badSuffix' => ( $noTrails ) ? null : $siteConfig->linkTrailRegex(),
46        ] );
47        // We match link trails greedily when they exist.
48        if ( !( $noTrails || substr( $text, -1 ) === ']' ) ) {
49            $this->greedy = true;
50        }
51    }
52
53    /** @inheritDoc */
54    public function escape( State $state ): Result {
55        $r = parent::escape( $state );
56        // If previous token was also a WikiLink, its linktrail will
57        // eat up any possible linkprefix characters, so we don't need
58        // a <nowiki> in this case.  (Eg: [[a]]-[[b]] in iswiki; the -
59        // character is both a link prefix and a link trail, but it gets
60        // preferentially associated with the [[a]] as a link trail.)
61        $r->greedy = $this->greedy;
62        return $r;
63    }
64
65    protected static function fromSelSerImpl(
66        string $text, Element $node, DataParsoid $dataParsoid,
67        Env $env, array $opts
68    ): ?WikiLinkText {
69        $stx = $dataParsoid->stx ?? '';
70        if (
71            DOMUtils::matchRel( $node, '#^mw:WikiLink(/Interwiki)?$#D' ) &&
72            in_array( $stx, [ 'simple', 'piped' ], true )
73        ) {
74            $rel = DOMCompat::getAttribute( $node, 'rel' );
75            return new WikiLinkText( $text, $node, $env->getSiteConfig(), $rel );
76        }
77        return null;
78    }
79}