Description icon link, area link title attributes

This commit is contained in:
Tim Starling 2006-12-13 05:55:37 +00:00
parent 778eb8eeb4
commit 284a684cea
3 changed files with 165 additions and 15 deletions

View file

@ -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' => '&lt;imagemap&gt;: at least one area specification must be given',
'imagemap_invalid_coord' => '&lt;imagemap&gt;: invalid coordinate at line $1, must be a number',
'imagemap_invalid_desc' => '&lt;imagemap&gt;: 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

82
desc.svg Normal file
View 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