Cparle has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/385352 )
Change subject: Treat svg systemLanguage attribs as arbitrary strings
......................................................................
Treat svg systemLanguage attribs as arbitrary strings
Also implement matching of systemLanguage attribs as
specified in the SVG spec
Note that librsvg that we use for rendering pngs of svg
files has a bug, and matches languages in the following
way instead of what is implemented in SVG::getMatchedLanguage()
public function getMatchedLanguage( $userPreferredLanguage, array $svgLanguages
) {
foreach ( $svgLanguages as $svgLang ) {
if ($svgLang == $userPreferredLanguage) {
return $svgLang;
}
$dashPosition = strpos( $userPreferredLanguage, '-' );
if ( $dashPosition !== false ) {
if (
strtolower( substr( $svgLang, 0, $dashPosition ) ) ==
strtolower( substr( $userPreferredLanguage, 0, $dashPosition ) )
) {
return $svgLang;
}
}
return null;
}
Bug: T154132
Change-Id: Ibff66a0844f0cecfae0260c6a7d20aeedc2849a2
---
M includes/filerepo/file/File.php
M includes/media/MediaHandler.php
M includes/media/SVG.php
M includes/media/SVGMetadataExtractor.php
M includes/page/ImagePage.php
M tests/phpunit/includes/media/SVGMetadataExtractorTest.php
6 files changed, 135 insertions(+), 91 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/52/385352/1
diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php
index 32f4504..e046f46 100644
--- a/includes/filerepo/file/File.php
+++ b/includes/filerepo/file/File.php
@@ -582,6 +582,25 @@
}
/**
+ * Get the language code from the available languages for this file
that matches the language
+ * requested by the user
+ *
+ * @param string $userPreferredLanguage
+ * @return string
+ */
+ public function getMatchedLanguage( $userPreferredLanguage ) {
+ $handler = $this->getHandler();
+ if ( $handler ) {
+ return $handler->getMatchedLanguage(
+ $userPreferredLanguage,
+ $handler->getAvailableLanguages( $this )
+ );
+ } else {
+ return null;
+ }
+ }
+
+ /**
* In files that support multiple language, what is the default language
* to use if none specified.
*
diff --git a/includes/media/MediaHandler.php b/includes/media/MediaHandler.php
index 481e880..a962e77 100644
--- a/includes/media/MediaHandler.php
+++ b/includes/media/MediaHandler.php
@@ -781,6 +781,23 @@
}
/**
+ * Get the language code from the available languages for this file
that matches the language
+ * requested by the user
+ *
+ * @param string $userPreferredLanguage
+ * @param array $availableLanguages
+ * @return string
+ */
+ public function getMatchedLanguage( $userPreferredLanguage, array
$availableLanguages ) {
+ foreach ($availableLanguages as $availableLanguage) {
+ if ($userPreferredLanguage == $availableLanguage) {
+ return $availableLanguage;
+ }
+ }
+ return null;
+ }
+
+ /**
* On file types that support renderings in multiple languages,
* which language is used by default if unspecified.
*
diff --git a/includes/media/SVG.php b/includes/media/SVG.php
index bd78b49..03a69d3 100644
--- a/includes/media/SVG.php
+++ b/includes/media/SVG.php
@@ -96,23 +96,53 @@
$metadata = $this->unpackMetadata( $metadata );
if ( isset( $metadata['translations'] ) ) {
foreach ( $metadata['translations'] as $lang =>
$langType ) {
- if ( $langType ===
SVGReader::LANG_FULL_MATCH ) {
- $langList[] = $lang;
- }
+ $langList[] = $lang;
}
}
}
- return $langList;
+ return array_unique( $langList );
}
/**
- * What language to render file in if none selected.
+ * SVG's systemLanguage matching rules state:
+ * 'The `systemLanguage` attribute ... [e]valuates to "true" if one of
the languages indicated
+ * by user preferences exactly equals one of the languages given in the
value of this parameter,
+ * or if one of the languages indicated by user preferences exactly
equals a prefix of one of
+ * the languages given in the value of this parameter such that the
first tag character
+ * following the prefix is "-".'
+ *
+ * Return the first element of $svgLanguages that matches
$userPreferredLanguage
+ *
+ * @see https://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute
+ * @param string $userPreferredLanguage
+ * @param array $svgLanguages
+ * @return bool
+ */
+ public function getMatchedLanguage( $userPreferredLanguage, array
$svgLanguages ) {
+ foreach ( $svgLanguages as $svgLang ) {
+ if ($svgLang == $userPreferredLanguage) {
+ return $svgLang;
+ }
+ list ($svgLangPrefix, ) = explode( '-', $svgLang);
+ if ($svgLangPrefix == $userPreferredLanguage) {
+ return $svgLang;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * What language to render file in if none selected
+ *
+ * SVG does not have a way of specifying which language is default,
therefore return the user's
+ * interface language
*
* @param File $file
- * @return string Language code.
+ * @return string
*/
public function getDefaultRenderLanguage( File $file ) {
- return 'en';
+ global $wgLang;
+ return $wgLang->getCode();
}
/**
@@ -479,7 +509,7 @@
return ( $value > 0 );
} elseif ( $name == 'lang' ) {
// Validate $code
- if ( $value === '' || !Language::isValidBuiltInCode(
$value ) ) {
+ if ( $value === '' || !Language::isValidCode( $value )
) {
wfDebug( "Invalid user language code\n" );
return false;
diff --git a/includes/media/SVGMetadataExtractor.php
b/includes/media/SVGMetadataExtractor.php
index 9b22cbe..a7daf13 100644
--- a/includes/media/SVGMetadataExtractor.php
+++ b/includes/media/SVGMetadataExtractor.php
@@ -43,8 +43,6 @@
const DEFAULT_WIDTH = 512;
const DEFAULT_HEIGHT = 512;
const NS_SVG = 'http://www.w3.org/2000/svg';
- const LANG_PREFIX_MATCH = 1;
- const LANG_FULL_MATCH = 2;
/** @var null|XMLReader */
private $reader = null;
@@ -265,25 +263,9 @@
// See
https://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute
$langList = explode( ',', $sysLang );
foreach ( $langList as $langItem ) {
- $langItem = trim( $langItem );
- if (
Language::isWellFormedLanguageTag( $langItem ) ) {
-
$this->languages[$langItem] = self::LANG_FULL_MATCH;
- }
- // Note, the standard says that
any prefix should work,
- // here we do only the initial
prefix, since that will catch
- // 99% of cases, and we are
going to compare against fallbacks.
- // This differs mildly from how
the spec says languages should be
- // handled, however it matches
better how the MediaWiki language
- // preference is generally
handled.
- $dash = strpos( $langItem, '-'
);
- // Intentionally checking both
!false and > 0 at the same time.
- if ( $dash ) {
- $itemPrefix = substr(
$langItem, 0, $dash );
- if (
Language::isWellFormedLanguageTag( $itemPrefix ) ) {
-
$this->languagePrefixes[$itemPrefix] = self::LANG_PREFIX_MATCH;
- }
- }
+ $this->languages[] = trim(
$langItem );
}
+ $this->languages = array_unique(
$this->languages );
}
switch ( $this->reader->localName ) {
case 'script':
diff --git a/includes/page/ImagePage.php b/includes/page/ImagePage.php
index 62f5d00..c37f73e 100644
--- a/includes/page/ImagePage.php
+++ b/includes/page/ImagePage.php
@@ -285,6 +285,24 @@
return parent::getContentObject();
}
+ private function getLanguageForRendering( WebRequest $request, File
$file ) {
+ $handler = $this->displayImg->getHandler();
+
+ $requestLanguage = $request->getVal( 'lang' );
+ if ( !is_null( $requestLanguage ) ) {
+ if ( $handler && $handler->validateParam( 'lang',
$requestLanguage ) ) {
+ return $requestLanguage;
+ }
+ }
+
+ $defaultLanguage = $handler->getDefaultRenderLanguage(
$this->displayImg );
+ if ( !is_null( $defaultLanguage ) ) {
+ return $defaultLanguage;
+ }
+
+ return null;
+ }
+
protected function openShowImage() {
global $wgEnableUploads, $wgSend404Code, $wgSVGMaxSize;
@@ -309,14 +327,9 @@
$params = [ 'page' => $page ];
}
- $renderLang = $request->getVal( 'lang' );
+ $renderLang = $this->getLanguageForRendering( $request,
$this->displayImg );
if ( !is_null( $renderLang ) ) {
- $handler = $this->displayImg->getHandler();
- if ( $handler && $handler->validateParam(
'lang', $renderLang ) ) {
- $params['lang'] = $renderLang;
- } else {
- $renderLang = null;
- }
+ $params['lang'] = $renderLang;
}
$width_orig = $this->displayImg->getWidth( $page );
@@ -544,12 +557,7 @@
$renderLangOptions =
$this->displayImg->getAvailableLanguages();
if ( count( $renderLangOptions ) >= 1 ) {
- $currentLanguage = $renderLang;
- $defaultLang =
$this->displayImg->getDefaultRenderLanguage();
- if ( is_null( $currentLanguage ) ) {
- $currentLanguage = $defaultLang;
- }
- $out->addHTML( $this->doRenderLangOpt(
$renderLangOptions, $currentLanguage, $defaultLang ) );
+ $out->addHTML( $this->doRenderLangOpt(
$renderLangOptions, $renderLang ) );
}
// Add cannot animate thumbnail warning
@@ -1047,58 +1055,30 @@
* Output a drop-down box for language options for the file
*
* @param array $langChoices Array of string language codes
- * @param string $curLang Language code file is being viewed in.
- * @param string $defaultLang Language code that image is rendered in
by default
+ * @param string $renderLang Language code for the language we want the
file to rendered in.
* @return string HTML to insert underneath image.
*/
- protected function doRenderLangOpt( array $langChoices, $curLang,
$defaultLang ) {
+ protected function doRenderLangOpt( array $langChoices, $renderLang ) {
global $wgScript;
- sort( $langChoices );
- $curLang = LanguageCode::bcp47( $curLang );
- $defaultLang = LanguageCode::bcp47( $defaultLang );
$opts = '';
- $haveCurrentLang = false;
- $haveDefaultLang = false;
- // We make a list of all the language choices in the file.
- // Additionally if the default language to render this file
- // is not included as being in this file (for example, in svgs
- // usually the fallback content is the english content) also
- // include a choice for that. Last of all, if we're viewing
- // the file in a language not on the list, add it as a choice.
+ $matchedRenderLang = $this->displayImg->getMatchedLanguage(
$renderLang );
+
foreach ( $langChoices as $lang ) {
- $code = LanguageCode::bcp47( $lang );
- $name = Language::fetchLanguageName( $code,
$this->getContext()->getLanguage()->getCode() );
- if ( $name !== '' ) {
- $display = $this->getContext()->msg(
'img-lang-opt', $code, $name )->text();
- } else {
- $display = $code;
- }
- $opts .= "\n" . Xml::option( $display, $code, $curLang
=== $code );
- if ( $curLang === $code ) {
- $haveCurrentLang = true;
- }
- if ( $defaultLang === $code ) {
- $haveDefaultLang = true;
- }
+ $opts .= $this->createXmlOptionStringForLanguage(
+ $lang,
+ $matchedRenderLang === $lang
+ );
}
- if ( !$haveDefaultLang ) {
- // Its hard to know if the content is really in the
default language, or
- // if its just unmarked content that could be in any
language.
- $opts = Xml::option(
- $this->getContext()->msg(
'img-lang-default' )->text(),
- $defaultLang,
- $defaultLang === $curLang
- ) . $opts;
- }
- if ( !$haveCurrentLang && $defaultLang !== $curLang ) {
- $name = Language::fetchLanguageName( $curLang,
$this->getContext()->getLanguage()->getCode() );
- if ( $name !== '' ) {
- $display = $this->getContext()->msg(
'img-lang-opt', $curLang, $name )->text();
- } else {
- $display = $curLang;
- }
- $opts = Xml::option( $display, $curLang, true ) . $opts;
+
+ //If the requested language was not matched, display an extra
option containing it
+ //This is to allow for the default case in an svg <switch> that
is displayed if no
+ //systemLanguage attribute matches
+ if ( is_null( $matchedRenderLang ) ) {
+ $opts .= $this->createXmlOptionStringForLanguage(
+ $renderLang,
+ true
+ );
}
$select = Html::rawElement(
@@ -1119,6 +1099,23 @@
return $langSelectLine;
}
+ private function createXmlOptionStringForLanguage( $lang, $selected )
+ {
+ $code = LanguageCode::bcp47( $lang );
+ $name = Language::fetchLanguageName( $code,
$this->getContext()->getLanguage()->getCode() );
+ if ( $name !== '' ) {
+ $display = $this->getContext()->msg( 'img-lang-opt',
$code, $name )->text();
+ } else {
+ $display = $lang;
+ }
+ return "\n" .
+ Xml::option(
+ $display,
+ $lang,
+ $selected
+ );
+ }
+
/**
* Get the width and height to display image at.
*
diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php
b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php
index 9bfd5f6..cb263ea 100644
--- a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php
+++ b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php
@@ -104,11 +104,10 @@
'originalWidth' => '17.7cm',
'originalHeight' => '13cm',
'translations' => [
- 'de' =>
SVGReader::LANG_FULL_MATCH,
- 'fr' =>
SVGReader::LANG_FULL_MATCH,
- 'nl' =>
SVGReader::LANG_FULL_MATCH,
- 'tlh-ca' =>
SVGReader::LANG_FULL_MATCH,
- 'tlh' =>
SVGReader::LANG_PREFIX_MATCH
+ 'de',
+ 'fr',
+ 'nl',
+ 'tlh-ca'
],
]
],
--
To view, visit https://gerrit.wikimedia.org/r/385352
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibff66a0844f0cecfae0260c6a7d20aeedc2849a2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Cparle <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits