Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParsoidMapFrame
0.00% covered (danger)
0.00%
0 / 63
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 / 63
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2
3namespace Kartographer\Tag;
4
5use DOMException;
6use Kartographer\ParsoidUtils;
7use MediaWiki\Title\Title;
8use Wikimedia\Parsoid\DOM\DocumentFragment;
9use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
10use Wikimedia\Parsoid\Utils\DOMCompat;
11
12/**
13 * @license MIT
14 */
15class ParsoidMapFrame extends ParsoidTagHandler {
16
17    public const TAG = 'mapframe';
18
19    /**
20     * @throws DOMException
21     * @note If this method's output DOM shape changes, bump $wgKartographerParsoidVersion in
22     *  extension.json so stale cached Parsoid output is rejected.
23     */
24    public function sourceToDom( ParsoidExtensionAPI $extApi, string $src, array $extArgs ): DocumentFragment {
25        [ $status, $args, $geometries ] = $this->parseTag( $extApi, $src, $extArgs );
26
27        // TODO if fullwidth, we really should use interactive mode..
28        // BUT not possible to use both modes at the same time right now. T248023
29        // Should be fixed, especially considering VE in page editing etc...
30        $staticMode = $this->config->get( 'KartographerStaticMapframe' );
31
32        $serverMayRenderOverlays = !$extApi->isPreview();
33        if ( $staticMode && !$serverMayRenderOverlays ) {
34            $extApi->getMetadata()->setJsConfigVar( 'wgKartographerStaticMapframePreview', 1 );
35        }
36
37        $extApi->getMetadata()->addModules( [ $staticMode && $serverMayRenderOverlays
38            ? 'ext.kartographer.staticframe'
39            : 'ext.kartographer.frame' ] );
40
41        if ( !$status->isGood() ) {
42            // Don't return until we've added modules, so that
43            // ParsoidDomProcessor knows that there is Kartographer markup
44            // on this page.
45            return $this->reportErrors( $extApi, self::TAG, $status );
46        }
47
48        $gen = new MapFrameAttributeGenerator( $args, $this->config );
49        $attrs = $gen->prepareAttrs();
50
51        $linkTarget = $extApi->getPageConfig()->getLinkTarget();
52        $pageTitle = Title::newFromLinkTarget( $linkTarget )->getPrefixedDBkey();
53        $revisionId = $extApi->getPageConfig()->getRevisionId();
54        $imgAttrs = $gen->prepareImgAttrs( $serverMayRenderOverlays, $pageTitle, $revisionId, 'parsoid' );
55
56        $doc = $extApi->getTopLevelDoc();
57        $dom = $doc->createDocumentFragment();
58
59        $thumbnail = $doc->createElement( 'img' );
60
61        ParsoidUtils::addAttributesToNode( $imgAttrs, $thumbnail );
62        if ( !isset( $imgAttrs['alt'] ) ) {
63            ParsoidUtils::createLangAttribute( $thumbnail, 'alt',
64                'kartographer-static-mapframe-alt', [], $extApi, null );
65        }
66
67        if ( !$serverMayRenderOverlays ) {
68            $noscript = $doc->createElement( 'noscript' );
69            $noscript->appendChild( $thumbnail );
70            $thumbnail = $noscript;
71            if ( $args->usesAutoPosition() ) {
72                // Impossible to render .png thumbnails that depend on unsaved ExternalData. Preview
73                // will replace this with a dynamic map anyway when JavaScript is available.
74                $thumbnail = $doc->createTextNode( '' );
75            }
76        }
77
78        $a = $doc->createElement( 'a' );
79        $dataKart = [
80            'groupId' => $args->groupId,
81            'showGroups' => $args->showGroups,
82            'geometries' => $geometries
83        ];
84        $a->setAttribute( 'data-kart', json_encode( $dataKart ) );
85        ParsoidUtils::addAttributesToNode( $attrs, $a );
86
87        $a->appendChild( $thumbnail );
88
89        if ( $args->frameless ) {
90            $dom->appendChild( $a );
91            return $dom;
92        }
93
94        $figure = $doc->createElement( 'figure' );
95        $figure->setAttribute( 'class', implode( ' ', $gen->getThumbClasses() ) );
96        $figure->setAttribute( 'typeof', 'mw:File/Thumb' );
97        $figure->appendChild( $a );
98
99        $figcaption = $doc->createElement( 'figcaption' );
100        $caption = (string)$args->text;
101        if ( $caption !== '' ) {
102            // T383004 the $caption can have embedded strip markers! These
103            // should be converted to pfragments.
104            $caption = $this->dataAccess->preprocessWikitext(
105                $extApi->getPageConfig(), $extApi->getMetadata(), $caption
106            );
107            $parsedCaption = $extApi->wikitextToDOM( $caption, [
108                'parseOpts' => [
109                    'extTag' => 'mapframe',
110                    'context' => 'inline',
111                ],
112                // the wikitext is embedded into a JSON attribute, processing in a new frame seems to be the right move
113                // to avoid DSR failures
114                'processInNewFrame' => true,
115                'clearDSROffsets' => true,
116            ], false );
117            DOMCompat::appendChild( $figcaption, $parsedCaption );
118        }
119        $figure->appendChild( $figcaption );
120        $dom->appendChild( $figure );
121        return $dom;
122    }
123
124}