Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParsoidMapLink
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
132
0.00% covered (danger)
0.00%
0 / 1
 sourceToDom
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2
3namespace Kartographer\Tag;
4
5use DOMException;
6use Kartographer\CoordFormatter;
7use Kartographer\ParsoidUtils;
8use MediaWiki\Json\FormatJson;
9use Wikimedia\Parsoid\DOM\DocumentFragment;
10use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
11use Wikimedia\Parsoid\Utils\DOMCompat;
12
13/**
14 * @license MIT
15 */
16class ParsoidMapLink extends ParsoidTagHandler {
17
18    public const TAG = 'maplink';
19
20    /**
21     * @throws DOMException
22     * @note If this method's output DOM shape changes, bump $wgKartographerParsoidVersion in
23     *  extension.json so stale cached Parsoid output is rejected.
24     */
25    public function sourceToDom( ParsoidExtensionAPI $extApi, string $src, array $extArgs ): DocumentFragment {
26        $extApi->getMetadata()->addModules( [ 'ext.kartographer.link' ] );
27        [ $status, $args, $geometries ] = $this->parseTag( $extApi, $src, $extArgs );
28        if ( !$status->isGood() ) {
29            return $this->reportErrors( $extApi, self::TAG, $status );
30        }
31
32        $gen = new MapLinkAttributeGenerator( $args );
33        $attrs = $gen->prepareAttrs();
34
35        $text = $args->getTextWithFallback();
36        if ( $text === null ) {
37            $formatter = new CoordFormatter( $args->lat, $args->lon );
38            $text = $formatter->formatParsoidSpan( $extApi, null );
39        } elseif ( $text !== '' && !ctype_alnum( $text ) ) {
40            // Don't parse trivial alphanumeric-only strings, e.g. counters like "A" or "99".
41            // T383004 The $caption can have embedded strip markers! These
42            // should be converted to pfragments
43            $text = $this->dataAccess->preprocessWikitext(
44                $extApi->getPageConfig(), $extApi->getMetadata(), $text
45            );
46            $text = $extApi->wikitextToDOM( $text, [
47                'parseOpts' => [
48                    'extTag' => 'maplink',
49                    'context' => 'inline',
50                ],
51                // the wikitext is embedded into a JSON attribute, processing in a new frame seems to be the right move
52                // to avoid DSR failures
53                'processInNewFrame' => true,
54                'clearDSROffsets' => true,
55            ], false );
56        }
57        $doc = $extApi->getTopLevelDoc();
58        if ( is_string( $text ) ) {
59            $text = ( trim( $text ) !== '' ) ? $doc->createTextNode( $text ) : null;
60        }
61
62        $dom = $doc->createDocumentFragment();
63        $a = $doc->createElement( 'a' );
64        if ( $args->groupId === null && $geometries ) {
65            $groupId = '_' . sha1( FormatJson::encode( $geometries, false,
66                    FormatJson::ALL_OK ) );
67            $args->groupId = $groupId;
68            $args->showGroups[] = $groupId;
69        }
70
71        if ( $args->showGroups ) {
72            $attrs['data-overlays'] = FormatJson::encode( $args->showGroups, false,
73                FormatJson::ALL_OK );
74            $dataKart = [
75                'groupId' => $args->groupId,
76                'showGroups' => $args->showGroups,
77                'geometries' => $geometries
78            ];
79            $a->setAttribute( 'data-kart', json_encode( $dataKart ) );
80        }
81
82        ParsoidUtils::addAttributesToNode( $attrs, $a );
83        if ( $text ) {
84            DOMCompat::appendChild( $a, $text );
85        }
86
87        $dom->appendChild( $a );
88        return $dom;
89    }
90
91}