FreedomFighterSparrow has uploaded a new change for review. https://gerrit.wikimedia.org/r/324722
Change subject: Add a page prop and a tracking category for errors ...................................................................... Add a page prop and a tracking category for errors Use an exception class for handling errors, instead of an internal function. Bug: T106075 Change-Id: I43d1740fdc9556b980c6f5985235df1722cc3614 --- A ImageMapException.php M ImageMap_body.php M extension.json M i18n/en.json M i18n/he.json 5 files changed, 360 insertions(+), 320 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ImageMap refs/changes/22/324722/1 diff --git a/ImageMapException.php b/ImageMapException.php new file mode 100644 index 0000000..b0a6c2e --- /dev/null +++ b/ImageMapException.php @@ -0,0 +1,27 @@ +<?php + +class ImageMapException extends Exception { + /** + * Constructor. + * + * @param $message Message to create error message from. Should have one $1 parameter. + * @param $code int optionally, an error code. + * @param $previous Exception that caused this exception. + */ + public function __construct( $message, $code = 0, Exception $previous = null ) { + parent::__construct( $message->inContentLanguage()->parse(), $code, $previous ); + } + /** + * Auto-renders exception as HTML error message in the wiki's content + * language. + * + * @return string Error message HTML. + */ + public function __toString() { + return Html::rawElement( + 'div', + array( 'class' => 'errorbox' ), + $this->getMessage() + ); + } +} diff --git a/ImageMap_body.php b/ImageMap_body.php index b65bb02..99dbb97 100644 --- a/ImageMap_body.php +++ b/ImageMap_body.php @@ -35,339 +35,350 @@ } /** - * @param $input - * @param $params + * @param $input string + * @param $params [] * @param $parser Parser + * + * @throws ImageMapException * @return string HTML (Image map, or error message) */ public static function render( $input, $params, $parser ) { global $wgUrlProtocols, $wgNoFollowLinks; $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' ); - $lines = explode( "\n", $input ); + try { + $lines = explode( "\n", $input ); - $first = true; - $lineNum = 0; - $mapHTML = ''; - $links = array(); + $first = true; + $lineNum = 0; + $mapHTML = ''; + $links = array(); - // Define canonical desc types to allow i18n of 'imagemap_desc_types' - $descTypesCanonical = 'top-right, bottom-right, bottom-left, top-left, none'; - $descType = self::BOTTOM_RIGHT; - $defaultLinkAttribs = false; - $realmap = true; - $extLinks = array(); - foreach ( $lines as $line ) { - ++$lineNum; - $externLink = false; + // Define canonical desc types to allow i18n of 'imagemap_desc_types' + $descTypesCanonical = 'top-right, bottom-right, bottom-left, top-left, none'; + $descType = self::BOTTOM_RIGHT; + $defaultLinkAttribs = false; + $realmap = true; + $extLinks = array(); + foreach ( $lines as $line ) { + ++$lineNum; + $externLink = false; - $line = trim( $line ); - if ( $line == '' || $line[0] == '#' ) { - continue; + $line = trim( $line ); + if ( $line == '' || $line[0] == '#' ) { + continue; + } + + if ( $first ) { + $first = false; + + // The first line should have an image specification on it + // Extract it and render the HTML + $bits = explode( '|', $line, 2 ); + if ( count( $bits ) == 1 ) { + $image = $bits[0]; + $options = ''; + } else { + list( $image, $options ) = $bits; + } + $imageTitle = Title::newFromText( $image ); + if ( !$imageTitle || !$imageTitle->inNamespace( NS_FILE ) ) { + throw new ImageMapException( wfMessage( 'imagemap_no_image' ) ); + } + if ( wfIsBadImage( $imageTitle->getDBkey(), $parser->mTitle ) ) { + throw new ImageMapException( wfMessage( 'imagemap_bad_image' ) ); + } + // Parse the options so we can use links and the like in the caption + $parsedOptions = $parser->recursiveTagParse( $options ); + $imageHTML = $parser->makeImage( $imageTitle, $parsedOptions ); + $parser->replaceLinkHolders( $imageHTML ); + $imageHTML = $parser->mStripState->unstripBoth( $imageHTML ); + $imageHTML = Sanitizer::normalizeCharReferences( $imageHTML ); + + $domDoc = new DOMDocument(); + wfSuppressWarnings(); + $ok = $domDoc->loadXML( $imageHTML ); + wfRestoreWarnings(); + if ( !$ok ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_image' ) ); + } + $xpath = new DOMXPath( $domDoc ); + $imgs = $xpath->query( '//img' ); + if ( !$imgs->length ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_image' ) ); + } + $imageNode = $imgs->item( 0 ); + $thumbWidth = $imageNode->getAttribute( 'width' ); + $thumbHeight = $imageNode->getAttribute( 'height' ); + + $imageObj = wfFindFile( $imageTitle ); + if ( !$imageObj || !$imageObj->exists() ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_image' ) ); + } + // Add the linear dimensions to avoid inaccuracy in the scale + // factor when one is much larger than the other + // (sx+sy)/(x+y) = s + $denominator = $imageObj->getWidth() + $imageObj->getHeight(); + $numerator = $thumbWidth + $thumbHeight; + if ( $denominator <= 0 || $numerator <= 0 ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_image' ) ); + } + $scale = $numerator / $denominator; + continue; + } + + // Handle desc spec + $cmd = strtok( $line, " \t" ); + if ( $cmd == 'desc' ) { + $typesText = wfMessage( 'imagemap_desc_types' )->inContentLanguage()->text(); + if ( $descTypesCanonical != $typesText ) { + // i18n desc types exists + $typesText = $descTypesCanonical . ', ' . $typesText; + } + $types = array_map( 'trim', explode( ',', $typesText ) ); + $type = trim( strtok( '' ) ); + $descType = array_search( $type, $types ); + if ( $descType > 4 ) { + // A localized descType is used. Subtract 5 to reach the canonical desc type. + $descType = $descType - 5; + } + // <0? In theory never, but paranoia... + if ( $descType === false || $descType < 0 ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_desc', $typesText ) ); + } + continue; + } + + $title = false; + // Find the link + $link = trim( strstr( $line, '[' ) ); + $m = array(); + if ( preg_match( '/^ \[\[ ([^|]*+) \| ([^\]]*+) \]\] \w* $ /x', $link, $m ) ) { + $title = Title::newFromText( $m[1] ); + $alt = trim( $m[2] ); + } elseif ( preg_match( '/^ \[\[ ([^\]]*+) \]\] \w* $ /x', $link, $m ) ) { + $title = Title::newFromText( $m[1] ); + if ( is_null( $title ) ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_title', $lineNum ) ); + } + $alt = $title->getFullText(); + } elseif ( in_array( substr( $link, 1, strpos( $link, '//' ) + 1 ), $wgUrlProtocols ) || in_array( substr( $link, 1, strpos( $link, ':' ) ), $wgUrlProtocols ) ) { + if ( preg_match( '/^ \[ ([^\s]*+) \s ([^\]]*+) \] \w* $ /x', $link, $m ) ) { + $title = $m[1]; + $alt = trim( $m[2] ); + $externLink = true; + } elseif ( preg_match( '/^ \[ ([^\]]*+) \] \w* $ /x', $link, $m ) ) { + $title = $alt = trim( $m[1] ); + $externLink = true; + } + } else { + throw new ImageMapException( wfMessage( 'imagemap_no_link', $lineNum ) ); + } + if ( !$title ) { + throw new ImageMapException( wfMessage( 'imagemap_invalid_title', $lineNum ) ); + } + + $shapeSpec = substr( $line, 0, -strlen( $link ) ); + + // Tokenize shape spec + $shape = strtok( $shapeSpec, " \t" ); + switch ( $shape ) { + case 'default': + $coords = array(); + break; + case 'rect': + $coords = self::tokenizeCoords( 4, $lineNum ); + if ( !is_array( $coords ) ) { + return $coords; + } + break; + case 'circle': + $coords = self::tokenizeCoords( 3, $lineNum ); + if ( !is_array( $coords ) ) { + return $coords; + } + break; + case 'poly': + $coords = array(); + $coord = strtok( " \t" ); + while ( $coord !== false ) { + $coords[] = $coord; + $coord = strtok( " \t" ); + } + if ( !count( $coords ) ) { + throw new ImageMapException( wfMessage( 'imagemap_missing_coord', $lineNum ) ); + } + if ( count( $coords ) % 2 !== 0 ) { + throw new ImageMapException( wfMessage( 'imagemap_poly_odd', $lineNum ) ); + } + break; + default: + throw new ImageMapException( wfMessage( 'imagemap_unrecognised_shape', $lineNum ) ); + } + + // Scale the coords using the size of the source image + foreach ( $coords as $i => $c ) { + $coords[$i] = intval( round( $c * $scale ) ); + } + + // Construct the area tag + $attribs = array(); + if ( $externLink ) { + $attribs['href'] = $title; + $attribs['class'] = 'plainlinks'; + if ( $wgNoFollowLinks ) { + $attribs['rel'] = 'nofollow'; + } + } elseif ( $title->getFragment() != '' && $title->getPrefixedDBkey() == '' ) { + // XXX: kluge to handle [[#Fragment]] links, should really fix getLocalURL() + // in Title.php to return an empty string in this case + $attribs['href'] = $title->getFragmentForURL(); + } else { + $attribs['href'] = $title->getLocalURL() . $title->getFragmentForURL(); + } + if ( $shape != 'default' ) { + $attribs['shape'] = $shape; + } + if ( $coords ) { + $attribs['coords'] = implode( ',', $coords ); + } + if ( $alt != '' ) { + if ( $shape != 'default' ) { + $attribs['alt'] = $alt; + } + $attribs['title'] = $alt; + } + if ( $shape == 'default' ) { + $defaultLinkAttribs = $attribs; + } else { + $mapHTML .= Xml::element( 'area', $attribs ) . "\n"; + } + if ( $externLink ) { + $extLinks[] = $title; + } else { + $links[] = $title; + } } if ( $first ) { - $first = false; + throw new ImageMapException( wfMessage( 'imagemap_no_image' ) ); + } - // The first line should have an image specification on it - // Extract it and render the HTML - $bits = explode( '|', $line, 2 ); - if ( count( $bits ) == 1 ) { - $image = $bits[0]; - $options = ''; + if ( $mapHTML == '' ) { + // no areas defined, default only. It's not a real imagemap, so we do not need some tags + $realmap = false; + } + + if ( $realmap ) { + // Construct the map + // Add random number to avoid breaking cached HTML fragments that are + // later joined together on the one page (bug 16471) + $mapName = "ImageMap_" . ++self::$id . '_' . mt_rand( 0, 0x7fffffff ); + $mapHTML = "<map name=\"$mapName\">\n$mapHTML</map>\n"; + + // 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( 'class', 'noresize' ); + if ( $defaultLinkAttribs ) { + $defaultAnchor = $div->appendChild( new DOMElement( 'a' ) ); + foreach ( $defaultLinkAttribs as $name => $value ) { + $defaultAnchor->setAttribute( $name, $value ); + } + $imageParent = $defaultAnchor; + } else { + $imageParent = $div; + } + + // Add the map HTML to the div + // We used to add it before the div, but that made tidy unhappy + if ( $mapHTML != '' ) { + $mapDoc = new DOMDocument(); + $mapDoc->loadXML( $mapHTML ); + $mapNode = $domDoc->importNode( $mapDoc->documentElement, true ); + $div->appendChild( $mapNode ); + } + + $imageParent->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 ) { + $marginLeft = 0; } else { - list( $image, $options ) = $bits; + $marginLeft = $thumbWidth - 20; } - $imageTitle = Title::newFromText( $image ); - if ( !$imageTitle || !$imageTitle->inNamespace( NS_FILE ) ) { - return self::error( 'imagemap_no_image' ); + if ( $descType == self::TOP_LEFT || $descType == self::TOP_RIGHT ) { + $marginTop = -$thumbHeight; + // 1px hack for IE, to stop it poking out the top + $marginTop += 1; + } else { + $marginTop = -20; } - if ( wfIsBadImage( $imageTitle->getDBkey(), $parser->mTitle ) ) { - return self::error( 'imagemap_bad_image' ); - } - // Parse the options so we can use links and the like in the caption - $parsedOptions = $parser->recursiveTagParse( $options ); - $imageHTML = $parser->makeImage( $imageTitle, $parsedOptions ); - $parser->replaceLinkHolders( $imageHTML ); - $imageHTML = $parser->mStripState->unstripBoth( $imageHTML ); - $imageHTML = Sanitizer::normalizeCharReferences( $imageHTML ); + $div->setAttribute( 'style', "height: {$thumbHeight}px; width: {$thumbWidth}px; " ); + $descWrapper = $div->appendChild( new DOMElement( 'div' ) ); + $descWrapper->setAttribute( 'style', + "margin-left: {$marginLeft}px; " . + "margin-top: {$marginTop}px; " . + "text-align: left;" + ); - $domDoc = new DOMDocument(); - wfSuppressWarnings(); - $ok = $domDoc->loadXML( $imageHTML ); - wfRestoreWarnings(); - if ( !$ok ) { - return self::error( 'imagemap_invalid_image' ); - } - $xpath = new DOMXPath( $domDoc ); - $imgs = $xpath->query( '//img' ); - if ( !$imgs->length ) { - return self::error( 'imagemap_invalid_image' ); - } - $imageNode = $imgs->item( 0 ); - $thumbWidth = $imageNode->getAttribute( 'width' ); - $thumbHeight = $imageNode->getAttribute( 'height' ); - - $imageObj = wfFindFile( $imageTitle ); - if ( !$imageObj || !$imageObj->exists() ) { - return self::error( 'imagemap_invalid_image' ); - } - // Add the linear dimensions to avoid inaccuracy in the scale - // factor when one is much larger than the other - // (sx+sy)/(x+y) = s - $denominator = $imageObj->getWidth() + $imageObj->getHeight(); - $numerator = $thumbWidth + $thumbHeight; - if ( $denominator <= 0 || $numerator <= 0 ) { - return self::error( 'imagemap_invalid_image' ); - } - $scale = $numerator / $denominator; - continue; + $descAnchor = $descWrapper->appendChild( new DOMElement( 'a' ) ); + $descAnchor->setAttribute( 'href', $imageTitle->getLocalURL() ); + $descAnchor->setAttribute( + 'title', + wfMessage( 'imagemap_description' )->inContentLanguage()->text() + ); + $descImg = $descAnchor->appendChild( new DOMElement( 'img' ) ); + $descImg->setAttribute( + 'alt', + wfMessage( 'imagemap_description' )->inContentLanguage()->text() + ); + $url = $config->get( 'ExtensionAssetsPath' ) . '/ImageMap/desc-20.png'; + $descImg->setAttribute( + 'src', + OutputPage::transformResourcePath( $config, $url ) + ); + $descImg->setAttribute( 'style', 'border: none;' ); } - // Handle desc spec - $cmd = strtok( $line, " \t" ); - if ( $cmd == 'desc' ) { - $typesText = wfMessage( 'imagemap_desc_types' )->inContentLanguage()->text(); - if ( $descTypesCanonical != $typesText ) { - // i18n desc types exists - $typesText = $descTypesCanonical . ', ' . $typesText; - } - $types = array_map( 'trim', explode( ',', $typesText ) ); - $type = trim( strtok( '' ) ); - $descType = array_search( $type, $types ); - if ( $descType > 4 ) { - // A localized descType is used. Subtract 5 to reach the canonical desc type. - $descType = $descType - 5; - } - // <0? In theory never, but paranoia... - if ( $descType === false || $descType < 0 ) { - return self::error( 'imagemap_invalid_desc', $typesText ); - } - continue; - } + // 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() ); - $title = false; - // Find the link - $link = trim( strstr( $line, '[' ) ); - $m = array(); - if ( preg_match( '/^ \[\[ ([^|]*+) \| ([^\]]*+) \]\] \w* $ /x', $link, $m ) ) { - $title = Title::newFromText( $m[1] ); - $alt = trim( $m[2] ); - } elseif ( preg_match( '/^ \[\[ ([^\]]*+) \]\] \w* $ /x', $link, $m ) ) { - $title = Title::newFromText( $m[1] ); - if ( is_null( $title ) ) { - return self::error( 'imagemap_invalid_title', $lineNum ); + // Register links + foreach ( $links as $title ) { + if ( $title->isExternal() || $title->getNamespace() == NS_SPECIAL ) { + // Don't register special or interwiki links... + } elseif ( $title->getNamespace() == NS_MEDIA ) { + // Regular Media: links are recorded as image usages + $parser->mOutput->addImage( $title->getDBkey() ); + } else { + // Plain ol' link + $parser->mOutput->addLink( $title ); } - $alt = $title->getFullText(); - } elseif ( in_array( substr( $link, 1, strpos( $link, '//' ) + 1 ), $wgUrlProtocols ) || in_array( substr( $link, 1, strpos( $link, ':' ) ), $wgUrlProtocols ) ) { - if ( preg_match( '/^ \[ ([^\s]*+) \s ([^\]]*+) \] \w* $ /x', $link, $m ) ) { - $title = $m[1]; - $alt = trim( $m[2] ); - $externLink = true; - } elseif ( preg_match( '/^ \[ ([^\]]*+) \] \w* $ /x', $link, $m ) ) { - $title = $alt = trim( $m[1] ); - $externLink = true; - } - } else { - return self::error( 'imagemap_no_link', $lineNum ); } - if ( !$title ) { - return self::error( 'imagemap_invalid_title', $lineNum ); + foreach ( $extLinks as $title ) { + $parser->mOutput->addExternalLink( $title ); } - - $shapeSpec = substr( $line, 0, -strlen( $link ) ); - - // Tokenize shape spec - $shape = strtok( $shapeSpec, " \t" ); - switch ( $shape ) { - case 'default': - $coords = array(); - break; - case 'rect': - $coords = self::tokenizeCoords( 4, $lineNum ); - if ( !is_array( $coords ) ) { - return $coords; - } - break; - case 'circle': - $coords = self::tokenizeCoords( 3, $lineNum ); - if ( !is_array( $coords ) ) { - return $coords; - } - break; - case 'poly': - $coords = array(); - $coord = strtok( " \t" ); - while ( $coord !== false ) { - $coords[] = $coord; - $coord = strtok( " \t" ); - } - if ( !count( $coords ) ) { - return self::error( 'imagemap_missing_coord', $lineNum ); - } - if ( count( $coords ) % 2 !== 0 ) { - return self::error( 'imagemap_poly_odd', $lineNum ); - } - break; - default: - return self::error( 'imagemap_unrecognised_shape', $lineNum ); - } - - // Scale the coords using the size of the source image - foreach ( $coords as $i => $c ) { - $coords[$i] = intval( round( $c * $scale ) ); - } - - // Construct the area tag - $attribs = array(); - if ( $externLink ) { - $attribs['href'] = $title; - $attribs['class'] = 'plainlinks'; - if ( $wgNoFollowLinks ) { - $attribs['rel'] = 'nofollow'; - } - } elseif ( $title->getFragment() != '' && $title->getPrefixedDBkey() == '' ) { - // XXX: kluge to handle [[#Fragment]] links, should really fix getLocalURL() - // in Title.php to return an empty string in this case - $attribs['href'] = $title->getFragmentForURL(); - } else { - $attribs['href'] = $title->getLocalURL() . $title->getFragmentForURL(); - } - if ( $shape != 'default' ) { - $attribs['shape'] = $shape; - } - if ( $coords ) { - $attribs['coords'] = implode( ',', $coords ); - } - if ( $alt != '' ) { - if ( $shape != 'default' ) { - $attribs['alt'] = $alt; - } - $attribs['title'] = $alt; - } - if ( $shape == 'default' ) { - $defaultLinkAttribs = $attribs; - } else { - $mapHTML .= Xml::element( 'area', $attribs ) . "\n"; - } - if ( $externLink ) { - $extLinks[] = $title; - } else { - $links[] = $title; - } + } catch ( ImageMapException $e ) { + $parser->addTrackingCategory( 'imagemap-error-category' ); + $output = "$e"; } - if ( $first ) { - return self::error( 'imagemap_no_image' ); - } + // Mark the page as using this extension, so we can track its use + $parser->getOutput()->setProperty( 'imagemap' , true ); - if ( $mapHTML == '' ) { - // no areas defined, default only. It's not a real imagemap, so we do not need some tags - $realmap = false; - } - - if ( $realmap ) { - // Construct the map - // Add random number to avoid breaking cached HTML fragments that are - // later joined together on the one page (bug 16471) - $mapName = "ImageMap_" . ++self::$id . '_' . mt_rand( 0, 0x7fffffff ); - $mapHTML = "<map name=\"$mapName\">\n$mapHTML</map>\n"; - - // 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( 'class', 'noresize' ); - if ( $defaultLinkAttribs ) { - $defaultAnchor = $div->appendChild( new DOMElement( 'a' ) ); - foreach ( $defaultLinkAttribs as $name => $value ) { - $defaultAnchor->setAttribute( $name, $value ); - } - $imageParent = $defaultAnchor; - } else { - $imageParent = $div; - } - - // Add the map HTML to the div - // We used to add it before the div, but that made tidy unhappy - if ( $mapHTML != '' ) { - $mapDoc = new DOMDocument(); - $mapDoc->loadXML( $mapHTML ); - $mapNode = $domDoc->importNode( $mapDoc->documentElement, true ); - $div->appendChild( $mapNode ); - } - - $imageParent->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 ) { - $marginLeft = 0; - } else { - $marginLeft = $thumbWidth - 20; - } - if ( $descType == self::TOP_LEFT || $descType == self::TOP_RIGHT ) { - $marginTop = -$thumbHeight; - // 1px hack for IE, to stop it poking out the top - $marginTop += 1; - } else { - $marginTop = -20; - } - $div->setAttribute( 'style', "height: {$thumbHeight}px; width: {$thumbWidth}px; " ); - $descWrapper = $div->appendChild( new DOMElement( 'div' ) ); - $descWrapper->setAttribute( 'style', - "margin-left: {$marginLeft}px; " . - "margin-top: {$marginTop}px; " . - "text-align: left;" - ); - - $descAnchor = $descWrapper->appendChild( new DOMElement( 'a' ) ); - $descAnchor->setAttribute( 'href', $imageTitle->getLocalURL() ); - $descAnchor->setAttribute( - 'title', - wfMessage( 'imagemap_description' )->inContentLanguage()->text() - ); - $descImg = $descAnchor->appendChild( new DOMElement( 'img' ) ); - $descImg->setAttribute( - 'alt', - wfMessage( 'imagemap_description' )->inContentLanguage()->text() - ); - $url = $config->get( 'ExtensionAssetsPath' ) . '/ImageMap/desc-20.png'; - $descImg->setAttribute( - 'src', - OutputPage::transformResourcePath( $config, $url ) - ); - $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 - foreach ( $links as $title ) { - if ( $title->isExternal() || $title->getNamespace() == NS_SPECIAL ) { - // Don't register special or interwiki links... - } elseif ( $title->getNamespace() == NS_MEDIA ) { - // Regular Media: links are recorded as image usages - $parser->mOutput->addImage( $title->getDBkey() ); - } else { - // Plain ol' link - $parser->mOutput->addLink( $title ); - } - } - foreach ( $extLinks as $title ) { - $parser->mOutput->addExternalLink( $title ); - } // Armour output against broken parser $output = str_replace( "\n", '', $output ); return $output; @@ -376,6 +387,8 @@ /** * @param $count int * @param $lineNum int|string + * + * @throws ImageMapException * @return array|string String with error (HTML), or array of coordinates */ static function tokenizeCoords( $count, $lineNum ) { @@ -383,22 +396,14 @@ for ( $i = 0; $i < $count; $i++ ) { $coord = strtok( " \t" ); if ( $coord === false ) { - return self::error( 'imagemap_missing_coord', $lineNum ); + throw new ImageMapException( wfMessage( 'imagemap_missing_coord', $lineNum ) ); } if ( !is_numeric( $coord ) || $coord > 1e9 || $coord < 0 ) { - return self::error( 'imagemap_invalid_coord', $lineNum ); + throw new ImageMapException( wfMessage( 'imagemap_invalid_coord', $lineNum ) ); } $coords[$i] = $coord; } return $coords; } - /** - * @param $name string - * @param $line string|int|bool - * @return string HTML - */ - static function error( $name, $line = false ) { - return '<p class="error">' . wfMessage( $name, $line )->text() . '</p>'; - } } diff --git a/extension.json b/extension.json index 572c149..cb9cd59 100644 --- a/extension.json +++ b/extension.json @@ -16,8 +16,12 @@ ] }, "AutoloadClasses": { - "ImageMap": "ImageMap_body.php" + "ImageMap": "ImageMap_body.php", + "ImageMapException": "ImageMapException.php" }, + "TrackingCategories": [ + "imagemap-error-category" + ], "ParserTestFiles": [ "imageMapParserTests.txt" ], diff --git a/i18n/en.json b/i18n/en.json index c396853..7226ab7 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -16,5 +16,7 @@ "imagemap_invalid_desc": "Error: Invalid desc specification, must be one of: <code>$1</code>.", "imagemap_description": "About this image", "imagemap_desc_types": "top-right, bottom-right, bottom-left, top-left, none", - "imagemap_poly_odd": "Error: Found poly with odd number of coordinates on line $1" -} \ No newline at end of file + "imagemap_poly_odd": "Error: Found poly with odd number of coordinates on line $1", + "imagemap-error-category": "Pages with imagemap rendering errors", + "imagemap-error-category-desc": "There was an error while rendering the imagemap." +} diff --git a/i18n/he.json b/i18n/he.json index 93372fd..383c8a7 100644 --- a/i18n/he.json +++ b/i18n/he.json @@ -16,5 +16,7 @@ "imagemap_invalid_coord": "שגיאה;: קוארדינאטה שגויה בשורה $1, היא חייבת להיות מספר", "imagemap_invalid_desc": "שגיאה: הגדרת פרמטר desc שגויה, צריך להיות אחד מהבאים: $1", "imagemap_description": "אודות התמונה", - "imagemap_poly_odd": "שגיאה: איזור poly עם מספר אי־זוגי של קואורדינטות בשורה $1" + "imagemap_poly_odd": "שגיאה: איזור poly עם מספר אי־זוגי של קואורדינטות בשורה $1", + "imagemap-error-category": "דפים עם שגיאות בהכנת מפת תמונה", + "imagemap-error-category-desc": "אירעה שגיאה בעת הכנת מפת תמונה להצגה." } -- To view, visit https://gerrit.wikimedia.org/r/324722 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I43d1740fdc9556b980c6f5985235df1722cc3614 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/ImageMap Gerrit-Branch: master Gerrit-Owner: FreedomFighterSparrow <freedomfighterspar...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits