mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/ImageMap
synced 2024-11-23 22:03:31 +00:00
Description icon link, area link title attributes
This commit is contained in:
parent
778eb8eeb4
commit
284a684cea
|
@ -2,7 +2,6 @@
|
|||
|
||||
/**
|
||||
* Image map extension.
|
||||
* TODO: image description link (icon)
|
||||
*
|
||||
* Syntax:
|
||||
* <imagemap>
|
||||
|
@ -11,6 +10,7 @@
|
|||
* rect 0 0 50 50 [[Foo type A]]
|
||||
* circle 50 50 20 [[Foo type B]]
|
||||
*
|
||||
* desc bottom-left
|
||||
* </imagemap>
|
||||
*
|
||||
* Coordinates are relative to the source image, not the thumbnail
|
||||
|
@ -28,22 +28,35 @@ $wgMessageCache->addMessages( array(
|
|||
'default, rect, circle or poly',
|
||||
'imagemap_no_areas' => '<imagemap>: at least one area specification must be given',
|
||||
'imagemap_invalid_coord' => '<imagemap>: invalid coordinate at line $1, must be a number',
|
||||
'imagemap_invalid_desc' => '<imagemap>: invalid desc specification, must be one of: $1',
|
||||
'imagemap_description' => 'About this image',
|
||||
# Note to translators: keep the same order
|
||||
'imagemap_desc_types' => 'top-right, bottom-right, bottom-left, top-left, none',
|
||||
));
|
||||
class ImageMap {
|
||||
static public $id = 0;
|
||||
|
||||
const TOP_RIGHT = 0;
|
||||
const BOTTOM_RIGHT = 1;
|
||||
const BOTTOM_LEFT = 2;
|
||||
const TOP_LEFT = 3;
|
||||
const NONE = 4;
|
||||
|
||||
static function render( $input, $params, $parser ) {
|
||||
global $wgScriptPath;
|
||||
|
||||
$lines = explode( "\n", $input );
|
||||
|
||||
$first = true;
|
||||
$lineNum = 0;
|
||||
$output = '';
|
||||
$links = array();
|
||||
$descType = self::BOTTOM_RIGHT;
|
||||
foreach ( $lines as $line ) {
|
||||
++$lineNum;
|
||||
|
||||
$line = trim( $line );
|
||||
if ( $line == '' ) {
|
||||
if ( $line == '' || $line[0] == '#' ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -65,14 +78,15 @@ class ImageMap {
|
|||
}
|
||||
$imageHTML = $parser->makeImage( $imageTitle, $options );
|
||||
|
||||
$sx = simplexml_load_string( $imageHTML );
|
||||
$imgs = $sx->xpath( '//img' );
|
||||
if ( !count( $imgs ) ) {
|
||||
$domDoc = DOMDocument::loadXML( $imageHTML );
|
||||
$xpath = new DOMXPath( $domDoc );
|
||||
$imgs = $xpath->query( '//img' );
|
||||
if ( !$imgs->length ) {
|
||||
return self::error( 'imagemap_invalid_image' );
|
||||
}
|
||||
$imageNode = $imgs[0];
|
||||
$thumbWidth = $imageNode['width'];
|
||||
$thumbHeight = $imageNode['height'];
|
||||
$imageNode = $imgs->item(0);
|
||||
$thumbWidth = $imageNode->getAttribute('width');
|
||||
$thumbHeight = $imageNode->getAttribute('height');
|
||||
|
||||
$imageObj = new Image( $imageTitle );
|
||||
# Add the linear dimensions to avoid inaccuracy in the scale
|
||||
|
@ -87,6 +101,19 @@ class ImageMap {
|
|||
continue;
|
||||
}
|
||||
|
||||
# Handle desc spec
|
||||
$cmd = strtok( $line, " \t" );
|
||||
if ( $cmd == 'desc' ) {
|
||||
$typesText = wfMsgForContent( 'imagemap_desc_types' );
|
||||
$types = array_map( 'trim', explode( ',', $typesText ) );
|
||||
$type = trim( strtok( '' ) );
|
||||
$descType = array_search( $type, $types );
|
||||
if ( $descType === false ) {
|
||||
return self::error( 'imagemap_invalid_desc', $typesText );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
# Find the link
|
||||
$link = trim( strstr( $line, '[[' ) );
|
||||
if ( preg_match( '/^ \[\[ ([^|]*+) \| ([^\]]*+) \]\] \w* $ /x', $link, $m ) ) {
|
||||
|
@ -94,7 +121,7 @@ class ImageMap {
|
|||
$alt = trim( $m[2] );
|
||||
} elseif ( preg_match( '/^ \[\[ ([^\]]*+) \]\] \w* $ /x', $link, $m ) ) {
|
||||
$title = Title::newFromText( $m[1] );
|
||||
$alt = false;
|
||||
$alt = $title->getFullText();
|
||||
} else {
|
||||
return self::error( 'imagemap_no_link', $lineNum );
|
||||
}
|
||||
|
@ -144,13 +171,14 @@ class ImageMap {
|
|||
# Construct the area tag
|
||||
$attribs = array(
|
||||
'shape' => $shape,
|
||||
'href' => $title->escapeLocalURL()
|
||||
'href' => $title->escapeLocalURL(),
|
||||
);
|
||||
if ( $coords ) {
|
||||
$attribs['coords'] = implode( ',', $coords );
|
||||
}
|
||||
if ( $alt != '' ) {
|
||||
$attribs['alt'] = $alt;
|
||||
$attribs['title'] = $alt;
|
||||
}
|
||||
$output .= Xml::element( 'area', $attribs ) . "\n";
|
||||
$links[] = $title;
|
||||
|
@ -168,15 +196,55 @@ class ImageMap {
|
|||
$mapName = "ImageMap_" . ++self::$id;
|
||||
$output = "<map name=\"$mapName\">\n$output</map>\n";
|
||||
|
||||
# Alter the image tag and output it
|
||||
$imageNode['usemap'] = $mapName;
|
||||
$output .= $imageNode->asXML();
|
||||
# Alter the image tag
|
||||
$imageNode->setAttribute( 'usemap', "#$mapName" );
|
||||
|
||||
# Add a surrounding div, remove the default link to the description page
|
||||
$anchor = $imageNode->parentNode;
|
||||
$parent = $anchor->parentNode;
|
||||
$div = $parent->insertBefore( new DOMElement( 'div' ), $anchor );
|
||||
$div->setAttribute( 'style', 'position: relative;' );
|
||||
$div->appendChild( $imageNode->cloneNode( true ) );
|
||||
$parent->removeChild( $anchor );
|
||||
|
||||
# Determine whether a "magnify" link is present
|
||||
$xpath = new DOMXPath( $domDoc );
|
||||
$magnify = $xpath->query( '//div[@class="magnify"]' );
|
||||
if ( !$magnify->length && $descType != self::NONE ) {
|
||||
# Add image description link
|
||||
if ( $descType == self::TOP_LEFT || $descType == self::BOTTOM_LEFT ) {
|
||||
$descLeft = 0;
|
||||
} else {
|
||||
$descLeft = $thumbWidth - 20;
|
||||
}
|
||||
if ( $descType == self::TOP_LEFT || $descType == self::TOP_RIGHT ) {
|
||||
$descTop = 0;
|
||||
} else {
|
||||
$descTop = $thumbHeight - 20;
|
||||
}
|
||||
$descAnchor = $div->appendChild( new DOMElement( 'a' ) );
|
||||
$descAnchor->setAttribute( 'href', $imageTitle->escapeLocalURL() );
|
||||
$descAnchor->setAttribute( 'title', wfMsgForContent( 'imagemap_description' ) );
|
||||
$descAnchor->setAttribute( 'style', "position:absolute; top: {$descTop}px; left: {$descLeft}px;" );
|
||||
$descImg = $descAnchor->appendChild( new DOMElement( 'img' ) );
|
||||
$descImg->setAttribute( 'alt', wfMsgForContent( 'imagemap_description' ) );
|
||||
$descImg->setAttribute( 'src', "$wgScriptPath/extensions/ImageMap/desc-20.png" );
|
||||
$descImg->setAttribute( 'style', 'border: none;' );
|
||||
}
|
||||
|
||||
# Output the result
|
||||
# We use saveXML() not saveHTML() because then we get XHTML-compliant output.
|
||||
# The disadvantage is that we have to strip out the DTD
|
||||
$output .= preg_replace( '/<\?xml[^?]*\?>/', '', $domDoc->saveXML() );
|
||||
|
||||
# Register links
|
||||
$parser->mOutput->addImage( $imageTitle->getDBkey() );
|
||||
foreach ( $links as $title ) {
|
||||
$parser->mOutput->addLink( $title );
|
||||
}
|
||||
|
||||
# Armour output against broken parser
|
||||
$output = str_replace( "\n", '', $output );
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
|
BIN
desc-20.png
Normal file
BIN
desc-20.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 488 B |
82
desc.svg
Normal file
82
desc.svg
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.44"
|
||||
sodipodi:docbase="C:\htdocs\w2\extensions\ImageMap"
|
||||
sodipodi:docname="desc.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="796.52647"
|
||||
inkscape:cy="480.05164"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:window-width="853"
|
||||
inkscape:window-height="609"
|
||||
inkscape:window-x="307"
|
||||
inkscape:window-y="247" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g3657"
|
||||
transform="translate(-99.99995,-350.0001)">
|
||||
<path
|
||||
transform="matrix(1.014493,0,0,1.029412,-27.53629,174.9305)"
|
||||
d="M 717.14285 463.79074 A 295.71429 291.42856 0 1 1 125.71426,463.79074 A 295.71429 291.42856 0 1 1 717.14285 463.79074 z"
|
||||
sodipodi:ry="291.42856"
|
||||
sodipodi:rx="295.71429"
|
||||
sodipodi:cy="463.79074"
|
||||
sodipodi:cx="421.42856"
|
||||
id="path1872"
|
||||
style="opacity:1;fill:blue;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<flowRoot
|
||||
transform="matrix(6.2409,0,0,4.446071,-1211.524,-1867.093)"
|
||||
style="font-size:144px;fill:white;fill-opacity:1;stroke:none;stroke-opacity:1;font-family:Times New Roman"
|
||||
id="flowRoot2764"
|
||||
xml:space="preserve"><flowRegion
|
||||
id="flowRegion2766"><rect
|
||||
style="font-size:144px;fill:white;fill-opacity:1;stroke:none;stroke-opacity:1;font-family:Times New Roman"
|
||||
y="495.21933"
|
||||
x="234.28572"
|
||||
height="297.14285"
|
||||
width="354.28571"
|
||||
id="rect2768" /></flowRegion><flowPara
|
||||
style="font-size:144px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:white;fill-opacity:1;stroke:none;stroke-opacity:1;font-family:Times New Roman"
|
||||
id="flowPara2770">i</flowPara></flowRoot> </g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
Loading…
Reference in a new issue