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 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParsoidMapLink
0.00% covered (danger)
0.00%
0 / 43
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 / 43
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;
11
12/**
13 * @license MIT
14 */
15class ParsoidMapLink extends ParsoidTagHandler {
16
17    public const TAG = 'maplink';
18
19    /**
20     * @param ParsoidExtensionAPI $extApi
21     * @param string $src
22     * @param array $extArgs
23     * @return DocumentFragment
24     * @throws DOMException
25     */
26    public function sourceToDom( ParsoidExtensionAPI $extApi, string $src, array $extArgs ) {
27        $extApi->getMetadata()->addModules( [ 'ext.kartographer.link' ] );
28        [ $status, $args, $geometries ] = $this->parseTag( $extApi, $src, $extArgs );
29        if ( !$status->isGood() ) {
30            return $this->reportErrors( $extApi, self::TAG, $status );
31        }
32
33        $gen = new MapLinkAttributeGenerator( $args );
34        $attrs = $gen->prepareAttrs();
35
36        $text = $args->getTextWithFallback();
37        if ( $text === null ) {
38            $formatter = new CoordFormatter( $args->lat, $args->lon );
39            $text = $formatter->formatParsoidSpan( $extApi, null );
40        } elseif ( $text !== '' && !ctype_alnum( $text ) ) {
41            // Don't parse trivial alphanumeric-only strings, e.g. counters like "A" or "99".
42            $text = $extApi->wikitextToDOM( $text, [
43                'parseOpts' => [
44                    'extTag' => 'maplink',
45                    'context' => 'inline',
46                ],
47                // the wikitext is embedded into a JSON attribute, processing in a new frame seems to be the right move
48                // to avoid DSR failures
49                'processInNewFrame' => true,
50                'clearDSROffsets' => true,
51            ], false );
52        }
53        $doc = $extApi->getTopLevelDoc();
54        if ( is_string( $text ) ) {
55            $text = ( trim( $text ) !== '' ) ? $doc->createTextNode( $text ) : null;
56        }
57
58        $dom = $doc->createDocumentFragment();
59        $a = $doc->createElement( 'a' );
60        if ( $args->groupId === null && $geometries ) {
61            $groupId = '_' . sha1( FormatJson::encode( $geometries, false,
62                    FormatJson::ALL_OK ) );
63            $args->groupId = $groupId;
64            $args->showGroups[] = $groupId;
65        }
66
67        if ( $args->showGroups ) {
68            $attrs['data-overlays'] = FormatJson::encode( $args->showGroups, false,
69                FormatJson::ALL_OK );
70            $dataKart = [
71                'groupId' => $args->groupId,
72                'showGroups' => $args->showGroups,
73                'geometries' => $geometries
74            ];
75            $a->setAttribute( 'data-kart', json_encode( $dataKart ) );
76        }
77
78        ParsoidUtils::addAttributesToNode( $attrs, $a );
79        if ( $text ) {
80            $a->appendChild( $text );
81        }
82
83        $dom->appendChild( $a );
84        return $dom;
85    }
86
87}