r45062 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45061‎ | r45062 | r45063 >
Date:05:00, 27 December 2008
Author:soxred93
Status:reverted (Comments)
Tags:
Comment:
Add Interwiki extension to core.
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/SpecialPage.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialInterwiki.php (added) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /trunk/phase3/maintenance/language/messages.inc (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/language/messages.inc
@@ -1465,6 +1465,9 @@
14661466 'deletedcontribs' => array(
14671467 'deletedcontributions',
14681468 ),
 1469+ 'interwiki' => array(
 1470+ 'interwiki',
 1471+ ),
14691472 'linksearch' => array(
14701473 'linksearch',
14711474 'linksearch-pat',
@@ -2948,6 +2951,7 @@
29492952 'allpages' => 'Special:AllPages',
29502953 'categories' => 'Special:Categories',
29512954 'deletedcontribs' => 'Special:DeletedContributions',
 2955+ 'deletedcontribs' => 'Special:Interwiki',
29522956 'linksearch' => 'Special:LinkSearch',
29532957 'listusers' => 'Special:ListUsers',
29542958 'newuserlog' => 'Special:Log/newusers',
Index: trunk/phase3/includes/AutoLoader.php
@@ -480,6 +480,7 @@
481481 'SpecialAllpages' => 'includes/specials/SpecialAllpages.php',
482482 'SpecialBookSources' => 'includes/specials/SpecialBooksources.php',
483483 'SpecialImport' => 'includes/specials/SpecialImport.php',
 484+ 'SpecialInterwiki' => 'includes/specials/SpecialInterwiki.php',
484485 'SpecialListGroupRights' => 'includes/specials/SpecialListgrouprights.php',
485486 'SpecialMostlinkedtemplates' => 'includes/specials/SpecialMostlinkedtemplates.php',
486487 'SpecialPrefixindex' => 'includes/specials/SpecialPrefixindex.php',
Index: trunk/phase3/includes/DefaultSettings.php
@@ -1210,6 +1210,7 @@
12111211 $wgGroupPermissions['sysop']['editusercssjs'] = true;
12121212 $wgGroupPermissions['sysop']['import'] = true;
12131213 $wgGroupPermissions['sysop']['importupload'] = true;
 1214+$wgGroupPermissions['sysop']['interwiki'] = true;
12141215 $wgGroupPermissions['sysop']['move'] = true;
12151216 $wgGroupPermissions['sysop']['move-subpages'] = true;
12161217 $wgGroupPermissions['sysop']['move-rootuserpages'] = true;
@@ -2791,6 +2792,7 @@
27922793 'upload',
27932794 'move',
27942795 'import',
 2796+ 'interwiki',
27952797 'patrol',
27962798 'merge',
27972799 'suppress',
@@ -2845,6 +2847,7 @@
28462848 'upload' => 'uploadlogpage',
28472849 'move' => 'movelogpage',
28482850 'import' => 'importlogpage',
 2851+ 'interwiki' => 'interwikilogpage',
28492852 'patrol' => 'patrol-log-page',
28502853 'merge' => 'mergelog',
28512854 'suppress' => 'suppressionlog',
@@ -2865,6 +2868,7 @@
28662869 'upload' => 'uploadlogpagetext',
28672870 'move' => 'movelogpagetext',
28682871 'import' => 'importlogpagetext',
 2872+ 'interwiki' => 'interwikilogpagetext',
28692873 'patrol' => 'patrol-log-header',
28702874 'merge' => 'mergelogpagetext',
28712875 'suppress' => 'suppressionlogtext',
@@ -2896,6 +2900,10 @@
28972901 'move/move_redir' => '1movedto2_redir',
28982902 'import/upload' => 'import-logentry-upload',
28992903 'import/interwiki' => 'import-logentry-interwiki',
 2904+ 'interwiki/interwiki' => 'interwiki_logentry',
 2905+ 'interwiki/iw_add' => 'interwiki_log_added',
 2906+ 'interwiki/iw_delete' => 'interwiki_log_deleted',
 2907+ 'interwiki/iw_edit' => 'interwiki_log_edited',
29002908 'merge/merge' => 'pagemerge-logentry',
29012909 'suppress/revision' => 'revdelete-logentry',
29022910 'suppress/file' => 'revdelete-logentry',
@@ -3014,6 +3022,7 @@
30153023 'Specialpages' => 'other',
30163024 'Blockme' => 'other',
30173025 'Booksources' => 'other',
 3026+ 'Interwiki' => 'other',
30183027 );
30193028
30203029 /**
Index: trunk/phase3/includes/specials/SpecialInterwiki.php
@@ -0,0 +1,263 @@
 2+<?php
 3+
 4+/**
 5+ * Constructor
 6+ */
 7+function wfSpecialInterwiki( $par ) {
 8+ global $wgRequest;
 9+
 10+ $form = new SpecialInterwiki( $wgRequest, $par );
 11+ $form->execute();
 12+}
 13+
 14+/**
 15+ * implements Special:Interwiki
 16+ * @ingroup SpecialPage
 17+ */
 18+class SpecialInterwiki extends SpecialPage {
 19+
 20+ function __construct() {
 21+ parent::__construct( 'Interwiki' );
 22+ }
 23+
 24+
 25+ function execute( $par = null ) {
 26+ global $wgRequest, $wgOut, $wgUser;
 27+
 28+ $admin = $wgUser->isAllowed( 'interwiki' );
 29+
 30+ $this->setHeaders();
 31+ if( $admin ){
 32+ $wgOut->setPagetitle( wfMsg( 'interwiki' ) );
 33+ } else {
 34+ $wgOut->setPagetitle( wfMsg( 'interwiki-title-norights' ) );
 35+ }
 36+ $action = $wgRequest->getVal( 'action', $par );
 37+
 38+ // checking
 39+ $selfTitle = $this->getTitle();
 40+
 41+ // Protect administrative actions against malicious requests
 42+ $safePost = $wgRequest->wasPosted() &&
 43+ $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
 44+
 45+ switch( $action ){
 46+ case "delete":
 47+ if( !$admin ){
 48+ $wgOut->permissionRequired('interwiki');
 49+ return;
 50+ }
 51+
 52+ $prefix = $wgRequest->getVal( 'prefix' );
 53+ $encPrefix = htmlspecialchars( $prefix );
 54+ $actionUrl = $selfTitle->escapeLocalURL( "action=submit" );
 55+ $button = wfMsgHtml( 'delete' );
 56+ $topmessage = wfMsgHtml( 'interwiki_delquestion', $encPrefix );
 57+ $deletingmessage = wfMsgHtml( 'interwiki_deleting', $encPrefix );
 58+ $reasonmessage = wfMsgHtml( 'deletecomment' );
 59+ $defaultreason = wfMsgForContent( 'interwiki_defaultreason' );
 60+ $token = htmlspecialchars( $wgUser->editToken() );
 61+
 62+ $wgOut->addHTML(
 63+ "<fieldset>
 64+ <legend>$topmessage</legend>
 65+ <form id=\"delete\" method=\"post\" action=\"{$actionUrl}\">
 66+ <table><tr>
 67+ <td>$deletingmessage</td>
 68+ </tr><tr>
 69+ <td>$reasonmessage &nbsp; <input tabindex='1' type='text' name=\"reason\" maxlength='200' size='60' value='$defaultreason' /></td>
 70+ </tr><tr><td>
 71+ <input type='submit' name='delete' id=\"interwikideletebutton\" value='{$button}' />
 72+ <input type='hidden' name='prefix' value='{$encPrefix}' />
 73+ <input type='hidden' name='do' value='delete' />
 74+ <input type='hidden' name='wpEditToken' value='{$token}' />
 75+ </td></tr></table>
 76+ </form>
 77+ </fieldset>\n"
 78+ );
 79+ break;
 80+ case "edit" :
 81+ case "add" :
 82+ if( !$admin ){
 83+ $wgOut->permissionRequired( 'interwiki' );
 84+ return;
 85+ }
 86+ if( $action == "edit" ){
 87+ $prefix = $wgRequest->getVal( 'prefix' );
 88+ $dbr = wfGetDB( DB_SLAVE );
 89+ $row = $dbr->selectRow( 'interwiki', '*', array( 'iw_prefix' => $prefix ) );
 90+ if( !$row ){
 91+ $wgOut->wrapWikiMsg( '<div class="errorbox">$1</div>', array( 'interwiki_editerror', $prefix ) );
 92+ return;
 93+ }
 94+ $prefix = htmlspecialchars( $row->iw_prefix );
 95+ $defaulturl = htmlspecialchars( $row->iw_url );
 96+ $trans = $row->iw_trans ? " checked='checked'" : '' ;
 97+ $local = $row->iw_local ? " checked='checked'" : '';
 98+ $old = "<input type='hidden' name='prefix' value='" . htmlspecialchars( $row->iw_prefix ) . "' />";
 99+ $topmessage = wfMsgHtml( 'interwiki_edittext' );
 100+ $intromessage = wfMsgHtml( 'interwiki_editintro' );
 101+ $button = wfMsgHtml( 'edit' );
 102+ } else {
 103+ $prefix = "<input tabindex='1' type='text' name='prefix' maxlength='20' size='20' />";
 104+ $local = '';
 105+ $trans = '';
 106+ $old = '';
 107+ $defaulturl = wfMsgHtml( 'interwiki_defaulturl' );
 108+ $topmessage = wfMsgHtml( 'interwiki_addtext' );
 109+ $intromessage = wfMsgHtml( 'interwiki_addintro' );
 110+ $button = wfMsgHtml( 'interwiki_addbutton' );
 111+ }
 112+
 113+ $actionUrl = $selfTitle->escapeLocalURL( 'action=submit' );
 114+ $prefixmessage = wfMsgHtml( 'interwiki_prefix' );
 115+ $localmessage = wfMsgHtml( 'interwiki_local' );
 116+ $transmessage = wfMsgHtml( 'interwiki_trans' );
 117+ $reasonmessage = wfMsgHtml( 'interwiki_reasonfield' );
 118+ $urlmessage = wfMsgHtml( 'interwiki_url' );
 119+ $token = htmlspecialchars( $wgUser->editToken() );
 120+ $defaultreason = htmlspecialchars( wfMsgForContent( 'interwiki_defaultreason' ) );
 121+
 122+ $wgOut->addHTML(
 123+ "<fieldset>
 124+ <legend>$topmessage</legend>
 125+ $intromessage
 126+ <form id='{$action}' method='post' action='{$actionUrl}'>
 127+ <table id='interwikitable-{$action}'><tr>
 128+ <td>$prefixmessage</td>
 129+ <td>$prefix</td>
 130+ </tr><tr>
 131+ <td>$localmessage</td>
 132+ <td><input type='checkbox' id='local' name='local' {$local}/></td>
 133+ </tr><tr>
 134+ <td>$transmessage</td>
 135+ <td><input type='checkbox' id='trans' name='trans' {$trans}/></td>
 136+ </tr><tr>
 137+ <td>$urlmessage</td>
 138+ <td><input tabindex='1' type='text' name='theurl' maxlength='200' size='60' value='$defaulturl' /></td>
 139+ </tr><tr>
 140+ <td>$reasonmessage</td>
 141+ <td><input tabindex='1' type='text' name='reason' maxlength='200' size='60' value='$defaultreason' /></td>
 142+ </tr></table>
 143+ <input type='submit' name='{$action}' id='interwiki{$action}button' value='{$button}' />
 144+ <input type='hidden' name='do' value='{$action}' />
 145+ $old
 146+ <input type='hidden' name='wpEditToken' value='{$token}' />
 147+ </form>
 148+ </fieldset>\n"
 149+ );
 150+ break;
 151+ case "submit":
 152+ if( !$admin ){
 153+ $wgOut->permissionRequired('interwiki');
 154+ return;
 155+ }
 156+ if( !$safePost ){
 157+ $wgOut->addWikiText( wfMsg('sessionfailure') );
 158+ return;
 159+ }
 160+
 161+ $prefix = $wgRequest->getVal('prefix');
 162+ $reason = $wgRequest->getText('reason');
 163+ $do = $wgRequest->getVal('do');
 164+ $dbw = wfGetDB( DB_MASTER );
 165+ switch( $do ){
 166+ case "delete":
 167+ $dbw->delete( 'interwiki', array( 'iw_prefix' => $prefix ), __METHOD__ );
 168+
 169+ if ($dbw->affectedRows() == 0) {
 170+ $wgOut->addWikiText( '<span class="error">' . wfMsg( 'interwiki_delfailed', $prefix ) . '</span>' );
 171+ } else {
 172+ $wgOut->addWikiText( wfMsg( 'interwiki_deleted', $prefix ));
 173+ $wgOut->returnToMain( false, $selfTitle );
 174+ $log = new LogPage( 'interwiki' );
 175+ $log->addEntry( 'iw_delete', $selfTitle, $reason, array( $prefix ) );
 176+ }
 177+ break;
 178+ case "edit":
 179+ case "add":
 180+ $theurl = $wgRequest->getVal('theurl');
 181+ $local = $wgRequest->getCheck('local') ? 1 : 0;
 182+ $trans = $wgRequest->getCheck('trans') ? 1 : 0;
 183+ $data = array( 'iw_prefix' => $prefix, 'iw_url' => $theurl,
 184+ 'iw_local' => $local, 'iw_trans' => $trans );
 185+
 186+ if( $do == 'add' ){
 187+ $dbw->insert( 'interwiki', $data, __METHOD__, 'IGNORE' );
 188+ } else {
 189+ $dbw->update( 'interwiki', $data, array( 'iw_prefix' => $prefix ), __METHOD__, 'IGNORE' );
 190+ }
 191+
 192+ if( $dbw->affectedRows() == 0 ) {
 193+ $wgOut->addWikiText( '<span class="error">' . wfMsg( "interwiki_{$do}failed", $prefix ) . '</span>' );
 194+ } else {
 195+ $wgOut->addWikiText( wfMsg( "interwiki_{$do}ed", $prefix ));
 196+ $wgOut->returnToMain( false, $selfTitle );
 197+ $log = new LogPage( 'interwiki' );
 198+ $log->addEntry( 'iw_'.$do, $selfTitle, $reason, array( $prefix, $theurl, $trans, $local ) );
 199+ }
 200+ break;
 201+ }
 202+ break;
 203+ default:
 204+ $prefixmessage = wfMsgHtml( 'interwiki_prefix' );
 205+ $urlmessage = wfMsgHtml( 'interwiki_url' );
 206+ $localmessage = wfMsgHtml( 'interwiki_local' );
 207+ $transmessage = wfMsgHtml( 'interwiki_trans' );
 208+
 209+ $wgOut->addWikiText( wfMsg( 'interwiki_intro', '[http://www.mediawiki.org/wiki/Interwiki_table MediaWiki.org]' ) );
 210+
 211+ if ($admin) {
 212+ $skin = $wgUser->getSkin();
 213+ $addtext = wfMsgHtml( 'interwiki_addtext' );
 214+ $addlink = $skin->makeLinkObj( $selfTitle, $addtext, 'action=add' );
 215+ $wgOut->addHTML( '<ul>' . '<li>' . $addlink . '</li>' . '</ul>' );
 216+ }
 217+
 218+ $out = "
 219+ <br />
 220+ <table width='100%' border='2' id='interwikitable'>
 221+ <tr id='interwikitable-header'><th>$prefixmessage</th> <th>$urlmessage</th> <th>$localmessage</th> <th>$transmessage</th>";
 222+ if( $admin ) {
 223+ $deletemessage = wfMsgHtml( 'delete' );
 224+ $editmessage = wfMsgHtml( 'edit' );
 225+ $out .= "<th>$editmessage</th>";
 226+ }
 227+
 228+ $out .= "</tr>\n";
 229+
 230+ $dbr = wfGetDB( DB_SLAVE );
 231+ $res = $dbr->select( 'interwiki', '*' );
 232+ $numrows = $dbr->numRows( $res );
 233+ if ($numrows == 0) {
 234+ $errormessage = wfMsgHtml('interwiki_error');
 235+ $out .= "<br /><div class=\"error\">$errormessage</div><br />";
 236+ }
 237+ while( $s = $dbr->fetchObject( $res ) ) {
 238+ $prefix = htmlspecialchars( $s->iw_prefix );
 239+ $url = htmlspecialchars( $s->iw_url );
 240+ $trans = htmlspecialchars( $s->iw_trans );
 241+ $local = htmlspecialchars( $s->iw_local );
 242+ $out .= "<tr id='interwikitable-row'>
 243+ <td id='interwikitable-prefix'>$prefix</td>
 244+ <td id='interwikitable-url'>$url</td>
 245+ <td id='interwikitable-local'>$local</td>
 246+ <td id='interwikitable-trans'>$trans</td>";
 247+ if( $admin ) {
 248+ $out .= '<td id="interwikitable-modify">';
 249+ $out .= $skin->makeLinkObj( $selfTitle, $editmessage,
 250+ 'action=edit&prefix=' . urlencode( $s->iw_prefix ) );
 251+ $out .= ', ';
 252+ $out .= $skin->makeLinkObj( $selfTitle, $deletemessage,
 253+ 'action=delete&prefix=' . urlencode( $s->iw_prefix ) );
 254+ $out .= '</td>';
 255+ }
 256+
 257+ $out .= "\n</tr>\n";
 258+ }
 259+ $dbr->freeResult( $res );
 260+ $out .= "</table><br />";
 261+ $wgOut->addHTML($out);
 262+ }
 263+ }
 264+}
Property changes on: trunk/phase3/includes/specials/SpecialInterwiki.php
___________________________________________________________________
Name: svn:eol-style
1265 + native
Index: trunk/phase3/includes/SpecialPage.php
@@ -147,6 +147,7 @@
148148 'Blockip' => array( 'SpecialPage', 'Blockip', 'block' ),
149149 'Undelete' => array( 'SpecialPage', 'Undelete', 'deletedhistory' ),
150150 'Import' => 'SpecialImport',
 151+ 'Interwiki' => array( 'SpecialPage', 'Interwiki' ),
151152 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ),
152153 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ),
153154 'Userrights' => 'UserrightsPage',
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -430,6 +430,7 @@
431431 'Blankpage' => array( 'BlankPage' ),
432432 'LinkSearch' => array( 'LinkSearch' ),
433433 'DeletedContributions' => array( 'DeletedContributions' ),
 434+ 'Interwiki' => array( 'Interwiki' ),
434435 );
435436
436437 /**
@@ -2187,6 +2188,45 @@
21882189 # Special:DeletedContributions
21892190 'deletedcontributions' => 'Deleted user contributions',
21902191
 2192+# Special:Interwiki
 2193+'interwiki' => 'View and edit interwiki data',
 2194+'interwiki-title-norights' => 'View interwiki data',
 2195+'interwiki-desc' => 'Adds a [[Special:Interwiki|special page]] to view and edit the interwiki table',
 2196+'interwiki_reasonfield' => 'Reason',
 2197+'interwiki_intro' => 'See $1 for more information about the interwiki table.
 2198+There is a [[Special:Log/interwiki|log of changes]] to the interwiki table.',
 2199+'interwiki_prefix' => 'Prefix',
 2200+'interwiki_url' => 'URL',
 2201+'interwiki_local' => 'Local',
 2202+'interwiki_trans' => 'Trans',
 2203+'interwiki_error' => 'Error: The interwiki table is empty, or something else went wrong.',
 2204+'interwiki_delquestion' => 'Deleting "$1"',
 2205+'interwiki_deleting' => 'You are deleting prefix "$1".',
 2206+'interwiki_deleted' => 'Prefix "$1" was successfully removed from the interwiki table.',
 2207+'interwiki_delfailed' => 'Prefix "$1" could not be removed from the interwiki table.',
 2208+'interwiki_addtext' => 'Add an interwiki prefix',
 2209+'interwiki_addintro' => 'You are adding a new interwiki prefix.
 2210+Remember that it cannot contain spaces ( ), colons (:), ampersands (&), or equal signs (=).',
 2211+'interwiki_addbutton' => 'Add',
 2212+'interwiki_added' => 'Prefix "$1" was successfully added to the interwiki table.',
 2213+'interwiki_addfailed' => 'Prefix "$1" could not be added to the interwiki table.
 2214+Possibly it already exists in the interwiki table.',
 2215+'interwiki_defaulturl' => 'http://www.example.com/$1',
 2216+'interwiki_edittext' => 'Editing an interwiki prefix',
 2217+'interwiki_editintro' => 'You are editing an interwiki prefix.
 2218+Remember that this can break existing links.',
 2219+'interwiki_edited' => 'Prefix "$1" was successfully modified in the interwiki table.',
 2220+'interwiki_editerror' => 'Prefix "$1" can not be modified in the interwiki table.
 2221+Possibly it does not exist.',
 2222+'interwikilogpage' => 'Interwiki table log',
 2223+'interwiki_log_added' => 'added prefix "$2" ($3) (trans: $4) (local: $5) to the interwiki table',
 2224+'interwiki_log_edited' => 'modified prefix "$2" : ($3) (trans: $4) (local: $5) in the interwiki table',
 2225+'interwiki_log_deleted' => 'removed prefix "$2" from the interwiki table',
 2226+'interwikilogpagetext' => 'This is a log of changes to the [[Special:Interwiki|interwiki table]].',
 2227+'interwiki_defaultreason' => 'no reason given',
 2228+'interwiki_logentry' => '', # do not translate this message
 2229+'right-interwiki' => 'Edit interwiki data',
 2230+
21912231 # Special:LinkSearch
21922232 'linksearch' => 'Search web links',
21932233 'linksearch-pat' => 'Search pattern:',

Follow-up revisions

RevisionCommit summaryAuthorDate
r45064Cleanup to r45062 (add Interwiki extension to core)...demon05:17, 27 December 2008
r45070Follow up on r45062....siebrand07:57, 27 December 2008
r45071Follow up on r45062....siebrand07:58, 27 December 2008
r45223This extension is obsolete per MediaWiki 1.14alpha r45062, when extension Int...siebrand15:08, 31 December 2008
r45238* Revert r45062 and related (Merge Interwiki extension to core) per brion....siebrand18:44, 31 December 2008

Comments

#Comment by MZMcBride (talk | contribs)   08:11, 27 December 2008

Assuming this is kept in, a couple of notes:

  1. There may be issues with WMF wikis due to caching (this is coming from ^demon)
  2. The 'interwiki' right would likely only be given to admins at Meta and nowhere else
  3. bugzilla:12763#c5 suggests there may be security implications here
#Comment by Siebrand (talk | contribs)   10:57, 27 December 2008
  • FIXME: PHP Notice: Undefined variable: encPrefix in /var/www/w/includes/specials/SpecialInterwiki.php on line 42
  • FIXME: messages 'interwiki_local' and 'interwiki_trans' are poor. There should be more explanation for their exact meaning.
  • FIXME: <Nikerabbit> that table is horrible. Could be at least class=wikitable
  • FIXME: <Nikerabbit> the i18n of that special page is unacceptable. The string is used for table header and a label when adding
#Comment by Siebrand (talk | contribs)   11:31, 27 December 2008
  • FIXME: $wgSpecialPageGroups should be set
#Comment by VasilievVV (talk | contribs)   19:36, 27 December 2008

This page cannot be run on Wikimedia now: this special page only updates interwikis on the wiki where it's used, while we need it to update all wikis.

"interwiki" shouldn't be assigned on WMF sites until that's fixed.

#Comment by Soxred93 (talk | contribs)   01:31, 28 December 2008

Can't we just assign "interwiki" to a new usergroup, and give it out to no one? Then give it out on Meta? That way, it'd be updated automatically on all wikis.

#Comment by VasilievVV (talk | contribs)   09:59, 28 December 2008

> That way, it'd be updated automatically on all wikis.

It wouldn't

#Comment by Brion VIBBER (talk | contribs)   17:48, 31 December 2008

The UI is terrible right now, and it's totally incompatible with Wikimedia.

I've disabled it in r45232... please continue working on it, it'd be a nice thing to have for third-party installations if the UI is cleaned up.

#Comment by Brion VIBBER (talk | contribs)   17:54, 31 December 2008

At this point I recommend moving the updates back to the extension and working on it there so it won't interfere with core updates.

#Comment by Siebrand (talk | contribs)   18:55, 31 December 2008

Reverted and later changed merged back into extension in r45238 and r45239.

Status & tagging log