From add60907903f8cf722d5b30430769bd333e09304 Mon Sep 17 00:00:00 2001 From: "Mark A. Hershberger" Date: Thu, 7 Jan 2010 09:32:09 +0000 Subject: [PATCH] Make LTR wgLang do the right thing on RTL wgContLang wikis. See bug 6100 and dupes like bug 4047, bug 19228, bug 9137, etc. --- includes/Linker.php | 62 ++++++++++++++++++++------------------- includes/SkinTemplate.php | 5 +++- includes/SpecialPage.php | 38 ++++++++++++------------ includes/Title.php | 11 +++++-- skins/Modern.php | 20 ++++++------- skins/MonoBook.php | 16 +++++----- skins/Vector.php | 8 ++--- 7 files changed, 86 insertions(+), 74 deletions(-) diff --git a/includes/Linker.php b/includes/Linker.php index abab9e3f75..27be4795cd 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -110,7 +110,7 @@ class Linker { if ( $t->isRedirect() ) { # Page is a redirect $colour = 'mw-redirect'; - } elseif ( $threshold > 0 && + } elseif ( $threshold > 0 && $t->exists() && $t->getLength() < $threshold && MWNamespace::isContent( $t->getNamespace() ) ) { # Page is a stub @@ -369,7 +369,7 @@ class Linker { } } - /** + /** * Returns the filename part of an url. * Used as alternative text for external images. */ @@ -383,7 +383,7 @@ class Linker { return $basename; } - /** + /** * Return the code for images which were added via external links, * via Parser::maybeMakeExternalImage(). */ @@ -621,7 +621,7 @@ class Linker { # So we don't need to pass it here in $query. However, the URL for the # zoom icon still needs it, so we make a unique query for it. See bug 14771 $url = $title->getLocalURL( $query ); - if( $page ) { + if( $page ) { $url = wfAppendQuery( $url, 'page=' . urlencode( $page ) ); } @@ -692,7 +692,7 @@ class Linker { } list( $inside, $trail ) = self::splitTrail( $trail ); - + wfProfileOut( __METHOD__ ); return Html::element( 'a', array( 'href' => $href, @@ -740,9 +740,9 @@ class Linker { } } - /** + /** * Make a link to a special page given its name and, optionally, - * a message key from the link text. + * a message key from the link text. * Usage example: $skin->specialLink( 'recentchanges' ) */ function specialLink( $name, $key = '' ) { @@ -761,14 +761,14 @@ class Linker { * @param boolean $escape Do we escape the link text? * @param String $linktype Type of external link. Gets added to the classes * @param array $attribs Array of extra attributes to - * - * @todo FIXME: This is a really crappy implementation. $linktype and + * + * @todo FIXME: This is a really crappy implementation. $linktype and * 'external' are mashed into the class attrib for the link (which is made - * into a string). Then, if we've got additional params in $attribs, we + * into a string). Then, if we've got additional params in $attribs, we * add to it. People using this might want to change the classes (or other - * default link attributes), but passing $attribsText is just messy. Would - * make a lot more sense to make put the classes into $attribs, let the - * hook play with them, *then* expand it all at once. + * default link attributes), but passing $attribsText is just messy. Would + * make a lot more sense to make put the classes into $attribs, let the + * hook play with them, *then* expand it all at once. */ function makeExternalLink( $url, $text, $escape = true, $linktype = '', $attribs = array() ) { if ( isset( $attribs[ 'class' ] ) ) $class = $attribs[ 'class' ]; # yet another hack :( @@ -895,7 +895,7 @@ class Linker { if( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) { $link = wfMsgHtml( 'rev-deleted-user' ); } else if( $rev->userCan( Revision::DELETED_USER ) ) { - $link = $this->userLink( $rev->getUser( Revision::FOR_THIS_USER ), + $link = $this->userLink( $rev->getUser( Revision::FOR_THIS_USER ), $rev->getUserText( Revision::FOR_THIS_USER ) ); } else { $link = wfMsgHtml( 'rev-deleted-user' ); @@ -917,7 +917,7 @@ class Linker { $link = wfMsgHtml( 'rev-deleted-user' ); } else if( $rev->userCan( Revision::DELETED_USER ) ) { $userId = $rev->getUser( Revision::FOR_THIS_USER ); - $userText = $rev->getUserText( Revision::FOR_THIS_USER ); + $userText = $rev->getUserText( Revision::FOR_THIS_USER ); $link = $this->userLink( $userId, $userText ) . ' ' . $this->userToolLinks( $userId, $userText ); } else { @@ -986,11 +986,11 @@ class Linker { unset( $this->autocommentLocal ); return $comment; } - + private function formatAutocommentsCallback( $match ) { $title = $this->autocommentTitle; $local = $this->autocommentLocal; - + $pre=$match[1]; $auto=$match[2]; $post=$match[3]; @@ -1009,7 +1009,7 @@ class Linker { if ( $local ) { $sectionTitle = Title::newFromText( '#' . $section ); } else { - $sectionTitle = Title::makeTitleSafe( $title->getNamespace(), + $sectionTitle = Title::makeTitleSafe( $title->getNamespace(), $title->getDBkey(), $section ); } if ( $sectionTitle ) { @@ -1091,11 +1091,11 @@ class Linker { if (isset($match[1][0]) && $match[1][0] == ':') $match[1] = substr($match[1], 1); list( $inside, $trail ) = Linker::splitTrail( $trail ); - + $linkText = $text; $linkTarget = Linker::normalizeSubpageLink( $this->commentContextTitle, $match[1], $linkText ); - + $target = Title::newFromText( $linkTarget ); if( $target ) { if( $target->getText() == '' && !$this->commentLocal && $this->commentContextTitle ) { @@ -1116,7 +1116,7 @@ class Linker { return $comment; } - + static function normalizeSubpageLink( $contextTitle, $target, &$text ) { # Valid link forms: # Foobar -- normal @@ -1277,14 +1277,14 @@ class Linker { /** * End a Table Of Contents line. - * tocUnindent() will be used instead if we're ending a line below + * tocUnindent() will be used instead if we're ending a line below * the new level. */ function tocLineEnd() { return "\n"; } - /** + /** * Wraps the TOC in a table and provides the hide/collapse javascript. * @param string $toc html of the Table Of Contents * @return string Full html of the TOC @@ -1306,7 +1306,7 @@ class Linker { . ' } ' ) . "\n"; } - + /** * Generate a table of contents from a section tree * Currently unused. @@ -1324,7 +1324,7 @@ class Linker { $lastLevel - $section['toclevel'] ); else $toc .= $this->tocLineEnd(); - + $toc .= $this->tocLine( $section['anchor'], $section['line'], $section['number'], $section['toclevel'], $section['index'] ); @@ -1347,6 +1347,8 @@ class Linker { * @return string HTML to use for edit link */ public function doEditSectionLink( Title $nt, $section, $tooltip = null ) { + // HTML generated here should probably have userlangattributes + // added to it for LTR text on RTL pages $attribs = array(); if( !is_null( $tooltip ) ) { $attribs['title'] = wfMsg( 'editsectionhint', $tooltip ); @@ -1644,7 +1646,7 @@ class Linker { wfProfileOut( __METHOD__ ); return false; } - + /** * Creates a (show/hide) link for deleting revisions/log entries * @@ -1662,7 +1664,7 @@ class Linker { $link = $this->link( $sp, $text, array(), $query, array( 'known', 'noclasses' ) ); return Xml::tags( $tag, array( 'class' => 'mw-revdelundel-link' ), "($link)" ); } - + /** * Creates a dead (show/hide) link for deleting revisions/log entries * @@ -2000,7 +2002,7 @@ class Linker { /** * Returns the attributes for the tooltip and access key */ - public function tooltipAndAccesskeyAttribs( $name ) { + public function tooltipAndAccesskeyAttribs( $name ) { global $wgEnableTooltipsAndAccesskeys; if ( !$wgEnableTooltipsAndAccesskeys ) return ''; @@ -2023,9 +2025,9 @@ class Linker { * @deprecated Returns raw bits of HTML, use titleAttrib() and accesskey() */ public function tooltipAndAccesskey( $name ) { - return Xml::expandAttributes( $this->tooltipAndAccesskeyAttribs( $name ) ); + return Xml::expandAttributes( $this->tooltipAndAccesskeyAttribs( $name ) ); } - + /** @deprecated Returns raw bits of HTML, use titleAttrib() */ public function tooltip( $name, $options = null ) { diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php index 8f98870e67..3c52dcd863 100644 --- a/includes/SkinTemplate.php +++ b/includes/SkinTemplate.php @@ -304,7 +304,10 @@ class SkinTemplate extends Skin { $tpl->setRef( 'userpage', $this->userpage ); $tpl->setRef( 'userpageurl', $this->userpageUrlDetails['href'] ); $tpl->set( 'userlang', $wgLang->getCode() ); - $tpl->set( 'userlangattributes', 'lang="' . $wgLang->getCode() . '" xml:lang="' . $wgLang->getCode() . '"' ); + $tpl->set( 'userlangattributes', 'lang="' . $wgLang->getCode() . '" xml:lang="' . $wgLang->getCode() . '" dir="' . $wgLang->getDir() . '"'); + if($this->mTitle->isSpecialPage()) { + $tpl->set( 'specialpageattributes', 'lang="' . $wgLang->getCode() . '" xml:lang="' . $wgLang->getCode() . '" dir="' . $wgLang->getDir() . '"'); + } $newtalks = $wgUser->getNewMessageLinks(); diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php index aa81a1a767..5903e36717 100644 --- a/includes/SpecialPage.php +++ b/includes/SpecialPage.php @@ -89,30 +89,30 @@ class SpecialPage { 'Fewestrevisions' => array( 'SpecialPage', 'Fewestrevisions' ), 'Withoutinterwiki' => array( 'SpecialPage', 'Withoutinterwiki' ), 'Protectedpages' => array( 'SpecialPage', 'Protectedpages' ), - 'Protectedtitles' => array( 'SpecialPage', 'Protectedtitles' ), - 'Shortpages' => array( 'SpecialPage', 'Shortpages' ), - 'Uncategorizedcategories' => array( 'SpecialPage', 'Uncategorizedcategories' ), - 'Uncategorizedimages' => array( 'SpecialPage', 'Uncategorizedimages' ), - 'Uncategorizedpages' => array( 'SpecialPage', 'Uncategorizedpages' ), + 'Protectedtitles' => array( 'SpecialPage', 'Protectedtitles' ), + 'Shortpages' => array( 'SpecialPage', 'Shortpages' ), + 'Uncategorizedcategories' => array( 'SpecialPage', 'Uncategorizedcategories' ), + 'Uncategorizedimages' => array( 'SpecialPage', 'Uncategorizedimages' ), + 'Uncategorizedpages' => array( 'SpecialPage', 'Uncategorizedpages' ), 'Uncategorizedtemplates' => array( 'SpecialPage', 'Uncategorizedtemplates' ), 'Unusedcategories' => array( 'SpecialPage', 'Unusedcategories' ), - 'Unusedimages' => array( 'SpecialPage', 'Unusedimages' ), + 'Unusedimages' => array( 'SpecialPage', 'Unusedimages' ), 'Unusedtemplates' => array( 'SpecialPage', 'Unusedtemplates' ), - 'Unwatchedpages' => array( 'SpecialPage', 'Unwatchedpages', 'unwatchedpages' ), + 'Unwatchedpages' => array( 'SpecialPage', 'Unwatchedpages', 'unwatchedpages' ), 'Wantedcategories' => array( 'SpecialPage', 'Wantedcategories' ), 'Wantedfiles' => array( 'SpecialPage', 'Wantedfiles' ), 'Wantedpages' => array( 'IncludableSpecialPage', 'Wantedpages' ), 'Wantedtemplates' => array( 'SpecialPage', 'Wantedtemplates' ), # List of pages - 'Allpages' => 'SpecialAllpages', - 'Prefixindex' => 'SpecialPrefixindex', + 'Allpages' => 'SpecialAllpages', + 'Prefixindex' => 'SpecialPrefixindex', 'Categories' => array( 'SpecialPage', 'Categories' ), 'Disambiguations' => array( 'SpecialPage', 'Disambiguations' ), - 'Listredirects' => array( 'SpecialPage', 'Listredirects' ), + 'Listredirects' => array( 'SpecialPage', 'Listredirects' ), # Login/create account - 'Userlogin' => array( 'SpecialPage', 'Userlogin' ), + 'Userlogin' => array( 'SpecialPage', 'Userlogin' ), 'CreateAccount' => array( 'SpecialRedirectToSpecial', 'CreateAccount', 'Userlogin', 'signup', array( 'uselang' ) ), # Users and rights @@ -120,15 +120,15 @@ class SpecialPage { 'Ipblocklist' => array( 'SpecialPage', 'Ipblocklist' ), 'Resetpass' => 'SpecialResetpass', 'DeletedContributions' => 'DeletedContributionsPage', - 'Preferences' => 'SpecialPreferences', - 'Contributions' => 'SpecialContributions', + 'Preferences' => 'SpecialPreferences', + 'Contributions' => 'SpecialContributions', 'Listgrouprights' => 'SpecialListGroupRights', 'Listusers' => array( 'SpecialPage', 'Listusers' ), 'Activeusers' => 'SpecialActiveUsers', 'Userrights' => 'UserrightsPage', # Recent changes and logs - 'Newimages' => array( 'IncludableSpecialPage', 'Newimages' ), + 'Newimages' => array( 'IncludableSpecialPage', 'Newimages' ), 'Log' => array( 'SpecialPage', 'Log' ), 'Watchlist' => array( 'SpecialPage', 'Watchlist' ), 'Newpages' => 'SpecialNewpages', @@ -168,14 +168,14 @@ class SpecialPage { 'Import' => 'SpecialImport', 'Undelete' => array( 'SpecialPage', 'Undelete', 'deletedhistory' ), 'Whatlinkshere' => 'SpecialWhatlinkshere', - 'MergeHistory' => array( 'SpecialPage', 'MergeHistory', 'mergehistory' ), - + 'MergeHistory' => array( 'SpecialPage', 'MergeHistory', 'mergehistory' ), + # Other 'Booksources' => 'SpecialBookSources', - + # Unlisted / redirects 'Blankpage' => 'SpecialBlankpage', - 'Blockme' => array( 'UnlistedSpecialPage', 'Blockme' ), + 'Blockme' => array( 'UnlistedSpecialPage', 'Blockme' ), 'Emailuser' => array( 'UnlistedSpecialPage', 'Emailuser' ), 'Listadmins' => array( 'SpecialRedirectToSpecial', 'Listadmins', 'Listusers', 'sysop' ), 'Listbots' => array( 'SpecialRedirectToSpecial', 'Listbots', 'Listusers', 'bot' ), @@ -798,7 +798,7 @@ Perhaps no page aliases are defined for it?" ); * Outputs a summary message on top of special pages * Per default the message key is the canonical name of the special page * May be overriden, i.e. by extensions to stick with the naming conventions - * for message keys: 'extensionname-xxx' + * for message keys: 'extensionname-xxx' * * @param string message key of the summary */ diff --git a/includes/Title.php b/includes/Title.php index f279ae375c..919107e034 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -2693,12 +2693,12 @@ class Title { if( !File::checkExtensionCompatibility( $file, $nt->getDBkey() ) ) { $errors[] = array('imagetypemismatch'); } - } + } $destfile = wfLocalFile( $nt ); if( !$wgUser->isAllowed( 'reupload-shared' ) && !$destfile->exists() && wfFindFile( $nt ) ) { $errors[] = array( 'file-exists-sharedrepo' ); } - + } if ( $auth ) { @@ -3657,6 +3657,13 @@ class Title { return $prepend . $namespaceKey; } + /** + * Returns true if this is a special page. + */ + public function isSpecialPage( ) { + return $this->getNamespace() == NS_SPECIAL; + } + /** * Returns true if this title resolves to the named special page * @param $name \type{\string} The special page name diff --git a/skins/Modern.php b/skins/Modern.php index 87687adeb0..aa95adc9d1 100644 --- a/skins/Modern.php +++ b/skins/Modern.php @@ -20,7 +20,7 @@ class SkinModern extends SkinTemplate { $template = 'ModernTemplate', $useHeadElement = true; /* - * We don't like the default getPoweredBy, the icon clashes with the + * We don't like the default getPoweredBy, the icon clashes with the * skin L&F. */ function getPoweredBy() { @@ -113,9 +113,9 @@ class ModernTemplate extends QuickTemplate { -
+
-
+
html("userlangattributes") ?>> - data['sidebar']; + data['sidebar']; if ( !isset( $sidebar['SEARCH'] ) ) $sidebar['SEARCH'] = true; if ( !isset( $sidebar['TOOLBOX'] ) ) $sidebar['TOOLBOX'] = true; if ( !isset( $sidebar['LANGUAGES'] ) ) $sidebar['LANGUAGES'] = true; @@ -185,8 +185,8 @@ class ModernTemplate extends QuickTemplate {
- - diff --git a/skins/MonoBook.php b/skins/MonoBook.php index 9218295074..3c2c1a30ec 100644 --- a/skins/MonoBook.php +++ b/skins/MonoBook.php @@ -81,13 +81,13 @@ class MonoBookTemplate extends QuickTemplate { class="mediawiki text('dir'); $this->text('capitalizeallnouns') ?> text('pageclass') ?> text('skinnameclass') ?>">
-
+
html("specialpageattributes") ?>> data['sitenotice']) { ?>
html('sitenotice') ?>

html('title') ?>

msg('tagline') ?>

-
html('subtitle') ?>
+
html('userlangattributes') ?>>html('subtitle') ?>
data['undelete']) { ?>
html('undelete') ?>
data['newtalk'] ) { ?>
html('newtalk') ?>
data['showjumplinks']) { ?> @@ -100,11 +100,11 @@ class MonoBookTemplate extends QuickTemplate {
-
+
html('userlangattributes') ?>>
msg('views') ?>
-
    html('userlangattributes') ?>> +
      data['content_actions'] as $key => $tab) { echo '
-