(bug 16497) Paginate Special:AllMessages
authorChad Horohoe <demon@users.mediawiki.org>
Wed, 15 Jul 2009 02:03:21 +0000 (02:03 +0000)
committerChad Horohoe <demon@users.mediawiki.org>
Wed, 15 Jul 2009 02:03:21 +0000 (02:03 +0000)
RELEASE-NOTES
includes/AutoLoader.php
includes/DefaultSettings.php
includes/SpecialPage.php
includes/specials/SpecialAllmessages.php
languages/messages/MessagesEn.php
maintenance/language/messages.inc
skins/common/allmessages.js [deleted file]
skins/common/shared.css
skins/modern/main.css
skins/monobook/main.css

index 5df82de..2019cba 100644 (file)
@@ -254,6 +254,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * Log in and log out links no longer return to page view when clicked from
   history view, edit page, or something similar
 * (bug 19513) RTL fixes for new Search UI
+* (bug 16497) Special:Allmessages is paginated
 
 == API changes in 1.16 ==
 
index 208c827..33b05ea 100644 (file)
@@ -479,6 +479,7 @@ $wgAutoloadLocalClasses = array(
        'MWTidy' => 'includes/parser/Tidy.php',
 
        # includes/specials
+       'SpecialAllmessages' => 'includes/specials/SpecialAllmessages.php',
        'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php',
        'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
        'ContribsPager' => 'includes/specials/SpecialContributions.php',
index e5cf0fe..d68f8b5 100644 (file)
@@ -1566,7 +1566,7 @@ $wgCacheEpoch = '20030516000000';
  * to ensure that client-side caches do not keep obsolete copies of global
  * styles.
  */
-$wgStyleVersion = '231';
+$wgStyleVersion = '232';
 
 
 # Server-side caching:
index d67607c..defb2eb 100644 (file)
@@ -145,7 +145,7 @@ class SpecialPage {
 
                # Wiki data and tools
                'Statistics'                            => 'SpecialStatistics',
-               'Allmessages'               => array( 'SpecialPage', 'Allmessages' ),
+               'Allmessages'               => 'SpecialAllmessages',
                'Version'                   => 'SpecialVersion',
                'Lockdb'                    => array( 'SpecialPage', 'Lockdb', 'siteadmin' ),
                'Unlockdb'                  => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ),
index 6470261..8b0ff19 100644 (file)
  * @file
  * @ingroup SpecialPage
  */
-
-/**
- * Constructor.
- */
-function wfSpecialAllmessages() {
-       global $wgOut, $wgRequest, $wgMessageCache;
-       global $wgUseDatabaseMessages, $wgLang;
-
-       # The page isn't much use if the MediaWiki namespace is not being used
-       if( !$wgUseDatabaseMessages ) {
-               $wgOut->addWikiMsg( 'allmessagesnotsupportedDB' );
-               return;
+class SpecialAllmessages extends SpecialPage {
+       
+       /**
+        * Constructor
+        */
+       public function __construct() {
+               parent::__construct( 'Allmessages' );
        }
+       
+       /**
+        * Execute
+        */
+       function execute( $par ) {
+               global $wgOut, $wgRequest;
+               
+               $this->setHeaders();
+               
+               global $wgUseDatabaseMessages;
+               if( !$wgUseDatabaseMessages ) {
+                       $wgOut->addWikiMsg( 'allmessagesnotsupportedDB' );
+                       return;
+               } else {
+                       $this->outputHeader( 'allmessagestext' );
+               }
 
-       wfProfileIn( __METHOD__ );
-
-       wfProfileIn( __METHOD__ . '-setup' );
-       $ot = $wgRequest->getText( 'ot' );
-
-       $navText = wfMsg( 'allmessagestext' );
-
-       # Make sure all extension messages are available
-
-       $wgMessageCache->loadAllMessages();
-
-       $sortedArray = Language::getMessagesFor( 'en' );
-       ksort( $sortedArray );
-
-       $messages = array();
-       foreach( $sortedArray as $key => $value ) {
-               $messages[$key]['enmsg'] = $value;
-               $messages[$key]['statmsg'] = wfMsgReal( $key, array(), false, false, false );
-               $messages[$key]['msg'] = wfMsgNoTrans( $key );
-               $sortedArray[$key] = NULL; // trade bytes from $sortedArray to this
+               $this->filter = $wgRequest->getVal( 'filter', 'all' );
+               $this->prefix = $wgRequest->getVal( 'prefix', '' );
+               
+               $this->table = new AllmessagesTablePager( $this,
+                                                                                       $conds=array(),
+                                                                                       wfGetLangObj( $wgRequest->getVal( 'lang', false ) ) );
+                                                                                       
+               $this->langCode = $this->table->lang->getCode();
+               
+               $wgOut->addHTML( $this->buildForm() .
+                                                $this->table->getNavigationBar() . 
+                                                $this->table->getLimitForm() . 
+                                                $this->table->getBody() . 
+                                                $this->table->getNavigationBar() );
                
        }
-       unset($sortedArray); // trade bytes from $sortedArray to this
-
-       wfProfileOut( __METHOD__ . '-setup' );
-
-       wfProfileIn( __METHOD__ . '-output' );
-       $wgOut->addScriptFile( 'allmessages.js' );
-       $title = SpecialPage::getTitleFor( 'Allmessages' );
-       if ( $ot == 'php' ) {
-               $navText .= wfAllMessagesMakePhp( $messages );
-               $wgOut->addHTML( $wgLang->pipeList( array(
-                       'PHP',
-                       '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'html' ) ) . '">HTML</a>',
-                       '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'xml' ) ) . '">XML</a>' .
-                       '<pre>' . htmlspecialchars( $navText ) . '</pre>'
-               ) ) );
-       } else if ( $ot == 'xml' ) {
-               $wgOut->disable();
-               header( 'Content-type: text/xml' );
-               echo wfAllMessagesMakeXml( $messages );
-       } else {
-               $wgOut->addHTML( $wgLang->pipeList( array(
-                       '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'php' ) ) . '">PHP</a>',
-                       'HTML',
-                       '<a href="' . $title->escapeLocalUrl( array( 'ot' => 'xml' ) ) . '">XML</a>'
-               ) ) );
-               $wgOut->addWikiText( $navText );
-               $wgOut->addHTML( wfAllMessagesMakeHTMLText( $messages ) );
-       }
-       wfProfileOut( __METHOD__ . '-output' );
-
-       wfProfileOut( __METHOD__ );
-}
-
-function wfAllMessagesMakeXml( &$messages ) {
-       global $wgLang;
-       $lang = $wgLang->getCode();
-       $txt = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
-       $txt .= "<messages lang=\"$lang\">\n";
-       foreach( $messages as $key => $m ) {
-               $txt .= "\t" . Xml::element( 'message', array( 'name' => $key ), $m['msg'] ) . "\n";
-               $messages[$key] = NULL; // trade bytes
-       }
-       $txt .= "</messages>";
-       return $txt;
-}
-
-/**
- * Create the messages array, formatted in PHP to copy to language files.
- * @param $messages Messages array.
- * @return The PHP messages array.
- * @todo Make suitable for language files.
- */
-function wfAllMessagesMakePhp( &$messages ) {
-       global $wgLang;
-       $txt = "\n\n\$messages = array(\n";
-       foreach( $messages as $key => $m ) {
-               if( $wgLang->getCode() != 'en' && $m['msg'] == $m['enmsg'] ) {
-                       continue;
-               } else if ( wfEmptyMsg( $key, $m['msg'] ) ) {
-                       $m['msg'] = '';
-                       $comment = ' #empty';
-               } else {
-                       $comment = '';
+       
+       function buildForm() {
+               $url = $this->getTitle()->escapeLocalURL();
+               $languages = Language::getLanguageNames( false );
+               ksort( $languages );
+               
+               $out  = "<form method=\"get\" action=\"$url\"><fieldset>\n" .
+                                       Xml::element( 'legend', null, wfMsg( 'allmessages' ) ) . "<table><tr>\n" .
+                               "<td class=\"mw-label\">" .
+                       Xml::label( wfMsg('allmessages-prefix'), 'am-form-prefix' ) .
+                   "</td>\n<td class=\"mw-input\">" .
+                       Xml::input( 'prefix', 20, str_replace('_',' ',$this->prefix), array( 'id' => 'am-form-prefix' ) ) . 
+                   "</select>" . 
+                               "</td>\n</tr><tr>\n<td class='mw-label'>" . 
+                       Xml::label( wfMsg('allmessages-filter'), 'am-form-filter' ) .
+                   "</td>\n<td class='mw-input'>" . 
+                       Xml::radioLabel( wfMsg('allmessages-filter-unmodified'),
+                                                        'filter',
+                                                        'unmodified',
+                                                        'am-form-filter-unmodified',
+                                                        ( $this->filter == 'unmodified' ? true : false )
+                                                       ) . 
+                       Xml::radioLabel( wfMsg('allmessages-filter-all'),
+                                                        'filter',
+                                                        'all',
+                                                        'am-form-filter-all',
+                                                        ( $this->filter == 'all' ? true : false )
+                                                       ) . 
+                       Xml::radioLabel( wfMsg('allmessages-filter-modified'),
+                                                        'filter',
+                                                        'modified',
+                                                        'am-form-filter-modified',
+                                                        ( $this->filter == 'modified' ? true : false )
+                                                       ) .
+                               "</td>\n</tr><tr>\n<td class=\"mw-label\">" .
+                       Xml::label( wfMsg('yourlanguage'), 'am-form-lang' ) .
+                   "</td>\n<td class=\"mw-input\">" .
+                       Xml::openElement( 'select', array( 'id' => 'am-form-lang', 'name' => 'lang' ) );
+               foreach( $languages as $lang => $name ) {
+                       $selected = $lang == $this->langCode ? 'selected="selected"' : '';
+                       $out .= "<option value=\"$lang\" $selected>$name</option>\n";
                }
-               $txt .= "'$key' => '" . preg_replace( '/(?<!\\\\)\'/', "\'", $m['msg']) . "',$comment\n";
-               $messages[$key] = NULL; // trade bytes
+               $out .= "</td>\n</tr><tr>\n<td></td><td>" . Xml::submitButton( wfMsg('allpagessubmit') ) . 
+                               "</table>" .
+                                       $this->table->getHiddenFields( array( 'title', 'prefix', 'filter', 'lang' ) ) .
+                               "</fieldset></form>";
+               return $out;
        }
-       $txt .= ');';
-       return $txt;
 }
 
-/**
- * Create a list of messages, formatted in HTML as a list of messages and values and showing differences between the default language file message and the message in MediaWiki: namespace.
- * @param $messages Messages array.
- * @return The HTML list of messages.
+/* use TablePager for prettified output. We have to pretend that we're 
+ * getting data from a table when in fact not all of it comes from the database.
  */
-function wfAllMessagesMakeHTMLText( &$messages ) {
-       global $wgLang, $wgContLang, $wgUser;
-       wfProfileIn( __METHOD__ );
-
-       $sk = $wgUser->getSkin();
-       $talk = wfMsg( 'talkpagelinktext' );
-
-       $input = Xml::element( 'input', array(
-               'type'    => 'text',
-               'id'      => 'allmessagesinput',
-               'onkeyup' => 'allmessagesfilter()'
-       ), '' );
-       $checkbox = Xml::element( 'input', array(
-               'type'    => 'button',
-               'value'   => wfMsgHtml( 'allmessagesmodified' ),
-               'id'      => 'allmessagescheckbox',
-               'onclick' => 'allmessagesmodified()'
-       ), '' );
-
-       $txt = '<span id="allmessagesfilter" style="display: none;">' . wfMsgHtml( 'allmessagesfilter' ) . 
-               " {$input}{$checkbox} " . '</span>';
-
-       $txt .= '
-<table border="1" cellspacing="0" width="100%" id="allmessagestable">
-       <tr>
-               <th rowspan="2">' . wfMsgHtml( 'allmessagesname' ) . '</th>
-               <th>' . wfMsgHtml( 'allmessagesdefault' ) . '</th>
-       </tr>
-       <tr>
-               <th>' . wfMsgHtml( 'allmessagescurrent' ) . '</th>
-       </tr>';
-
-       wfProfileIn( __METHOD__ . "-check" );
-
-       # This is a nasty hack to avoid doing independent existence checks
-       # without sending the links and table through the slow wiki parser.
-       $pageExists = array(
-               NS_MEDIAWIKI => array(),
-               NS_MEDIAWIKI_TALK => array()
-       );
-       $dbr = wfGetDB( DB_SLAVE );
-       $res = $dbr->select( 'page',
-               array( 'page_namespace', 'page_title' ),
-               array( 'page_namespace' => array(NS_MEDIAWIKI,NS_MEDIAWIKI_TALK) ),
-               __METHOD__,
-               array( 'USE INDEX' => 'name_title' )
-       );
-       while( $s = $dbr->fetchObject( $res ) ) {
-               $pageExists[$s->page_namespace][$s->page_title] = 1;
-       }
-       $dbr->freeResult( $res );
-       wfProfileOut( __METHOD__ . "-check" );
-
-       wfProfileIn( __METHOD__ . "-output" );
-
-       $i = 0;
-
-       foreach( $messages as $key => $m ) {
-               $title = $wgLang->ucfirst( $key );
-               if( $wgLang->getCode() != $wgContLang->getCode() ) {
-                       $title .= '/' . $wgLang->getCode();
+class AllmessagesTablePager extends TablePager {
+       
+       var $messages  = NULL;
+       var $talkPages = NULL;
+       
+       function __construct( $page, $conds, $langObj = NULL ) {
+               parent::__construct();
+               $this->mIndexField = 'am_title';
+               $this->mPage = $page;
+               $this->mConds = $conds;
+               $this->mDefaultDirection = true;        //always sort ascending
+               
+               global $wgLang, $wgContLang, $wgRequest;
+               
+               $this->talk = $wgLang->lc( htmlspecialchars( wfMsg( 'talkpagelinktext' ) ) );
+               
+               $this->lang = ( $langObj ? $langObj : $wgContLang );
+               $this->langcode = $this->lang->getCode();
+               $this->foreign  = $this->langcode != $wgContLang->getCode();
+               
+               if( $wgRequest->getVal( 'filter', 'all' ) === 'all' ){
+                       $this->custom = NULL;   //So won't match in either case
+               } else {
+                       $this->custom = $wgRequest->getVal( 'filter' ) == 'unmodified' ? 1 : 0;
                }
-
-               $titleObj = Title::makeTitle( NS_MEDIAWIKI, $title );
-               $talkPage = Title::makeTitle( NS_MEDIAWIKI_TALK, $title );
-
-               $changed = ( $m['statmsg'] != $m['msg'] );
-               $message = htmlspecialchars( $m['statmsg'] );
-               $mw = htmlspecialchars( $m['msg'] );
-
-               $linkText = "<span id=\"sp-allmessages-i-$i\">" . htmlspecialchars( $key ) . '</span>';
-
-               if( array_key_exists( $title, $pageExists[NS_MEDIAWIKI] ) ) {
-                       // FIXME: the span should be taken care of in $customAttribs, shouldn't it?
-                       $pageLink = $sk->linkKnown(
-                               $titleObj,
-                               $linkText
-                       );
+               
+               $prefix = $wgLang->ucfirst( $wgRequest->getVal( 'prefix', '' ) );
+               $prefix = $prefix != '' ? Title::makeTitleSafe( NS_MEDIAWIKI, $wgRequest->getVal( 'prefix', NULL ) ) : NULL;
+               if( $prefix !== NULL ){
+                       $this->prefix = '/^' . preg_quote( $prefix->getDBkey() ) . '/i';
                } else {
-                       $pageLink = $sk->link(
-                               $titleObj,
-                               $linkText,
-                               array(),
-                               array(),
-                               array( 'broken' )
-                       );
+                       $this->prefix = false;
                }
-               if( array_key_exists( $title, $pageExists[NS_MEDIAWIKI_TALK] ) ) {
-                       $talkLink = $sk->linkKnown( $talkPage, htmlspecialchars( $talk ) );
+               $this->getSkin();
+               
+               //The suffix that may be needed for message names if we're in a 
+               //different language (eg [[MediaWiki:Foo/fr]]: $suffix = '/fr'
+               if( $this->foreign ) {
+                       $this->suffix = '/' . $this->langcode;
+               } else { 
+                       $this->suffix = '';
+               }
+       }
+       
+       function getAllMessages( $desc ){
+               
+               wfProfileIn( __METHOD__ . '-cache' );
+               
+               # Make sure all extension messages are available
+               global $wgMessageCache;
+               $wgMessageCache->loadAllMessages( 'en' );
+               $sortedArray = Language::getMessagesFor( 'en' );
+               if( $desc ){
+                       krsort( $sortedArray );
                } else {
-                       $talkLink = $sk->link(
-                               $talkPage,
-                               htmlspecialchars( $talk ),
-                               array(),
-                               array(),
-                               array( 'broken' )
-                       );
+                       ksort( $sortedArray );
                }
+               
+               $this->messages = array();
+               foreach( $sortedArray as $key => $value ) {
+                       // All messages start with lowercase, but wikis might have both
+                       // upper and lowercase MediaWiki: pages if $wgCapitalLinks=false.
+                       $ukey = $this->lang->ucfirst( $key );
+                       
+                       // The value without any overrides from the MediaWiki: namespace
+                       $this->messages[$ukey]['default'] = wfMsgGetKey( $key, /*useDB*/false, $this->langcode, false );
+                       
+                       // The message that's actually used by the site
+                       $this->messages[$ukey]['actual'] = wfMsgGetKey( $key, /*useDB*/true, $this->langcode, false );  
+                       
+                       $this->messages[$ukey]['customised'] = 0; //for now
+                       
+                       $sortedArray[$key] = NULL; // trade bytes from $sortedArray to this     
+               }
+       
+               wfProfileOut( __METHOD__ . '-cache' );
+               
+               return true;
+       }
+       
+       # We only need a list of which messages have *been* customised; 
+       # their content is already in the message cache.
+       function markCustomisedMessages(){
+               $this->talkPages = array();
+               
+               wfProfileIn( __METHOD__ . "-db" );
 
-               $anchor = 'msg_' . htmlspecialchars( strtolower( $title ) );
-               $anchor = "<a id=\"$anchor\" name=\"$anchor\"></a>";
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select( 'page',
+                                                        array( 'page_namespace', 'page_title' ),
+                                                        array( 'page_namespace' => array(NS_MEDIAWIKI,NS_MEDIAWIKI_TALK) ),
+                                                        __METHOD__,
+                                                        array( 'USE INDEX' => 'name_title' )
+                                                  );
+               
+               while( $s = $dbr->fetchObject( $res ) ) {
+                       if( $s->page_namespace == NS_MEDIAWIKI ){
+                               if( $this->foreign ){
+                                       $title = explode( '/', $s->page_title );
+                                       if( $this->langcode == $title[1] && array_key_exists( $title[0], $this->messages ) ){
+                                               $this->messages["{$title[0]}"]['customised'] = 1;
+                                   }
+                               } else if( array_key_exists( $s->page_title , $this->messages ) ){
+                                       $this->messages[$s->page_title]['customised'] = 1;
+                               }
+                       } else if( $s->page_namespace == NS_MEDIAWIKI_TALK ){
+                               $this->talkPages[$s->page_title] = 1;
+                       }
+               }
+               $dbr->freeResult( $res );
+               
+               wfProfileOut( __METHOD__ . "-db" );
+               
+               return true;
+       }
+       
+       /* This function normally does a database query to get the results; we need
+        * to make a pretend result using a FakeResultWrapper.
+        */
+       function reallyDoQuery( $offset , $limit , $descending ){
+               $mResult = new FakeResultWrapper( array() );
+               
+               if( !$this->messages ) $this->getAllMessages( $descending );
+               if( $this->talkPages === NULL ) $this->markCustomisedMessages();
+               
+               $count = 0;
+               foreach( $this->messages as $key => $value ){
+                       if( $value['customised'] !== $this->custom &&
+                           ( $descending && ( $key < $offset || !$offset ) || !$descending && $key > $offset ) &&
+                               (( $this->prefix && preg_match( $this->prefix, $key ) ) || $this->prefix === false )
+                         ){
+                               $mResult->result[] = array( 'am_title'      => $key,
+                                                                                   'am_actual'     => $value['actual'],
+                                                                                   'am_default'    => $value['default'],
+                                                                                       'am_customised' => $value['customised'],
+                                                                         );
+                               unset( $this->messages[$key] ); // save a few bytes 
+                               $count++;
+                       }
+                       if( $count == $limit ) break;
+               }
+               unset( $this->messages ); //no longer needed, free up some memory
+               return $mResult;
+       }
+       
+       function getStartBody() {
+               return "<table border=\"1\" class=\"TablePager\" style=\"width:100%;\" id=\"allmessagestable\"><thead>\n<tr>" . 
+                          "<th rowspan=\"2\">" . wfMsg('allmessagesname') . "</th><th>" . wfMsg('allmessagesdefault') . 
+                          "</tr>\n<tr><th>" . wfMsg('allmessagescurrent') . "</th></tr>\n";
+       }
+       
+       function formatValue( $field , $value ){
+               global $wgLang;
+               switch( $field ){
+                       
+                       case 'am_title' : 
+                               
+                               $title = Title::makeTitle( NS_MEDIAWIKI, $value . $this->suffix );
+                               $talk  = Title::makeTitle( NS_MEDIAWIKI_TALK, $value . $this->suffix );
 
-               if( $changed ) {
-                       $txt .= "
-                               <tr class=\"orig\" id=\"sp-allmessages-r1-$i\">
-                                       <td rowspan=\"2\">
-                                               $anchor$pageLink<br />$talkLink
-                                       </td><td>
-                               $message
-                                       </td>
-                               </tr><tr class=\"new\" id=\"sp-allmessages-r2-$i\">
-                                       <td>
-                               $mw
-                                       </td>
-                               </tr>";
+                               if( $this->mCurrentRow->am_customised ){
+                                       $title = $this->mSkin->linkKnown( $title, $wgLang->lcfirst( $value ) );
+                               } else {
+                                       $title = $this->mSkin->link( $title, 
+                                                                                               $wgLang->lcfirst( $value ),
+                                                                                               array(),
+                                                                                               array(),
+                                                                                               array( 'broken' ) );
+                               }
+                               if( array_key_exists( $talk->getDBkey() , $this->talkPages ) ) {
+                                       $talk = $this->mSkin->linkKnown( $talk , $this->talk );
+                               } else {
+                                       $talk = $this->mSkin->link( $talk, 
+                                                                                               $this->talk, 
+                                                                                               array(), 
+                                                                                               array(), 
+                                                                                               array( 'broken' ) );
+                               }
+                               return $title . ' (' . $talk . ')';
+                               
+                       case 'am_default' :
+                               return Sanitizer::escapeHtmlAllowEntities( $value, ENT_QUOTES );
+                       case 'am_actual' : 
+                               return Sanitizer::escapeHtmlAllowEntities( $value, ENT_QUOTES );
+               }
+               return '';
+       }
+       
+       function formatRow( $row ){
+               //Do all the normal stuff
+               $s = parent::formatRow( $row );
+               
+               //But if there's a customised message, add that too.
+               if( $row->am_customised ){
+                       $s .= Xml::openElement( 'tr', $this->getRowAttrs( $row, true ) );
+                       $formatted = strval( $this->formatValue( 'am_actual', $row->am_actual ) );
+                       if ( $formatted == '' ) {
+                               $formatted = '&nbsp;';
+                       }
+                       $s .= Xml::tags( 'td', $this->getCellAttrs( 'am_actual', $row->am_actual ), $formatted ) 
+                          . "</tr>\n";
+               }
+               return $s;              
+       }
+       
+       function getRowAttrs( $row, $isSecond=false ){
+               $arr = array();
+               global $wgLang;
+               if( $row->am_customised ){
+                       $arr['class'] =  'allmessages-customised';
+               } 
+               if( !$isSecond ){
+                       $arr['id'] = Sanitizer::escapeId( 'msg_' . $wgLang->lcfirst( $row->am_title ) );
+               }
+               return $arr;
+       }
+       
+       function getCellAttrs( $field, $value ){
+               if( $this->mCurrentRow->am_customised && $field == 'am_title' ){
+                       return array( 'rowspan' => '2', 'class' => $field );
                } else {
-                       $txt .= "
-                               <tr class=\"def\" id=\"sp-allmessages-r1-$i\">
-                                       <td>
-                                               $anchor$pageLink<br />$talkLink
-                                       </td><td>
-                               $mw
-                                       </td>
-                               </tr>";
+                       return array( 'class' => $field );
                }
-               $messages[$key] = NULL; // trade bytes
-               $i++;
        }
-       $txt .= '</table>';
-       wfProfileOut( __METHOD__ . '-output' );
+       
+       // This is not actually used, as getStartBody is overridden above
+       function getFieldNames() {
+               return array( 'am_title'   => wfMsg('allmessagesname'),
+                                         'am_default' => wfMsg('allmessagesdefault') );
+       }
+       function getTitle() {
+               return SpecialPage::getTitleFor( 'Allmessages', false );
+       }
+       function isFieldSortable( $x ){
+               return false;
+       }
+       function getDefaultSort(){
+               return '';
+       }
+       function getQueryInfo(){
+               return '';
+       }
+}
+/* Overloads the relevant methods of the real ResultsWrapper so it
+ * doesn't go anywhere near an actual database.
+ */
+class FakeResultWrapper extends ResultWrapper {
+       
+       var $result     = array();
+       var $db         = NULL;         //And it's going to stay that way :D
+       var $pos        = 0;
+       var $currentRow = NULL;
+       
+       function __construct( $array ){
+               $this->result = $array;
+       }
+       
+       function numRows() {
+               return count( $this->result ); 
+       }
+       
+       function fetchRow() {
+               $this->currentRow = $this->result[$this->pos++];
+               return $this->currentRow;
+       }
+       
+       function seek( $row ) {
+               $this->pos = $row;
+       }
 
-       wfProfileOut( __METHOD__ );
-       return $txt;
+       function free() {}
+       
+       // Callers want to be able to access fields with $this->fieldName
+       function fetchObject(){
+               $this->currentRow = $this->result[$this->pos++];
+               return (object)$this->currentRow; 
+       }
+       
+       function rewind() {
+               $this->pos = 0;
+               $this->currentRow = NULL;
+       }
 }
index 1cde043..00f81ef 100644 (file)
@@ -3047,8 +3047,11 @@ In the latter case you can also use a link, for example [[{{#Special:Export}}/{{
 'allmessagestext'           => 'This is a list of system messages available in the MediaWiki namespace.
 Please visit [http://www.mediawiki.org/wiki/Localisation MediaWiki Localisation] and [http://translatewiki.net translatewiki.net] if you wish to contribute to the generic MediaWiki localisation.',
 'allmessagesnotsupportedDB' => "This page cannot be used because '''\$wgUseDatabaseMessages''' has been disabled.",
-'allmessagesfilter'         => 'Message name filter:',
-'allmessagesmodified'       => 'Show only modified',
+'allmessages-filter'            => 'Filter by customisation state:',
+'allmessages-filter-unmodified' => 'Unmodified',
+'allmessages-filter-all'        => 'All',
+'allmessages-filter-modified'   => 'Modified',
+'allmessages-prefix'            => 'Filter by prefix:',
 
 # Thumbnails
 'thumbnail-more'           => 'Enlarge',
index c2a7c53..d1aed28 100644 (file)
@@ -2058,8 +2058,11 @@ $wgMessageStructure = array(
                'allmessagescurrent',
                'allmessagestext',
                'allmessagesnotsupportedDB',
-               'allmessagesfilter',
-               'allmessagesmodified',
+               'allmessages-filter',
+               'allmessages-filter-unmodified',
+               'allmessages-filter-all',
+               'allmessages-filter-modified',
+               'allmessages-prefix',
        ),
        'thumbnails' => array(
                'thumbnail-more',
diff --git a/skins/common/allmessages.js b/skins/common/allmessages.js
deleted file mode 100644 (file)
index 9f07a48..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-var allmessages_nodelist = false;
-var allmessages_modified = false;
-var allmessages_timeout = false;
-var allmessages_running = false;
-
-function allmessagesmodified() {
-       allmessages_modified = !allmessages_modified;
-       allmessagesfilter();
-}
-
-function allmessagesfilter() {
-       if ( allmessages_timeout )
-               window.clearTimeout( allmessages_timeout );
-
-       if ( !allmessages_running )
-               allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
-}
-
-function allmessagesfilter_do() {
-       if ( !allmessages_nodelist )
-               return;
-
-       var text = document.getElementById('allmessagesinput').value.toLowerCase();
-       var nodef = allmessages_modified;
-
-       allmessages_running = true;
-
-       for ( var name in allmessages_nodelist ) {
-               var nodes = allmessages_nodelist[name];
-               var display = ( name.toLowerCase().indexOf( text ) == -1 ? 'none' : '' );
-
-               for ( var i = 0; i < nodes.length; i++)
-                       nodes[i].style.display =
-                               ( nodes[i].className == "def" && nodef
-                                 ? 'none' : display );
-       }
-
-       if ( text != document.getElementById('allmessagesinput').value.toLowerCase() ||
-            nodef != allmessages_modified )
-               allmessagesfilter_do();  // repeat
-
-       allmessages_running = false;
-}
-
-function allmessagesfilter_init() {
-       if ( allmessages_nodelist )
-               return;
-
-       var nodelist = new Array();
-       var templist = new Array();
-
-       var table = document.getElementById('allmessagestable');
-       if ( !table ) return;
-
-       var rows = document.getElementsByTagName('tr');
-       for ( var i = 0; i < rows.length; i++ ) {
-               var id = rows[i].getAttribute('id')
-               if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
-               templist[ id ] = rows[i];
-       }
-
-       var spans = table.getElementsByTagName('span');
-       for ( var i = 0; i < spans.length; i++ ) {
-               var id = spans[i].getAttribute('id')
-               if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
-               if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;
-
-               var nodes = new Array();
-               var row1 = templist[ id.replace('i', 'r1') ];
-               var row2 = templist[ id.replace('i', 'r2') ];
-
-               if ( row1 ) nodes[nodes.length] = row1;
-               if ( row2 ) nodes[nodes.length] = row2;
-               nodelist[ spans[i].firstChild.nodeValue ] = nodes;
-       }
-
-       var k = document.getElementById('allmessagesfilter');
-       if (k) { k.style.display = ''; }
-
-       allmessages_nodelist = nodelist;
-}
-
-hookEvent( "load", allmessagesfilter_init );
index 21a8b7a..e07803b 100644 (file)
@@ -620,6 +620,23 @@ table.collapsed tr.collapsable {
 .imagelist .TablePager_col_img_description { white-space: normal }
 .imagelist th.TablePager_sort { background-color: #ccccff }
 
+ /* Allmessages table */
+#allmessagestable .allmessages-customised td.am_default {
+       background-color: #fcffc4;
+}
+
+#allmessagestable tr.allmessages-customised:hover td.am_default {
+       background-color: #faff90;
+}
+
+#allmessagestable td.am_actual {
+       background-color: #e2ffe2;
+}
+
+#allmessagestable tr.allmessages-customised:hover + tr.allmessages-customised td.am_actual {
+       background-color: #b1ffb1;
+}
+
 /* filetoc */
 ul#filetoc {
        text-align: center;
index 824cf4b..fd84833 100644 (file)
@@ -775,25 +775,6 @@ p.revision_saved {
        font-weight:bold;
 }
 
-/* Allmessages table */
-
-#allmessagestable th {
-       background-color: #b2b2ff;
-}
-
-#allmessagestable tr.orig {
-       background-color: #ffe2e2;
-}
-
-#allmessagestable tr.new {
-       background-color: #e2ffe2;
-}
-
-#allmessagestable tr.def {
-       background-color: #f0f0ff;
-}
-
-
 /* noarticletext */
 div.noarticletext {
        border: 1px solid #ccc;
index bc94df5..b4043c2 100644 (file)
@@ -1259,25 +1259,6 @@ p.revision_saved {
        font-weight:bold;
 }
 
-/* Allmessages table */
-
-#allmessagestable th {
-       background-color: #b2b2ff;
-}
-
-#allmessagestable tr.orig {
-       background-color: #ffe2e2;
-}
-
-#allmessagestable tr.new {
-       background-color: #e2ffe2;
-}
-
-#allmessagestable tr.def {
-       background-color: #f0f0ff;
-}
-
-
 /* noarticletext */
 div.noarticletext {
        border: 1px solid #ccc;