r53094 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r53093‎ | r53094 | r53095 >
Date:03:37, 11 July 2009
Author:avar
Status:deferred
Tags:
Comment:
* Improved the horrid argument parser replacing it with something even
more horrid. But now it can parse values and supply defaults at the
same time. This is required because to validate a some parameters
other parameters need to have already been validated.

* marker= works again

* Changed field names to something that's more comfortable to type
Modified paths:
  • /trunk/extensions/SlippyMap/SlippyMap.class.php (modified) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.i18n.php (modified) (history)
  • /trunk/extensions/SlippyMap/slippyMapParserTests.txt (modified) (history)

Diff [purge]

Index: trunk/extensions/SlippyMap/SlippyMap.i18n.php
@@ -37,6 +37,8 @@
3838 'slippymap_error_invalid_attribute_width_value_nan' => "The value <tt>$1</tt> is not valid for the <tt>width</tt> attribute, the given value must be a valid number.",
3939 'slippymap_error_invalid_attribute_height_value_nan' => "The value <tt>$1</tt> is not valid for the <tt>height</tt> attribute, the given value must be a valid number.",
4040 'slippymap_error_invalid_attribute_mode_value_not_a_mode' => "The value <tt>$1</tt> is not valid for the <tt>mode</tt> attribute, valid modes are $2.",
 41+ 'slippymap_error_invalid_attribute_layer_value_not_a_layer' => "The value <tt>$1</tt> is not valid for the <tt>layer</tt> attribute, valid layers are $2.",
 42+ 'slippymap_error_invalid_attribute_marker_value_not_a_marker' => "The value <tt>$1</tt> is not valid for the <tt>marker</tt> attribute, valid markers are $2.",
4143 'slippymap_error_unknown_attribute' => "The attribute <tt>$1</tt> is unknown.",
4244
4345 // Value out of range
Index: trunk/extensions/SlippyMap/SlippyMap.class.php
@@ -11,27 +11,37 @@
1212 /* Fields */
1313
1414 /**
 15+ * Our parser instance, passed from above
 16+ *
1517 * @var object
1618 */
17 - protected $mParser;
 19+ protected $parser;
1820
1921 /**
20 - *
 22+ * List of arguments that we use, parsed in this order.
2123 */
22 - protected $mArgsRequired = array(
 24+ protected $argsList = array(
 25+ /* Find out ASAP what mode we're in when parsing arguments */
 26+ 'mode',
 27+ 'layer',
 28+
2329 'lat',
24 - 'lon'
 30+ 'lon',
 31+ 'zoom',
 32+
 33+ 'width',
 34+ 'height',
 35+
 36+ 'caption',
 37+ 'marker'
2538 );
2639
27 - protected $mArgsList = array(
28 - 'lat' => 'mLat',
29 - 'lon' => 'mLon',
30 - 'zoom' => 'mZoom',
31 - 'width' => 'mWidth',
32 - 'height' => 'mHeight',
33 - 'mode' => 'mMode',
34 - 'layer' => 'mLayer',
35 - 'caption' => 'mCaption',
 40+ /**
 41+ * List of arguments that must be supplied
 42+ */
 43+ protected $argsRequired = array(
 44+ 'lat',
 45+ 'lon'
3646 );
3747
3848 /**
@@ -44,12 +54,8 @@
4555 *
4656 * @var array
4757 */
48 - protected $mArgsError = array();
 58+ protected $argsError = array();
4959
50 - /**
51 - */
52 - protected $mArgs = array();
53 -
5460 /* Functions */
5561
5662 /**
@@ -58,8 +64,7 @@
5965 * @param object $parser Parser instance
6066 */
6167 public function __construct( $parser ) {
62 - $this->mParser = $parser;
63 - $this->mMode = 'osm';
 68+ $this->parser = $parser;
6469 }
6570
6671 /**
@@ -77,20 +82,20 @@
7883
7984 /* <slippymap></slippymap> */
8085 if ( $input === '' ) {
81 - $this->mArgsError[] = wfMsg( 'slippymap_error_empty_element', wfMsg( 'slippymap_extname' ), wfMsg( 'slippymap_tagname' ) );
 86+ $this->argsError[] = wfMsg( 'slippymap_error_empty_element', wfMsg( 'slippymap_extname' ), wfMsg( 'slippymap_tagname' ) );
8287 }
8388
8489 /* No arguments */
8590 if ( count( $args ) == 0 ) {
86 - $this->mArgsError[] = wfMsg( 'slippymap_error_missing_arguments', wfMSg( 'slippymap_tagname' ) );
 91+ $this->argsError[] = wfMsg( 'slippymap_error_missing_arguments', wfMSg( 'slippymap_tagname' ) );
8792
8893 /* Some arguments */
8994 } else {
9095
9196 /* Make sure we have lat/lon/zoom */
92 - foreach ($this->mArgsRequired as $requiredArg) {
 97+ foreach ($this->argsRequired as $requiredArg) {
9398 if ( ! isset( $args[$requiredArg] ) ) {
94 - $this->mArgsError[] = wfMsg( 'slippymap_error_missing_attribute_' . $requiredArg );
 99+ $this->argsError[] = wfMsg( 'slippymap_error_missing_attribute_' . $requiredArg );
95100 }
96101 }
97102
@@ -98,29 +103,19 @@
99104 * we want to protect our namespace
100105 */
101106 foreach ( array_keys( $args ) as $user_key ) {
102 - if ( ! isset( $this->mArgsList[$user_key] ) )
103 - $this->mArgsError[] = wfMsg( 'slippymap_error_unknown_attribute', $user_key );
 107+ if ( ! in_array( $user_key, $this->argsList ) )
 108+ $this->argsError[] = wfMsg( 'slippymap_error_unknown_attribute', $user_key );
104109 }
105110
106111 /**
107 - * Go through the list of options and add them to our
108 - * fields if they validate.
 112+ * Go through the list of options and add them to our
 113+ * fields if they validate, also adds default values.
109114 */
110 - foreach ( $this->mArgsList as $key => $classVar ) {
111 - if ( isset( $args[$key] ) ) {
112 - $val = $args[$key];
113 -
114 - if ( $this->validateArgument($key, $val) ) {
115 - $this->$classVar = $args[$key];
116 - } else {
117 - /* Invalid value */
118 - }
119 - }
120 - }
 115+ $this->populateArguments($args);
121116 }
122117
123 - if ( count( $this->mArgsError ) == 0 ) {
124 - $this->defaultOptions();
 118+ if ( count( $this->argsError ) == 0 ) {
 119+
125120 wfProfileOut( __METHOD__ );
126121 return true;
127122 } else {
@@ -128,163 +123,176 @@
129124 }
130125 }
131126
132 - /**
133 - * Fill in defaults for those options for those options that
134 - * weren't set during extractOptions()
135 - */
136 - public function defaultOptions( ) {
 127+ private function populateArguments( $args ) {
 128+ wfProfileIn( __METHOD__ );
137129 global $wgSlippyMapModes;
 130+ global $wgLang;
 131+ global $wgSlippyMapSizeRestrictions;
138132
139 - if ( ! isset( $this->mMode ) ) {
140 - $modes = array_keys( $wgSlippyMapModes );
141 - $default_mode = $modes[0];
 133+ foreach ($this->argsList as $key) {
 134+ $has_val = isset( $args[$key] );
 135+ $val = $has_val ? $args[$key] : null;
142136
143 - $this->mMode = $default_mode;
144 - }
 137+ /* mode */
 138+ if ( $key === 'mode' ) {
 139+ if ( ! $has_val ) {
 140+ $modes = array_keys( $wgSlippyMapModes );
 141+ $default_mode = $modes[0];
145142
146 - if ( ! isset( $this->mLayer ) ) {
147 - $this->mLayer = $wgSlippyMapModes[$this->mMode]['layers'][0];
148 - }
 143+ $this->mode = $default_mode;
 144+ } else {
 145+ $modes = array_keys( $wgSlippyMapModes );
 146+ if ( ! in_array( $val, $modes ) ) {
 147+ $this->argsError[] = wfMsg(
 148+ 'slippymap_error_invalid_attribute_' . $key . '_value_not_a_mode',
 149+ $val,
 150+ $wgLang->listToText( array_map( array( &$this, 'addHtmlTT' ), $modes ) )
 151+ );
 152+ return null;
 153+ } else {
 154+ $this->mode = $val;
 155+ }
 156+ }
 157+ }
149158
150 - if ( ! isset( $this->mZoom ) ) {
151 - $this->mZoom = $wgSlippyMapModes[$this->mMode]['defaultZoomLevel'];
152 - }
 159+ /* layer */
 160+ if ( $key === 'layer' ) {
 161+ if ( ! $has_val ) {
 162+ $this->layer = $wgSlippyMapModes[$this->mode]['layers'][0];
 163+ } else {
 164+ $layers = $wgSlippyMapModes[$this->mode]['layers'];
 165+ if ( ! in_array( $val, $layers ) ) {
 166+ $this->argsError[] = wfMsg(
 167+ 'slippymap_error_invalid_attribute_' . $key . '_value_not_a_layer',
 168+ $val,
 169+ $wgLang->listToText( array_map( array( &$this, 'addHtmlTT' ), $layers ) )
 170+ );
 171+ } else {
 172+ $this->layer = $val;
 173+ }
 174+ }
 175+ }
153176
154 - if ( ! isset( $this->mMarker ) ) {
155 - $this->mMarker = 0;
156 - }
157 -
158 - if ( ! isset( $this->mCaption ) ) {
159 - $this->mCaption = '';
160 - }
161 -
162 - if ( ! isset( $this->mWidth ) || ! isset( $this->mHeight ) ) {
163 - $thumbsize = self::getUserThumbSize();
164 -
165 - if ( ! isset( $this->mWidth ) )
166 - $this->mWidth = $thumbsize;
167 - if ( ! isset( $this->mHeight ) )
168 - $this->mHeight = $thumbsize * .72;
169 -
170 - // trim off the 'px' on the end of pixel measurement numbers (ignore if present)
171 - if ( substr( $this->mWidth, -2 ) == 'px' )
172 - $this->mWidth = (int) substr( $this->width, 0, -2 );
173 -
174 - if ( substr( $this->mHeight, - 2 ) == 'px' )
175 - $this->mHeight = (int) substr( $this->height, 0, -2 );
176 - }
177 - }
178 -
179 - private static function getUserThumbSize() {
180 - global $wgUser, $wgOut, $wgThumbLimits;
181 -
182 - return $wgThumbLimits[$wgUser->getOption( 'thumbsize' )];
183 - }
184 -
185 - /**
186 - * Validate the values of a keys listed in $this->mArgsList.
187 - *
188 - * @param string $key A key we know to be good
189 - * @param string $val A user supplied value to validate for the key
190 - */
191 - private function validateArgument( $key, $val ) {
192 - global $wgSlippyMapSizeRestrictions;
193 - global $wgSlippyMapModes;
194 - global $wgLang;
195 -
196 - wfProfileIn( __METHOD__ );
197 -
198 - $ok = false;
199 -
200 - switch ( $key ) {
201 - case 'lat':
202 - case 'lon':
 177+ /* lat */
 178+ if ( $key === 'lat' && $has_val ) {
203179 if ( ! preg_match( '~^ -? [0-9]{1,3} (?: \\. [0-9]{1,20} )? $~x', $val ) ) {
204 - $this->mArgsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
 180+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
205181 } else {
206 - /* Note: I'm not calling $wgLang->formatNum( $val ) here on purpose */
207 - if ( $key === 'lat' && ( $val > 90 || $val < -90 ) ) {
208 - $this->mArgsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range', $val );
209 - } else if ( $key === 'lon' && ( $val > 180 || $val < -180 ) ) {
210 - $this->mArgsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range', $val );
 182+ if ( $val > 90 || $val < -90 ) {
 183+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range', $val );
211184 } else {
212 - $ok = true;
 185+ $this->lat = $val;
213186 }
214187 }
215 - break;
 188+ }
 189+
 190+ /* lon */
 191+ if ( $key === 'lon' && $has_val ) {
 192+ if ( ! preg_match( '~^ -? [0-9]{1,3} (?: \\. [0-9]{1,20} )? $~x', $val ) ) {
 193+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
 194+ } else {
 195+ if ( $val > 180 || $val < -180 ) {
 196+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range', $val );
 197+ } else {
 198+ $this->lon = $val;
 199+ }
 200+ }
 201+ }
216202
217 - case 'zoom':
218 - if ( ! preg_match( '~^ [0-9]{1,2} $~x', $val ) ) {
219 - $this->mArgsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
 203+ /* zoom */
 204+ if ( $key === 'zoom' ) {
 205+ if ( ! $has_val ) {
 206+ $this->zoom = $wgSlippyMapModes[$this->mode]['defaultZoomLevel'];
220207 } else {
221 - /* TODO: Make configurable depending on layer settings */
222 - $min_zoom = 0;
223 - $max_zoom = 18;
 208+ if ( ! preg_match( '~^ [0-9]{1,2} $~x', $val ) ) {
 209+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
 210+ } else {
 211+ /* TODO: Make configurable depending on layer settings */
 212+ $min_zoom = 0;
 213+ $max_zoom = 18;
224214
225 - /* Note: I'm not calling $wgLang->formatNum( $val ) here on purpose */
226 - if ( ( $val > $max_zoom || $val < $min_zoom ) ) {
227 - $this->mArgsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range', $val, $min_zoom, $max_zoom );
 215+ /* Note: I'm not calling $wgLang->formatNum( $val ) here on purpose */
 216+ if ( ( $val > $max_zoom || $val < $min_zoom ) ) {
 217+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range', $val, $min_zoom, $max_zoom );
 218+ } else {
 219+ $this->zoom = $val;
 220+ }
 221+ }
 222+ }
 223+ }
 224+
 225+ /* width / height */
 226+ if ( $key === 'width' || $key == 'height' ) {
 227+ if ( ! $has_val ) {
 228+ $thumbsize = self::getUserThumbSize();
 229+
 230+ if ( $key === 'width' ) {
 231+ $this->width = $thumbsize;
 232+ } else if ( $key === 'height' ) {
 233+ $this->height = $thumbsize * .72;
 234+ }
 235+
 236+ if ( substr( $this->$key, -2 ) == 'px' )
 237+ $this->$key = (int) substr( $this->$key, 0, -2 );
 238+ } else {
 239+ if ( ! preg_match( '~^ [0-9]{1,20} $~x', $val ) ) {
 240+ $this->argsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
228241 } else {
229 - $ok = true;
 242+ list ($min_width, $max_width) = $wgSlippyMapSizeRestrictions['width'];
 243+ list ($min_height, $max_height) = $wgSlippyMapSizeRestrictions['height'];
 244+
 245+ if ( $key == 'width' && ( $val > $max_width || $val < $min_width ) ) {
 246+ $this->argsError[] = wfMsg(
 247+ 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range',
 248+ $val,
 249+ $min_width,
 250+ $max_width
 251+ );
 252+ } else if ( $key == 'height' && ( $val > $max_height || $val < $min_height ) ) {
 253+ $this->argsError[] = wfMsg(
 254+ 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range',
 255+ $val,
 256+ $min_width,
 257+ $max_width
 258+ );
 259+ } else {
 260+ $this->$key = $val;
 261+ }
230262 }
231263 }
232 - break;
 264+ }
233265
234 - case 'width':
235 - case 'height':
236 - if ( ! preg_match( '~^ [0-9]{1,20} $~x', $val ) ) {
237 - $this->mArgsError[] = wfMsg( 'slippymap_error_invalid_attribute_' . $key . '_value_nan', $val );
 266+ /* marker */
 267+ if ( $key === 'marker' ) {
 268+ if ( ! $has_val ) {
 269+ $this->marker = 0;
238270 } else {
239 - list ($min_width, $max_width) = $wgSlippyMapSizeRestrictions['width'];
240 - list ($min_height, $max_height) = $wgSlippyMapSizeRestrictions['height'];
241 -
242 - if ( $key == 'width' && ( $val > $max_width || $val < $min_width ) ) {
243 - $this->mArgsError[] = wfMsg(
244 - 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range',
 271+ if ( ! preg_match( '~^ (?: 0 | 1 ) $~x', $val ) ) {
 272+ $this->argsError[] = wfMsg(
 273+ 'slippymap_error_invalid_attribute_' . $key . '_value_not_a_marker',
245274 $val,
246 - $min_width,
247 - $max_width
 275+ $wgLang->listToText( array_map( array( &$this, 'addHtmlTT' ), array( 0, 1 ) ) )
248276 );
249 - } else if ( $key == 'height' && ( $val > $max_height || $val < $min_height ) ) {
250 - $this->mArgsError[] = wfMsg(
251 - 'slippymap_error_invalid_attribute_' . $key . '_value_out_of_range',
252 - $val,
253 - $min_width,
254 - $max_width
255 - );
256277 } else {
257 - $ok = true;
 278+ $this->marker = $val;
258279 }
259280 }
260 - break;
 281+ }
261282
262 - case 'mode':
263 - $modes = array_keys( $wgSlippyMapModes );
264 - if ( ! in_array( $val, $modes ) ) {
265 - $this->mArgsError[] = wfMsg(
266 - 'slippymap_error_invalid_attribute_' . $key . '_value_not_a_mode',
267 - $val,
268 - $wgLang->listToText( array_map( array( &$this, 'addHtmlTT' ), $modes ) )
269 - );
270 - } else {
271 - $ok = true;
272 - }
273 - break;
274 - case 'layer':
275 - /* TODO validate */
276 - case 'caption':
277 - /* Anything goes as far as the caption is concerned. It's the parser's problem if it's not OK */
278 - $ok = true;
279 - break;
280 -
281 - default:
282 - die("internal error: Unknown parameter");
 283+ if ( $key == 'caption' ) {
 284+ $this->caption = "foo";
 285+ }
283286 }
284287
285288 wfProfileOut( __METHOD__ );
286 - return $ok;
287289 }
288290
 291+ private static function getUserThumbSize() {
 292+ global $wgUser, $wgOut, $wgThumbLimits;
 293+
 294+ return $wgThumbLimits[$wgUser->getOption( 'thumbsize' )];
 295+ }
 296+
289297 /**
290298 * Callback function for array_map to add <tt> to array elements.
291299 */
@@ -305,29 +313,29 @@
306314 $mapcode = <<<EOT
307315
308316 <script type="{$wgJsMimeType}">slippymaps.push(new slippymap_map($id, {
309 - mode: '{$this->mMode}',
310 - layer: '{$this->mLayer}',
311 - lat: {$this->mLat},
312 - lon: {$this->mLon},
313 - zoom: {$this->mZoom},
314 - width: {$this->mWidth},
315 - height: {$this->mHeight},
316 - marker: {$this->mMarker}
 317+ mode: '{$this->mode}',
 318+ layer: '{$this->layer}',
 319+ lat: {$this->lat},
 320+ lon: {$this->lon},
 321+ zoom: {$this->zoom},
 322+ width: {$this->width},
 323+ height: {$this->height},
 324+ marker: {$this->marker}
317325 }));</script>
318326
319327 <!-- mapframe -->
320 - <div class="mapframe" style="width:{$this->mWidth}px">
 328+ <div class="mapframe" style="width:{$this->width}px">
321329 EOT;
322330
323 - $static_rendering = $wgSlippyMapModes[$this->mMode]['static_rendering'];
 331+ $static_rendering = $wgSlippyMapModes[$this->mode]['static_rendering'];
324332 if ( isset( $static_rendering ) ) {
325333 $mapcode .= self::getStaticMap( $id, $static_rendering );
326334 } else {
327335 $mapcode .= self::getDynamicMap( $id );
328336 }
329337
330 - if ( $this->mCaption ) {
331 - $mapcode .= "<div class='mapcaption'>" . $this->mParser->recursiveTagParse($this->mCaption) . "</div>";
 338+ if ( $this->caption ) {
 339+ $mapcode .= "<div class='mapcaption'>" . $this->parser->recursiveTagParse($this->caption) . "</div>";
332340 }
333341
334342 $mapcode .= <<<EOT
@@ -349,7 +357,7 @@
350358 global $wgJsMimeType;
351359 $mapcode = <<<EOT
352360 <!-- map div -->
353 - <div id="map{$id}" class="map" style="width:{$this->mWidth}px; height:{$this->mHeight}px;">
 361+ <div id="map{$id}" class="map" style="width:{$this->width}px; height:{$this->height}px;">
354362 <script type="{$wgJsMimeType}">slippymaps[{$id}].init();</script>
355363 <!-- /map div -->
356364 </div>
@@ -366,22 +374,22 @@
367375 $staticType = $static_rendering['type'];
368376 $staticOptions = $static_rendering['options'];
369377
370 - $static = new $staticType($this->mLat, $this->mLon, $this->mZoom, $this->mWidth, $this->mHeight, $staticOptions);
 378+ $static = new $staticType($this->lat, $this->lon, $this->zoom, $this->width, $this->height, $staticOptions);
371379 $rendering_url = $static->getUrl();
372380
373381 $clickToActivate = wfMsgHtml('slippymap_clicktoactivate');
374382 $mapcode = <<<EOT
375383
376384 <!-- map div -->
377 - <div id="map{$id}" class="map" style="width:{$this->mWidth}px; height:{$this->mHeight}px;">
 385+ <div id="map{$id}" class="map" style="width:{$this->width}px; height:{$this->height}px;">
378386 <!-- Static preview -->
379387 <img
380388 id="mapPreview{$id}"
381389 class="mapPreview"
382390 src="{$rendering_url}"
383391 onclick="slippymaps[{$id}].init();"
384 - width="{$this->mWidth}"
385 - height="{$this->mHeight}"
 392+ width="{$this->width}"
 393+ height="{$this->height}"
386394 alt="Slippy Map"
387395 title="{$clickToActivate}"/>
388396 <!-- /map div -->
@@ -394,27 +402,27 @@
395403 /* /AIDS */
396404
397405 /**
398 - * Reads $this->mArgsError and returns HTML explaining what the
 406+ * Reads $this->argsError and returns HTML explaining what the
399407 * user did wrong.
400408 */
401409 public function renderErrors() {
402 - return $this->mParser->recursiveTagParse( $this->errorHtml() );
 410+ return $this->parser->recursiveTagParse( $this->errorHtml() );
403411 }
404412
405413 protected function errorHtml() {
406 - if ( count( $this->mArgsError ) == 1 ) {
 414+ if ( count( $this->argsError ) == 1 ) {
407415 return
408416 Xml::tags(
409417 'strong',
410418 array( 'class' => 'error' ),
411419 wfMsg( 'slippymap_error',
412420 wfMsg( 'slippymap_extname' ),
413 - $this->mArgsError[0]
 421+ $this->argsError[0]
414422 )
415423 );
416424 } else {
417425 $li = '';
418 - foreach ($this->mArgsError as $error) {
 426+ foreach ($this->argsError as $error) {
419427 $li .= Xml::tags(
420428 'li',
421429 array( 'class' => 'error' ),
Index: trunk/extensions/SlippyMap/slippyMapParserTests.txt
@@ -191,6 +191,45 @@
192192 !! end
193193
194194 !! test
 195+SlippyMap: Valid/Invalid marker arguments
 196+!! input
 197+== Valid ==
 198+
 199+<slippymap lat=61 lon=95 zoom=1 marker=0 dummy/>
 200+
 201+<slippymap lat=61 lon=95 zoom=1 marker=1 dummy/>
 202+
 203+== Invalid ==
 204+
 205+<slippymap lat=61 lon=95 zoom=1 marker=on dummy/>
 206+
 207+<slippymap lat=61 lon=95 zoom=1 marker=off dummy/>
 208+
 209+<slippymap lat=61 lon=95 zoom=1 marker=11 dummy/>
 210+
 211+<slippymap lat=61 lon=95 zoom=1 marker=00 dummy/>
 212+
 213+<slippymap lat=61 lon=95 zoom=1 marker=true dummy/>
 214+
 215+<slippymap lat=61 lon=95 zoom=1 marker=false dummy/>
 216+
 217+!! result
 218+<a name="Valid" id="Valid"></a><h2><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Valid">edit</a>]</span> <span class="mw-headline"> Valid </span></h2>
 219+<p>A dummy map
 220+</p><p>A dummy map
 221+</p>
 222+<a name="Invalid" id="Invalid"></a><h2><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Invalid">edit</a>]</span> <span class="mw-headline"> Invalid </span></h2>
 223+<p><strong class="error">SlippyMap error: The value <tt>on</tt> is not valid for the <tt>marker</tt> attribute, valid markers are <tt>0</tt> and <tt>1</tt>.</strong>
 224+</p><p><strong class="error">SlippyMap error: The value <tt>off</tt> is not valid for the <tt>marker</tt> attribute, valid markers are <tt>0</tt> and <tt>1</tt>.</strong>
 225+</p><p><strong class="error">SlippyMap error: The value <tt>11</tt> is not valid for the <tt>marker</tt> attribute, valid markers are <tt>0</tt> and <tt>1</tt>.</strong>
 226+</p><p><strong class="error">SlippyMap error: The value <tt>00</tt> is not valid for the <tt>marker</tt> attribute, valid markers are <tt>0</tt> and <tt>1</tt>.</strong>
 227+</p><p><strong class="error">SlippyMap error: The value <tt>true</tt> is not valid for the <tt>marker</tt> attribute, valid markers are <tt>0</tt> and <tt>1</tt>.</strong>
 228+</p><p><strong class="error">SlippyMap error: The value <tt>false</tt> is not valid for the <tt>marker</tt> attribute, valid markers are <tt>0</tt> and <tt>1</tt>.</strong>
 229+</p>
 230+!! end
 231+
 232+
 233+!! test
195234 SlippyMap: Valid caption arguments
196235 !! input
197236 == Valid ==

Status & tagging log