r49307 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r49306‎ | r49307 | r49308 >
Date:10:24, 8 April 2009
Author:avar
Status:deferred
Tags:
Comment:
* Hack the generated JavaScript to allow multiple SlippyMaps per page

* Addded horrid ParseAfterTidy hack so the parser won't have a field
day with my JavaScript, eventually the JS should be added to the
<head> section via some hook (and not have so much duplication)

* Quote some JavaScript code with Xml::escapeJsString, other stuff still needs more escaping!

* Comment out unused KML code
Modified paths:
  • /trunk/extensions/SlippyMap/SlippyMap.class.php (modified) (history)
  • /trunk/extensions/SlippyMap/SlippyMap.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SlippyMap/SlippyMap.php
@@ -59,17 +59,15 @@
6060 $wgAutoloadClasses['SlippyMap'] = $dir . 'SlippyMap.class.php';
6161 $wgExtensionMessagesFiles['SlippyMap'] = $dir . 'SlippyMap.i18n.php';
6262
63 -# Bump this when updating OpenStreetMap.js to help update caches
64 -$wgSlippyMapVersion = 1;
65 -
6663 function wfslippymap() {
67 - global $wgParser, $wgMapOfServiceUrl;
 64+ global $wgParser, $wgHooks, $wgMapOfServiceUrl;
6865 # register the extension with the WikiText parser
6966 # the first parameter is the name of the new tag.
7067 # In this case it defines the tag <slippymap> ... </slippymap>
7168 # the second parameter is the callback function for
7269 # processing the text between the tags
7370 $wgParser->setHook( 'slippymap', array( 'SlippyMap', 'parse' ) );
 71+ $wgHooks['ParserAfterTidy'][] = 'SlippyMap::ParserAfterTidy';
7472 $wgMapOfServiceUrl = "http://osm-tah-cache.firefishy.com/~ojw/MapOf/?";
7573 return true;
7674 }
Index: trunk/extensions/SlippyMap/SlippyMap.class.php
@@ -37,12 +37,18 @@
3838 # @addtogroup Extensions
3939 #
4040
 41+# Evil hack as documented at
 42+# http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F
 43+# This is here so that random <p> and <pre> tags aren't added to the inline JavaScript output
 44+$SlippyMapMarkerList = array( );
 45+
 46+# The number of Slippy Maps we have had thus far, to get unique JavaScript variables
 47+$SlippyMapCounter = 1;
 48+
4149 class SlippyMap {
42 -
4350 # The callback function for converting the input text to HTML output
4451 static function parse( $input, $argv ) {
45 - global $wgScriptPath, $wgMapOfServiceUrl, $wgSlippyMapVersion;
46 -
 52+ global $SlippyMapMarkerList, $SlippyMapCounter;
4753 wfLoadExtensionMessages( 'SlippyMap' );
4854
4955 // Support old style parameters from $input
@@ -132,6 +138,19 @@
133139 $error = 'slippymap tag contents. Were you trying to input KML? KML support ' .
134140 'is disabled pending discussions about wiki syntax';
135141 $showkml = false;
 142+// KML code:
 143+// if ( $showkml ) {
 144+// $input = str_replace( array( '%', "\n" , "'" , '"' , '<' , '>' , ' ' ),
 145+// array( '%25', '%0A', '%27', '%22', '%3C', '%3E', '%20' ), $input );
 146+// $output .= 'var vector = new OpenLayers.Layer.Vector("Vector Layer"); ' .
 147+// ' map.addLayer(vector); ' .
 148+// ' kml = new OpenLayers.Format.KML( { "internalProjection": map.baseLayer.projection, ' .
 149+// ' "externalProjection": epsg4326, ' .
 150+// ' "extractStyles": true, ' .
 151+// ' "extractAttributes": true } ); ' .
 152+// " features = kml.read(unescape('$input')); " .
 153+// ' vector.addFeatures( features ); ';
 154+// }
136155 } else {
137156 $showkml = false;
138157 }
@@ -184,11 +203,11 @@
185204 $layer = strtolower( $layer );
186205 $layerObjectDef = '';
187206 if ( $layer == 'osmarender' ) {
188 - $layerObjectDef = 'OpenLayers.Layer.OSM.Osmarender("Osmarender"); ';
 207+ $layerObjectDef = 'OpenLayers.Layer.OSM.Osmarender("Osmarender");';
189208 } elseif ( $layer == 'mapnik' ) {
190 - $layerObjectDef = 'OpenLayers.Layer.OSM.Mapnik("Mapnik"); ';
 209+ $layerObjectDef = 'OpenLayers.Layer.OSM.Mapnik("Mapnik");';
191210 } elseif ( $layer == 'maplint' ) {
192 - $layerObjectDef = 'OpenLayers.Layer.OSM.Maplint("Maplint"); ';
 211+ $layerObjectDef = 'OpenLayers.Layer.OSM.Maplint("Maplint");';
193212 } else {
194213 $error = wfMsg( 'slippymap_invalidlayer', htmlspecialchars( $layer ) );
195214 }
@@ -198,112 +217,159 @@
199218 $output = '';
200219 $output .= "<span class=\"error\">" . wfMsg( 'slippymap_maperror' ) . ' ' . $error . "</span><br />";
201220 $output .= htmlspecialchars( $input );
 221+ return $output;
202222 } else {
203 - // HTML output for the slippy map.
204 - // Note that this must all be output on one line (no linefeeds)
205 - // otherwise MediaWiki adds <BR> tags, which is bad in the middle of a block of javascript.
206 - // There are other ways of fixing this, but not for MediaWiki v4
207 - // (See http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F)
 223+ $output = self::makeSlippyMapHTMLandJS($lon, $lat, $zoom, $height, $width, $layerObjectDef, $marker, $SlippyMapCounter++);
208224
209 - $output = '<!-- slippy map -->';
 225+ $markercount = count($SlippyMapMarkerList);
 226+ $pMarker = "SlippyMap-marker".$markercount."-SlippyMap";
 227+ $SlippyMapMarkerList[$markercount] = $output;
 228+ return $pMarker;
 229+ }
 230+ }
210231
211 - // This inline stylesheet defines how the two extra buttons look, and where they are positioned.
212 - $output .= "<style> .buttonsPanel div { float:left; display:block; position:relative; left:50px; margin-left:3px; margin-top:7px; width:36px; height:19px; }</style>\n";
213 - $output .= "<style> .buttonsPanel .getWikiCodeButtonItemInactive { width:36px; height:19px; background-image:url('" . $wgScriptPath . "/extensions/SlippyMap/wikicode-button.png'); }</style>\n";
214 - $output .= "<style> .buttonsPanel .resetButtonItemInactive { width:36px; height:19px; background-image:url('" . $wgScriptPath . "/extensions/SlippyMap/reset-button.png'); }</style>\n";
 232+ static function makeSlippyMapHTMLandJS($lon, $lat, $zoom, $height, $width, $layerObjectDef, $marker, $unique) {
 233+ global $wgScriptPath, $wgMapOfServiceUrl;
 234+ // HTML output for the slippy map.
 235+ // Note that this must all be output on one line (no linefeeds)
 236+ // otherwise MediaWiki adds <BR> tags, which is bad in the middle of a block of javascript.
 237+ // There are other ways of fixing this, but not for MediaWiki v4
 238+ // (See http://www.mediawiki.org/wiki/Manual:Tag_extensions#How_can_I_avoid_modification_of_my_extension.27s_HTML_output.3F)
215239
216 - $output .= "<!-- bring in the OpenLayers javascript library -->";
217 - $output .= "<script src=\"http://openlayers.org/api/OpenLayers.js\"></script> ";
 240+ $slippymap_code_marker = '';
 241+ if ( $marker ) {
 242+ $slippymap_code_marker = <<<EOT
 243+var markers${unique} = new OpenLayers.Layer.Markers( "Markers" );
 244+map${unique}.addLayer(markers${unique});
 245+var size${unique} = new OpenLayers.Size(20,34);
 246+var offset${unique} = new OpenLayers.Pixel(-(size${unique}.w/2), -size${unique}.h);
 247+var icon${unique} = new OpenLayers.Icon('http://boston.openguides.org/markers/YELLOW.png', size${unique},offset);
 248+markers${unique}.addMarker(new OpenLayers.Marker( lonLat${unique}, icon${unique} ));
 249+EOT;
 250+ }
218251
219 - $output .= "<!-- bring in the OpenStreetMap OpenLayers layers. ";
220 - $output .= " Using this hosted file will make sure we are kept up ";
221 - $output .= " to date with any necessary changes --> ";
222 - $output .= "<script src=\"http://openstreetmap.org/openlayers/OpenStreetMap.js\"></script> ";
 252+ $slippymap_code_escaped = Xml::escapeJsString( wfMsg( 'slippymap_code' ) );
 253+ $slippymap_button_code = Xml::escapeJsString( wfMsg( 'slippymap_button_code' ) );
 254+ $slippymap_resetview = Xml::escapeJsString( wfMsg( 'slippymap_resetview' ) );
223255
224 - $output .= '<script type="text/javascript">';
 256+ $slippymap_zoom_snippet = '';
 257+ if ( $height > 320 ) {
 258+ // Add the zoom bar control, except if the map is only little
 259+ $slippymap_zoom_snippet = 'new OpenLayers.Control.PanZoomBar(),';
 260+ } else if ( $height > 140 ) {
 261+ $slippymap_zoom_snippet = 'new OpenLayers.Control.PanZoom(),';
 262+ }
225263
226 - $output .= "var lon= ${lon}; var lat= ${lat}; var zoom= ${zoom}; var lonLat;";
 264+ $output = <<<EOT
 265+<!-- Slippy Map -->
227266
228 - $output .= 'var map; ';
 267+<!-- This inline stylesheet defines how the two extra buttons look, and where they are positioned. -->
 268+<style> .buttonsPanel div { float:left; display:block; position:relative; left:50px; margin-left:3px; margin-top:7px; width:36px; height:19px; }</style>
 269+<style> .buttonsPanel .getWikiCodeButtonItemInactive { width:36px; height:19px; background-image:url('" . $wgScriptPath . "/extensions/SlippyMap/wikicode-button.png'); }</style>
 270+<style> .buttonsPanel .resetButtonItemInactive { width:36px; height:19px; background-image:url('" . $wgScriptPath . "/extensions/SlippyMap/reset-button.png'); }</style>
229271
230 - $output .= 'addOnloadHook( slippymap_init ); ';
 272+<!-- bring in the OpenLayers javascript library -->
 273+<script src="http://openlayers.org/api/OpenLayers.js"></script>
231274
232 - $output .= 'function slippymap_resetPosition() {';
233 - $output .= ' map.setCenter(lonLat, zoom);';
234 - $output .= '}';
 275+<!-- bring in the OpenStreetMap OpenLayers layers.
 276+ Using this hosted file will make sure we are kept up
 277+ to date with any necessary changes -->
 278+<script src="http://openstreetmap.org/openlayers/OpenStreetMap.js"></script>
235279
236 - $output .= 'function slippymap_getWikicode() {';
237 - $output .= ' LL = map.getCenter().transform(map.getProjectionObject(), new OpenLayers.Projection("EPSG:4326"));';
238 - $output .= ' Z = map.getZoom(); ';
239 - $output .= ' size = map.getSize();';
 280+<script type="text/javascript">
 281+ var lon${unique} = ${lon};
 282+ var lat${unique} = ${lat};
 283+ var zoom${unique} = ${zoom};
240284
241 - $output .= ' prompt( "' . wfMsg( 'slippymap_code' ) . '", "<slippymap h="+size.h+" w="+size.w+" z="+Z+" lat="+LL.lat+" lon="+LL.lon+" layer=mapnik marker=1></slippymap>" ); ';
242 - $output .= '}';
 285+ var lonLat${unique};
 286+ var map${unique};
243287
244 - $output .= 'function slippymap_init() { ';
245 - $output .= ' map = new OpenLayers.Map("map", { ';
246 - $output .= ' controls:[ ';
247 - $output .= ' new OpenLayers.Control.Navigation(), ';
 288+ addOnloadHook( slippymap_init );
248289
249 - if ( $height > 320 ) {
250 - // Add the zoom bar control, except if the map is only little
251 - $output .= ' new OpenLayers.Control.PanZoomBar(),';
252 - } else if ( $height > 140 ) {
253 - $output .= ' new OpenLayers.Control.PanZoom(),';
254 - }
 290+ function slippymap_resetPosition() {
 291+ map${unique}.setCenter(lonLat${unique}, zoom${unique});
 292+ }
255293
256 - $output .= ' new OpenLayers.Control.Attribution()], ';
257 - $output .= ' maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34), ';
258 - $output .= ' maxResolution:156543.0399, units:\'meters\', projection: "EPSG:900913"} ); ';
 294+ function slippymap_getWikicode() {
 295+ LL = map${unique}.getCenter().transform(map${unique}.getProjectionObject(), new OpenLayers.Projection("EPSG:4326"));
 296+ Z = map${unique}.getZoom();
 297+ size = map${unique}.getSize();
 298+ prompt(
 299+ "${slippymap_code_escaped}",
 300+ "<slippymap h=" + size.h + " w=" + size.w + " z=" + Z + " lat=" + LL.lat + " lon=" + LL.lon + " layer=mapnik marker=1 />"
 301+ );
 302+ }
259303
260 - $output .= ' layer = new ' . $layerObjectDef;
 304+ function slippymap_init() {
 305+ // FIXME: Replace with OpenLayers.Layer.OSM?: http://trac.openlayers.org/changeset/9240
 306+ map${unique} = new OpenLayers.Map("map${unique}", {
 307+ controls:[
 308+ new OpenLayers.Control.Navigation(),
 309+ $slippymap_zoom_snippet
 310+ new OpenLayers.Control.Attribution()
 311+ ],
 312+ maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
 313+ maxResolution:156543.0399,
 314+ units: 'meters',
 315+ projection: "EPSG:900913"
 316+ });
261317
262 - $output .= ' map.addLayer(layer); ';
 318+ layer = new ${layerObjectDef};
 319+ map${unique}.addLayer(layer);
 320+ epsg4326 = new OpenLayers.Projection("EPSG:4326");
 321+ lonLat${unique} = new OpenLayers.LonLat(lon${unique}, lat${unique}).transform( epsg4326, map${unique}.getProjectionObject() );
263322
264 - $output .= ' epsg4326 = new OpenLayers.Projection("EPSG:4326"); ';
265 - $output .= ' lonLat = new OpenLayers.LonLat(lon, lat).transform( epsg4326, map.getProjectionObject()); ';
 323+ $slippymap_code_marker
266324
267 - if ( $marker ) {
268 - $output .= 'var markers = new OpenLayers.Layer.Markers( "Markers" ); ' .
269 - ' map.addLayer(markers); ' .
270 - ' var size = new OpenLayers.Size(20,34); ' .
271 - ' var offset = new OpenLayers.Pixel(-(size.w/2), -size.h); ' .
272 - " var icon = new OpenLayers.Icon('http://boston.openguides.org/markers/YELLOW.png',size,offset);" .
273 - ' markers.addMarker(new OpenLayers.Marker( lonLat,icon)); ';
274 - }
 325+ map${unique}.setCenter(lonLat${unique}, zoom${unique});
275326
276 - if ( $showkml ) {
277 - $input = str_replace( array( '%', "\n" , "'" , '"' , '<' , '>' , ' ' ),
278 - array( '%25', '%0A', '%27', '%22', '%3C', '%3E', '%20' ), $input );
279 - $output .= 'var vector = new OpenLayers.Layer.Vector("Vector Layer"); ' .
280 - ' map.addLayer(vector); ' .
281 - ' kml = new OpenLayers.Format.KML( { "internalProjection": map.baseLayer.projection, ' .
282 - ' "externalProjection": epsg4326, ' .
283 - ' "extractStyles": true, ' .
284 - ' "extractAttributes": true } ); ' .
285 - " features = kml.read(unescape('$input')); " .
286 - ' vector.addFeatures( features ); ';
287 - }
 327+ var getWikiCodeButton = new OpenLayers.Control.Button({
 328+ title: "${slippymap_button_code}",
 329+ displayClass: "getWikiCodeButton",
 330+ trigger: slippymap_getWikicode
 331+ });
288332
289 - $output .= ' map.setCenter (lonLat, zoom); ';
290 - $output .= ' var getWikiCodeButton = new OpenLayers.Control.Button({title: "' . wfMsg( 'slippymap_button_code' ) . '", displayClass: "getWikiCodeButton", trigger: slippymap_getWikicode}); ';
291 - $output .= ' var resetButton = new OpenLayers.Control.Button({title: "' . wfMsg( 'slippymap_resetview' ) . '", displayClass: "resetButton", trigger: slippymap_resetPosition}); ';
292 - $output .= ' var panel = new OpenLayers.Control.Panel( { displayClass: "buttonsPanel"}); ';
293 - $output .= ' panel.addControls([getWikiCodeButton, resetButton]); ';
294 - $output .= ' map.addControl(panel); ';
295 - $output .= '} ';
 333+ var resetButton = new OpenLayers.Control.Button({
 334+ title: "${slippymap_resetview}",
 335+ displayClass: "resetButton",
 336+ trigger: slippymap_resetPosition
 337+ });
296338
 339+ var panel${unique} = new OpenLayers.Control.Panel( { displayClass: "buttonsPanel" } );
 340+ panel${unique}.addControls([getWikiCodeButton, resetButton]);
 341+ map${unique}.addControl(panel${unique});
 342+ }
 343+</script>
297344
298 - $output .= "</script> ";
 345+<div style="width: {$width}px; height:{$height}px; border-style:solid; border-width:1px; border-color:lightgrey;" id="map${unique}">
 346+<noscript>
 347+ <a href="http://www.openstreetmap.org/?lat=${lat}&lon=${lon}&zoom=${zoom}" title="See this map on OpenStreetMap.org" style="text-decoration:none">
 348+ <img
 349+ src="${wgMapOfServiceUrl}lat=${lat}&long=${lon}&z=${zoom}&w=${width}&h=${height}&format=jpeg"
 350+ width="${width}"
 351+ height="${height}"
 352+ border="0"
 353+ alt="Slippy Map" />
 354+ <br />
 355+ </a>
 356+</noscript>
 357+</div>
 358+EOT;
299359
300 - $output .= "<div style=\"width: {$width}px; height:{$height}px; border-style:solid; border-width:1px; border-color:lightgrey;\" id=\"map\">";
301 - $output .= "<noscript><a href=\"http://www.openstreetmap.org/?lat=$lat&lon=$lon&zoom=$zoom\" title=\"See this map on OpenStreetMap.org\" style=\"text-decoration:none\">";
302 - $output .= "<img src=\"" . $wgMapOfServiceUrl . "lat=${lat}&long=${lon}&z=${zoom}&w=${width}&h=${height}&format=jpeg\" width=\"${width}\" height=\"${height}\" border=\"0\" alt=\"Slippy Map\"><br />";
303 - $output .= '</a></noscript>';
304 - $output .= '</div>';
 360+ return $output;
 361+ }
305362
306 - if ( sizeof( $oldStyleParamStrings ) > 2 ) $output .= '<div style="font-size:0.8em;"><i>please change to <a href="http://wiki.openstreetmap.org/index.php/Slippy_Map_MediaWiki_Extension">new syntax</a></i></div>';
 363+ // Hack, see beginning of file for why
 364+ static function ParserAfterTidy(&$parser, &$text) {
 365+ global $SlippyMapMarkerList;
 366+ $keys = array();
 367+ $marker_count = count($SlippyMapMarkerList);
 368+
 369+ for ($i = 0; $i < $marker_count; $i++) {
 370+ $keys[] = 'SlippyMap-marker' . $i . '-SlippyMap';
307371 }
308 - return $output;
 372+
 373+ $text = str_replace($keys, $SlippyMapMarkerList, $text);
 374+ return true;
309375 }
310376 }

Status & tagging log