Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 17
CRAP
0.00% covered (danger)
0.00%
0 / 1
TraditionalMode
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 17
650
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 appendAttr
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 ul
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 perRow
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 setAdditionalOptions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 caption
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 dimensions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 scaleMedia
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 thumbWidth
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 thumbHeight
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 thumbStyle
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 boxWidth
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 boxStyle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 galleryText
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 line
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
2
 render
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 getModuleStyles
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Ext\Gallery;
5
6use Wikimedia\Parsoid\DOM\Document;
7use Wikimedia\Parsoid\DOM\DocumentFragment;
8use Wikimedia\Parsoid\DOM\Element;
9use Wikimedia\Parsoid\Ext\DOMDataUtils;
10use Wikimedia\Parsoid\Ext\DOMUtils;
11use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
12use Wikimedia\Parsoid\Utils\DOMCompat;
13
14class TraditionalMode extends Mode {
15    /**
16     * Create a TraditionalMode singleton.
17     * @param ?string $mode Only used by subclasses.
18     */
19    protected function __construct( ?string $mode = null ) {
20        parent::__construct( $mode ?? 'traditional' );
21        $this->scale = 1;
22        $this->padding = (object)[ 'thumb' => 30, 'box' => 5, 'border' => 8 ];
23    }
24
25    /** @var float */
26    protected $scale;
27    /** @var \stdClass */
28    protected $padding;
29
30    private function appendAttr( Element $ul, string $k, string $v ): void {
31        $val = DOMCompat::getAttribute( $ul, $k );
32        $val = ( $val === null || trim( $val ) === '' ) ? $v : "$val $v";
33        $ul->setAttribute( $k, $val );
34    }
35
36    private function ul(
37        Opts $opts, DocumentFragment $domFragment
38    ): Element {
39        $ul = $domFragment->ownerDocument->createElement( 'ul' );
40        $cl = 'gallery mw-gallery-' . $this->mode;
41        $ul->setAttribute( 'class', $cl );
42        foreach ( $opts->attrs as $k => $v ) {
43            $this->appendAttr( $ul, $k, $v );
44        }
45        $domFragment->appendChild( $ul );
46        $this->perRow( $opts, $ul );
47        $this->setAdditionalOptions( $opts, $ul );
48        return $ul;
49    }
50
51    protected function perRow( Opts $opts, Element $ul ): void {
52        if ( $opts->imagesPerRow > 0 ) {
53            $padding = $this->padding;
54            $total = $opts->imageWidth + $padding->thumb + $padding->box + $padding->border;
55            $total *= $opts->imagesPerRow;
56            $this->appendAttr( $ul, 'style', 'max-width: ' . $total . 'px;' );
57        }
58    }
59
60    protected function setAdditionalOptions( Opts $opts, Element $ul ): void {
61    }
62
63    private function caption(
64        Opts $opts, Element $ul, DocumentFragment $caption
65    ): void {
66        $doc = $ul->ownerDocument;
67        $li = $doc->createElement( 'li' );
68        $li->setAttribute( 'class', 'gallerycaption' );
69        DOMUtils::migrateChildren( $caption, $li );
70        $ul->appendChild( $doc->createTextNode( "\n" ) );
71        $ul->appendChild( $li );
72    }
73
74    /** @inheritDoc */
75    public function dimensions( Opts $opts ): string {
76        return "{$opts->imageWidth}x{$opts->imageHeight}px";
77    }
78
79    /**
80     * @param Opts $opts
81     * @param Element $wrapper
82     * @return int|float
83     */
84    protected function scaleMedia( Opts $opts, Element $wrapper ) {
85        return $opts->imageWidth;
86    }
87
88    /**
89     * @param float|int $width
90     * @return float|int
91     */
92    protected function thumbWidth( $width ) {
93        return $width + $this->padding->thumb;
94    }
95
96    /**
97     * @param float|int $height
98     * @return float|int
99     */
100    protected function thumbHeight( $height ) {
101        return $height + $this->padding->thumb;
102    }
103
104    /**
105     * @param float|int $width
106     * @param float|int $height
107     * @return string
108     */
109    protected function thumbStyle( $width, $height ): string {
110        $style = [ 'width: ' . $this->thumbWidth( $width ) . 'px;' ];
111        if ( $this->mode === 'traditional' ) {
112            $style[] = 'height: ' . $this->thumbHeight( $height ) . 'px;';
113        }
114        return implode( ' ', $style );
115    }
116
117    /**
118     * @param float|int $width
119     * @return float|int
120     */
121    protected function boxWidth( $width ) {
122        return $this->thumbWidth( $width ) + $this->padding->box;
123    }
124
125    /**
126     * @param float|int $width
127     * @param float|int $height
128     * @return string
129     */
130    protected function boxStyle( $width, $height ): string {
131        return 'width: ' . $this->boxWidth( $width ) . 'px;';
132    }
133
134    protected function galleryText(
135        Document $doc, Element $box, ?Element $gallerytext,
136        float $width
137    ): void {
138        $div = $doc->createElement( 'div' );
139        $div->setAttribute( 'class', 'gallerytext' );
140        if ( $gallerytext ) {
141            ParsoidExtensionAPI::migrateChildrenAndTransferWrapperDataAttribs(
142                $gallerytext, $div
143            );
144        }
145        $box->appendChild( $div );
146    }
147
148    private function line( Opts $opts, Element $ul, ParsedLine $o ): void {
149        $doc = $ul->ownerDocument;
150
151        $width = $this->scaleMedia( $opts, $o->thumb );
152        $height = $opts->imageHeight;
153
154        $box = $doc->createElement( 'li' );
155        $box->setAttribute( 'class', 'gallerybox' );
156        $box->setAttribute( 'style', $this->boxStyle( $width, $height ) );
157        DOMDataUtils::getDataParsoid( $box )->dsr = $o->dsr;
158
159        $thumb = $doc->createElement( 'div' );
160        $thumb->setAttribute( 'class', 'thumb' );
161        $thumb->setAttribute( 'style', $this->thumbStyle( $width, $height ) );
162
163        $wrapper = $doc->createElement( 'span' );
164        $wrapper->setAttribute( 'typeof', $o->rdfaType );
165        ParsoidExtensionAPI::migrateChildrenAndTransferWrapperDataAttribs(
166            $o->thumb, $wrapper
167        );
168        $thumb->appendChild( $wrapper );
169
170        $box->appendChild( $thumb );
171        $this->galleryText( $doc, $box, $o->gallerytext, $width );
172        $ul->appendChild( $doc->createTextNode( "\n" ) );
173        $ul->appendChild( $box );
174    }
175
176    /** @inheritDoc */
177    public function render(
178        ParsoidExtensionAPI $extApi, Opts $opts, ?DocumentFragment $caption,
179        array $lines
180    ): DocumentFragment {
181        $domFragment = $extApi->htmlToDom( '' );
182        $ul = $this->ul( $opts, $domFragment );
183        if ( $caption ) {
184            $this->caption( $opts, $ul, $caption );
185        }
186        foreach ( $lines as $l ) {
187            $this->line( $opts, $ul, $l );
188        }
189        $ul->appendChild( $domFragment->ownerDocument->createTextNode( "\n" ) );
190        return $domFragment;
191    }
192
193    public function getModuleStyles(): array {
194        return [ 'mediawiki.page.gallery.styles' ];
195    }
196
197}