Merge "WebStart.php: Make lines shorter to make phpcs happier"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sat, 26 Sep 2015 17:30:53 +0000 (17:30 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 26 Sep 2015 17:30:53 +0000 (17:30 +0000)
47 files changed:
includes/Linker.php
includes/WebRequest.php
includes/api/ApiBase.php
includes/clientpool/RedisConnectionPool.php
includes/context/RequestContext.php
includes/debug/logger/monolog/BufferHandler.php
includes/debug/logger/monolog/KafkaHandler.php
includes/deferred/DataUpdate.php
includes/deferred/LinksDeletionUpdate.php
includes/diff/TableDiffFormatter.php
includes/installer/Installer.php
includes/libs/HttpStatus.php
includes/media/Bitmap.php
includes/media/ExifBitmap.php
includes/media/MediaHandler.php
includes/media/XMP.php
includes/objectcache/MultiWriteBagOStuff.php
includes/page/ImagePage.php
includes/search/SearchHighlighter.php
includes/tidy/Html5Depurate.php
includes/tidy/TidyDriverBase.php
includes/utils/AvroValidator.php
languages/messages/MessagesDty.php
maintenance/populateContentModel.php
phpcs.xml
resources/Resources.php
resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.css [deleted file]
resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleOptionWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleSearchWidget.js [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less [new file with mode: 0644]
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/StatusTest.php
tests/phpunit/includes/WikiMapTest.php
tests/phpunit/includes/content/CssContentTest.php
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/debug/logger/monolog/KafkaHandlerTest.php
tests/phpunit/includes/filebackend/SwiftFileBackendTest.php
tests/phpunit/includes/filerepo/FileBackendDBRepoWrapperTest.php
tests/phpunit/includes/filerepo/MigrateFileRepoLayoutTest.php
tests/phpunit/includes/media/WebPTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/utils/BatchRowUpdateTest.php
tests/phpunit/maintenance/MaintenanceTest.php
tests/phpunit/phpunit.php

index 9b5ff27..2e33bd1 100644 (file)
@@ -1274,14 +1274,17 @@ class Linker {
         * temporarily to a value pass. Should be adjusted further. --brion
         *
         * @param string $comment
-        * @param Title|null $title Title object (to generate link to the section in autocomment) or null
+        * @param Title|null $title Title object (to generate link to the section in autocomment)
+        *  or null
         * @param bool $local Whether section links should refer to local page
-        * @param string|null $wikiId Id (as used by WikiMap) of the wiki to generate links to. For use with external changes.
+        * @param string|null $wikiId Id (as used by WikiMap) of the wiki to generate links to.
+        *  For use with external changes.
         *
         * @return mixed|string
         */
-       public static function formatComment( $comment, $title = null, $local = false, $wikiId = null ) {
-
+       public static function formatComment(
+               $comment, $title = null, $local = false, $wikiId = null
+       ) {
                # Sanitize text a bit:
                $comment = str_replace( "\n", " ", $comment );
                # Allow HTML entities (for bug 13815)
@@ -1306,11 +1309,14 @@ class Linker {
         * @param string $comment Comment text
         * @param Title|null $title An optional title object used to links to sections
         * @param bool $local Whether section links should refer to local page
-        * @param string|null $wikiId Id of the wiki to link to (if not the local wiki), as used by WikiMap.
+        * @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
+        *  as used by WikiMap.
         *
         * @return string Formatted comment (wikitext)
         */
-       private static function formatAutocomments( $comment, $title = null, $local = false, $wikiId = null ) {
+       private static function formatAutocomments(
+               $comment, $title = null, $local = false, $wikiId = null
+       ) {
                // @todo $append here is something of a hack to preserve the status
                // quo. Someone who knows more about bidi and such should decide
                // (1) what sane rendering even *is* for an LTR edit summary on an RTL
@@ -1334,7 +1340,12 @@ class Linker {
                                $auto = $match[2];
                                $post = $match[3] !== '';
                                $comment = null;
-                               Hooks::run( 'FormatAutocomments', array( &$comment, $pre, $auto, $post, $title, $local, $wikiId ) );
+
+                               Hooks::run(
+                                       'FormatAutocomments',
+                                       array( &$comment, $pre, $auto, $post, $title, $local, $wikiId )
+                               );
+
                                if ( $comment === null ) {
                                        $link = '';
                                        if ( $title ) {
@@ -1386,7 +1397,8 @@ class Linker {
         * @param string $comment Text to format links in
         * @param Title|null $title An optional title object used to links to sections
         * @param bool $local Whether section links should refer to local page
-        * @param string|null $wikiId Id of the wiki to link to (if not the local wiki), as used by WikiMap.
+        * @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
+        *  as used by WikiMap.
         *
         * @return string
         */
@@ -1489,18 +1501,25 @@ class Linker {
         *
         * @param Title $title
         * @param string $text
-        * @param string|null $wikiId Id of the wiki to link to (if not the local wiki), as used by WikiMap.
+        * @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
+        *  as used by WikiMap.
         * @param string|string[] $options See the $options parameter in Linker::link.
         *
         * @return string HTML link
         */
-       public static function makeCommentLink( Title $title, $text, $wikiId = null, $options = array() ) {
+       public static function makeCommentLink(
+               Title $title, $text, $wikiId = null, $options = array()
+       ) {
                if ( $wikiId !== null && !$title->isExternal() ) {
                        $link = Linker::makeExternalLink(
-                                       WikiMap::getForeignURL( $wikiId, $title->getPrefixedText(), $title->getFragment() ),
-                                       $text,
-                                       /* escape = */ false // Already escaped
-                               );
+                               WikiMap::getForeignURL(
+                                       $wikiId,
+                                       $title->getPrefixedText(),
+                                       $title->getFragment()
+                               ),
+                               $text,
+                               /* escape = */ false // Already escaped
+                       );
                } else {
                        $link = Linker::link( $title, $text, array(), array(), $options );
                }
@@ -1594,11 +1613,14 @@ class Linker {
         * @param string $comment
         * @param Title|null $title Title object (to generate link to section in autocomment) or null
         * @param bool $local Whether section links should refer to local page
-        * @param string|null $wikiId Id (as used by WikiMap) of the wiki to generate links to. For use with external changes.
+        * @param string|null $wikiId Id (as used by WikiMap) of the wiki to generate links to.
+        *  For use with external changes.
         *
         * @return string
         */
-       public static function commentBlock( $comment, $title = null, $local = false, $wikiId = null ) {
+       public static function commentBlock(
+               $comment, $title = null, $local = false, $wikiId = null
+       ) {
                // '*' used to be the comment inserted by the software way back
                // in antiquity in case none was provided, here for backwards
                // compatibility, acc. to brion -ævar
index b4b8be9..f402f3b 100644 (file)
@@ -315,7 +315,9 @@ class WebRequest {
                        }
                } else {
                        global $wgContLang;
-                       $data = isset( $wgContLang ) ? $wgContLang->normalize( $data ) : UtfNormal\Validator::cleanUp( $data );
+                       $data = isset( $wgContLang ) ?
+                               $wgContLang->normalize( $data ) :
+                               UtfNormal\Validator::cleanUp( $data );
                }
                return $data;
        }
@@ -754,7 +756,8 @@ class WebRequest {
         * Appends or replaces value of query variables.
         *
         * @param array $array Array of values to replace/add to query
-        * @param bool $onlyquery Whether to only return the query string and not the complete URL [deprecated]
+        * @param bool $onlyquery Whether to only return the query string
+        *  and not the complete URL [deprecated]
         * @return string
         */
        public function appendQueryArray( $array, $onlyquery = true ) {
index d53797b..7743384 100644 (file)
@@ -206,7 +206,8 @@ abstract class ApiBase extends ContextSource {
                                // Fix up the ugly "even numbered elements are description, odd
                                // numbered elemts are the link" format (see doc for self::getExamples)
                                $tmp = array();
-                               for ( $i = 0; $i < count( $examples ); $i += 2 ) {
+                               $examplesCount = count( $examples );
+                               for ( $i = 0; $i < $examplesCount; $i += 2 ) {
                                        $tmp[$examples[$i + 1]] = $examples[$i];
                                }
                                $examples = $tmp;
index ec0573e..8a88fab 100644 (file)
@@ -442,7 +442,9 @@ class RedisConnRef {
         * @param Redis $conn
         * @param LoggerInterface $logger
         */
-       public function __construct( RedisConnectionPool $pool, $server, Redis $conn, LoggerInterface $logger ) {
+       public function __construct(
+               RedisConnectionPool $pool, $server, Redis $conn, LoggerInterface $logger
+       ) {
                $this->pool = $pool;
                $this->server = $server;
                $this->conn = $conn;
index 93adde1..42a2aee 100644 (file)
@@ -159,7 +159,10 @@ class RequestContext implements IContextSource, MutableContext {
                if ( $this->title === null ) {
                        global $wgTitle; # fallback to $wg till we can improve this
                        $this->title = $wgTitle;
-                       wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetAllCallers( 5 ) . ' with no title set.' );
+                       wfDebugLog(
+                               'GlobalTitleFail',
+                               __METHOD__ . ' called by ' . wfGetAllCallers( 5 ) . ' with no title set.'
+                       );
                }
 
                return $this->title;
index 3ebd0b1..ea286b3 100644 (file)
@@ -37,7 +37,7 @@ class BufferHandler extends BaseBufferHandler {
         * {@inheritDoc}
         */
        public function handle( array $record ) {
-               if (!$this->initialized) {
+               if ( !$this->initialized ) {
                        DeferredUpdates::addCallableUpdate( array( $this, 'close' ) );
                        $this->initialized = true;
                }
index 59d7764..1583cd1 100644 (file)
@@ -133,7 +133,7 @@ class KafkaHandler extends AbstractProcessingHandler {
                                }
                        }
                        if ( $messages ) {
-                               $this->addMessages($channel, $messages);
+                               $this->addMessages( $channel, $messages );
                        }
                }
 
index f5d6845..9cbb62f 100644 (file)
@@ -152,4 +152,5 @@ interface EnqueueableDataUpdate {
         * Push the update into the job queue
         */
        public function enqueueUpdate();
-}
\ No newline at end of file
+}
+
index bbdfcf1..7351e4c 100644 (file)
@@ -102,4 +102,5 @@ class LinksDeletionUpdate extends SqlDataUpdate {
                        }
                }
        }
-}
\ No newline at end of file
+}
+
index 83e04a5..4737f08 100644 (file)
@@ -62,8 +62,14 @@ class TableDiffFormatter extends DiffFormatter {
        protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
                // '<!--LINE \d+ -->' get replaced by a localised line number
                // in DifferenceEngine::localiseLineNumbers
-               $r = '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l' . $xbeg . '" ><!--LINE ' . $xbeg . "--></td>\n" .
-                       '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
+               $r = '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l' .
+                       $xbeg .
+                       '" ><!--LINE ' .
+                       $xbeg .
+                       "--></td>\n" .
+                       '<td colspan="2" class="diff-lineno"><!--LINE ' .
+                       $ybeg .
+                       "--></td></tr>\n";
 
                return $r;
        }
index 72e11db..d98ca79 100644 (file)
@@ -538,9 +538,11 @@ abstract class Installer {
                global $wgAutoloadClasses;
                $wgAutoloadClasses = array();
 
+               // @codingStandardsIgnoreStart
                // LocalSettings.php should not call functions, except wfLoadSkin/wfLoadExtensions
                // Define the required globals here, to ensure, the functions can do it work correctly.
                global $wgExtensionDirectory, $wgStyleDirectory;
+               // @codingStandardsIgnoreEnd
 
                MediaWiki\suppressWarnings();
                $_lsExists = file_exists( "$IP/LocalSettings.php" );
index 442298a..3d7dee7 100644 (file)
@@ -102,7 +102,10 @@ class HttpStatus {
                }
 
                if ( $version === null ) {
-                       $version = isset( $_SERVER['SERVER_PROTOCOL'] ) && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.0' ? '1.0' : '1.1';
+                       $version = isset( $_SERVER['SERVER_PROTOCOL'] ) &&
+                               $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.0' ?
+                                       '1.0' :
+                                       '1.1';
                }
 
                header( "HTTP/$version $code $message" );
index 1f00650..0b5b8b6 100644 (file)
@@ -339,7 +339,9 @@ class BitmapHandler extends TransformationalImageHandler {
 
                $src_image = call_user_func( $loader, $params['srcPath'] );
 
-               $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ? $this->getRotation( $image ) : 0;
+               $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ?
+                       $this->getRotation( $image ) :
+                       0;
                list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
                $dst_image = imagecreatetruecolor( $width, $height );
 
index 5ba5c68..b2d2443 100644 (file)
@@ -269,9 +269,11 @@ class ExifBitmapHandler extends BitmapHandler {
        }
 
        /**
-        * Swaps an embedded ICC profile for another, if found. Depends on exiftool, no-op if not installed.
+        * Swaps an embedded ICC profile for another, if found.
+        * Depends on exiftool, no-op if not installed.
         * @param string $filepath File to be manipulated (will be overwritten)
-        * @param string $oldProfileString Exact name of color profile to look for (the one that will be replaced)
+        * @param string $oldProfileString Exact name of color profile to look for
+        *  (the one that will be replaced)
         * @param string $profileFilepath ICC profile file to apply to the file
         * @since 1.26
         * @return bool
index 3a59996..9b19921 100644 (file)
@@ -866,14 +866,21 @@ abstract class MediaHandler {
         * Gets configuration for the file warning message. Return value of
         * the following structure:
         *   array(
-        *     'module' => 'example.filewarning.messages', // Required, module with messages loaded for the client
-        *     'messages' => array( // Required, array of names of messages
-        *       'main' => 'example-filewarning-main', // Required, main warning message
-        *       'header' => 'example-filewarning-header', // Optional, header for warning dialog
-        *       'footer' => 'example-filewarning-footer', // Optional, footer for warning dialog
-        *       'info' => 'example-filewarning-info', // Optional, text for more-information link (see below)
+        *     // Required, module with messages loaded for the client
+        *     'module' => 'example.filewarning.messages',
+        *     // Required, array of names of messages
+        *     'messages' => array(
+        *       // Required, main warning message
+        *       'main' => 'example-filewarning-main',
+        *       // Optional, header for warning dialog
+        *       'header' => 'example-filewarning-header',
+        *       // Optional, footer for warning dialog
+        *       'footer' => 'example-filewarning-footer',
+        *       // Optional, text for more-information link (see below)
+        *       'info' => 'example-filewarning-info',
         *     ),
-        *     'link' => 'http://example.com', // Optional, link for more information
+        *     // Optional, link for more information
+        *     'link' => 'http://example.com',
         *   )
         *
         * Returns null if no warning is necessary.
index 64a7e8a..e424b9b 100644 (file)
@@ -429,8 +429,14 @@ class XMPReader implements LoggerAwareInterface {
                }
                $len = unpack( 'Nlength/Noffset', substr( $content, 32, 8 ) );
 
-               if ( !$len || $len['length'] < 4 || $len['offset'] < 0 || $len['offset'] > $len['length'] ) {
-                       $this->logger->info( __METHOD__ . 'Error reading extended XMP block, invalid length or offset.' );
+               if ( !$len ||
+                       $len['length'] < 4 ||
+                       $len['offset'] < 0 ||
+                       $len['offset'] > $len['length']
+               ) {
+                       $this->logger->info(
+                               __METHOD__ . 'Error reading extended XMP block, invalid length or offset.'
+                       );
 
                        return false;
                }
@@ -710,7 +716,6 @@ class XMPReader implements LoggerAwareInterface {
         * @throws RuntimeException
         */
        private function endElementModeLi( $elm ) {
-
                list( $ns, $tag ) = explode( ' ', $this->curItem[0], 2 );
                $info = $this->items[$ns][$tag];
                $finalName = isset( $info['map_name'] )
@@ -734,7 +739,9 @@ class XMPReader implements LoggerAwareInterface {
                                $this->results['xmp-' . $info['map_group']][$finalName]['_type'] = 'lang';
                        }
                } else {
-                       throw new RuntimeException( __METHOD__ . " expected </rdf:seq> or </rdf:bag> but instead got $elm." );
+                       throw new RuntimeException(
+                               __METHOD__ . " expected </rdf:seq> or </rdf:bag> but instead got $elm."
+                       );
                }
        }
 
index 1a52930..cb3754a 100644 (file)
@@ -60,7 +60,9 @@ class MultiWriteBagOStuff extends BagOStuff {
                parent::__construct( $params );
 
                if ( empty( $params['caches'] ) || !is_array( $params['caches'] ) ) {
-                       throw new InvalidArgumentException( __METHOD__ . ': "caches" parameter must be an array of caches' );
+                       throw new InvalidArgumentException(
+                               __METHOD__ . ': "caches" parameter must be an array of caches'
+                       );
                }
 
                $this->caches = array();
index 9b9e3cb..e1cd76c 100644 (file)
@@ -248,7 +248,9 @@ class ImagePage extends Article {
                Hooks::run( 'ImagePageShowTOC', array( $this, &$r ) );
 
                if ( $metadata ) {
-                       $r[] = '<li><a href="#metadata">' . $this->getContext()->msg( 'metadata' )->escaped() . '</a></li>';
+                       $r[] = '<li><a href="#metadata">' .
+                               $this->getContext()->msg( 'metadata' )->escaped() .
+                               '</a></li>';
                }
 
                return '<ul id="filetoc">' . implode( "\n", $r ) . '</ul>';
@@ -389,9 +391,13 @@ class ImagePage extends Article {
                                        }
                                        if ( count( $otherSizes ) ) {
                                                $msgsmall .= ' ' .
-                                               Html::rawElement( 'span', array( 'class' => 'mw-filepage-other-resolutions' ),
-                                                       $this->getContext()->msg( 'show-big-image-other' )->rawParams( $lang->pipeList( $otherSizes ) )->
-                                                       params( count( $otherSizes ) )->parse()
+                                               Html::rawElement(
+                                                       'span',
+                                                       array( 'class' => 'mw-filepage-other-resolutions' ),
+                                                       $this->getContext()->msg( 'show-big-image-other' )
+                                                               ->rawParams( $lang->pipeList( $otherSizes ) )
+                                                               ->params( count( $otherSizes ) )
+                                                               ->parse()
                                                );
                                        }
                                } elseif ( $width == 0 && $height == 0 ) {
@@ -667,9 +673,14 @@ EOT
                $wrap = "<div class=\"sharedUploadNotice\">\n$1\n</div>\n";
                $repo = $this->mPage->getFile()->getRepo()->getDisplayName();
 
-               if ( $descUrl && $descText && $this->getContext()->msg( 'sharedupload-desc-here' )->plain() !== '-' ) {
+               if ( $descUrl &&
+                       $descText &&
+                       $this->getContext()->msg( 'sharedupload-desc-here' )->plain() !== '-'
+               ) {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-here', $repo, $descUrl ) );
-               } elseif ( $descUrl && $this->getContext()->msg( 'sharedupload-desc-there' )->plain() !== '-' ) {
+               } elseif ( $descUrl &&
+                       $this->getContext()->msg( 'sharedupload-desc-there' )->plain() !== '-'
+               ) {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-there', $repo, $descUrl ) );
                } else {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload', $repo ), ''/*BACKCOMPAT*/ );
@@ -854,7 +865,9 @@ EOT
                                $liContents = $link;
                        } elseif ( count( $redirects[$element->page_title] ) === 0 ) {
                                # Redirect without usages
-                               $liContents = $this->getContext()->msg( 'linkstoimage-redirect' )->rawParams( $link, '' )->parse();
+                               $liContents = $this->getContext()->msg( 'linkstoimage-redirect' )
+                                       ->rawParams( $link, '' )
+                                       ->parse();
                        } else {
                                # Redirect with usages
                                $li = '';
@@ -923,7 +936,10 @@ EOT
                        } else {
                                $link = Linker::makeExternalLink( $file->getDescriptionUrl(),
                                        $file->getTitle()->getPrefixedText() );
-                               $fromSrc = $this->getContext()->msg( 'shared-repo-from', $file->getRepo()->getDisplayName() )->text();
+                               $fromSrc = $this->getContext()->msg(
+                                       'shared-repo-from',
+                                       $file->getRepo()->getDisplayName()
+                               )->text();
                        }
                        $out->addHTML( "<li>{$link} {$fromSrc}</li>\n" );
                }
@@ -1068,8 +1084,10 @@ EOT
                );
                $submit = Xml::submitButton( $this->getContext()->msg( 'img-lang-go' )->text() );
 
-               $formContents = $this->getContext()->msg( 'img-lang-info' )->rawParams( $select, $submit )->parse()
-                       . Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() );
+               $formContents = $this->getContext()->msg( 'img-lang-info' )
+                       ->rawParams( $select, $submit )
+                       ->parse();
+               $formContents .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() );
 
                $langSelectLine = Html::rawElement( 'div', array( 'id' => 'mw-imglangselector-line' ),
                        Html::rawElement( 'form', array( 'action' => $wgScript ), $formContents )
@@ -1141,7 +1159,9 @@ EOT
                } else {
                        # Creating thumb links triggers thumbnail generation.
                        # Just generate the thumb for the current users prefs.
-                       $thumbSizes = array( $this->getImageLimitsFromOption( $this->getContext()->getUser(), 'thumbsize' ) );
+                       $thumbSizes = array(
+                               $this->getImageLimitsFromOption( $this->getContext()->getUser(), 'thumbsize' )
+                       );
                        if ( !$this->displayImg->mustRender() ) {
                                // We can safely include a link to the "full-size" preview,
                                // without actually rendering.
index 7d5d38f..98c05b5 100644 (file)
@@ -547,7 +547,9 @@ class SearchHighlighter {
                $text = ltrim( $text ) . "\n"; // make sure the preg_match may find the last line
                $text = str_replace( "\n\n", "\n", $text ); // remove empty lines
                preg_match( "/^(.*\n){0,$contextlines}/", $text, $match );
-               $text = htmlspecialchars( substr( trim( $match[0] ), 0, $contextlines * $contextchars ) ); // trim and limit to max number of chars
+
+               // Trim and limit to max number of chars
+               $text = htmlspecialchars( substr( trim( $match[0] ), 0, $contextlines * $contextchars ) );
                return str_replace( "\n", '<br>', $text );
        }
 }
index 23e445f..e2187f0 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 namespace MediaWiki\Tidy;
+
 use MWHttpRequest;
 use Exception;
 
index 1d994aa..61fd3e4 100644 (file)
@@ -36,5 +36,5 @@ abstract class TidyDriverBase {
         * @param string HTML document fragment to clean up
         * @param string The corrected HTML output
         */
-       public abstract function tidy( $text );
+       abstract public function tidy( $text );
 }
index 89341ea..b9d30d7 100644 (file)
@@ -36,25 +36,25 @@ class AvroValidator {
         *  returned.
         */
        public static function getErrors( AvroSchema $schema, $datum ) {
-               switch ( $schema->type) {
+               switch ( $schema->type ) {
                case AvroSchema::NULL_TYPE:
-                       if ( !is_null($datum) ) {
+                       if ( !is_null( $datum ) ) {
                                return self::wrongType( 'null', $datum );
                        }
                        return array();
                case AvroSchema::BOOLEAN_TYPE:
-                       if ( !is_bool($datum) ) {
+                       if ( !is_bool( $datum ) ) {
                                return self::wrongType( 'boolean', $datum );
                        }
                        return array();
                case AvroSchema::STRING_TYPE:
                case AvroSchema::BYTES_TYPE:
-                       if ( !is_string($datum) ) {
+                       if ( !is_string( $datum ) ) {
                                return self::wrongType( 'string', $datum );
                        }
                        return array();
                case AvroSchema::INT_TYPE:
-                       if ( !is_int($datum) ) {
+                       if ( !is_int( $datum ) ) {
                                return self::wrongType( 'integer', $datum );
                        }
                        if ( AvroSchema::INT_MIN_VALUE > $datum
@@ -68,7 +68,7 @@ class AvroValidator {
                        }
                        return array();
                case AvroSchema::LONG_TYPE:
-                       if ( !is_int($datum) ) {
+                       if ( !is_int( $datum ) ) {
                                return self::wrongType( 'integer', $datum );
                        }
                        if ( AvroSchema::LONG_MIN_VALUE > $datum
@@ -83,16 +83,16 @@ class AvroValidator {
                        return array();
                case AvroSchema::FLOAT_TYPE:
                case AvroSchema::DOUBLE_TYPE:
-                       if ( !is_float($datum) && !is_int($datum) ) {
+                       if ( !is_float( $datum ) && !is_int( $datum ) ) {
                                return self::wrongType( 'float or integer', $datum );
                        }
                        return array();
                case AvroSchema::ARRAY_SCHEMA:
-                       if (!is_array($datum)) {
+                       if ( !is_array( $datum ) ) {
                                return self::wrongType( 'array', $datum );
                        }
                        $errors = array();
-                       foreach ($datum as $d) {
+                       foreach ( $datum as $d ) {
                                $result = self::getErrors( $schema->items(), $d );
                                if ( $result ) {
                                        $errors[] = $result;
@@ -100,12 +100,12 @@ class AvroValidator {
                        }
                        return $errors;
                case AvroSchema::MAP_SCHEMA:
-                       if (!is_array($datum)) {
+                       if ( !is_array( $datum ) ) {
                                return self::wrongType( 'array', $datum );
                        }
                        $errors = array();
-                       foreach ($datum as $k => $v) {
-                               if ( !is_string($k) ) {
+                       foreach ( $datum as $k => $v ) {
+                               if ( !is_string( $k ) ) {
                                        $errors[] = self::wrongType( 'string key', $k );
                                }
                                $result = self::getErrors( $schema->values(), $v );
@@ -116,7 +116,7 @@ class AvroValidator {
                        return $errors;
                case AvroSchema::UNION_SCHEMA:
                        $errors = array();
-                       foreach ($schema->schemas() as $schema) {
+                       foreach ( $schema->schemas() as $schema ) {
                                $result = self::getErrors( $schema, $datum );
                                if ( !$result ) {
                                        return array();
index f90746c..937b1bc 100644 (file)
@@ -8,4 +8,5 @@
  *
  */
 
-$fallback = 'ne';
\ No newline at end of file
+$fallback = 'ne';
+
index 3f5d6b6..7bca0ec 100644 (file)
@@ -178,7 +178,7 @@ class PopulateContentModel extends Maintenance {
                                        if ( $dbFormat === $defaultFormat ) {
                                                $toSave[$defaultModel][] = $row->{$key};
                                        } else { // non-default format, just update now
-                                               $this->output( "Updating model to match format for $table $id of $title... ");
+                                               $this->output( "Updating model to match format for $table $id of $title... " );
                                                $dbw->update(
                                                        $table,
                                                        array( $model_column => $defaultModel ),
index 36ad394..8a28177 100644 (file)
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,6 +1,14 @@
 <?xml version="1.0"?>
 <ruleset name="MediaWiki">
-       <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki"/>
+       <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki">
+               <!-- Disable failing rules -->
+               <exclude name="Generic.Files.LineLength"/>
+               <exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
+               <exclude name="MediaWiki.NamingConventions.PrefixedGlobalFunctions.wfPrefix"/>
+               <exclude name="Squiz.Classes.ValidClassName.NotCamelCaps"/>
+               <exclude name="MediaWiki.WhiteSpace.SpaceAfterControlStructure.Incorrect"/>
+               <exclude name="Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed"/>
+       </rule>
        <file>.</file>
        <arg name="encoding" value="utf8"/>
        <arg name="extensions" value="php,php5,inc,sample"/>
index b35ebad..6aeb206 100644 (file)
@@ -1893,7 +1893,9 @@ return array(
                        'resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.NamespaceInputWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.ComplexNamespaceInputWidget.js',
+                       'resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js',
+                       'resources/src/mediawiki.widgets/mw.widgets.TitleSearchWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.ComplexTitleInputWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.TitleOptionWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.UserInputWidget.js',
@@ -1903,7 +1905,7 @@ return array(
                        'default' => array(
                                'resources/src/mediawiki.widgets/mw.widgets.CalendarWidget.less',
                                'resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.less',
-                               'resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.css',
+                               'resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less',
                        ),
                ),
                'dependencies' => array(
diff --git a/resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.css b/resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.css
deleted file mode 100644 (file)
index 2c24b2b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*!
- * MediaWiki Widgets - TitleInputWidget styles.
- *
- * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-
-.mw-widget-titleInputWidget-menu-withImages .mw-widget-titleOptionWidget {
-       -webkit-box-sizing: border-box;
-       -moz-box-sizing: border-box;
-       box-sizing: border-box;
-       min-height: 3.75em;
-       margin-left: 3.75em;
-}
-
-.mw-widget-titleInputWidget-menu-withImages .mw-widget-titleOptionWidget:not(:last-child) {
-       margin-bottom: 1px;
-}
-
-.mw-widget-titleInputWidget-menu-withImages .oo-ui-iconElement .oo-ui-iconElement-icon {
-       display: block;
-       width: 3.75em;
-       height: 3.75em;
-       left: -3.75em;
-       background-color: #ccc;
-       opacity: 0.4;
-}
-
-.mw-widget-titleInputWidget-menu-withImages .oo-ui-iconElement .mw-widget-titleOptionWidget-hasImage {
-       border: 0;
-       background-size: cover;
-       opacity: 1;
-}
-
-.mw-widget-titleInputWidget-menu-withImages .mw-widget-titleOptionWidget .oo-ui-labelElement-label {
-       line-height: 2.8em;
-}
-
-.mw-widget-titleOptionWidget-description {
-       display: none;
-}
-
-.mw-widget-titleInputWidget-menu-withDescriptions .mw-widget-titleOptionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
-}
-
-.mw-widget-titleInputWidget-menu-withDescriptions .mw-widget-titleOptionWidget-description {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
-}
-
-.oo-ui-menuOptionWidget:not(.oo-ui-optionWidget-selected) .mw-widget-titleOptionWidget-description,
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted .mw-widget-titleOptionWidget-description {
-       color: #888;
-}
index d5a7abc..fc1007e 100644 (file)
         *
         * @class
         * @extends OO.ui.TextInputWidget
+        * @mixins mw.widgets.TitleWidget
         * @mixins OO.ui.mixin.LookupElement
         *
         * @constructor
-        * @param {Object} [config] Configuration options
-        * @cfg {number} [limit=10] Number of results to show
-        * @cfg {number} [namespace] Namespace to prepend to queries
-        * @cfg {boolean} [relative=true] If a namespace is set, return a title relative to it
         * @cfg {boolean} [suggestions=true] Display search suggestions
-        * @cfg {boolean} [showRedirectTargets=true] Show the targets of redirects
-        * @cfg {boolean} [showRedlink] Show red link to exact match if it doesn't exist
-        * @cfg {boolean} [showImages] Show page images
-        * @cfg {boolean} [showDescriptions] Show page descriptions
-        * @cfg {Object} [cache] Result cache which implements a 'set' method, taking keyed values as an argument
         */
        mw.widgets.TitleInputWidget = function MwWidgetsTitleInputWidget( config ) {
-               var widget = this;
-
-               // Config initialization
-               config = $.extend( {
-                       maxLength: 255,
-                       limit: 10
-               }, config );
+               config = config || {};
 
                // Parent constructor
-               mw.widgets.TitleInputWidget.parent.call( this, $.extend( {}, config, { autocomplete: false } ) );
+               mw.widgets.TitleInputWidget.parent.call( this, $.extend( {}, config, {
+                       validate: this.isQueryValid.bind( this ),
+                       autocomplete: false
+               } ) );
 
                // Mixin constructors
+               mw.widgets.TitleWidget.call( this, config );
                OO.ui.mixin.LookupElement.call( this, config );
 
                // Properties
-               this.limit = config.limit;
-               this.maxLength = config.maxLength;
-               this.namespace = config.namespace !== undefined ? config.namespace : null;
-               this.relative = config.relative !== undefined ? config.relative : true;
                this.suggestions = config.suggestions !== undefined ? config.suggestions : true;
-               this.showRedirectTargets = config.showRedirectTargets !== false;
-               this.showRedlink = !!config.showRedlink;
-               this.showImages = !!config.showImages;
-               this.showDescriptions = !!config.showDescriptions;
-               this.cache = config.cache;
 
                // Initialization
                this.$element.addClass( 'mw-widget-titleInputWidget' );
-               this.lookupMenu.$element.addClass( 'mw-widget-titleInputWidget-menu' );
+               this.lookupMenu.$element.addClass( 'mw-widget-titleWidget-menu' );
                if ( this.showImages ) {
-                       this.lookupMenu.$element.addClass( 'mw-widget-titleInputWidget-menu-withImages' );
+                       this.lookupMenu.$element.addClass( 'mw-widget-titleWidget-menu-withImages' );
                }
                if ( this.showDescriptions ) {
-                       this.lookupMenu.$element.addClass( 'mw-widget-titleInputWidget-menu-withDescriptions' );
+                       this.lookupMenu.$element.addClass( 'mw-widget-titleWidget-menu-withDescriptions' );
                }
                this.setLookupsDisabled( !this.suggestions );
-
-               this.interwikiPrefixes = [];
-               this.interwikiPrefixesPromise = new mw.Api().get( {
-                       action: 'query',
-                       meta: 'siteinfo',
-                       siprop: 'interwikimap'
-               } ).done( function ( data ) {
-                       $.each( data.query.interwikimap, function ( index, interwiki ) {
-                               widget.interwikiPrefixes.push( interwiki.prefix );
-                       } );
-               } );
        };
 
        /* Setup */
 
        OO.inheritClass( mw.widgets.TitleInputWidget, OO.ui.TextInputWidget );
+       OO.mixinClass( mw.widgets.TitleInputWidget, mw.widgets.TitleWidget );
        OO.mixinClass( mw.widgets.TitleInputWidget, OO.ui.mixin.LookupElement );
 
        /* Methods */
 
        /**
-        * Get the namespace to prepend to titles in suggestions, if any.
-        *
-        * @return {number|null} Namespace number
+        * @inheritdoc mw.widgets.TitleWidget
         */
-       mw.widgets.TitleInputWidget.prototype.getNamespace = function () {
-               return this.namespace;
+       mw.widgets.TitleInputWidget.prototype.getQueryValue = function () {
+               return this.getValue();
        };
 
        /**
-        * Set the namespace to prepend to titles in suggestions, if any.
-        *
-        * @param {number|null} namespace Namespace number
+        * @inheritdoc mw.widgets.TitleWidget
         */
        mw.widgets.TitleInputWidget.prototype.setNamespace = function ( namespace ) {
-               this.namespace = namespace;
+               // Mixin method
+               mw.widgets.TitleWidget.prototype.setNamespace.call( this, namespace );
+
                this.lookupCache = {};
                this.closeLookupMenu();
        };
 
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.TitleInputWidget.prototype.getLookupRequest = function () {
+               return this.getSuggestionsPromise();
+       };
+
+       /**
+        * @inheritdoc OO.ui.mixin.LookupElement
+        */
+       mw.widgets.TitleInputWidget.prototype.getLookupCacheDataFromResponse = function ( response ) {
+               return response.query || {};
+       };
+
+       /**
+        * @inheritdoc OO.ui.mixin.LookupElement
+        */
+       mw.widgets.TitleInputWidget.prototype.getLookupMenuOptionsFromData = function ( response ) {
+               return this.getOptionsFromData( response );
+       };
+
        /**
         * @inheritdoc
         */
                return retval;
        };
 
-       /**
-        * @inheritdoc
-        */
-       mw.widgets.TitleInputWidget.prototype.getLookupRequest = function () {
-               var req,
-                       widget = this,
-                       promiseAbortObject = { abort: function () {
-                               // Do nothing. This is just so OOUI doesn't break due to abort being undefined.
-                       } };
-
-               if ( mw.Title.newFromText( this.value ) ) {
-                       return this.interwikiPrefixesPromise.then( function () {
-                               var params, props,
-                                       interwiki = widget.value.substring( 0, widget.value.indexOf( ':' ) );
-                               if (
-                                       interwiki && interwiki !== '' &&
-                                       widget.interwikiPrefixes.indexOf( interwiki ) !== -1
-                               ) {
-                                       return $.Deferred().resolve( { query: {
-                                               pages: [ {
-                                                       title: widget.value
-                                               } ]
-                                       } } ).promise( promiseAbortObject );
-                               } else {
-                                       params = {
-                                               action: 'query',
-                                               generator: 'prefixsearch',
-                                               gpssearch: widget.value,
-                                               gpsnamespace: widget.namespace !== null ? widget.namespace : undefined,
-                                               gpslimit: widget.limit,
-                                               ppprop: 'disambiguation'
-                                       };
-                                       props = [ 'info', 'pageprops' ];
-                                       if ( widget.showRedirectTargets ) {
-                                               params.redirects = '1';
-                                       }
-                                       if ( widget.showImages ) {
-                                               props.push( 'pageimages' );
-                                               params.pithumbsize = 80;
-                                               params.pilimit = widget.limit;
-                                       }
-                                       if ( widget.showDescriptions ) {
-                                               props.push( 'pageterms' );
-                                               params.wbptterms = 'description';
-                                       }
-                                       params.prop = props.join( '|' );
-                                       req = new mw.Api().get( params );
-                                       promiseAbortObject.abort = req.abort.bind( req ); // todo: ew
-                                       return req;
-                               }
-                       } ).promise( promiseAbortObject );
-               } else {
-                       // Don't send invalid titles to the API.
-                       // Just pretend it returned nothing so we can show the 'invalid title' section
-                       return $.Deferred().resolve( {} ).promise( promiseAbortObject );
-               }
-       };
-
-       /**
-        * Get lookup cache item from server response data.
-        *
-        * @method
-        * @param {Mixed} response Response from server
-        */
-       mw.widgets.TitleInputWidget.prototype.getLookupCacheDataFromResponse = function ( response ) {
-               return response.query || {};
-       };
-
-       /**
-        * Get list of menu items from a server response.
-        *
-        * @param {Object} data Query result
-        * @returns {OO.ui.MenuOptionWidget[]} Menu items
-        */
-       mw.widgets.TitleInputWidget.prototype.getLookupMenuOptionsFromData = function ( data ) {
-               var i, len, index, pageExists, pageExistsExact, suggestionPage, page, redirect, redirects,
-                       items = [],
-                       titles = [],
-                       titleObj = mw.Title.newFromText( this.value ),
-                       redirectsTo = {},
-                       pageData = {};
-
-               if ( data.redirects ) {
-                       for ( i = 0, len = data.redirects.length; i < len; i++ ) {
-                               redirect = data.redirects[ i ];
-                               redirectsTo[ redirect.to ] = redirectsTo[ redirect.to ] || [];
-                               redirectsTo[ redirect.to ].push( redirect.from );
-                       }
-               }
-
-               for ( index in data.pages ) {
-                       suggestionPage = data.pages[ index ];
-                       pageData[ suggestionPage.title ] = {
-                               missing: suggestionPage.missing !== undefined,
-                               redirect: suggestionPage.redirect !== undefined,
-                               disambiguation: OO.getProp( suggestionPage, 'pageprops', 'disambiguation' ) !== undefined,
-                               imageUrl: OO.getProp( suggestionPage, 'thumbnail', 'source' ),
-                               description: OO.getProp( suggestionPage, 'terms', 'description' )
-                       };
-
-                       // Throw away pages from wrong namespaces. This can happen when 'showRedirectTargets' is true
-                       // and we encounter a cross-namespace redirect.
-                       if ( this.namespace === null || this.namespace === suggestionPage.ns ) {
-                               titles.push( suggestionPage.title );
-                       }
-
-                       redirects = redirectsTo[ suggestionPage.title ] || [];
-                       for ( i = 0, len = redirects.length; i < len; i++ ) {
-                               pageData[ redirects[ i ] ] = {
-                                       missing: false,
-                                       redirect: true,
-                                       disambiguation: false,
-                                       description: mw.msg( 'mw-widgets-titleinput-description-redirect', suggestionPage.title )
-                               };
-                               titles.push( redirects[ i ] );
-                       }
-               }
-
-               // If not found, run value through mw.Title to avoid treating a match as a
-               // mismatch where normalisation would make them matching (bug 48476)
-
-               pageExistsExact = titles.indexOf( this.value ) !== -1;
-               pageExists = pageExistsExact || (
-                       titleObj && titles.indexOf( titleObj.getPrefixedText() ) !== -1
-               );
-
-               if ( !pageExists ) {
-                       pageData[ this.value ] = {
-                               missing: true, redirect: false, disambiguation: false,
-                               description: mw.msg( 'mw-widgets-titleinput-description-new-page' )
-                       };
-               }
-
-               if ( this.cache ) {
-                       this.cache.set( pageData );
-               }
-
-               // Offer the exact text as a suggestion if the page exists
-               if ( pageExists && !pageExistsExact ) {
-                       titles.unshift( this.value );
-               }
-               // Offer the exact text as a new page if the title is valid
-               if ( this.showRedlink && !pageExists && titleObj ) {
-                       titles.push( this.value );
-               }
-               for ( i = 0, len = titles.length; i < len; i++ ) {
-                       page = pageData[ titles[ i ] ] || {};
-                       items.push( new mw.widgets.TitleOptionWidget( this.getOptionWidgetData( titles[ i ], page ) ) );
-               }
-
-               return items;
-       };
-
-       /**
-        * Get menu option widget data from the title and page data
-        *
-        * @param {mw.Title} title Title object
-        * @param {Object} data Page data
-        * @return {Object} Data for option widget
-        */
-       mw.widgets.TitleInputWidget.prototype.getOptionWidgetData = function ( title, data ) {
-               var mwTitle = new mw.Title( title );
-               return {
-                       data: this.namespace !== null && this.relative
-                               ? mwTitle.getRelativeText( this.namespace )
-                               : title,
-                       title: mwTitle,
-                       imageUrl: this.showImages ? data.imageUrl : null,
-                       description: this.showDescriptions ? data.description : null,
-                       missing: data.missing,
-                       redirect: data.redirect,
-                       disambiguation: data.disambiguation,
-                       query: this.value
-               };
-       };
-
-       /**
-        * Get title object corresponding to given value, or #getValue if not given.
-        *
-        * @param {string} [value] Value to get a title for
-        * @returns {mw.Title|null} Title object, or null if value is invalid
-        */
-       mw.widgets.TitleInputWidget.prototype.getTitle = function ( value ) {
-               var title = value !== undefined ? value : this.getValue(),
-                       // mw.Title doesn't handle null well
-                       titleObj = mw.Title.newFromText( title, this.namespace !== null ? this.namespace : undefined );
-
-               return titleObj;
-       };
-
        /**
         * @inheritdoc
         */
        mw.widgets.TitleInputWidget.prototype.cleanUpValue = function ( value ) {
                var widget = this;
+
+               // Parent method
                value = mw.widgets.TitleInputWidget.parent.prototype.cleanUpValue.call( this, value );
+
                return $.trimByteLength( this.value, value, this.maxLength, function ( value ) {
                        var title = widget.getTitle( value );
                        return title ? title.getMain() : value;
                } ).newVal;
        };
 
-       /**
-        * @inheritdoc
-        */
-       mw.widgets.TitleInputWidget.prototype.isValid = function () {
-               return $.Deferred().resolve( !!this.getTitle() ).promise();
-       };
-
 }( jQuery, mediaWiki ) );
index ec0c935..1154c9f 100644 (file)
                                        .text( config.description )
                        );
                }
+
+               // Events
+               this.$link.on( 'click', function () {
+                       return false;
+               } );
        };
 
        /* Setup */
diff --git a/resources/src/mediawiki.widgets/mw.widgets.TitleSearchWidget.js b/resources/src/mediawiki.widgets/mw.widgets.TitleSearchWidget.js
new file mode 100644 (file)
index 0000000..0e2546f
--- /dev/null
@@ -0,0 +1,83 @@
+/*!
+ * MediaWiki Widgets - TitleSearchWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function ( $, mw ) {
+
+       /**
+        * Creates an mw.widgets.TitleSearchWidget object.
+        *
+        * @class
+        * @extends OO.ui.SearchWidget
+        * @mixins mw.widgets.TitleWidget
+        *
+        * @constructor
+        */
+       mw.widgets.TitleSearchWidget = function MwWidgetsTitleSearchWidget( config ) {
+               config = config || {};
+
+               // Parent constructor
+               mw.widgets.TitleSearchWidget.parent.call( this, config );
+
+               // Mixin constructors
+               mw.widgets.TitleWidget.call( this, config );
+
+               this.query.setValidation( this.isQueryValid.bind( this ) );
+
+               // Events
+               this.results.connect( this, { choose: 'onTitleSearchResultsChoose' } );
+
+               // Initialization
+               this.$element.addClass( 'mw-widget-titleSearchWidget' );
+               this.results.$element.addClass( 'mw-widget-titleWidget-menu' );
+               if ( this.showImages ) {
+                       this.results.$element.addClass( 'mw-widget-titleWidget-menu-withImages' );
+               }
+               if ( this.showDescriptions ) {
+                       this.results.$element.addClass( 'mw-widget-titleWidget-menu-withDescriptions' );
+               }
+               if ( this.maxLength !== undefined ) {
+                       this.getQuery().$input.attr( 'maxlength', this.maxLength );
+               }
+       };
+
+       /* Setup */
+
+       OO.inheritClass( mw.widgets.TitleSearchWidget, OO.ui.SearchWidget );
+       OO.mixinClass( mw.widgets.TitleSearchWidget, mw.widgets.TitleWidget );
+
+       /* Methods */
+
+       /**
+        * @inheritdoc mw.widgets.TitleWidget
+        */
+       mw.widgets.TitleSearchWidget.prototype.getQueryValue = function () {
+               return this.getQuery().getValue();
+       };
+
+       /**
+        * Handle choose events from the result widget
+        *
+        * @param {OO.ui.OptionWidget} item Chosen item
+        */
+       mw.widgets.TitleSearchWidget.prototype.onTitleSearchResultsChoose = function ( item ) {
+               this.getQuery().setValue( item.getData() );
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.TitleSearchWidget.prototype.onQueryChange = function () {
+               var widget = this;
+
+               this.getSuggestionsPromise().done( function ( response ) {
+                       // Parent method
+                       mw.widgets.TitleSearchWidget.parent.prototype.onQueryChange.call( widget );
+
+                       widget.results.addItems( widget.getOptionsFromData( response.query || {} ) );
+               } );
+       };
+
+}( jQuery, mediaWiki ) );
diff --git a/resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js b/resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
new file mode 100644 (file)
index 0000000..f51c559
--- /dev/null
@@ -0,0 +1,285 @@
+/*!
+ * MediaWiki Widgets - TitleWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function ( $, mw ) {
+
+       /**
+        * Mixin for title widgets
+        *
+        * @class
+        * @abstract
+        *
+        * @constructor
+        * @param {Object} [config] Configuration options
+        * @cfg {number} [limit=10] Number of results to show
+        * @cfg {number} [namespace] Namespace to prepend to queries
+        * @cfg {number} [maxLength=255] Maximum query length
+        * @cfg {boolean} [relative=true] If a namespace is set, return a title relative to it
+        * @cfg {boolean} [suggestions=true] Display search suggestions
+        * @cfg {boolean} [showRedirectTargets=true] Show the targets of redirects
+        * @cfg {boolean} [showRedlink] Show red link to exact match if it doesn't exist
+        * @cfg {boolean} [showImages] Show page images
+        * @cfg {boolean} [showDescriptions] Show page descriptions
+        * @cfg {Object} [cache] Result cache which implements a 'set' method, taking keyed values as an argument
+        */
+       mw.widgets.TitleWidget = function MwWidgetsTitleWidget( config ) {
+               var widget = this;
+
+               // Config initialization
+               config = $.extend( {
+                       maxLength: 255,
+                       limit: 10
+               }, config );
+
+               // Properties
+               this.limit = config.limit;
+               this.maxLength = config.maxLength;
+               this.namespace = config.namespace !== undefined ? config.namespace : null;
+               this.relative = config.relative !== undefined ? config.relative : true;
+               this.suggestions = config.suggestions !== undefined ? config.suggestions : true;
+               this.showRedirectTargets = config.showRedirectTargets !== false;
+               this.showRedlink = !!config.showRedlink;
+               this.showImages = !!config.showImages;
+               this.showDescriptions = !!config.showDescriptions;
+               this.cache = config.cache;
+
+               // Initialization
+               this.interwikiPrefixes = [];
+               this.interwikiPrefixesPromise = new mw.Api().get( {
+                       action: 'query',
+                       meta: 'siteinfo',
+                       siprop: 'interwikimap'
+               } ).done( function ( data ) {
+                       $.each( data.query.interwikimap, function ( index, interwiki ) {
+                               widget.interwikiPrefixes.push( interwiki.prefix );
+                       } );
+               } );
+       };
+
+       /* Setup */
+
+       OO.initClass( mw.widgets.TitleWidget );
+
+       /* Methods */
+
+       /**
+        * Get the current value of the search query
+        *
+        * @abstract
+        * @return {string} Search query
+        */
+       mw.widgets.TitleWidget.prototype.getQueryValue = null;
+
+       /**
+        * Get the namespace to prepend to titles in suggestions, if any.
+        *
+        * @return {number|null} Namespace number
+        */
+       mw.widgets.TitleWidget.prototype.getNamespace = function () {
+               return this.namespace;
+       };
+
+       /**
+        * Set the namespace to prepend to titles in suggestions, if any.
+        *
+        * @param {number|null} namespace Namespace number
+        */
+       mw.widgets.TitleWidget.prototype.setNamespace = function ( namespace ) {
+               this.namespace = namespace;
+       };
+
+       /**
+        * Get a promise which resolves with an API repsonse for suggested
+        * links for the current query.
+        */
+       mw.widgets.TitleWidget.prototype.getSuggestionsPromise = function () {
+               var req,
+                       query = this.getQueryValue(),
+                       widget = this,
+                       promiseAbortObject = { abort: function () {
+                               // Do nothing. This is just so OOUI doesn't break due to abort being undefined.
+                       } };
+
+               if ( mw.Title.newFromText( query ) ) {
+                       return this.interwikiPrefixesPromise.then( function () {
+                               var params, props,
+                                       interwiki = query.substring( 0, query.indexOf( ':' ) );
+                               if (
+                                       interwiki && interwiki !== '' &&
+                                       widget.interwikiPrefixes.indexOf( interwiki ) !== -1
+                               ) {
+                                       return $.Deferred().resolve( { query: {
+                                               pages: [ {
+                                                       title: query
+                                               } ]
+                                       } } ).promise( promiseAbortObject );
+                               } else {
+                                       params = {
+                                               action: 'query',
+                                               generator: 'prefixsearch',
+                                               gpssearch: query,
+                                               gpsnamespace: widget.namespace !== null ? widget.namespace : undefined,
+                                               gpslimit: widget.limit,
+                                               ppprop: 'disambiguation'
+                                       };
+                                       props = [ 'info', 'pageprops' ];
+                                       if ( widget.showRedirectTargets ) {
+                                               params.redirects = '1';
+                                       }
+                                       if ( widget.showImages ) {
+                                               props.push( 'pageimages' );
+                                               params.pithumbsize = 80;
+                                               params.pilimit = widget.limit;
+                                       }
+                                       if ( widget.showDescriptions ) {
+                                               props.push( 'pageterms' );
+                                               params.wbptterms = 'description';
+                                       }
+                                       params.prop = props.join( '|' );
+                                       req = new mw.Api().get( params );
+                                       promiseAbortObject.abort = req.abort.bind( req ); // todo: ew
+                                       return req;
+                               }
+                       } ).promise( promiseAbortObject );
+               } else {
+                       // Don't send invalid titles to the API.
+                       // Just pretend it returned nothing so we can show the 'invalid title' section
+                       return $.Deferred().resolve( {} ).promise( promiseAbortObject );
+               }
+       };
+
+       /**
+        * Get option widgets from the server response
+        *
+        * @param {Object} data Query result
+        * @returns {OO.ui.OptionWidget[]} Menu items
+        */
+       mw.widgets.TitleWidget.prototype.getOptionsFromData = function ( data ) {
+               var i, len, index, pageExists, pageExistsExact, suggestionPage, page, redirect, redirects,
+                       items = [],
+                       titles = [],
+                       titleObj = mw.Title.newFromText( this.getQueryValue() ),
+                       redirectsTo = {},
+                       pageData = {};
+
+               if ( data.redirects ) {
+                       for ( i = 0, len = data.redirects.length; i < len; i++ ) {
+                               redirect = data.redirects[ i ];
+                               redirectsTo[ redirect.to ] = redirectsTo[ redirect.to ] || [];
+                               redirectsTo[ redirect.to ].push( redirect.from );
+                       }
+               }
+
+               for ( index in data.pages ) {
+                       suggestionPage = data.pages[ index ];
+                       pageData[ suggestionPage.title ] = {
+                               missing: suggestionPage.missing !== undefined,
+                               redirect: suggestionPage.redirect !== undefined,
+                               disambiguation: OO.getProp( suggestionPage, 'pageprops', 'disambiguation' ) !== undefined,
+                               imageUrl: OO.getProp( suggestionPage, 'thumbnail', 'source' ),
+                               description: OO.getProp( suggestionPage, 'terms', 'description' )
+                       };
+
+                       // Throw away pages from wrong namespaces. This can happen when 'showRedirectTargets' is true
+                       // and we encounter a cross-namespace redirect.
+                       if ( this.namespace === null || this.namespace === suggestionPage.ns ) {
+                               titles.push( suggestionPage.title );
+                       }
+
+                       redirects = redirectsTo[ suggestionPage.title ] || [];
+                       for ( i = 0, len = redirects.length; i < len; i++ ) {
+                               pageData[ redirects[ i ] ] = {
+                                       missing: false,
+                                       redirect: true,
+                                       disambiguation: false,
+                                       description: mw.msg( 'mw-widgets-titleinput-description-redirect', suggestionPage.title )
+                               };
+                               titles.push( redirects[ i ] );
+                       }
+               }
+
+               // If not found, run value through mw.Title to avoid treating a match as a
+               // mismatch where normalisation would make them matching (bug 48476)
+
+               pageExistsExact = titles.indexOf( this.getQueryValue() ) !== -1;
+               pageExists = pageExistsExact || (
+                       titleObj && titles.indexOf( titleObj.getPrefixedText() ) !== -1
+               );
+
+               if ( !pageExists ) {
+                       pageData[ this.getQueryValue() ] = {
+                               missing: true, redirect: false, disambiguation: false,
+                               description: mw.msg( 'mw-widgets-titleinput-description-new-page' )
+                       };
+               }
+
+               if ( this.cache ) {
+                       this.cache.set( pageData );
+               }
+
+               // Offer the exact text as a suggestion if the page exists
+               if ( pageExists && !pageExistsExact ) {
+                       titles.unshift( this.getQueryValue() );
+               }
+               // Offer the exact text as a new page if the title is valid
+               if ( this.showRedlink && !pageExists && titleObj ) {
+                       titles.push( this.getQueryValue() );
+               }
+               for ( i = 0, len = titles.length; i < len; i++ ) {
+                       page = pageData[ titles[ i ] ] || {};
+                       items.push( new mw.widgets.TitleOptionWidget( this.getOptionWidgetData( titles[ i ], page ) ) );
+               }
+
+               return items;
+       };
+
+       /**
+        * Get menu option widget data from the title and page data
+        *
+        * @param {mw.Title} title Title object
+        * @param {Object} data Page data
+        * @return {Object} Data for option widget
+        */
+       mw.widgets.TitleWidget.prototype.getOptionWidgetData = function ( title, data ) {
+               var mwTitle = new mw.Title( title );
+               return {
+                       data: this.namespace !== null && this.relative
+                               ? mwTitle.getRelativeText( this.namespace )
+                               : title,
+                       title: mwTitle,
+                       imageUrl: this.showImages ? data.imageUrl : null,
+                       description: this.showDescriptions ? data.description : null,
+                       missing: data.missing,
+                       redirect: data.redirect,
+                       disambiguation: data.disambiguation,
+                       query: this.getQueryValue()
+               };
+       };
+
+       /**
+        * Get title object corresponding to given value, or #getQueryValue if not given.
+        *
+        * @param {string} [value] Value to get a title for
+        * @returns {mw.Title|null} Title object, or null if value is invalid
+        */
+       mw.widgets.TitleWidget.prototype.getTitle = function ( value ) {
+               var title = value !== undefined ? value : this.getQueryValue(),
+                       // mw.Title doesn't handle null well
+                       titleObj = mw.Title.newFromText( title, this.namespace !== null ? this.namespace : undefined );
+
+               return titleObj;
+       };
+
+       /**
+        * Check if the query is valid
+        *
+        * @return {boolean} The query is valid
+        */
+       mw.widgets.TitleWidget.prototype.isQueryValid = function () {
+               return !!this.getTitle();
+       };
+
+}( jQuery, mediaWiki ) );
diff --git a/resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less b/resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less
new file mode 100644 (file)
index 0000000..93c4b20
--- /dev/null
@@ -0,0 +1,63 @@
+/*!
+ * MediaWiki Widgets - TitleWidget styles.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+.mw-widget-titleOptionWidget-description {
+       display: none;
+}
+
+.mw-widget-titleWidget {
+       &-menu-withImages {
+               .mw-widget-titleOptionWidget {
+                       -webkit-box-sizing: border-box;
+                       -moz-box-sizing: border-box;
+                       box-sizing: border-box;
+                       min-height: 3.75em;
+                       margin-left: 3.75em;
+               }
+
+               .mw-widget-titleOptionWidget:not(:last-child) {
+                       margin-bottom: 1px;
+               }
+
+               .oo-ui-iconElement .oo-ui-iconElement-icon {
+                       display: block;
+                       width: 3.75em;
+                       height: 3.75em;
+                       left: -3.75em;
+                       background-color: #ccc;
+                       opacity: 0.4;
+               }
+
+               .oo-ui-iconElement .mw-widget-titleOptionWidget-hasImage {
+                       border: 0;
+                       background-size: cover;
+                       opacity: 1;
+               }
+
+               .mw-widget-titleOptionWidget .oo-ui-labelElement-label {
+                       line-height: 2.8em;
+               }
+       }
+
+       &-menu-withDescriptions {
+               .mw-widget-titleOptionWidget .oo-ui-labelElement-label {
+                       line-height: 1.5em;
+               }
+
+               .mw-widget-titleOptionWidget-description {
+                       display: block;
+                       white-space: nowrap;
+                       text-overflow: ellipsis;
+                       overflow: hidden;
+               }
+       }
+}
+
+.oo-ui-menuOptionWidget:not(.oo-ui-optionWidget-selected) .mw-widget-titleOptionWidget-description,
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted .mw-widget-titleOptionWidget-description {
+       color: #888;
+}
index bd30397..0d71922 100644 (file)
@@ -223,7 +223,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
        protected function tearDown() {
                $status = ob_get_status();
-               if ( isset( $status['name'] ) && $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier' ) {
+               if ( isset( $status['name'] ) &&
+                       $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier'
+               ) {
                        ob_end_flush();
                }
 
index f0d905e..fbb3982 100644 (file)
@@ -323,8 +323,6 @@ class OutputPageTest extends MediaWikiTestCase {
                                        array( 'Cookie', array( 'string-contains=phpsessid' ) ),
                                        array( 'Cookie', array( 'string-contains=phpsessid' ) ),
                                        array( 'Accept-Language', array( 'string-contains=en', 'string-contains=en' ) ),
-
-
                                ),
                                'Vary: Cookie, Accept-Language',
                                'X-Vary-Options: Cookie;string-contains=phpsessid,Accept-Language;string-contains=en',
@@ -359,6 +357,7 @@ class NullMessageBlobStore extends MessageBlobStore {
 
        public function updateMessage( $key ) {
        }
+
        public function clear() {
        }
 }
index 291ed31..7ec898f 100644 (file)
@@ -64,7 +64,16 @@ class StatusTest extends MediaWikiLangTestCase {
                $this->assertTrue( $status->ok );
                $status = Status::newFatal( 'foo', 1, 2 );
                $this->assertFalse( $status->ok );
-               $this->assertArrayEquals( array( array( 'type' => 'error', 'message' => 'foo', 'params' => array( 1, 2 ) ) ), $status->errors );
+               $this->assertArrayEquals(
+                       array(
+                               array(
+                                       'type' => 'error',
+                                       'message' => 'foo',
+                                       'params' => array( 1, 2 )
+                               )
+                       ),
+                       $status->errors
+               );
        }
 
        /**
index 9233416..f7ae08e 100644 (file)
@@ -62,7 +62,7 @@ class WikiMapTest extends MediaWikiLangTestCase {
        public function provideMakeForeignLink() {
                return array(
                        'unknown' => array( false, 'xyzzy', 'Foo' ),
-                       'enwiki' => array( '<a class="external" rel="nofollow" href="http://en.example.org/w/Foo">Foo</a>', 'enwiki', 'Foo' ),
+                       'enwiki' => array( '<a class="external" rel="nofollow" href="http://en.example.org/w/Foo">Foo</a>', 'enwiki', 'Foo' ),
                        'ruwiki' => array( '<a class="external" rel="nofollow" href="//ru.example.org/wiki/%D0%A4%D1%83">вар</a>', 'ruwiki', 'Фу', 'вар' ),
                );
        }
@@ -77,7 +77,7 @@ class WikiMapTest extends MediaWikiLangTestCase {
        public function provideForeignUserLink() {
                return array(
                        'unknown' => array( false, 'xyzzy', 'Foo' ),
-                       'enwiki' => array( '<a class="external" rel="nofollow" href="http://en.example.org/w/User:Foo">User:Foo</a>', 'enwiki', 'Foo' ),
+                       'enwiki' => array( '<a class="external" rel="nofollow" href="http://en.example.org/w/User:Foo">User:Foo</a>', 'enwiki', 'Foo' ),
                        'ruwiki' => array( '<a class="external" rel="nofollow" href="//ru.example.org/wiki/User:%D0%A4%D1%83">вар</a>', 'ruwiki', 'Фу', 'вар' ),
                );
        }
@@ -92,7 +92,7 @@ class WikiMapTest extends MediaWikiLangTestCase {
        public function provideGetForeignURL() {
                return array(
                        'unknown' => array( false, 'xyzzy', 'Foo' ),
-                       'enwiki' => array( 'http://en.example.org/w/Foo', 'enwiki', 'Foo' ),
+                       'enwiki' => array( 'http://en.example.org/w/Foo', 'enwiki', 'Foo' ),
                        'ruwiki with fragement' => array( '//ru.example.org/wiki/%D0%A4%D1%83#%D0%B2%D0%B0%D1%80', 'ruwiki', 'Фу', 'вар' ),
                );
        }
index c4d87c2..59bfb03 100644 (file)
@@ -111,7 +111,7 @@ class CssContentTest extends JavaScriptContentTest {
                );
        }
 
-               public static function dataEquals() {
+       public static function dataEquals() {
                return array(
                        array( new CssContent( 'hallo' ), null, false ),
                        array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ),
index 0ee2712..898fa53 100644 (file)
@@ -253,7 +253,7 @@ class JavaScriptContentTest extends TextContentTest {
         * @covers JavaScriptContent::updateRedirect
         * @dataProvider provideUpdateRedirect
         */
-       public function testUpdateRedirect( $oldText, $expectedText) {
+       public function testUpdateRedirect( $oldText, $expectedText ) {
                $this->setMwGlobals( array(
                        'wgServer' => '//example.org',
                        'wgScriptPath' => '/w/index.php',
index ef6f847..9866ce1 100644 (file)
@@ -52,10 +52,10 @@ class KafkaHandlerTest extends MediaWikiTestCase {
                $produce = $this->getMockBuilder( 'Kafka\Produce' )
                        ->disableOriginalConstructor()
                        ->getMock();
-               $produce->expects($this->any())
-                       ->method('getAvailablePartitions')
-                       ->will($this->returnValue( array( 'A' ) ) );
-               $produce->expects($this->once())
+               $produce->expects( $this->any() )
+                       ->method( 'getAvailablePartitions' )
+                       ->will( $this->returnValue( array( 'A' ) ) );
+               $produce->expects( $this->once() )
                        ->method( 'setMessages' )
                        ->with( $expect, $this->anything(), $this->anything() );
 
index a618889..adcbe74 100644 (file)
@@ -145,4 +145,5 @@ class SwiftFileBackendTest extends MediaWikiTestCase {
                        )
                );
        }
-}
\ No newline at end of file
+}
+
index 681e368..ea3f862 100644 (file)
@@ -99,7 +99,7 @@ class FileBackendDBRepoWrapperTest extends MediaWikiTestCase {
                        ->will( $this->returnValue( '96246614d75ba1703bdfd5d7660bb57407aaf5d9' ) );
 
                $backendMock->expects( $this->once() )
-                       ->method( 'getFileContentsMulti')
+                       ->method( 'getFileContentsMulti' )
                        ->will( $this->returnValue( array( $sha1Path => 'foo' ) ) );
 
                $result = $wrapperMock->getFileContentsMulti( array( 'srcs' => array( $filenamePath ) ) );
index 551d3a7..679382b 100644 (file)
@@ -64,12 +64,12 @@ class MigrateFileRepoLayoutTest extends MediaWikiTestCase {
 
        protected function deleteFilesRecursively( $directory ) {
                foreach ( glob( $directory . '/*' ) as $file ) {
-               if ( is_dir( $file ) ) {
-                       $this->deleteFilesRecursively( $file );
-               } else {
-                       unlink( $file );
-               }
-               }
+                       if ( is_dir( $file ) ) {
+                               $this->deleteFilesRecursively( $file );
+                       } else {
+                               unlink( $file );
+                       }
+               }
 
                rmdir( $directory );
        }
@@ -103,7 +103,7 @@ class MigrateFileRepoLayoutTest extends MediaWikiTestCase {
                        . '/'
                        . substr( $sha1, 2, 1 )
                        . '/'
-                       . $sha1 ;
+                       . $sha1;
 
                $this->assertEquals( file_get_contents( $expectedOriginalFilepath ), $this->text, 'New sha1 file should be exist and have the right contents' );
 
index d36710a..285f280 100644 (file)
@@ -24,7 +24,7 @@ class WebPHandlerTest extends MediaWikiTestCase {
                        array( "\x52\x49\x46\x46\x90\x68\x01\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x83\x68\x01\x00\x2F\x8F\x01\x4B\x10\x8D\x38\x6C\xDB\x46\x92\xE0\xE0\x82\x7B\x6C",
                                array( 'compression' => 'lossless', 'width' => 400, 'height' => 301 ) ),
                        array( "\x52\x49\x46\x46\x64\x5B\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x8F\x01\x00\x2C\x01\x00\x41\x4C\x50\x48\xE5\x0E",
-                               array( 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 400, 'height' => 301) ),
+                               array( 'compression' => 'unknown', 'animated' => false, 'transparency' => true, 'width' => 400, 'height' => 301 ) ),
                        array( "\x52\x49\x46\x46\xA8\x72\x00\x00\x57\x45\x42\x50\x56\x50\x38\x4C\x9B\x72\x00\x00\x2F\x81\x81\x62\x10\x8D\x40\x8C\x24\x39\x6E\x73\x73\x38\x01\x96",
                                array( 'compression' => 'lossless', 'width' => 386, 'height' => 395 ) ),
                        array( "\x52\x49\x46\x46\xE0\x42\x00\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x10\x00\x00\x00\x81\x01\x00\x8A\x01\x00\x41\x4C\x50\x48\x56\x10",
@@ -50,9 +50,9 @@ class WebPHandlerTest extends MediaWikiTestCase {
                        array( "\x52\x49\x46\x46\x7A\x19\x03\x00\x57\x45\x42\x50\x56\x50\x38\x20\x6E\x19\x03\x00\xB2\xF8\x09\x9D\x01\x2A\x00\x05\xD0\x02\x3E\xAD\x46\x99\x4A\xA5",
                                array( 'compression' => 'lossy', 'width' => 1280, 'height' => 720 ) ),
                        array( "\x52\x49\x46\x46\x44\xB3\x02\x00\x57\x45\x42\x50\x56\x50\x38\x20\x38\xB3\x02\x00\x52\x57\x06\x9D\x01\x2A\x00\x04\x04\x03\x3E\xA5\x44\x96\x49\x26",
-                               array( 'compression' => 'lossy', 'width' => 1024, 'height' => 772) ),
+                               array( 'compression' => 'lossy', 'width' => 1024, 'height' => 772 ) ),
                        array( "\x52\x49\x46\x46\x02\x43\x01\x00\x57\x45\x42\x50\x56\x50\x38\x20\xF6\x42\x01\x00\x12\xC0\x05\x9D\x01\x2A\x00\x04\xF0\x02\x3E\x79\x34\x93\x47\xA4",
-                               array( 'compression' => 'lossy', 'width' => 1024, 'height' => 752) ),
+                               array( 'compression' => 'lossy', 'width' => 1024, 'height' => 752 ) ),
 
                        // Animated file from https://groups.google.com/a/chromium.org/d/topic/blink-dev/Y8tRC4mdQz8/discussion
                        array( "\x52\x49\x46\x46\xD0\x0B\x02\x00\x57\x45\x42\x50\x56\x50\x38\x58\x0A\x00\x00\x00\x12\x00\x00\x00\x3F\x01\x00\x3F\x01\x00\x41\x4E",
index 13c2838..df9b552 100644 (file)
@@ -207,7 +207,12 @@ class SpecialSearchTestMockResultSet extends SearchResultSet {
        protected $results;
        protected $suggestion;
 
-       public function __construct( $suggestion = null, $rewrittenQuery = null, array $results = array(), $containedSyntax = false) {
+       public function __construct(
+               $suggestion = null,
+               $rewrittenQuery = null,
+               array $results = array(),
+               $containedSyntax = false
+       ) {
                $this->suggestion = $suggestion;
                $this->rewrittenQuery = $rewrittenQuery;
                $this->results = $results;
index a2b35f3..4684658 100644 (file)
@@ -23,7 +23,7 @@ class BatchRowUpdateTest extends MediaWikiTestCase {
                $writer->write( $updates );
        }
 
-       static protected function mockUpdate( array $changes ) {
+       protected static function mockUpdate( array $changes ) {
                static $i = 0;
                return array(
                        'primaryKey' => array( 'event_id' => $i++ ),
@@ -53,7 +53,7 @@ class BatchRowUpdateTest extends MediaWikiTestCase {
                $this->assertEquals( count( $response ) - 1, $pos );
        }
 
-       static public function provider_readerGetPrimaryKey() {
+       public static function provider_readerGetPrimaryKey() {
                $row = array(
                        'id_field' => 42,
                        'some_col' => 'dvorak',
@@ -84,7 +84,7 @@ class BatchRowUpdateTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $reader->extractPrimaryKeys( (object) $row ), $message );
        }
 
-       static public function provider_readerSetFetchColumns() {
+       public static function provider_readerSetFetchColumns() {
                return array(
 
                        array(
@@ -136,7 +136,7 @@ class BatchRowUpdateTest extends MediaWikiTestCase {
                $reader->rewind();
        }
 
-       static public function provider_readerSelectConditions() {
+       public static function provider_readerSelectConditions() {
                return array(
 
                        array(
index e2fc824..454e9c1 100644 (file)
@@ -816,7 +816,10 @@ class MaintenanceTest extends MediaWikiTestCase {
         */
        public function testGetConfig() {
                $this->assertInstanceOf( 'Config', $this->m->getConfig() );
-               $this->assertSame( ConfigFactory::getDefaultInstance()->makeConfig( 'main' ), $this->m->getConfig() );
+               $this->assertSame(
+                       ConfigFactory::getDefaultInstance()->makeConfig( 'main' ),
+                       $this->m->getConfig()
+               );
        }
 
        /**
index af924a0..5591aa1 100755 (executable)
@@ -42,14 +42,28 @@ class PHPUnitMaintClass extends Maintenance {
                        false, # not required
                        false # no arg needed
                );
-               $this->addOption( 'regex', 'Only run parser tests that match the given regex.', false, true );
+               $this->addOption(
+                       'regex',
+                       'Only run parser tests that match the given regex.',
+                       false,
+                       true
+               );
                $this->addOption( 'file', 'File describing parser tests.', false, true );
                $this->addOption( 'use-filebackend', 'Use filebackend', false, true );
                $this->addOption( 'use-bagostuff', 'Use bagostuff', false, true );
                $this->addOption( 'use-jobqueue', 'Use jobqueue', false, true );
-               $this->addOption( 'keep-uploads', 'Re-use the same upload directory for each test, don\'t delete it.', false, false );
+               $this->addOption(
+                       'keep-uploads',
+                       'Re-use the same upload directory for each test, don\'t delete it.',
+                       false,
+                       false
+               );
                $this->addOption( 'use-normal-tables', 'Use normal DB tables.', false, false );
-               $this->addOption( 'reuse-db', 'Init DB only if tables are missing and keep after finish.', false, false );
+               $this->addOption(
+                       'reuse-db', 'Init DB only if tables are missing and keep after finish.',
+                       false,
+                       false
+               );
        }
 
        public function finalSetup() {