Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 73 |
|
0.00% |
0 / 17 |
CRAP | |
0.00% |
0 / 1 |
TraditionalMode | |
0.00% |
0 / 73 |
|
0.00% |
0 / 17 |
650 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
appendAttr | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
ul | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 | |||
perRow | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
setAdditionalOptions | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
caption | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
dimensions | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
scaleMedia | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
thumbWidth | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
thumbHeight | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
thumbStyle | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
boxWidth | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
boxStyle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
galleryText | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
line | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
2 | |||
render | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
getModuleStyles | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace Wikimedia\Parsoid\Ext\Gallery; |
5 | |
6 | use Wikimedia\Parsoid\DOM\Document; |
7 | use Wikimedia\Parsoid\DOM\DocumentFragment; |
8 | use Wikimedia\Parsoid\DOM\Element; |
9 | use Wikimedia\Parsoid\Ext\DOMDataUtils; |
10 | use Wikimedia\Parsoid\Ext\DOMUtils; |
11 | use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI; |
12 | use Wikimedia\Parsoid\Utils\DOMCompat; |
13 | |
14 | class 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 | } |