Merge "Remove hitcounters and associated code"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 20 Oct 2014 21:12:54 +0000 (21:12 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 20 Oct 2014 21:12:54 +0000 (21:12 +0000)
12 files changed:
1  2 
RELEASE-NOTES-1.25
includes/AutoLoader.php
includes/DefaultSettings.php
includes/parser/CoreParserFunctions.php
includes/parser/Parser.php
includes/skins/SkinTemplate.php
includes/specialpage/SpecialPageFactory.php
languages/i18n/en.json
languages/i18n/qqq.json
languages/messages/MessagesEn.php
resources/src/mediawiki.legacy/commonPrint.css
tests/phpunit/MediaWikiTestCase.php

diff --combined RELEASE-NOTES-1.25
@@@ -18,21 -18,9 +18,21 @@@ production
    for 'languageScripts'.
  * Added a new hook, "ContentAlterParserOutput", to allow extensions to modify the
    parser output for a content object before links update.
 +* (bug 35785) Enhanced recent changes and extended watchlist are now default.
 +  Documentation: https://meta.wikimedia.org/wiki/Help:Enhanced_recent_changes
 +  and https://www.mediawiki.org/wiki/Manual:$wgDefaultUserOptions.
  * (bug 67341) SVG images will no longer be base64-encoded when being embedded
    in CSS. This results in slight size increase before gzip compression (due to
    percent-encoding), but up to 20% decrease after it.
 +* Upgrade jStorage to v0.4.12.
 +* MediaWiki now natively supports page status indicators: icons (or short text
 +  snippets) usually displayed in the top-right corner of the page. They have
 +  been in use on Wikipedia for a long time, implemented using templates and CSS
 +  absolute positioning.
 +  - Basic wikitext syntax: <indicator name="foo">[[File:Foo.svg|20px]]</indicator>
 +  - Usage instructions: https://www.mediawiki.org/wiki/Help:Page_status_indicators
 +  - Adjusting custom skins to support indicators:
 +    https://www.mediawiki.org/wiki/Manual:Skinning#Page_status_indicators
  
  === Bug fixes in 1.25 ===
  * (bug 71003) No additional code will be generated to try to load CSS-embedded
  === Action API changes in 1.25 ===
  * (bug 65403) XML tag highlighting is now only performed for formats
    "xmlfm" and "wddxfm".
 +* action=paraminfo supports generalized submodules (modules=query+value),
 +  querymodules and formatmodules are deprecated
 +* action=paraminfo no longer outputs descriptions and other help text by
 +  default. If needed, it may be requested using the new 'helpformat' parameter.
 +* action=help has been completely rewritten, and outputs help in HTML
 +  rather than plain text.
 +* Hitting api.php without specifying an action now displays only the help for
 +  the main module, with links to submodule help.
 +* API help is no longer displayed on errors.
 +* Internationalized messages returned by the API will be in the wiki's content
 +  language by default. 'uselang' is now a recognized API parameter;
 +  "uselang=user" may be used to select the language from the current user's
 +  preferences.
 +* Default output format for the API is now jsonfm.
 +* Simplified continuation will return a "batchcomplete" property in the result
 +  when a batch of pages is complete.
 +* Pretty-printed HTML output now has nicer formatting and (if available)
 +  better syntax highlighting.
  
  === Action API internal changes in 1.25 ===
 +* ApiHelp has been rewritten to support i18n and paginated HTML output.
 +  Most existing modules should continue working without changes, but should do
 +  the following:
 +  * Add an i18n message "apihelp-{$moduleName}-description" to replace getDescription().
 +  * Add i18n messages "apihelp-{$moduleName}-param-{$param}" for each parameter
 +    to replace getParamDescription(). If necessary, the settings array returned
 +    by getParams() can use the new ApiBase::PARAM_HELP_MSG key to override the
 +    message.
 +  * Implement getExamplesMessages() to replace getExamples().
 +* Modules with submodules (like action=query) must have their submodules
 +  override ApiBase::getParent() to return the correct parent object.
 +* The 'APIGetDescription' and 'APIGetParamDescription' hooks are deprecated,
 +  and will have no effect for modules using i18n messages. Use
 +  'APIGetDescriptionMessages' and 'APIGetParamDescriptionMessages' instead.
 +* Api formatters will no longer be asked to display the help screen on errors.
 +* ApiMain::getCredits() was removed. The credits are available in the
 +  'api-credits' i18n message.
 +* ApiFormatBase has been changed to support i18n and syntax highlighting via
 +  extensions with the new 'ApiFormatHighlight' hook. Core syntax highlighting
 +  has been removed.
 +* ApiFormatBase now always buffers. Output is done when
 +  ApiFormatBase::closePrinter is called.
 +* The following methods have been deprecated and may be removed in a future
 +  release:
 +  * ApiBase::getDescription
 +  * ApiBase::getParamDescription
 +  * ApiBase::getExamples
 +  * ApiBase::makeHelpMsg
 +  * ApiBase::makeHelpArrayToString
 +  * ApiBase::makeHelpMsgParameters
 +  * ApiFormatBase::setUnescapeAmps
 +  * ApiFormatBase::getWantsHelp
 +  * ApiFormatBase::setHelp
 +  * ApiFormatBase::formatHTML
 +  * ApiFormatBase::setBufferResult
 +  * ApiFormatBase::getDescription
 +  * ApiMain::setHelp
 +  * ApiMain::reallyMakeHelpMsg
 +  * ApiMain::makeHelpMsgHeader
  
  === Languages updated in 1.25 ===
  
@@@ -130,6 -61,7 +130,7 @@@ changes to languages because of Bugzill
  * Deprecated OutputPage::readOnlyPage() and OutputPage::rateLimited().
    Also, the former will now throw an MWException if called with one or more
    arguments.
+ * Removed hitcounters and associated code.
  
  == Compatibility ==
  
diff --combined includes/AutoLoader.php
@@@ -106,8 -106,6 +106,8 @@@ $wgAutoloadLocalClasses = array
        'HTMLSelectField' => 'includes/htmlform/HTMLSelectField.php',
        'HTMLSelectLimitField' => 'includes/htmlform/HTMLSelectLimitField.php',
        'HTMLSelectOrOtherField' => 'includes/htmlform/HTMLSelectOrOtherField.php',
 +      'HTMLSelectNamespace' => 'includes/htmlform/HTMLSelectNamespace.php',
 +      'HTMLTagFilter' => 'includes/htmlform/HTMLTagFilter.php',
        'HTMLSubmitField' => 'includes/htmlform/HTMLSubmitField.php',
        'HTMLTextAreaField' => 'includes/htmlform/HTMLTextAreaField.php',
        'HTMLTextField' => 'includes/htmlform/HTMLTextField.php',
  
        # includes/debug
        'MWDebug' => 'includes/debug/MWDebug.php',
 +      'MWLogger' => 'includes/debug/logger/Logger.php',
 +      'MWLoggerMonologHandler' => 'includes/debug/logger/monolog/Handler.php',
 +      'MWLoggerMonologProcessor' => 'includes/debug/logger/monolog/Processor.php',
 +      'MWLoggerMonologSpi' => 'includes/debug/logger/monolog/Spi.php',
 +      'MWLoggerNullSpi' => 'includes/debug/logger/NullSpi.php',
 +      'MWLoggerSpi' => 'includes/debug/logger/Spi.php',
  
        # includes/deferred
        'DataUpdate' => 'includes/deferred/DataUpdate.php',
        'SiteStatsUpdate' => 'includes/deferred/SiteStatsUpdate.php',
        'SqlDataUpdate' => 'includes/deferred/SqlDataUpdate.php',
        'SquidUpdate' => 'includes/deferred/SquidUpdate.php',
-       'ViewCountUpdate' => 'includes/deferred/ViewCountUpdate.php',
  
        # includes/diff
        'DiffEngine' => 'includes/diff/DairikiDiff.php',
        'NewFilesPager' => 'includes/specials/SpecialNewimages.php',
        'NewPagesPager' => 'includes/specials/SpecialNewpages.php',
        'PageArchive' => 'includes/specials/SpecialUndelete.php',
-       'PopularPagesPage' => 'includes/specials/SpecialPopularpages.php',
        'ProtectedPagesPager' => 'includes/specials/SpecialProtectedpages.php',
        'ProtectedTitlesPager' => 'includes/specials/SpecialProtectedtitles.php',
        'RandomPage' => 'includes/specials/SpecialRandompage.php',
        'SpecialAllMessages' => 'includes/specials/SpecialAllMessages.php',
        'SpecialAllMyUploads' => 'includes/specials/SpecialMyRedirectPages.php',
        'SpecialAllPages' => 'includes/specials/SpecialAllPages.php',
 +      'SpecialApiHelp' => 'includes/specials/SpecialApiHelp.php',
        'SpecialBlankpage' => 'includes/specials/SpecialBlankpage.php',
        'SpecialBlock' => 'includes/specials/SpecialBlock.php',
        'SpecialBlockList' => 'includes/specials/SpecialBlockList.php',
@@@ -2092,7 -2092,7 +2092,7 @@@ $wgLanguageConverterCacheType = CACHE_A
   */
  $wgObjectCaches = array(
        CACHE_NONE => array( 'class' => 'EmptyBagOStuff' ),
 -      CACHE_DB => array( 'class' => 'SqlBagOStuff', 'table' => 'objectcache' ),
 +      CACHE_DB => array( 'class' => 'SqlBagOStuff' ),
  
        CACHE_ANYTHING => array( 'factory' => 'ObjectCache::newAnything' ),
        CACHE_ACCEL => array( 'factory' => 'ObjectCache::newAccelerator' ),
@@@ -3797,7 -3797,6 +3797,7 @@@ $wgNamespacesWithSubpages = array
  $wgTrackingCategories = array(
        'index-category',
        'noindex-category',
 +      'duplicate-args-category',
        'expensive-parserfunction-category',
        'post-expand-template-argument-category',
        'post-expand-template-inclusion-category',
@@@ -4116,15 -4115,6 +4116,6 @@@ $wgTranscludeCacheExpiry = 3600
   */
  $wgArticleCountMethod = 'link';
  
- /**
-  * wgHitcounterUpdateFreq sets how often page counters should be updated, higher
-  * values are easier on the database. A value of 1 causes the counters to be
-  * updated on every hit, any higher value n cause them to update *on average*
-  * every n hits. Should be set to either 1 or something largish, eg 1000, for
-  * maximum efficiency.
-  */
- $wgHitcounterUpdateFreq = 1;
  /**
   * How many days user must be idle before he is considered inactive. Will affect
   * the number shown on Special:Statistics, Special:ActiveUsers, and the
@@@ -4275,7 -4265,7 +4266,7 @@@ $wgDefaultUserOptions = array
        'enotifrevealaddr' => 0,
        'enotifusertalkpages' => 1,
        'enotifwatchlistpages' => 1,
 -      'extendwatchlist' => 0,
 +      'extendwatchlist' => 1,
        'fancysig' => 0,
        'forceeditsummary' => 0,
        'gender' => 'unknown',
        'thumbsize' => 5,
        'underline' => 2,
        'uselivepreview' => 0,
 -      'usenewrc' => 0,
 +      'usenewrc' => 1,
        'watchcreations' => 1,
        'watchdefault' => 1,
        'watchdeletion' => 0,
@@@ -5224,43 -5214,6 +5215,43 @@@ $wgDebugDumpSqlLength = 500
   */
  $wgDebugLogGroups = array();
  
 +/**
 + * Default service provider for creating MWLogger instances.
 + *
 + * This can either be the name of a class implementing the MWLoggerSpi
 + * interface with a zero argument constructor or a callable that will return
 + * an MWLoggerSpi instance. Alternately the MWLogger::registerProvider method
 + * can be called to inject an MWLoggerSpi instance into MWLogger and bypass
 + * the use of this configuration variable.
 + *
 + * @since 1.25
 + * @var $wgMWLoggerDefaultSpi string|callable
 + * @see MwLogger
 + */
 +$wgMWLoggerDefaultSpi = 'MWLoggerNullSpi';
 +
 +/**
 + * Configuration for MWLoggerMonologSpi logger factory.
 + *
 + * Default configuration installs a null handler that will silently discard
 + * all logging events.
 + *
 + * @since 1.25
 + * @see MWLoggerMonologSpi
 + */
 +$wgMWLoggerMonologSpiConfig = array(
 +      'loggers' => array(
 +              '@default' => array(
 +                      'handlers' => array( 'null' ),
 +              ),
 +      ),
 +      'handlers' => array(
 +              'null' => array(
 +                      'class' => '\\Monolog\\Logger\\NullHandler',
 +              ),
 +      ),
 +);
 +
  /**
   * Display debug data at the bottom of the main content area.
   *
@@@ -5422,12 -5375,6 +5413,6 @@@ $wgAggregateStatsID = false
   */
  $wgStatsFormatString = "stats/%s - %s 1 1 1 1 %s\n";
  
- /**
-  * Whereas to count the number of time an article is viewed.
-  * Does not work if pages are cached (for example with squid).
-  */
- $wgDisableCounters = false;
  /**
   * InfoAction retrieves a list of transclusion links (both to and from).
   * This number puts a limit on that query in the case of highly transcluded
@@@ -6205,7 -6152,6 +6190,7 @@@ $wgExtensionMessagesFiles = array()
   */
  $wgMessagesDirs = array(
        'core' => "$IP/languages/i18n",
 +      'api' => "$IP/includes/api/i18n",
        'oojs-ui' => "$IP/resources/lib/oojs-ui/i18n",
  );
  
@@@ -44,7 -44,7 +44,7 @@@ class CoreParserFunctions 
                        'canonicalurle', 'formatnum', 'grammar', 'gender', 'plural',
                        'numberofpages', 'numberofusers', 'numberofactiveusers',
                        'numberofarticles', 'numberoffiles', 'numberofadmins',
-                       'numberingroup', 'numberofedits', 'numberofviews', 'language',
+                       'numberingroup', 'numberofedits', 'language',
                        'padleft', 'padright', 'anchorencode', 'defaultsort', 'filepath',
                        'pagesincategory', 'pagesize', 'protectionlevel',
                        'namespacee', 'namespacenumber', 'talkspace', 'talkspacee',
                $text = $parser->doQuotes( $text );
  
                // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever
 -              $text = preg_replace( '/' . preg_quote( $parser->uniqPrefix(), '/' ) . '.*?'
 -                      . preg_quote( Parser::MARKER_SUFFIX, '/' ) . '/', '', $text );
 +              $text = $parser->killMarkers( $text );
  
                // list of disallowed tags for DISPLAYTITLE
                // these will be escaped even though they are allowed in normal wiki text
        public static function numberofedits( $parser, $raw = null ) {
                return self::formatRaw( SiteStats::edits(), $raw );
        }
-       public static function numberofviews( $parser, $raw = null ) {
-               global $wgDisableCounters;
-               return !$wgDisableCounters ? self::formatRaw( SiteStats::views(), $raw ) : '';
-       }
        public static function pagesinnamespace( $parser, $namespace = 0, $raw = null ) {
                return self::formatRaw( SiteStats::pagesInNs( intval( $namespace ) ), $raw );
        }
@@@ -112,20 -112,8 +112,20 @@@ class Parser 
        const OT_MSG = 3;
        const OT_PLAIN = 4; # like extractSections() - portions of the original are returned unchanged.
  
 -      # Marker Suffix needs to be accessible staticly.
 +      /**
 +       * Prefix for temporary replacement strings generated by the preprocessor
 +       * ("strip markers"). Using \x7f at the front gives us a little extra
 +       * robustness since it shouldn't match when butted up against
 +       * identifier-like string constructs.
 +       *
 +       * Must not consist of all title characters, or else it will change
 +       * the behavior of <nowiki> in a link.
 +       */
 +      const MARKER_PREFIX = "\x7fUNIQ";
 +      /** Suffix for strip markers */
        const MARKER_SUFFIX = "-QINU\x7f";
 +      /** Regex which matches the state ID part of strip markers */
 +      const MARKER_STATE_ID_REGEX = '[0-9a-f]{16}';
  
        # Markers used for wrapping the table of contents
        const TOC_START = '<mw:toc>';
                $this->mLangLinkLanguages = array();
                $this->currentRevisionCache = null;
  
 -              /**
 -               * Prefix for temporary replacement strings for the multipass parser.
 -               * \x07 should never appear in input as it's disallowed in XML.
 -               * Using it at the front also gives us a little extra robustness
 -               * since it shouldn't match when butted up against identifier-like
 -               * string constructs.
 -               *
 -               * Must not consist of all title characters, or else it will change
 -               * the behavior of <nowiki> in a link.
 -               */
 -              $this->mUniqPrefix = "\x7fUNIQ" . self::getRandomString();
 -              $this->mStripState = new StripState( $this->mUniqPrefix );
 +              $stripId = self::getRandomString();
 +              $this->mUniqPrefix = self::MARKER_PREFIX . $stripId;
 +              $this->mStripState = new StripState( $stripId );
  
                # Clear these on every parse, bug 4549
                $this->mTplRedirCache = $this->mTplDomCache = array();
                        case 'numberofedits':
                                $value = $pageLang->formatNum( SiteStats::edits() );
                                break;
-                       case 'numberofviews':
-                               global $wgDisableCounters;
-                               $value = !$wgDisableCounters ? $pageLang->formatNum( SiteStats::views() ) : '';
-                               break;
                        case 'currenttimestamp':
                                $value = wfTimestamp( TS_MW, $ts );
                                break;
@@@ -260,7 -260,7 +260,7 @@@ class SkinTemplate extends Skin 
         */
        protected function prepareQuickTemplate() {
                global $wgContLang, $wgScript, $wgStylePath, $wgMimeType, $wgJsMimeType,
-                       $wgDisableCounters, $wgSitename, $wgLogo, $wgMaxCredits,
+                       $wgSitename, $wgLogo, $wgMaxCredits,
                        $wgShowCreditsIfMax, $wgArticlePath,
                        $wgScriptPath, $wgServer;
  
                $tpl->set( 'logo', $this->logoText() );
  
                $tpl->set( 'copyright', false );
+               // No longer used
                $tpl->set( 'viewcount', false );
                $tpl->set( 'lastmod', false );
                $tpl->set( 'credits', false );
                $tpl->set( 'numberofwatchingusers', false );
                if ( $out->isArticle() && $title->exists() ) {
                        if ( $this->isRevisionCurrent() ) {
-                               if ( !$wgDisableCounters ) {
-                                       $viewcount = $this->getWikiPage()->getCount();
-                                       if ( $viewcount ) {
-                                               $tpl->set( 'viewcount', $this->msg( 'viewcount' )->numParams( $viewcount )->parse() );
-                                       }
-                               }
                                if ( $wgMaxCredits != 0 ) {
                                        $tpl->set( 'credits', Action::factory( 'credits', $this->getWikiPage(),
                                                $this->getContext() )->getCredits( $wgMaxCredits, $wgShowCreditsIfMax ) );
                $tpl->set( 'footerlinks', array(
                        'info' => array(
                                'lastmod',
-                               'viewcount',
                                'numberofwatchingusers',
                                'credits',
                                'copyright',
                        }
                }
  
 +              $tpl->set( 'indicators', $out->getIndicators() );
 +
                $tpl->set( 'sitenotice', $this->getSiteNotice() );
                $tpl->set( 'bottomscripts', $this->bottomScripts() );
                $tpl->set( 'printfooter', $this->printSource() );
@@@ -156,7 -156,6 +156,7 @@@ class SpecialPageFactory 
                'Booksources' => 'SpecialBookSources',
  
                // Unlisted / redirects
 +              'ApiHelp' => 'SpecialApiHelp',
                'Blankpage' => 'SpecialBlankpage',
                'Diff' => 'SpecialDiff',
                'Emailuser' => 'SpecialEmailUser',
         */
        private static function getPageList() {
                global $wgSpecialPages;
-               global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
+               global $wgDisableInternalSearch, $wgEmailAuthentication;
                global $wgEnableEmail, $wgEnableJavaScriptTest;
                global $wgPageLanguageUseDB;
  
  
                        self::$list = self::$coreList;
  
-                       if ( !$wgDisableCounters ) {
-                               self::$list['Popularpages'] = 'PopularPagesPage';
-                       }
                        if ( !$wgDisableInternalSearch ) {
                                self::$list['Search'] = 'SpecialSearch';
                        }
diff --combined languages/i18n/en.json
        "viewsourcetext": "You can view and copy the source of this page:",
        "viewyourtext": "You can view and copy the source of <strong>your edits</strong> to this page:",
        "protectedinterface": "This page provides interface text for the software on this wiki, and is protected to prevent abuse.\nTo add or change translations for all wikis, please use [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project.",
 -      "editinginterface": "<strong>Warning:</strong> You are editing a page that is used to provide interface text for the software.\nChanges to this page will affect the appearance of the user interface for other users on this wiki.\nTo add or change translations for all wikis, please use [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project.",
 +      "editinginterface": "<strong>Warning:</strong> You are editing a page that is used to provide interface text for the software.\nChanges to this page will affect the appearance of the user interface for other users on this wiki.",
 +      "translateinterface": "To add or change translations for all wikis, please use [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project.",
        "cascadeprotected": "This page has been protected from editing because it is included in the following {{PLURAL:$1|page, which is|pages, which are}} protected with the \"cascading\" option turned on:\n$2",
        "namespaceprotected": "You do not have permission to edit pages in the <strong>$1</strong> namespace.",
        "customcssprotected": "You do not have permission to edit this CSS page because it contains another user's personal settings.",
        "content-model-text": "plain text",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
 +      "duplicate-args-category": "Pages using duplicate arguments in template calls",
 +      "duplicate-args-category-desc": "The page contains template calls that use duplicates of arguments, such as <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "<strong>Warning:</strong> This page contains too many expensive parser function calls.\n\nIt should have less than $2 {{PLURAL:$2|call|calls}}, there {{PLURAL:$1|is now $1 call|are now $1 calls}}.",
        "expensive-parserfunction-category": "Pages with too many expensive parser function calls",
        "post-expand-template-inclusion-warning": "<strong>Warning:</strong> Template include size is too large.\nSome templates will not be included.",
        "gender-female": "She edits wiki pages",
        "prefs-help-gender": "Setting this preference is optional.\nThe software uses its value to address you and to mention you to others using the appropriate grammatical gender.\nThis information will be public.",
        "email": "Email",
 -      "prefs-help-realname": "Real name is optional.\nIf you choose to provide it, this will be used for giving you attribution for your work.",
 +      "prefs-help-realname": "Real name is optional.\nIf provided, it may be used to give you attribution for your work.",
        "prefs-help-email": "Email address is optional, but is needed for password resets, should you forget your password.",
        "prefs-help-email-others": "You can also choose to let others contact you by email through a link on your user or talk page.\nYour email address is not revealed when other users contact you.",
        "prefs-help-email-required": "Email address is required.",
        "statistics-summary": "",
        "statistics-header-pages": "Page statistics",
        "statistics-header-edits": "Edit statistics",
-       "statistics-header-views": "View statistics",
        "statistics-header-users": "User statistics",
        "statistics-header-hooks": "Other statistics",
        "statistics-articles": "Content pages",
        "statistics-files": "Uploaded files",
        "statistics-edits": "Page edits since {{SITENAME}} was set up",
        "statistics-edits-average": "Average edits per page",
-       "statistics-views-total": "Views total",
-       "statistics-views-total-desc": "Views to non-existing pages and special pages are not included",
-       "statistics-views-peredit": "Views per edit",
        "statistics-users": "Registered [[Special:ListUsers|users]]",
        "statistics-users-active": "Active users",
        "statistics-users-active-desc": "Users who have performed an action in the last {{PLURAL:$1|day|$1 days}}",
-       "statistics-mostpopular": "Most viewed pages",
        "statistics-footer": "",
        "pageswithprop": "Pages with a page property",
        "pageswithprop-summary": "",
        "unusedcategories-summary": "",
        "unusedimages": "Unused files",
        "unusedimages-summary": "",
-       "popularpages": "Popular pages",
-       "popularpages-summary": "",
        "wantedcategories": "Wanted categories",
        "wantedcategories-summary": "",
        "wantedpages": "Wanted pages",
        "pager-older-n": "{{PLURAL:$1|older 1|older $1}}",
        "suppress": "Oversight",
        "querypage-disabled": "This special page is disabled for performance reasons.",
 +      "apihelp": "API help",
 +      "apihelp-summary": "",
 +      "apihelp-no-such-module": "Module \"$1\" not found.",
 +      "apihelp-link": "[[Special:ApiHelp/$1|$2]]",
        "booksources": "Book sources",
        "booksources-summary": "",
        "booksources-search-legend": "Search for book sources",
        "accesskey-pt-mycontris": "y",
        "accesskey-pt-login": "o",
        "accesskey-pt-logout": "",
 +      "accesskey-pt-createaccount": "",
        "accesskey-ca-talk": "t",
        "accesskey-ca-edit": "e",
        "accesskey-ca-addsection": "+",
        "accesskey-feed-atom": "",
        "accesskey-t-contributions": "",
        "accesskey-t-emailuser": "",
 +      "accesskey-t-info": "",
        "accesskey-t-permalink": "",
        "accesskey-t-print": "p",
        "accesskey-t-upload": "u",
        "tooltip-pt-mycontris": "A list of your contributions",
        "tooltip-pt-login": "You are encouraged to log in; however, it is not mandatory",
        "tooltip-pt-logout": "Log out",
 +      "tooltip-pt-createaccount": "You are encouraged to create an account and log in; however, it is not mandatory",
        "tooltip-ca-talk": "Discussion about the content page",
        "tooltip-ca-edit": "You can edit this page. Please use the preview button before saving",
        "tooltip-ca-addsection": "Start a new section",
        "tooltip-feed-atom": "Atom feed for this page",
        "tooltip-t-contributions": "A list of contributions of this user",
        "tooltip-t-emailuser": "Send an email to this user",
 +      "tooltip-t-info": "More information about this page",
        "tooltip-t-upload": "Upload files",
        "tooltip-t-specialpages": "A list of all special pages",
        "tooltip-t-print": "Printable version of this page",
        "pageinfo-robot-policy": "Indexing by robots",
        "pageinfo-robot-index": "Allowed",
        "pageinfo-robot-noindex": "Disallowed",
-       "pageinfo-views": "Number of views",
        "pageinfo-watchers": "Number of page watchers",
        "pageinfo-few-watchers": "Fewer than $1 {{PLURAL:$1|watcher|watchers}}",
        "pageinfo-redirects-name": "Number of redirects to this page",
        "unknown_extension_tag": "Unknown extension tag \"$1\"",
        "duplicate-defaultsort": "<strong>Warning:</strong> Default sort key \"$2\" overrides earlier default sort key \"$1\".",
        "duplicate-displaytitle": "<strong>Warning:</strong> Display title \"$2\" overrides earlier display title \"$1\".",
 +      "invalid-indicator-name": "<strong>Error:</strong> Page status indicators' <code>name</code> attribute must not be empty.",
        "version": "Version",
        "version-summary": "",
        "version-extensions": "Installed extensions",
diff --combined languages/i18n/qqq.json
                        "פוילישער",
                        "គីមស៊្រុន",
                        "아라",
 -                      "Jdforrester"
 +                      "Jdforrester",
 +                      "Mar(c)"
                ]
        },
        "sidebar": "{{notranslate}}",
        "viewyourtext": "Same as {{msg-mw|viewsourcetext}} but when showing the text submitted by the user, this happens e.g. when the user was blocked while he is editing the page",
        "protectedinterface": "Message shown if a user without the \"editinterface\" right tries to edit a page in the MediaWiki namespace.\n\nSee also {{msg-mw|editinginterface}}. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "editinginterface": "A message shown when editing pages in the namespace MediaWiki:.\n\nSee also {{msg-mw|protectedinterface}}.",
 +      "translateinterface": "A message shown when editing pages in the namespace MediaWiki:, which have a default message text.\n\nSee also {{msg-mw|protectedinterface}}, {{msg-mw|editinginterface}}.",
        "cascadeprotected": "Parameters:\n* $1 - number of cascade-protected pages, used for PLURAL\n* $2 - list of cascade-protected pages\n* $3 - (Unused) the action the user attempted to perform",
        "namespaceprotected": "Parameters:\n* $1 - namespace name\n* $2 - (Unused) the action the user attempted to perform",
        "customcssprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "content-model-text": "Name for the plain text content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}\n{{Identical|Plain text}}",
        "content-model-javascript": "Name for the JavaScript content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
        "content-model-css": "Name for the CSS content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
 +      "duplicate-args-category": "This message is used as a category name for a [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages are placed automatically if they contain template calls that use duplicates of arguments, such as <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
 +      "duplicate-args-category-desc": "Duplicate arguments category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Duplicate-args-category}}",
        "expensive-parserfunction-warning": "On some (expensive) [[MetaWikipedia:Help:ParserFunctions|parser functions]] (e.g. <code><nowiki>{{#ifexist:}}</nowiki></code>) there is a limit of how many times it may be used. This is an error message shown when the limit is exceeded.\n\nParameters:\n* $1 - the current number of parser function calls\n* $2 - the allowed number of parser function calls\nSee also [[:mw:Manual:$wgExpensiveParserFunctionLimit|$wgExpensiveParserFunctionLimit in the MediaWiki manual]].\n\nSee also:\n* {{msg-mw|Expensive-parserfunction-category}}",
        "expensive-parserfunction-category": "This message is used as a category name for a [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages are placed automatically if they contain too many calls to expensive parser functions.\n\nSee also:\n* {{msg-mw|Expensive-parserfunction-category-desc}}\n* {{msg-mw|Expensive-parserfunction-warning}}",
        "post-expand-template-inclusion-warning": "When templates are expanded, there is a size limit for the number of bytes yielded. Usually that occurs from excessively nested templates, recursive templates, or ones having x-zillion of #if #case or similar contructs in them. When the wikicode parser detects this, it outputs a red warning message to the page.\n\n\nSee also:\n* {{msg-mw|Post-expand-template-inclusion-category}}",
        "statistics-summary": "{{doc-specialpagesummary|statistics}}",
        "statistics-header-pages": "Used in [[Special:Statistics]]",
        "statistics-header-edits": "Used in [[Special:Statistics]]",
-       "statistics-header-views": "Used in [[Special:Statistics]]",
        "statistics-header-users": "Used in [[Special:Statistics]].\n{{Identical|User statistics}}",
        "statistics-header-hooks": "Header of a section on [[Special:Statistics]] containing data provided by MediaWiki extensions",
        "statistics-articles": "Used in [[Special:Statistics]].\n\nA 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].\n\nPossible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.\n\n{{Identical|Content page}}",
        "statistics-files": "Used in [[Special:Statistics]].\n{{Identical|Uploaded file}}",
        "statistics-edits": "Used in [[Special:Statistics]]",
        "statistics-edits-average": "Used in [[Special:Statistics]]",
-       "statistics-views-total": "Used in [[Special:Statistics]]",
-       "statistics-views-total-desc": "This message follows the message {{msg-mw|statistics-views-total}}, in [[Special:Statistics]].",
-       "statistics-views-peredit": "Used in [[Special:Statistics]]",
        "statistics-users": "{{doc-important|Do not translate \"Special:ListUsers\"}}\nUsed in [[Special:Statistics]].",
        "statistics-users-active": "Used in [[Special:Statistics]]",
        "statistics-users-active-desc": "Description shown beneath ''Active users'' in [[Special:Statistics]]. Parameters:\n* $1 - Value of <code>$wgRCMaxAge</code> in days",
-       "statistics-mostpopular": "Used in [[Special:Statistics]]",
        "statistics-footer": "{{notranslate}}",
        "pageswithprop": "{{doc-special|PagesWithProp}}\n{{Identical|Page with page property}}",
        "pageswithprop-summary": "{{doc-specialpagesummary|pageswithprop}}",
        "unusedcategories-summary": "{{doc-specialpagesummary|unusedcategories}}",
        "unusedimages": "{{doc-special|UnusedImages}}",
        "unusedimages-summary": "{{doc-specialpagesummary|unusedimages}}",
-       "popularpages": "{{doc-special|PopularPages}}",
-       "popularpages-summary": "{{doc-specialpagesummary|popularpages}}",
        "wantedcategories": "{{doc-special|WantedCategories}}",
        "wantedcategories-summary": "{{doc-specialpagesummary|wantedcategories}}",
        "wantedpages": "{{doc-special|WantedPages}}\n{{Identical|Wanted page}}",
        "pager-older-n": "This is part of the navigation message on the top and bottom of Special pages which are lists of things in date order, e.g. the User's contributions page. It is passed as the first argument of {{msg-mw|Viewprevnext}}. $1 is the number of items shown per page.",
        "suppress": "{{Identical|Oversight}}",
        "querypage-disabled": "On special pages that use expensive database queries but are not cacheable, this message is displayed when 'miser mode' is on (i.e. no expensive queries allowed).",
 +      "apihelp": "{{doc-special|ApiHelp}}",
 +      "apihelp-summary": "{{doc-specialpagesummary|ApiHelp}}",
 +      "apihelp-no-such-module": "Used as an error message if the requested API module is not found.\n\nParameters:\n* $1 - Requested module name",
 +      "apihelp-link": "{{notranslate}} Used to construct a link to [[Special:ApiHelp]]\n\nParameters:\n* $1 - module to link\n* $2 - link text",
        "booksources": "{{doc-special|BookSources}}\n\n'''This message shouldn't be changed unless it has serious mistakes.'''\n\nIt's used as the page name of the configuration page of [[Special:BookSources]]. Changing it breaks existing sites using the default version of this message.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
        "booksources-summary": "{{doc-specialpagesummary|booksources}}",
        "booksources-search-legend": "Box heading on [[Special:BookSources|book sources]] special page. The box is for searching for places where a particular book can be bought or viewed.",
        "wlheader-enotif": "Message at the top of [[Special:Watchlist]], after {{msg-mw|watchlist-details}}. Has to be a full sentence.\n\nSee also:\n* {{msg-mw|Watchlist-options|fieldset}}\n* {{msg-mw|enotif reset|Submit button text}}",
        "wlheader-showupdated": "Message at the top of [[Special:Watchlist]], after {{msg-mw|watchlist-details}}. Has to be a full sentence.",
        "wlnote": "Used on [[Special:Watchlist]] when a maximum number of hours or days is specified.\n\nParameters:\n* $1 - the number of changes shown\n* $2 - the number of hours for which the changes are shown\n* $3 - a date alone\n* $4 - a time alone",
 -      "wlshowlast": "Appears on [[Special:Watchlist]]. Parameters:\n* $1 - a choice of different numbers of hours (\"1 | 2 | 6 | 12\")\n* $2 - a choice of different numbers of days (\"1 | 3 | 7\")\nClicking on your choice changes the list of changes you see (without changing the default in my preferences).",
 +      "wlshowlast": "Appears on [[Special:Watchlist]]. Parameters:\n* $1 - a choice of different numbers of hours (\"1 | 2 | 6 | 12\")\n* $2 - a choice of different numbers of days (\"1 | 3 | 7\" and the maximum number of days available)\nClicking on your choice changes the list of changes you see (without changing the default in my preferences).",
        "watchlist-options": "Legend of the fieldset of [[Special:Watchlist]]\n\nSee also:\n* {{msg-mw|Watchlist-details|watchlist header}}\n* {{msg-mw|Wlheader-enotif|watchlist header}}\n* {{msg-mw|enotif reset|Submit button text}}",
        "watching": "Text displayed when clicked on the watch tab: {{msg-mw|Watch}}. It means the wiki is adding that page to your watchlist.",
        "unwatching": "Text displayed when clicked on the unwatch tab: {{msg-mw|Unwatch}}. It means the wiki is removing that page from your watchlist.",
        "accesskey-pt-mycontris": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}",
        "accesskey-pt-login": "{{doc-accesskey}}",
        "accesskey-pt-logout": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Logout}}\n* {{msg-mw|Accesskey-pt-logout}}\n* {{msg-mw|Tooltip-pt-logout}}",
 +      "accesskey-pt-createaccount": "{{doc-accesskey}}",
        "accesskey-ca-talk": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Talk}}\n* {{msg-mw|Accesskey-ca-talk}}\n* {{msg-mw|Tooltip-ca-talk}}",
        "accesskey-ca-edit": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Edit}}\n* {{msg-mw|Accesskey-ca-edit}}\n* {{msg-mw|Tooltip-ca-edit}}",
        "accesskey-ca-addsection": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Addsection}}\n* {{msg-mw|Accesskey-ca-addsection}}\n* {{msg-mw|Tooltip-ca-addsection}}",
        "accesskey-feed-atom": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Feed-atom}}\n* {{msg-mw|Accesskey-feed-atom}}\n* {{msg-mw|Tooltip-feed-atom}}",
        "accesskey-t-contributions": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Contributions}}\n* {{msg-mw|Accesskey-t-contributions}}\n* {{msg-mw|Tooltip-t-contributions}}",
        "accesskey-t-emailuser": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Emailuser}}\n* {{msg-mw|Accesskey-t-emailuser}}\n* {{msg-mw|Tooltip-t-emailuser}}",
 +      "accesskey-t-info": "{{doc-accesskey}}",
        "accesskey-t-permalink": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Permalink}}\n* {{msg-mw|Accesskey-t-permalink}}\n* {{msg-mw|Tooltip-t-permalink}}",
        "accesskey-t-print": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Printableversion}}\n* {{msg-mw|Accesskey-t-print}}\n* {{msg-mw|Tooltip-t-print}}",
        "accesskey-t-upload": "{{doc-accesskey}}\nSee also:\n* {{msg-mw|Upload}}\n* {{msg-mw|Accesskey-t-upload}}\n* {{msg-mw|Tooltip-t-upload}}",
        "tooltip-pt-preferences": "Tooltip shown when hovering over the {{msg-mw|Mypreferences}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Mypreferences}}\n* {{msg-mw|Accesskey-pt-preferences}}\n* {{msg-mw|Tooltip-pt-preferences}}\n{{Identical|Preferences}}",
        "tooltip-pt-watchlist": "Tooltip shown when hovering over the {{msg-mw|Mywatchlist}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Mywatchlist}}\n* {{msg-mw|Accesskey-pt-watchlist}}\n* {{msg-mw|Tooltip-pt-watchlist}}",
        "tooltip-pt-mycontris": "Tooltip shown when hovering over the {{msg-mw|Mycontris}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}",
 -      "tooltip-pt-login": "Tooltip shown when hovering over the link 'Log in / create account' in the upper right corner show on all pages while not logged in.",
 +      "tooltip-pt-login": "Tooltip shown when hovering over the link 'Log in' in the upper right corner show on all pages while not logged in.",
        "tooltip-pt-logout": "Tooltip shown when hovering over the {{msg-mw|Logout}} link in your personal toolbox (upper right side).\n\nSee also:\n* {{msg-mw|Logout}}\n* {{msg-mw|Accesskey-pt-logout}}\n* {{msg-mw|Tooltip-pt-logout}}\n{{Identical|Log out}}",
 +      "tooltip-pt-createaccount": "Tooltip shown when hovering over the link 'Create account' in the upper right corner show on all pages while not logged in.",
        "tooltip-ca-talk": "Tooltip shown when hovering over the {{msg-mw|Talk}} tab.\n\nA 'content page' is a page that forms part of the purpose of the wiki. It includes the main page and pages in the main namespace and any other namespaces that are included when the wiki is customised. For example on Wikimedia Commons 'content pages' include pages in the file and category namespaces. On Wikinews 'content pages' include pages in the Portal namespace. For a technical definition of 'content namespaces' see [[mw:Manual:Using_custom_namespaces#Content_namespaces|MediaWiki]].\n\nPossible alternatives to the word 'content' are 'subject matter' or 'wiki subject' or 'wiki purpose'.\n\nSee also:\n* {{msg-mw|Talk}}\n* {{msg-mw|Accesskey-ca-talk}}\n* {{msg-mw|Tooltip-ca-talk}}\n{{Identical|Content page}}",
        "tooltip-ca-edit": "The tooltip when hovering over the {{msg-mw|Edit}} tab.\n\nSee also:\n* {{msg-mw|Edit}}\n* {{msg-mw|Accesskey-ca-edit}}\n* {{msg-mw|Tooltip-ca-edit}}",
        "tooltip-ca-addsection": "Tooltip shown when hovering over the \"addsection\" tab (shown on talk pages).\n\nSee also:\n* {{msg-mw|Addsection}}\n* {{msg-mw|Accesskey-ca-addsection}}\n* {{msg-mw|Tooltip-ca-addsection}}",
        "tooltip-feed-atom": "Used as tooltip for Atom feed link.\n\nSee also:\n* {{msg-mw|Feed-atom}}\n* {{msg-mw|Accesskey-feed-atom}}\n* {{msg-mw|Tooltip-feed-atom}}",
        "tooltip-t-contributions": "Tooltip shown when hovering over {{msg-mw|Contributions}} in the toolbox.\n\nSee also:\n* {{msg-mw|Contributions}}\n* {{msg-mw|Accesskey-t-contributions}}\n* {{msg-mw|Tooltip-t-contributions}}",
        "tooltip-t-emailuser": "Tooltip shown when hovering over the {{msg-mw|Emailuser}} link in the toolbox (sidebar, below).\n\nSee also:\n* {{msg-mw|Emailuser}}\n* {{msg-mw|Accesskey-t-emailuser}}\n* {{msg-mw|Tooltip-t-emailuser}}",
 +      "tooltip-t-info": "Tooltip shown when hovering over the {{msg-mw|pageinfo-toolboxlink}} link in the toolbox (sidebar, below).",
        "tooltip-t-upload": "Tooltip shown when hovering over the link to upload files shown in the side bar menu on all pages.\n\nSee also:\n* {{msg-mw|Upload}}\n* {{msg-mw|Accesskey-t-upload}}\n* {{msg-mw|Tooltip-t-upload}}\n{{Identical|Upload file}}",
        "tooltip-t-specialpages": "The tooltip when hovering over the link {{msg-mw|Specialpages}} going to a list of all special pages available in the wiki.\n\nSee also:\n* {{msg-mw|Specialpages}}\n* {{msg-mw|Accesskey-t-specialpages}}\n* {{msg-mw|Tooltip-t-specialpages}}",
        "tooltip-t-print": "Tooltip shown when hovering over the link to printable version shown in the side bar menu on all pages.\n\nSee also:\n* {{msg-mw|Printableversion}}\n* {{msg-mw|Accesskey-t-print}}\n* {{msg-mw|Tooltip-t-print}}",
        "pageinfo-robot-policy": "The search engine status of the page.\n\nUsed as label. Followed by any one of the following messages:\n*{{msg-mw|Pageinfo-robot-index}}\n*{{msg-mw|Pageinfo-robot-noindex}}",
        "pageinfo-robot-index": "An indication that the page is indexable by search engines, that is listed in their search results.\n\nPreceded by the label {{msg-mw|Pageinfo-robot-policy}}.",
        "pageinfo-robot-noindex": "An indication that the page is not indexable (that is, is not listed on the results page of a search engine).\n\nPreceded by the label {{msg-mw|Pageinfo-robot-policy}}.",
-       "pageinfo-views": "The number of times the page has been viewed.",
        "pageinfo-watchers": "Header of the row in the first table of the info action.",
        "pageinfo-few-watchers": "Message displayed when there are fewer than $wgUnwatchedPageThreshold watchers. $1 is the value of $wgUnwatchedPageThreshold.",
        "pageinfo-redirects-name": "Header of the row in the first table of the info action.\n\nFollowed by {{msg-mw|Pageinfo-redirects-value}}.\n\nUsed as link text. The link points to \"{{int:Whatlinkshere-title}}\" page ([[Special:WhatLinksHere]]).\n\nSee example: [{{canonicalurl:Main page|action=info}} Main page?action=info]",
        "unknown_extension_tag": "This is an error shown when you use an unknown extension tag name.\n\nThis feature allows tags like <code><nowiki><pre></nowiki></code> to be called with a parser like <code><nowiki>{{#tag:pre}}</nowiki></code>.\n\nParameters:\n* $1 - the unknown extension tag name",
        "duplicate-defaultsort": "See definition of [[w:Sorting|sort key]] on Wikipedia. Parameters:\n* $1 - old default sort key\n* $2 - new default sort key",
        "duplicate-displaytitle": "Warning shown when a page has its display title set multiple times. Parameters:\n* $1 - old display title\n* $2 - new display title",
 +      "invalid-indicator-name": "Warning shown when the [https://www.mediawiki.org/wiki/Help:Page_status_indicators &lt;indicator name=\"''unique-identifier''\">''content''&lt;/indicator>] parser tag is used incorrectly.",
        "version": "{{doc-special|Version}}\n{{Identical|Version}}",
        "version-summary": "{{doc-specialpagesummary|version}}",
        "version-extensions": "Header on [[Special:Version]].",
@@@ -240,7 -240,6 +240,6 @@@ $magicWords = array
        'numberofusers'           => array( 1, 'NUMBEROFUSERS' ),
        'numberofactiveusers'     => array( 1, 'NUMBEROFACTIVEUSERS' ),
        'numberofedits'           => array( 1, 'NUMBEROFEDITS' ),
-       'numberofviews'           => array( 1, 'NUMBEROFVIEWS' ),
        'pagename'                => array( 1, 'PAGENAME' ),
        'pagenamee'               => array( 1, 'PAGENAMEE' ),
        'namespace'               => array( 1, 'NAMESPACE' ),
@@@ -388,7 -387,6 +387,7 @@@ $specialPageAliases = array
        'Allmessages'               => array( 'AllMessages' ),
        'AllMyUploads'              => array( 'AllMyUploads', 'AllMyFiles' ),
        'Allpages'                  => array( 'AllPages' ),
 +      'ApiHelp'                   => array( 'ApiHelp' ),
        'Ancientpages'              => array( 'AncientPages' ),
        'Badtitle'                  => array( 'Badtitle' ),
        'Blankpage'                 => array( 'BlankPage' ),
@@@ -537,7 -535,7 +536,7 @@@ $preloadedMessages = array
        'accesskey-ca-history',
        'accesskey-ca-nstab-main',
        'accesskey-ca-talk',
 -      'accesskey-ca-view',
 +      'accesskey-ca-viewsource',
        'accesskey-n-currentevents',
        'accesskey-n-help',
        'accesskey-n-mainpage-description',
        'accesskey-n-recentchanges',
        'accesskey-p-logo',
        'accesskey-pt-login',
 +      'accesskey-pt-createaccount',
        'accesskey-search',
        'accesskey-search-fulltext',
        'accesskey-search-go',
 +      'accesskey-t-info',
        'accesskey-t-permalink',
 +      'accesskey-t-print',
        'accesskey-t-recentchangeslinked',
        'accesskey-t-specialpages',
        'accesskey-t-whatlinkshere',
        'actions',
        'anonnotice',
 +      'brackets',
 +      'comma-separator',
        'currentevents',
        'currentevents-url',
        'disclaimerpage',
        'navigation',
        'nav-login-createaccount',
        'nstab-main',
 -      'nstab-talk',
        'opensearch-desc',
        'pagecategories',
        'pagecategorieslink',
        'search',
        'searcharticle',
        'searchbutton',
 +      'searchsuggest-search',
        'sidebar',
        'navigation-heading',
        'site-atom-feed',
        'tooltip-ca-history',
        'tooltip-ca-nstab-main',
        'tooltip-ca-talk',
 -      'tooltip-ca-view',
 +      'tooltip-ca-viewsource',
        'tooltip-n-currentevents',
        'tooltip-n-help',
        'tooltip-n-mainpage-description',
        'tooltip-n-randompage',
        'tooltip-n-recentchanges',
        'tooltip-p-logo',
 -      'tooltip-p-navigation',
 -      'tooltip-p-tb',
        'tooltip-pt-login',
 +      'tooltip-pt-createaccount',
        'tooltip-search',
        'tooltip-search-fulltext',
        'tooltip-search-go',
 +      'tooltip-t-info',
        'tooltip-t-permalink',
 +      'tooltip-t-print',
        'tooltip-t-recentchangeslinked',
        'tooltip-t-specialpages',
        'tooltip-t-whatlinkshere',
        'viewcount',
        'views',
        'whatlinkshere',
 +      'word-separator',
  );
  
@@@ -23,7 -23,6 +23,6 @@@ div#column-one
  #toc.tochidden,
  div#f-poweredbyico,
  div#f-copyrightico,
- li#viewcount,
  li#about,
  li#disclaimer,
  li#mobileview,
@@@ -203,7 -202,6 +202,7 @@@ a.stub 
  /**
   * Floating divs
   */
 +/* @noflip */
  div.floatright {
        float: right;
        clear: right;
@@@ -215,7 -213,6 +214,7 @@@ div.floatright p 
        font-style: italic;
  }
  
 +/* @noflip */
  div.floatleft {
        float: left;
        clear: left;
@@@ -481,7 -481,6 +481,6 @@@ abstract class MediaWikiTestCase extend
                                'page_namespace' => 0,
                                'page_title' => ' ',
                                'page_restrictions' => null,
-                               'page_counter' => 0,
                                'page_is_redirect' => 0,
                                'page_is_new' => 0,
                                'page_random' => 0,
                $this->assertEmpty( $errors, implode( "\n", $errors ) );
        }
  
 +      /**
 +       * @param array $matcher
 +       * @param string $actual
 +       * @param bool $isHtml
 +       *
 +       * @return bool
 +       */
 +      private static function tagMatch( $matcher, $actual, $isHtml = true ) {
 +              $dom = PHPUnit_Util_XML::load( $actual, $isHtml );
 +              $tags = PHPUnit_Util_XML::findNodes( $dom, $matcher, $isHtml );
 +              return count( $tags ) > 0 && $tags[0] instanceof DOMNode;
 +      }
 +
        /**
         * Note: we are overriding this method to remove the deprecated error
         * @see https://bugzilla.wikimedia.org/show_bug.cgi?id=69505
         * @see https://github.com/sebastianbergmann/phpunit/issues/1292
 +       * @deprecated
         *
         * @param array $matcher
         * @param string $actual
        public static function assertTag( $matcher, $actual, $message = '', $isHtml = true ) {
                //trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  
 -              $dom = PHPUnit_Util_XML::load( $actual, $isHtml );
 -              $tags = PHPUnit_Util_XML::findNodes( $dom, $matcher, $isHtml );
 -              $matched = count( $tags ) > 0 && $tags[0] instanceof DOMNode;
 +              self::assertTrue( self::tagMatch( $matcher, $actual, $isHtml ), $message );
 +      }
 +
 +      /**
 +       * @see MediaWikiTestCase::assertTag
 +       * @deprecated
 +       *
 +       * @param array $matcher
 +       * @param string $actual
 +       * @param string $message
 +       * @param bool $isHtml
 +       */
 +      public static function assertNotTag( $matcher, $actual, $message = '', $isHtml = true ) {
 +              //trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  
 -              self::assertTrue( $matched, $message );
 +              self::assertFalse( self::tagMatch( $matcher, $actual, $isHtml ), $message );
        }
  }