Merge "Optimize order of styles and scripts"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 17 Mar 2015 21:31:04 +0000 (21:31 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 17 Mar 2015 21:31:04 +0000 (21:31 +0000)
63 files changed:
RELEASE-NOTES-1.25
autoload.php
includes/User.php
includes/api/ApiParse.php
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/nl.json
includes/api/i18n/qqq.json
includes/content/JsonContent.php
includes/db/DatabaseSqlite.php
includes/htmlform/HTMLRadioField.php
includes/installer/SqliteInstaller.php
includes/logging/BlockLogFormatter.php
includes/parser/ParserOptions.php
includes/registration/ExtensionRegistry.php
includes/specialpage/SpecialPage.php
includes/specials/SpecialAllPages.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialJavaScriptTest.php
includes/specials/SpecialLog.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRunJobs.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWhatlinkshere.php
includes/utils/AutoloadGenerator.php
languages/i18n/arq.json
languages/i18n/be-tarask.json
languages/i18n/ca.json
languages/i18n/de.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/fi.json
languages/i18n/hi.json
languages/i18n/hy.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/kk-cyrl.json
languages/i18n/ksh.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/sw.json
languages/i18n/tr.json
maintenance/fixUserRegistration.php
maintenance/sqlite.inc
maintenance/sqlite.php
maintenance/update.php
tests/TestsAutoLoader.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/parser/parserTestsParserHook.php
tests/phpunit/data/helpers/WellProtectedClass.php [new file with mode: 0644]
tests/phpunit/includes/TestingAccessWrapper.php [new file with mode: 0644]
tests/phpunit/includes/TestingAccessWrapperTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryTestBase.php
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/structure/AvailableRightsTest.php [new file with mode: 0644]

index 5e08efd..88bfc15 100644 (file)
@@ -174,6 +174,8 @@ production.
   This requires the fa_sha1 field being populated.
 * Removed rel="archives" from the "View history" link, as it did not pass
   HTML validation.
+* $wgUseTidy is now set when parserTests are run with the tidy option to match
+  output on wiki.
 
 === Action API changes in 1.25 ===
 * (T67403) XML tag highlighting is now only performed for formats
index 3e003f1..6b83fcb 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 // This file is generated by maintenance/generateLocalAutoload.php, do not adjust manually
-
+// @codingStandardsIgnoreFile
 global $wgAutoloadLocalClasses;
 
 $wgAutoloadLocalClasses = array(
@@ -174,8 +174,8 @@ $wgAutoloadLocalClasses = array(
        'BloomCacheRedis' => __DIR__ . '/includes/cache/bloom/BloomCacheRedis.php',
        'BloomFilterTitleHasLogs' => __DIR__ . '/includes/cache/bloom/BloomFilters.php',
        'BmpHandler' => __DIR__ . '/includes/media/BMP.php',
-       'BufferingStatsdDataFactory' => __DIR__ . '/includes/libs/BufferingStatsdDataFactory.php',
        'BrokenRedirectsPage' => __DIR__ . '/includes/specials/SpecialBrokenRedirects.php',
+       'BufferingStatsdDataFactory' => __DIR__ . '/includes/libs/BufferingStatsdDataFactory.php',
        'CLDRPluralRuleConverter' => __DIR__ . '/languages/utils/CLDRPluralRuleConverter.php',
        'CLDRPluralRuleConverterExpression' => __DIR__ . '/languages/utils/CLDRPluralRuleConverterExpression.php',
        'CLDRPluralRuleConverterFragment' => __DIR__ . '/languages/utils/CLDRPluralRuleConverterFragment.php',
@@ -290,7 +290,6 @@ $wgAutoloadLocalClasses = array(
        'DatabaseOracle' => __DIR__ . '/includes/db/DatabaseOracle.php',
        'DatabasePostgres' => __DIR__ . '/includes/db/DatabasePostgres.php',
        'DatabaseSqlite' => __DIR__ . '/includes/db/DatabaseSqlite.php',
-       'DatabaseSqliteStandalone' => __DIR__ . '/includes/db/DatabaseSqlite.php',
        'DatabaseUpdater' => __DIR__ . '/includes/installer/DatabaseUpdater.php',
        'DateFormats' => __DIR__ . '/maintenance/language/date-formats.php',
        'DateFormatter' => __DIR__ . '/includes/parser/DateFormatter.php',
index c811dd5..b1d434d 100644 (file)
@@ -4412,7 +4412,7 @@ class User implements IDBAccessObject {
 
        /**
         * Get a list of all available permissions.
-        * @return array Array of permission names
+        * @return string[] Array of permission names
         */
        public static function getAllRights() {
                if ( self::$mAllRights === false ) {
index 83e105b..20592ca 100644 (file)
@@ -70,6 +70,9 @@ class ApiParse extends ApiBase {
 
                if ( isset( $params['section'] ) ) {
                        $this->section = $params['section'];
+                       if ( !preg_match( '/^((T-)?\d+|new)$/', $this->section ) ) {
+                               $this->dieUsage( "The section parameter must be a valid section id or 'new'", "invalidsection" );
+                       }
                } else {
                        $this->section = false;
                }
@@ -203,7 +206,14 @@ class ApiParse extends ApiBase {
                        }
 
                        if ( $this->section !== false ) {
-                               $this->content = $this->getSectionContent( $this->content, $titleObj->getPrefixedText() );
+                               if ( $this->section === 'new' ) {
+                                       // Insert the section title above the content.
+                                       if ( !is_null( $params['sectiontitle'] ) && $params['sectiontitle'] !== '' ) {
+                                               $this->content = $this->content->addSectionHeader( $params['sectiontitle'] );
+                                       }
+                               } else {
+                                       $this->content = $this->getSectionContent( $this->content, $titleObj->getPrefixedText() );
+                               }
                        }
 
                        if ( $params['pst'] || $params['onlypst'] ) {
@@ -706,6 +716,9 @@ class ApiParse extends ApiBase {
                        'onlypst' => false,
                        'effectivelanglinks' => false,
                        'section' => null,
+                       'sectiontitle' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                       ),
                        'disablepp' => false,
                        'disableeditsection' => false,
                        'generatexml' => array(
index 4237ff8..1c6af66 100644 (file)
        "apihelp-parse-param-pst": "Do a pre-save transform on the input before parsing it. Only valid when used with text.",
        "apihelp-parse-param-onlypst": "Do a pre-save transform (PST) on the input, but don't parse it. Returns the same wikitext, after a PST has been applied. Only valid when used with <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "Includes language links supplied by extensions (for use with <kbd>$1prop=langlinks</kbd>).",
-       "apihelp-parse-param-section": "Only retrieve the content of this section number.",
+       "apihelp-parse-param-section": "Only retrieve the content of this section number or when <kbd>new</kbd> generate a new section.\n\n<kbd>new</kbd> section is only honored when specifying <var>text</var>.",
+       "apihelp-parse-param-sectiontitle": "New section title when <var>section</var> is <kbd>new</kbd>.\n\nUnlike page editing, this does not fall back to <var>summary</var> when omitted or empty.",
        "apihelp-parse-param-disablepp": "Disable the PP Report from the parser output.",
        "apihelp-parse-param-disableeditsection": "Disable edit section links from the parser output.",
        "apihelp-parse-param-generatexml": "Generate XML parse tree (requires content model <code>$1</code>).",
index 1b17871..79f6ac2 100644 (file)
        "apihelp-feedcontributions-param-feedformat": "El formato del canal.",
        "apihelp-feedcontributions-param-year": "A partir del año (y anteriores).",
        "apihelp-feedcontributions-param-month": "A partir del mes (y anteriores).",
+       "apihelp-feedcontributions-param-tagfilter": "Filtrar las contribuciones que tienen estas etiquetas.",
        "apihelp-feedcontributions-param-deletedonly": "Mostrar solo las contribuciones borradas.",
+       "apihelp-feedcontributions-param-toponly": "Mostrar solo ediciones que son últimas revisiones.",
+       "apihelp-feedcontributions-param-newonly": "Mostrar solo ediciones que son creaciones de páginas.",
+       "apihelp-feedcontributions-param-showsizediff": "Mostrar la diferencia de tamaño entre revisiones.",
+       "apihelp-feedcontributions-example-simple": "Devolver las contribuciones del usuario <kbd>Ejemplo</kbd>.",
+       "apihelp-feedrecentchanges-description": "Devuelve un canal de cambios recientes.",
        "apihelp-feedrecentchanges-param-feedformat": "El formato del canal.",
+       "apihelp-feedrecentchanges-param-invert": "Todos los espacios de nombres menos el que está seleccionado.",
+       "apihelp-feedrecentchanges-param-associated": "Incluir el espacio de nombres asociado (discusión o principal).",
+       "apihelp-feedrecentchanges-param-limit": "Número máximo de resultados que devolver.",
        "apihelp-feedrecentchanges-param-from": "Mostrar los cambios realizados a partir de entonces.",
        "apihelp-feedrecentchanges-param-hideminor": "Ocultar cambios menores.",
        "apihelp-feedrecentchanges-param-hidebots": "Ocultar los cambios realizados por bots.",
        "apihelp-feedrecentchanges-example-30days": "Mostrar los cambios recientes limitados a 30 días",
        "apihelp-feedwatchlist-description": "Devuelve el canal de una lista de seguimiento.",
        "apihelp-feedwatchlist-param-feedformat": "El formato del canal.",
+       "apihelp-feedwatchlist-param-linktosections": "Enlazar directamente a las secciones cambiadas de ser posible.",
+       "apihelp-feedwatchlist-example-default": "Mostrar el canal de la lista de seguimiento.",
        "apihelp-feedwatchlist-example-all6hrs": "Mostrar todos los cambios en páginas vigiladas en las últimas 6 horas.",
        "apihelp-filerevert-description": "Revertir el archivo a una versión anterior.",
        "apihelp-filerevert-param-filename": "Nombre de archivo final, sin el prefijo Archivo:",
        "apihelp-filerevert-param-comment": "Comentario de carga.",
+       "apihelp-help-description": "Mostrar la ayuda para los módulos especificados.",
        "apihelp-help-example-main": "Ayuda del módulo principal",
        "apihelp-help-example-recursive": "Toda la ayuda en una página",
        "apihelp-help-example-help": "Ayuda del módulo de ayuda en sí",
        "apihelp-imagerotate-description": "Girar una o más imágenes.",
+       "apihelp-imagerotate-param-rotation": "Grados que rotar una imagen en sentido horario.",
+       "apihelp-imagerotate-example-simple": "Rotar <kbd>File:Ejemplo.png</kbd> <kbd>90</kbd> grados.",
+       "apihelp-imagerotate-example-generator": "Rotar todas las imágenes en la  <kbd>Categoría:Girar</kbd> <kbd>180</kbd> grados.",
        "apihelp-import-param-summary": "Resumen de importación.",
        "apihelp-import-param-xml": "Se cargó el archivo XML.",
        "apihelp-import-param-rootpage": "Importar como subpágina de esta página.",
        "apihelp-patrol-example-revid": "Patrullar una revisión",
        "apihelp-protect-param-reason": "Motivo de la (des)protección.",
        "apihelp-protect-example-protect": "Proteger una página",
+       "apihelp-query+allcategories-description": "Enumerar todas las categorías.",
+       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Solo puede usarse con <var>$3user</var>.",
        "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "No puede ser utilizado con <var>$3user</var>.",
        "apihelp-query+allimages-param-sha1": "Suma SHA1 de la imagen. Invalida $1sha1base36.",
        "apihelp-query+allimages-param-sha1base36": "Suma SHA1 de la imagen en base 36 (usada en MediaWiki).",
        "apihelp-query+blocks-example-simple": "Listar bloques.",
        "apihelp-query+categoryinfo-example-simple": "Obtener información acerca de <kbd>Category:Foo</kbd> y <kbd>Category:Bar</kbd>",
        "apihelp-query+categorymembers-example-generator": "Obtener información sobre las primeras 10 páginas de la <kbd>Categoría:Física</kbd>",
+       "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modo|Modos}}: $2",
        "apihelp-query+deletedrevs-example-mode3-talk": "Listar las primeras 50 páginas en el espacio de nombres {{ns:talk}} (modo 3).",
        "apihelp-query+duplicatefiles-example-simple": "Buscar duplicados de [[:File:Alber Einstein Head.jpg]].",
        "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados en todos los ficheros.",
        "apihelp-query+watchlistraw-example-simple": "Listar las páginas de la lista de seguimiento del usuario actual.",
        "apihelp-unblock-example-user": "Desbloquear al usuario <kbd>Bob</kbd> con el motivo <kbd>Lo siento, Bob</kbd>",
        "apihelp-undelete-example-revisions": "Restaurar dos revisiones de la página <kbd>Portada</kbd>.",
+       "apihelp-upload-param-watch": "Vigilar la página.",
+       "apihelp-upload-param-ignorewarnings": "Ignorar las advertencias.",
        "apihelp-upload-example-url": "Subir desde una URL.",
+       "apihelp-userrights-param-user": "Nombre de usuario.",
+       "apihelp-userrights-param-add": "Agregar el usuario a estos grupos.",
+       "apihelp-userrights-param-remove": "Eliminar el usuario de estos grupos.",
+       "apihelp-userrights-param-reason": "Motivo del cambio.",
        "apihelp-userrights-example-user": "Agregar al usuario <kbd>FooBot</kbd> al grupo <kbd>bot</kbd> y eliminarlo de los grupos <kbd>sysop</kbd> y <kbd>burócrata</kbd>.",
        "apihelp-watch-example-watch": "Vigilar la página <kbd>Portada</kbd>.",
        "apihelp-watch-example-unwatch": "Dejar de vigilar la <kbd>Portada</kbd>.",
+       "api-help-main-header": "Módulo principal",
+       "api-help-flag-deprecated": "Este módulo está en desuso.",
+       "api-help-flag-readrights": "Este módulo requiere permisos de lectura.",
+       "api-help-flag-writerights": "Este módulo requiere permisos de escritura.",
+       "api-help-flag-mustbeposted": "Este módulo solo acepta solicitudes POST.",
+       "api-help-flag-generator": "Este módulo puede utilizarse como un generador.",
        "api-help-parameters": "{{PLURAL:$1|Parámetro|Parámetros}}:",
+       "api-help-param-deprecated": "En desuso.",
+       "api-help-param-required": "Este parámetro es obligatorio.",
+       "api-help-param-list": "{{PLURAL:$1|1=Un valor|2=Valores (separados por <kbd>{{!}}</kbd>)}}: $2",
+       "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Debe estar vacío|Puede estar vacío, o $2}}",
        "api-help-param-multi-separate": "Separar los valores con <kbd>|</kbd>.",
        "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:"
 }
index 1ac872f..40bc7e9 100644 (file)
        "apihelp-query+fileusage-param-prop": "Que propiedades obter:\n;pageid:ID de cada páxina.\n;título:Título de cada páxina.\n;redirect:Marca de se a páxina é unha redirección.",
        "apihelp-query+fileusage-param-namespace": "Só incluír páxinas nestes espazos de nomes.",
        "apihelp-query+fileusage-param-limit": "Cantos mostrar.",
-       "apihelp-query+fileusage-param-show": "Mostrar só elementos que cumplen estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
+       "apihelp-query+fileusage-param-show": "Mostrar só elementos que cumpren estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
        "apihelp-query+fileusage-example-simple": "Obter unha lista de páxinas usando [[:File:Example.jpg]]",
        "apihelp-query+fileusage-example-generator": "Obter infomación sobre páxinas que usan [[:File:Example.jpg]]",
        "apihelp-query+imageinfo-description": "Devolve información de ficheiros e historial de subidas.",
        "apihelp-query+imageusage-param-pageid": "ID de páxina a buscar. Non pode usarse xunto con $1title.",
        "apihelp-query+imageusage-param-namespace": "Nome de espazos a numerar.",
        "apihelp-query+imageusage-param-dir": "Dirección na cal listar.",
+       "apihelp-query+info-paramvalue-prop-displaytitle": "Devolve a forma na que se visualiza actualmente o título da páxina.",
+       "apihelp-query+info-param-token": "Usar  [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] no canto diso.",
+       "apihelp-query+info-example-simple": "Obter información sobre a páxina <kbd>Main Page</kbd>.",
+       "apihelp-query+info-example-protection": "Obter información xeral e de protección  sobre a páxina <kbd>Main Page</kbd>.",
+       "apihelp-query+iwbacklinks-param-prefix": "Prefixo para a interwiki.",
+       "apihelp-query+iwbacklinks-param-title": "Ligazón interwiki a buscar. Debe usarse con <var>$1blprefix</var>.",
+       "apihelp-query+iwbacklinks-param-limit": "Número total de páxinas a devolver.",
+       "apihelp-query+iwbacklinks-param-prop": "Que propiedades obter:\n;iwprefix:Engade o prefixo da interwiki.\n;iwtitle:Engade o título da interwiki.",
+       "apihelp-query+iwbacklinks-param-dir": "Dirección na cal listar.",
+       "apihelp-query+iwbacklinks-example-simple": "Obter as páxinas ligadas a [[wikibooks:Test]]",
+       "apihelp-query+iwbacklinks-example-generator": "Obter información sobre as páxinas que ligan a [[wikibooks:Test]].",
+       "apihelp-query+iwlinks-description": "Devolve todas as ligazóns interwiki ás páxinas indicadas.",
+       "apihelp-query+iwlinks-param-url": "Se obter a URL completa (non pode usarse con $1prop).",
+       "apihelp-query+iwlinks-param-prop": "Que propiedades adicionais obter para cada ligazón interwiki:\n;url:Engade a URL completa.",
+       "apihelp-query+iwlinks-param-limit": "Cantas ligazóns interwiki devolver.",
+       "apihelp-query+iwlinks-param-prefix": "Só devolver ligazóns interwiki con este prefixo.",
+       "apihelp-query+iwlinks-param-title": "Ligazón interwiki a buscar. Debe usarse con <var>$1prefix</var>.",
+       "apihelp-query+iwlinks-param-dir": "Dirección na cal listar.",
+       "apihelp-query+iwlinks-example-simple": "Obter as ligazóns interwiki da páxina <kbd>Main Page</kbd>.",
+       "apihelp-query+langbacklinks-description": "Atopar todas as páxinas que ligan coa ligazón de lingua dada. \n\nPode usarse para atopar todas as ligazóns cun código de lingua, ou todas as ligazón a un título (cunha lingua dada). Non usar cun parámetro que sexa \"todas as ligazóns de lingua\".\n\nDecátese que isto pode non considerar as ligazóns de idioma engadidas polas extensións.",
+       "apihelp-query+langbacklinks-param-lang": "Lingua para a ligazón de lingua.",
+       "apihelp-query+langbacklinks-param-title": "Ligazón de lingua a buscar. Debe usarse con $1lang.",
+       "apihelp-query+langbacklinks-param-limit": "Número total de páxinas a devolver.",
+       "apihelp-query+langbacklinks-param-prop": "Que propiedades obter:\n;lllang:Engade o código de lingua á ligazón de páxina.\n;lltitle:Engade o título da ligazón de lingua.",
+       "apihelp-query+langbacklinks-param-dir": "Dirección na cal listar.",
+       "apihelp-query+langbacklinks-example-simple": "Obter as páxinas ligadas a [[:fr:Test]].",
+       "apihelp-query+langbacklinks-example-generator": "Obter información sobre as páxinas que ligan a [[:fr:Test]].",
+       "apihelp-query+langlinks-description": "Devolve todas as ligazóns interwiki ás páxinas indicadas.",
+       "apihelp-query+langlinks-param-limit": "Cantas ligazóns de lingua devolver.",
+       "apihelp-query+langlinks-param-url": "Se obter a URL completa (non pode usarse con <var>$1prop</var>).",
+       "apihelp-query+langlinks-param-prop": "Que propiedades adicionais obter para cada ligazón interlingüística:\n;url:Engade a URL completa.\n;langname:Engade o nome localizado da lingua (o mellor intento). Use <var>$1inlanguagecode</var> para controlar a lingua.\n;autonym:Engade o nome nativo da lingua.",
+       "apihelp-query+langlinks-param-lang": "Devolver só ligazóns de lingua con este código de lingua.",
+       "apihelp-query+langlinks-param-title": "Ligazón a buscar. Debe usarse con <var>$1lang</var>.",
+       "apihelp-query+langlinks-param-dir": "Dirección na cal listar.",
+       "apihelp-query+langlinks-param-inlanguagecode": "Código de lingua para nomes de lingua localizados.",
+       "apihelp-query+langlinks-example-simple": "Obter ligazóns interlingua da páxina <kbd>Main Page</kbd>.",
+       "apihelp-query+links-description": "Devolve todas as ligazóns das páxinas indicadas.",
+       "apihelp-query+links-param-namespace": "Mostra ligazóns só neste espazo de nomes.",
+       "apihelp-query+links-param-limit": "Cantas ligazóns devolver.",
+       "apihelp-query+links-param-titles": "Listar só as ligazóns a eses títulos. Útil para verificar se unha páxina concreta liga a un título determinado.",
+       "apihelp-query+links-param-dir": "Dirección na cal listar.",
+       "apihelp-query+links-example-simple": "Obter as ligazóns da páxina <kbd>Main Page</kbd>.",
+       "apihelp-query+links-example-generator": "Obter información sobre as ligazóns de páxina da <kbd>Main Page</kbd>.",
+       "apihelp-query+links-example-namespaces": "Obter as ligazóns á páxina <kbd>Main Page</kbd> nos espazos de nome {{ns:user}} e {{ns:template}}.",
+       "apihelp-query+linkshere-description": "Atopar todas as páxinas que ligan coas páxinas dadas.",
+       "apihelp-query+linkshere-param-prop": "Que propiedades obter:\n;pageid:ID de cada páxina.\n;título:Título de cada páxina.\n;redirect:Marca de se a páxina é unha redirección.",
+       "apihelp-query+linkshere-param-namespace": "Só incluír páxinas nestes espazos de nomes.",
+       "apihelp-query+linkshere-param-limit": "Cantos mostrar.",
+       "apihelp-query+linkshere-param-show": "Mostrar só elementos que cumpren estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
+       "apihelp-query+linkshere-example-simple": "Obter unha lista que ligan á [[Main Page]]",
+       "apihelp-query+linkshere-example-generator": "Obter a información das páxinas que ligan á [[Main Page]].",
+       "apihelp-query+logevents-description": "Obter os eventos dos rexistros.",
+       "apihelp-query+logevents-param-type": "Filtrar as entradas do rexistro para mostrar só as deste tipo.",
+       "apihelp-query+logevents-param-action": "Filtrar accións no rexistro para mostrar só esta acción. Ignora <var>$1type</var>. Accións comodín como  <kbd>action/*</kbd> permiten especificar calquera cadea para o asterisco.",
+       "apihelp-query+logevents-param-start": "Selo de tempo no que comezar a enumeración.",
+       "apihelp-query+logevents-param-end": "Selo de tempo para rematar a enumeración.",
+       "apihelp-query+logevents-param-user": "Filtrar entradas ás feitas polo usuario indicado.",
+       "apihelp-query+logevents-param-title": "Filtrar entradas ás asociadas á páxina indicada.",
+       "apihelp-query+logevents-param-namespace": "Filtrar entradas ás do espazo de nomes indicado.",
+       "apihelp-query+logevents-param-prefix": "Filtrar entradas ás que comezan por este prefixo.",
+       "apihelp-query+logevents-param-tag": "Só listar entradas de evento marcadas con esta etiqueta.",
+       "apihelp-query+logevents-param-limit": "Número total de entradas de evento a devolver.",
+       "apihelp-query+logevents-example-simple": "Lista de eventos recentes do rexistro.",
+       "apihelp-query+pagepropnames-description": "Listar os nomes de todas as propiedades de páxina usados na wiki.",
        "apihelp-query+pagepropnames-param-limit": "Máximo número de nomes a retornar.",
+       "apihelp-query+pagepropnames-example-simple": "Obter os dez primeiros nomes de propiedade.",
+       "apihelp-query+pageprops-description": "Obter varias propiedades definidas no contido da páxina.",
+       "apihelp-query+pageprops-param-prop": "Listar só esas propiedades. Útil para verificar se unha páxina concreta usa unha propiedade de páxina determinada.",
+       "apihelp-query+pageprops-example-simple": "Obter as propiedades para <kbd>Category:Foo</kbd>.",
        "apihelp-query+pageswithprop-description": "Mostrar a lista de páxinas que empregan unha propiedade determinada.",
+       "apihelp-query+pageswithprop-param-propname": "Propiedade de páxina pola que enumerar as páxinas.",
+       "apihelp-query+pageswithprop-param-prop": "Que información incluír:\n;ids:Engade o ID da páxina.\n;title:Engade o título e o ID do espazo de nomes da páxina.\n;value:Engade o valor da propiedade da páxina.",
+       "apihelp-query+pageswithprop-param-limit": "Máximo número de páxinas a retornar.",
+       "apihelp-query+pageswithprop-param-dir": "En que dirección ordenar.",
+       "apihelp-query+pageswithprop-example-simple": "Lista as dez primeiras páxinas que usan  <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+       "apihelp-query+pageswithprop-example-generator": "Obter a infomación de páxina das dez primeiras páxinas que usan <code>_&#95;NOTOC_&#95;</code>.",
+       "apihelp-query+prefixsearch-description": "Facer unha busca de prefixo nos títulos das páxinas.",
        "apihelp-query+prefixsearch-param-search": "Buscar texto.",
        "apihelp-query+prefixsearch-param-namespace": "Espazo de nomes no que buscar.",
        "apihelp-query+prefixsearch-param-limit": "Número máximo de resultados a visualizar.",
        "apihelp-query+prefixsearch-param-offset": "Número de resultados a saltar.",
+       "apihelp-query+prefixsearch-example-simple": "Buscar títulos de páxina que comecen con <kbd>meaning</kbd>.",
+       "apihelp-query+protectedtitles-description": "Listar todos os títulos protexidos en creación.",
        "apihelp-query+protectedtitles-param-namespace": "Só listar títulos nestes espazos de nomes.",
        "apihelp-query+protectedtitles-param-level": "Só listar títulos con estos niveis de protección.",
        "apihelp-query+protectedtitles-param-limit": "Número total de páxinas a devolver.",
+       "apihelp-query+protectedtitles-param-start": "Comezar a listar neste selo de tempo de protección.",
+       "apihelp-query+protectedtitles-param-end": "Rematar de listar neste selo de tempo de protección.",
+       "apihelp-query+protectedtitles-param-prop": "Que propiedades obter:\n;timestamp:Engade o selo de tempo de cando se fixo a protección.\n;user:Engade o usuario que fixo a protección.\n;userid:Engade o ID do usuario que fixo a protección.\n;comment:Engade o comentario da protección.\n;parsedcomment:Engade o comentario analizado da protección.\n;expiry:Engade o selo de tempo no que rematará a protección\n;level:Engade o nivel de protección.",
        "apihelp-query+protectedtitles-example-simple": "Listar títulos protexidos",
        "apihelp-query+protectedtitles-example-generator": "Atopar ligazóns ós títulos protexidos no espazo de nomes principal",
+       "apihelp-query+querypage-description": "Obtén unha lista proporcionada por unha páxina especial basada en QueryPage.",
        "apihelp-query+querypage-param-page": "Nome da páxina especial. Teña en conta que diferencia entre maiúsculas e minúsculas.",
        "apihelp-query+querypage-param-limit": "Número de resultados a visualizar.",
        "apihelp-query+querypage-example-ancientpages": "Resultados devoltos de [[Special:Ancientpages]].",
        "apihelp-query+random-param-namespace": "Devolver páxinas só neste espazo de nomes.",
        "apihelp-query+random-param-limit": "Limitar cantas páxinas aleatorias se van devolver.",
+       "apihelp-query+random-param-redirect": "Cargar unha redirección aleatoria no canto dunha páxina aleatoria.",
+       "apihelp-query+random-example-simple": "Obter dúas páxinas aleatorias do espazo de nomes principal.",
+       "apihelp-query+random-example-generator": "Obter a información da páxina de dúas páxinas aleatorias do espazo de nomes principal.",
        "apihelp-query+recentchanges-description": "Enumerar cambios recentes.",
        "apihelp-query+recentchanges-param-start": "Selo de tempo para comezar a enumeración.",
        "apihelp-query+recentchanges-param-end": "Selo de tempo para rematar a enumeración.",
+       "apihelp-query+recentchanges-param-namespace": "Filtrar os cambios a só eses espazos de nomes.",
        "apihelp-query+recentchanges-param-user": "Só listar cambios deste usuario.",
        "apihelp-query+recentchanges-param-excludeuser": "Non listar cambios deste usuario.",
        "apihelp-query+recentchanges-param-tag": "Só listar cambios marcados con esta etiqueta.",
+       "apihelp-query+recentchanges-param-token": "Usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> no canto diso.",
+       "apihelp-query+recentchanges-param-show": "Só mostrar elementos que cumpran esos criterios. Por exemplo, para ver só edicións menores feitas por usuarios conectados, activar $1show=minor|!anon.",
        "apihelp-query+recentchanges-param-limit": "Número total de páxinas a devolver.",
        "apihelp-query+recentchanges-param-type": "Que tipos de cambios mostrar.",
        "apihelp-query+recentchanges-param-toponly": "Listar só cambios que son a última revisión.",
        "apihelp-query+recentchanges-example-simple": "Listar cambios recentes.",
+       "apihelp-query+recentchanges-example-generator": "Obter a información de páxina sobre cambios recentes sen vixiancia.",
+       "apihelp-query+redirects-description": "Devolve todas as redireccións das páxinas indicadas.",
+       "apihelp-query+redirects-param-prop": "Que propiedades recuperar:\n;pageid:ID de páxina de cada redirección.\n;title:Título de cada redirección.\n;fragment:Fragmento de cada redirección, se hai algún.",
        "apihelp-query+redirects-param-namespace": "Só incluir páxinas nestes espacios de nomes.",
+       "apihelp-query+redirects-param-limit": "Cantos redireccións devolver.",
+       "apihelp-query+redirects-param-show": "Só mostrar elementos que cumpran estos criterios:\n;fragment:Só mostrar redireccións que teñan un fragmento.\n;!fragment:Só mostrar redireccións que non teñan un fragmento.",
        "apihelp-query+redirects-example-simple": "Obter unha lista de redireccións á [[Main Page]]",
        "apihelp-query+redirects-example-generator": "Obter información sobre tódalas redireccións á [[Main Page]]",
+       "apihelp-query+revisions-paraminfo-singlepageonly": "Só pode usarse cunha única páxina (mode #2).",
+       "apihelp-query+revisions-param-startid": "Desde que ID de revisión comezar a enumeración.",
+       "apihelp-query+revisions-param-endid": "Rematar a enumeración de revisión neste ID de revisión.",
+       "apihelp-query+revisions-param-start": "Desde que selo de tempo comezar a enumeración.",
+       "apihelp-query+revisions-param-end": "Enumerar desde este selo de tempo.",
        "apihelp-query+revisions-param-user": "Só incluir revisión feitas polo usuario.",
        "apihelp-query+revisions-param-excludeuser": "Excluír revisións feitas polo usuario.",
        "apihelp-query+revisions-param-tag": "Só listar revisións marcadas con esta etiqueta.",
+       "apihelp-query+revisions-param-token": "Que identificadores obter para cada revisión.",
+       "apihelp-query+revisions-example-content": "Obter datos con contido da última revisión dos títulos <kbd>API</kbd> e <kbd>Main Page</kbd>.",
        "apihelp-query+revisions-example-last5": "Mostrar as cinco últimas revisión da <kbd>Páxina Principal</kbd>.",
        "apihelp-query+revisions-example-first5": "Mostar as cinco primeiras revisións da <kbd>Páxina Principal</kbd>.",
        "apihelp-query+revisions-example-first5-after": "Mostrar as cinco primeiras revisións da <kbd>Páxina Principal</kbd> feitas despois de 2006-05-01.",
        "apihelp-query+revisions-example-first5-not-localhost": "Mostrar as cinco primeiras revisións da <kbd>Páxina Principal</kbd> que non foron feitas polo usuario anónimo <kbd>127.0.0.1</kbd>.",
        "apihelp-query+revisions-example-first5-user": "Mostrar as cinco primeiras revisión da <kbd>Páxina Principal</kbd> feitas polo usuario <kbd>MediaWiki default</kbd>.",
        "apihelp-query+revisions+base-param-limit": "Limitar cantas revisións se van devolver.",
+       "apihelp-query+revisions+base-param-expandtemplates": "Expandir os modelos no contido da revisión (require $1prop=content).",
+       "apihelp-query+revisions+base-param-generatexml": "Xenerar a árbore de análise XML para o contido da revisión (require $1prop=content).",
+       "apihelp-query+revisions+base-param-parse": "Analizar o contido da revisión (require $1prop=content). Por razóns de rendemento, se se usa esta opción, $1limit cámbiase a 1.",
+       "apihelp-query+revisions+base-param-section": "Recuperar unicamente o contido deste número de sección.",
+       "apihelp-query+revisions+base-param-diffto": "ID de revisión a comparar con cada revisión. Use <kbd>prev</kbd>, <kbd>next</kbd> e <kbd>cur</kbd> para a versión precedente, seguinte e actual respectivamente.",
+       "apihelp-query+revisions+base-param-difftotext": "Texto co que comparar cada revisión. Só compara un número limitado de revisións. Ignora <var>$1diffto</var>.  Se <var>$1section</var> ten valor, só se comparará co texto esa sección.",
+       "apihelp-query+revisions+base-param-contentformat": "Formato de serialización usado por <var>$1difftotext</var> e esperado para a saída do contido.",
        "apihelp-query+search-description": "Facer unha busca por texto completo.",
        "apihelp-query+search-param-search": "Buscar tódolos títulos de páxina (ou contido) que teñan este valor.",
        "apihelp-query+search-param-namespace": "Buscar só nestes espazos de nomes.",
        "apihelp-query+search-param-info": "Que metadatos devolver.",
        "apihelp-query+search-param-limit": "Número total de páxinas a devolver.",
        "apihelp-query+search-param-interwiki": "Incluir na busca resultados de interwikis, se é posible.",
+       "apihelp-query+search-param-backend": "Que servidor de busca usar, se non se indica usa o que hai por defecto.",
        "apihelp-query+search-example-simple": "Buscar por <kbd>significado</kbd>.",
        "apihelp-query+search-example-text": "Buscar texto por <kbd>significado</kbd>.",
+       "apihelp-query+search-example-generator": "Obter información da páxina sobre as páxinas devoltas por unha busca por <kbd>significado</kbd>.",
        "apihelp-query+siteinfo-description": "Devolver información xeral sobre o sitio.",
+       "apihelp-query+siteinfo-param-filteriw": "Só devolver entradas locais ou só non locais da correspondencia interwiki.",
+       "apihelp-query+siteinfo-param-showalldb": "Listar todos os servidores de base de datos, non só o que teña máis retardo.",
        "apihelp-query+siteinfo-param-numberingroup": "Listar o número de usuarios nos grupos de usuarios.",
+       "apihelp-query+siteinfo-param-inlanguagecode": "Código de lingua para os nomes de lingua localizados (a mellor forma posible) e nomes de presentación.",
+       "apihelp-query+siteinfo-example-simple": "Obter información do sitio.",
+       "apihelp-query+siteinfo-example-interwiki": "Obter unha lista de prefixos interwiki locais.",
+       "apihelp-query+siteinfo-example-replag": "Revisar o retardo de replicación actual.",
+       "apihelp-query+stashimageinfo-description": "Devolve a información dos ficheiros almacenados.",
+       "apihelp-query+stashimageinfo-param-filekey": "Clave que identifica unha subida precedente e que foi almacenada temporalmente.",
+       "apihelp-query+stashimageinfo-param-sessionkey": "Alias para $1filekey, para compatibilidade con versións antigas.",
+       "apihelp-query+stashimageinfo-example-simple": "Devolve a información dun ficheiro almacenado.",
+       "apihelp-query+stashimageinfo-example-params": "Devolve as miniaturas de dous ficheiros almacenados.",
+       "apihelp-query+tags-description": "Lista de marcas de cambios.",
        "apihelp-query+tags-param-limit": "Máximo número de etiquetas a listar.",
        "apihelp-query+tags-example-simple": "Listar as marcas dispoñibles",
+       "apihelp-query+templates-description": "Devolve todas as páxinas incluídas na páxina indicada.",
        "apihelp-query+templates-param-namespace": "Mostrar modelos só neste espazo de nomes.",
        "apihelp-query+templates-param-limit": "Número de modelos a devolver.",
+       "apihelp-query+templates-param-templates": "Listar só eses modelos. Útil para verificar se unha páxina concreta ten un modelo determinado.",
        "apihelp-query+templates-param-dir": "Dirección na cal listar.",
        "apihelp-query+templates-example-simple": "Coller os modelos usado na <kbd>Páxina Principal</kbd>.",
        "apihelp-query+templates-example-generator": "Obter información sobre os modelos usados na <kbd>Páxina Principal</kbd>.",
        "apihelp-query+templates-example-namespaces": "Obter páxinas nos espazos de nomes {{ns:user}} e {{ns:template}} que se transclúen na <kbd>Páxina Principal</kbd>.",
+       "apihelp-query+tokens-description": "Recupera os identificadores das accións de modificación de datos.",
+       "apihelp-query+tokens-param-type": "Tipos de identificadores a consultar.",
+       "apihelp-query+tokens-example-simple": "Recuperar un identificador csrf (por defecto).",
+       "apihelp-query+tokens-example-types": "Recuperar un identificador vixiancia e un de patrulla.",
+       "apihelp-query+transcludedin-description": "Atopar todas as páxinas que inclúen ás páxinas indicadas.",
+       "apihelp-query+transcludedin-param-prop": "Que propiedades obter:\n;pageid:ID de páxina de cada páxina.\n;title:Título de cada páxina.\n;redirect:Marca si a páxina é unha redirección.",
        "apihelp-query+transcludedin-param-namespace": "Só incluir páxinas nestes espacios de nomes.",
        "apihelp-query+transcludedin-param-limit": "Cantos mostrar.",
+       "apihelp-query+transcludedin-param-show": "Mostrar só elementos que cumpren estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
+       "apihelp-query+transcludedin-example-simple": "Obter unha lista de páxinas que inclúen a <kbd>Main Page</kbd>.",
+       "apihelp-query+transcludedin-example-generator": "Obter información sobre as páxinas que inclúen <kbd>Main Page</kbd>.",
        "apihelp-query+usercontribs-description": "Mostrar tódalas edicións dun usuario.",
        "apihelp-query+usercontribs-param-limit": "Máximo número de contribucións a mostar.",
+       "apihelp-query+usercontribs-param-start": "Selo de tempo de comezo ó que volver.",
+       "apihelp-query+usercontribs-param-end": "Selo de tempo de fin ó que volver.",
+       "apihelp-query+usercontribs-param-user": "Usuarios para os que recuperar as contribucións.",
+       "apihelp-query+usercontribs-param-userprefix": "Recuperar as contribucións de todos os usuarios cuxo nome comece por este valor. Ignora $1user.",
        "apihelp-query+usercontribs-param-namespace": "Só listar contribucións nestes espazos de nomes.",
        "apihelp-query+usercontribs-param-tag": "Só listar revisións marcadas con esta etiqueta.",
        "apihelp-query+usercontribs-param-toponly": "Listar só cambios que son a última revisión.",
        "apihelp-query+userinfo-example-data": "Obter información adicional sobre o usuario actual.",
        "apihelp-query+users-description": "Obter información sobre unha lista de usuarios.",
        "apihelp-query+users-param-users": "Lista de usuarios para os que obter información.",
+       "apihelp-query+users-param-token": "Usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> no canto diso.",
        "apihelp-query+users-example-simple": "Mostar información para o usuario <kbd>Exemplo</kbd>.",
+       "apihelp-query+watchlist-description": "Ver os cambios recentes das páxinas na lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlist-param-allrev": "Incluír múltiples revisións da mesma páxina dentro do intervalo de tempo indicado.",
        "apihelp-query+watchlist-param-start": "Selo de tempo para comezar a enumeración",
        "apihelp-query+watchlist-param-end": "Selo de tempo para rematar a enumeración.",
+       "apihelp-query+watchlist-param-namespace": "Filtrar os cambios a só os espazos de nomes indicados.",
        "apihelp-query+watchlist-param-user": "Só listar cambios deste usuario.",
        "apihelp-query+watchlist-param-excludeuser": "Non listar cambios deste usuario.",
        "apihelp-query+watchlist-param-limit": "Cantos resultados totais mostrar por petición.",
+       "apihelp-query+watchlist-param-show": "Só mostrar elementos que cumpran esos criterios. Por exemplo, para ver só edicións menores feitas por usuarios conectados, activar $1show=minor|!anon.",
+       "apihelp-query+watchlist-param-type": "Que tipos de cambios mostrar:\n;edit:Modificacións normais de páxina.\n;external:Modificacións externas.\n;new:Creación de páxinas.\n;log:Entradas no rexistro.",
+       "apihelp-query+watchlist-param-owner": "Usado con $1token para acceder á lista de páxinas de vixiancia doutro usuario.",
+       "apihelp-query+watchlist-param-token": "Identificador de seguridade (dispoñible nas [[Special:Preferences#mw-prefsection-watchlist|preferencias]] de usuario) para permitir o acceso a outros á súa páxina de vixiancia.",
+       "apihelp-query+watchlist-example-simple": "Listar a última revisión das páxinas recentemente modificadas da lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlist-example-props": "Buscar información adicional sobre a última revisión das páxinas modificadas recentemente da lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlist-example-allrev": "Buscar a información sobre todos os cambios recentes das páxinas da lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlist-example-generator": "Buscar a información de páxina das páxinas cambiadas recentemente da lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlist-example-generator-rev": "Buscar a información da revisión dos cambios recentes de páxinas na lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlist-example-wlowner": "Listar a última revisión das páxinas cambiadas recentemente da lista de vixiancia do usuario <kbd>Example</kbd>.",
+       "apihelp-query+watchlistraw-description": "Obter todas as páxinas da lista de vixiancia do usuario actual.",
        "apihelp-query+watchlistraw-param-namespace": "Só listar páxinas nestes espazos de nomes.",
        "apihelp-query+watchlistraw-param-limit": "Cantos resultados totais mostrar por petición.",
+       "apihelp-query+watchlistraw-param-prop": "Que propiedades adicionais obter:\n;changed:Engade o selo de tempo da última notificación ó usuario dunha modificación.",
        "apihelp-query+watchlistraw-param-show": "Só listar os elementos que cumplen estos criterios.",
+       "apihelp-query+watchlistraw-param-owner": "Usado con $1token para acceder á lista de páxinas de vixiancia doutro usuario.",
+       "apihelp-query+watchlistraw-param-token": "Identificador de seguridade (dispoñible nas [[Special:Preferences#mw-prefsection-watchlist|preferencias]] de usuario) para permitir o acceso a outros á súa páxina de vixiancia.",
        "apihelp-query+watchlistraw-example-simple": "Listar páxinas na lista de vixiancia do usuario actual.",
+       "apihelp-query+watchlistraw-example-generator": "Buscar a información de páxina das páxinas da lista de vixiancia do usuario actual.",
        "apihelp-revisiondelete-description": "Borrar e restaurar revisións.",
+       "apihelp-revisiondelete-param-type": "Tipo de borrado de revisión a ser tratada.",
+       "apihelp-revisiondelete-param-target": "Título de páxina para o borrado da revisión, se requerido para o tipo.",
+       "apihelp-revisiondelete-param-ids": "Identificadores para as revisións a ser  borradas.",
        "apihelp-revisiondelete-param-hide": "Que ocultar para cada revisión.",
        "apihelp-revisiondelete-param-show": "Que mostrar para cada revisión.",
+       "apihelp-revisiondelete-param-suppress": "Eliminar os datos dos administradores así coma dos doutros.",
        "apihelp-revisiondelete-param-reason": "Razón para o borrado ou restaurado.",
        "apihelp-revisiondelete-example-revision": "Ocultar contido para revisión <kbd>12345</kbd> na <kbd>Páxina Principal</kbd>.",
+       "apihelp-revisiondelete-example-log": "Ocultar todos os datos da entrada de rexistro <kbd>67890</kbd> coa razón <kbd>BLP violation</kbd>.",
+       "apihelp-rollback-description": "Desfacer a última modificación da páxina.\n\nSe o último usuario que modificou a páxina fixo varias modificacións nunha fila, desfaranse todas.",
+       "apihelp-rollback-param-title": "Título da páxina a desfacer. Non pode usarse xunto con <var>$1pageid</var>.",
+       "apihelp-rollback-param-pageid": "ID da páxina a desfacer. Non pode usarse xunto con <var>$1title</var>.",
+       "apihelp-rollback-param-user": "Nome do usuario cuxas modificacións van a desfacerse.",
+       "apihelp-rollback-param-summary": "Personalizar o resumo de edición. Se está baleiro, usarase o resumo por defecto.",
        "apihelp-rollback-param-markbot": "Marcar as edicións revertidas e a reversión como edicións de bot.",
+       "apihelp-rollback-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
        "apihelp-rollback-example-simple": "Desfacer as últimas edicións á <kbd>Páxina Principal</kbd> do usuario <kbd>Exemplo</kbd>.",
+       "apihelp-rollback-example-summary": "Desfacer as últimas edicións á páxina <kbd>Main Page</kbd> polo usuario da dirección IP <kbd>192.0.2.5</kbd> co resumo de edición <kbd>Revertindo vandalismo</kbd>, marcar esas edicións e a reversión como edicións de bot.",
+       "apihelp-rsd-description": "Exportar un esquema RSD (Really Simple Discovery, Descubrimento Moi Simple).",
+       "apihelp-rsd-example-simple": "Exportar o esquema RSD.",
        "apihelp-setnotificationtimestamp-param-entirewatchlist": "Traballar en tódalas páxinas vixiadas.",
        "apihelp-setnotificationtimestamp-example-all": "Restaurar o estado de notificación para toda a páxina de vixiancia",
        "apihelp-setnotificationtimestamp-example-page": "Restaurar o estado de notificación para a <kbd>Páxina Principal</kbd>.",
index 6552dc4..fcc7f7b 100644 (file)
@@ -5,7 +5,8 @@
                        "Amire80",
                        "Inkbug",
                        "Danny-w",
-                       "YaronSh"
+                       "YaronSh",
+                       "ערן"
                ]
        },
        "apihelp-main-param-action": "איזו פעולה לבצע.",
@@ -40,6 +41,7 @@
        "apihelp-delete-param-watch": "הוספת העמוד לרשימת המעקב של המשתמש הנוכחי.",
        "apihelp-delete-param-unwatch": "הסרת הדף מרשימת המעקב של של המשתמש הנוכחי.",
        "apihelp-delete-example-simple": "מחיקת הדף הראשי",
+       "apihelp-edit-param-text": "תוכן הדף.",
        "apihelp-edit-param-minor": "עריכה משנית.",
        "apihelp-edit-example-edit": "עריכת דף",
        "apihelp-emailuser-description": "שליחת דוא\"ל למשתמש.",
        "apihelp-feedcontributions-param-deletedonly": "הצגת תרומות שנמחקו בלבד.",
        "apihelp-feedcontributions-param-toponly": "הצגת עריכות שהן הגרסה העדכנית ביותר בלבד.",
        "apihelp-feedcontributions-example-simple": "החזרת תרומות עבור המשתמש <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-param-hideminor": "הסתרת שינוים משניים.",
+       "apihelp-feedrecentchanges-param-hidebots": "הסתרת שינויים שנעשו על ידי בוטים.",
+       "apihelp-feedrecentchanges-param-hideanons": "הסתרת שינויים שנעשו על ידי אנונימים.",
+       "apihelp-feedrecentchanges-param-hideliu": "הסתרת שינויים שנעשו על ידי משתמשים רשומים.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "הסתרת שינויים שנבדקו.",
+       "apihelp-feedrecentchanges-param-hidemyself": "הסתרת שינוים שנעשו על ידי המשתמש הנוכחי.",
        "apihelp-feedrecentchanges-param-tagfilter": "סינון לפי תגית.",
+       "apihelp-feedrecentchanges-param-target": "הצגת שינויים שנעשו בדפים המקושרים לדף זה בלבד.",
+       "apihelp-feedrecentchanges-example-simple": "הצגת שינויים אחרונים.",
+       "apihelp-feedrecentchanges-example-30days": "הצגת שינויים אחרונים עבור 30 ימים.",
        "apihelp-help-description": "הצגת עזרה עבור היחידות שצוינו.",
        "apihelp-help-param-helpformat": "תסדיר פלט העזרה.",
        "apihelp-help-param-toc": "לכלול תוכן עניינים בפלט HTML.",
index 218d24c..085113d 100644 (file)
@@ -2,9 +2,11 @@
        "@metadata": {
                "authors": [
                        "Beta16",
-                       "Nivit"
+                       "Nivit",
+                       "Toadino2"
                ]
        },
+       "apihelp-block-description": "Blocca  un utente.",
        "apihelp-query+recentchanges-example-simple": "Elenco modifiche recenti.",
        "apihelp-upload-example-url": "Carica da un URL.",
        "api-help-parameters": "{{PLURAL:$1|Parametro|Parametri}}:",
index e4e25a3..72816b9 100644 (file)
@@ -7,7 +7,8 @@
                        "Mar(c)",
                        "Valhallasw",
                        "Sikjes",
-                       "Macofe"
+                       "Macofe",
+                       "SPQRobin"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentatie]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-maillijst]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aankondigingen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & verzoeken]\n</div>\n<strong>Status:</strong> Alle functies die op deze pagina worden weergegeven horen te werken. Aan de API wordt actief gewerkt, en deze kan gewijzigd worden. Abonneer u op  de [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-maillijst mediawiki-api-announce] voor meldingen over aanpassingen.\n\n<strong>Foutieve verzoeken:</strong> als de API foutieve verzoeken ontvangt, wordt er geantwoord met een HTTP-header met de sleutel \"MediaWiki-API-Error\" en daarna worden de waarde van de header en de foutcode op dezelfde waarde ingesteld. Zie [[mw:API:Errors_and_warnings|API: Errors and warnings]] voor meer informatie.",
@@ -24,6 +25,7 @@
        "apihelp-block-param-reason": "Reden voor blokkade.",
        "apihelp-block-param-autoblock": "Blokkeer automatisch het laatst gebruikte IP-adres en ieder volgend IP-adres van waaruit ze proberen in te loggen.",
        "apihelp-block-param-reblock": "De huidige blokkade aanpassen als de gebruiker al geblokkeerd is.",
+       "apihelp-createaccount-param-name": "Gebruikersnaam.",
        "apihelp-delete-description": "Verwijder een pagina.",
        "apihelp-delete-example-simple": "Verwijder <kbd>Hoofdpagina</kbd>.",
        "apihelp-delete-example-reason": "Verwijder <kbd>Hoofdpagina</kbd> met als reden <kbd>Voorbereiding voor verplaatsing</kbd>.",
index 3f5084d..3ecb7a5 100644 (file)
        "apihelp-parse-param-onlypst": "{{doc-apihelp-param|parse|onlypst}}",
        "apihelp-parse-param-effectivelanglinks": "{{doc-apihelp-param|parse|effectivelanglinks}}",
        "apihelp-parse-param-section": "{{doc-apihelp-param|parse|section}}",
+       "apihelp-parse-param-sectiontitle": "{{doc-apihelp-param|parse|sectiontitle}}",
        "apihelp-parse-param-disablepp": "{{doc-apihelp-param|parse|disablepp}}",
        "apihelp-parse-param-disableeditsection": "{{doc-apihelp-param|parse|disableeditsection}}",
        "apihelp-parse-param-generatexml": "{{doc-apihelp-param|parse|generatexml|params=* $1 - Value of the constant CONTENT_MODEL_WIKITEXT|paramstart=2}}",
index 1d9ee33..bf3a25b 100644 (file)
@@ -68,7 +68,7 @@ class JsonContent extends TextContent {
         * @return string
         */
        public function beautifyJSON() {
-               return FormatJson::encode( $this->getData()->getValue(), true );
+               return FormatJson::encode( $this->getData()->getValue(), true, FormatJson::UTF8_OK );
        }
 
        /**
index 0b51972..ed86bab 100644 (file)
@@ -29,8 +29,11 @@ class DatabaseSqlite extends DatabaseBase {
        /** @var bool Whether full text is enabled */
        private static $fulltextEnabled = null;
 
+       /** @var string Directory */
+       protected $dbDir;
+
        /** @var string File name for SQLite database file */
-       public $mDatabaseFile;
+       protected $dbPath;
 
        /** @var string Transaction mode */
        protected $trxMode;
@@ -49,30 +52,61 @@ class DatabaseSqlite extends DatabaseBase {
 
        /**
         * Additional params include:
-        *   - trxMode : one of (deferred, immediate, exclusive)
+        *   - dbDirectory : directory containing the DB and the lock file directory
+        *                   [defaults to $wgSQLiteDataDir]
+        *   - dbFilePath  : use this to force the path of the DB file
+        *   - trxMode     : one of (deferred, immediate, exclusive)
         * @param array $p
         */
        function __construct( array $p ) {
                global $wgSharedDB, $wgSQLiteDataDir;
 
-               $this->mDBname = $p['dbname'];
-               parent::__construct( $p );
-               // parent doesn't open when $user is false, but we can work with $dbName
-               if ( $p['dbname'] && !$this->isOpen() ) {
-                       if ( $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ) ) {
-                               if ( $wgSharedDB ) {
-                                       $this->attachDatabase( $wgSharedDB );
+               $this->dbDir = isset( $p['dbDirectory'] ) ? $p['dbDirectory'] : $wgSQLiteDataDir;
+
+               if ( isset( $p['dbFilePath'] ) ) {
+                       $this->mFlags = isset( $p['flags'] ) ? $p['flags'] : 0;
+                       // Standalone .sqlite file mode
+                       $this->openFile( $p['dbFilePath'] );
+                       // @FIXME: clean up base constructor so this can call super instead
+                       $this->mTrxAtomicLevels = new SplStack;
+               } else {
+                       $this->mDBname = $p['dbname'];
+                       // Stock wiki mode using standard file names per DB
+                       parent::__construct( $p );
+                       // parent doesn't open when $user is false, but we can work with $dbName
+                       if ( $p['dbname'] && !$this->isOpen() ) {
+                               if ( $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ) ) {
+                                       if ( $wgSharedDB ) {
+                                               $this->attachDatabase( $wgSharedDB );
+                                       }
                                }
                        }
                }
 
                $this->trxMode = isset( $p['trxMode'] ) ? strtoupper( $p['trxMode'] ) : null;
-               if ( $this->trxMode && !in_array( $this->trxMode, array( 'IMMEDIATE', 'EXCLUSIVE' ) ) ) {
+               if ( $this->trxMode &&
+                       !in_array( $this->trxMode, array( 'DEFERRED', 'IMMEDIATE', 'EXCLUSIVE' ) )
+               ) {
                        $this->trxMode = null;
                        wfWarn( "Invalid SQLite transaction mode provided." );
                }
 
-               $this->lockMgr = new FSLockManager( array( 'lockDirectory' => "$wgSQLiteDataDir/locks" ) );
+               $this->lockMgr = new FSLockManager( array( 'lockDirectory' => "{$this->dbDir}/locks" ) );
+       }
+
+       /**
+        * @param string $filename
+        * @param array $p Options map; supports:
+        *   - flags       : (same as __construct counterpart)
+        *   - trxMode     : (same as __construct counterpart)
+        *   - dbDirectory : (same as __construct counterpart)
+        * @return DatabaseSqlite
+        * @since 1.25
+        */
+       public static function newStandaloneInstance( $filename, array $p = array() ) {
+               $p['dbFilePath'] = $filename;
+
+               return new self( $p );
        }
 
        /**
@@ -103,10 +137,8 @@ class DatabaseSqlite extends DatabaseBase {
         * @return PDO
         */
        function open( $server, $user, $pass, $dbName ) {
-               global $wgSQLiteDataDir;
-
                $this->close();
-               $fileName = self::generateFileName( $wgSQLiteDataDir, $dbName );
+               $fileName = self::generateFileName( $this->dbDir, $dbName );
                if ( !is_readable( $fileName ) ) {
                        $this->mConn = false;
                        throw new DBConnectionError( $this, "SQLite database not accessible" );
@@ -123,10 +155,10 @@ class DatabaseSqlite extends DatabaseBase {
         * @throws DBConnectionError
         * @return PDO|bool SQL connection or false if failed
         */
-       function openFile( $fileName ) {
+       protected function openFile( $fileName ) {
                $err = false;
 
-               $this->mDatabaseFile = $fileName;
+               $this->dbPath = $fileName;
                try {
                        if ( $this->mFlags & DBO_PERSISTENT ) {
                                $this->mConn = new PDO( "sqlite:$fileName", '', '',
@@ -156,6 +188,14 @@ class DatabaseSqlite extends DatabaseBase {
                return false;
        }
 
+       /**
+        * @return string SQLite DB file path
+        * @since 1.25
+        */
+       public function getDbFilePath() {
+               return $this->dbPath;
+       }
+
        /**
         * Does not actually close the connection, just destroys the reference for GC to do its work
         * @return bool
@@ -206,8 +246,7 @@ class DatabaseSqlite extends DatabaseBase {
                $cachedResult = false;
                $table = 'dummy_search_test';
 
-               $db = new DatabaseSqliteStandalone( ':memory:' );
-
+               $db = self::newStandaloneInstance( ':memory:' );
                if ( $db->query( "CREATE VIRTUAL TABLE $table USING FTS3(dummy_field)", __METHOD__, true ) ) {
                        $cachedResult = 'FTS3';
                }
@@ -223,14 +262,13 @@ class DatabaseSqlite extends DatabaseBase {
         * @param string $name Database name to be used in queries like
         *   SELECT foo FROM dbname.table
         * @param bool|string $file Database file name. If omitted, will be generated
-        *   using $name and $wgSQLiteDataDir
+        *   using $name and configured data directory
         * @param string $fname Calling function name
         * @return ResultWrapper
         */
        function attachDatabase( $name, $file = false, $fname = __METHOD__ ) {
-               global $wgSQLiteDataDir;
                if ( !$file ) {
-                       $file = self::generateFileName( $wgSQLiteDataDir, $name );
+                       $file = self::generateFileName( $this->dbDir, $name );
                }
                $file = $this->addQuotes( $file );
 
@@ -863,11 +901,9 @@ class DatabaseSqlite extends DatabaseBase {
        }
 
        public function lock( $lockName, $method, $timeout = 5 ) {
-               global $wgSQLiteDataDir;
-
-               if ( !is_dir( "$wgSQLiteDataDir/locks" ) ) { // create dir as needed
-                       if ( !is_writable( $wgSQLiteDataDir ) || !mkdir( "$wgSQLiteDataDir/locks" ) ) {
-                               throw new DBError( "Cannot create directory \"$wgSQLiteDataDir/locks\"." );
+               if ( !is_dir( "{$this->dbDir}/locks" ) ) { // create dir as needed
+                       if ( !is_writable( $this->dbDir ) || !mkdir( "{$this->dbDir}/locks" ) ) {
+                               throw new DBError( "Cannot create directory \"{$this->dbDir}/locks\"." );
                        }
                }
 
@@ -961,23 +997,6 @@ class DatabaseSqlite extends DatabaseBase {
        }
 } // end DatabaseSqlite class
 
-/**
- * This class allows simple acccess to a SQLite database independently from main database settings
- * @ingroup Database
- */
-class DatabaseSqliteStandalone extends DatabaseSqlite {
-       public function __construct( $fileName, $flags = 0 ) {
-               global $wgSQLiteDataDir;
-
-               $this->mTrxAtomicLevels = new SplStack;
-               $this->lockMgr = new FSLockManager( array( 'lockDirectory' => "$wgSQLiteDataDir/locks" ) );
-
-               $this->mFlags = $flags;
-               $this->tablePrefix( null );
-               $this->openFile( $fileName );
-       }
-}
-
 /**
  * @ingroup Database
  */
index 8765407..0f00540 100644 (file)
@@ -56,7 +56,7 @@ class HTMLRadioField extends HTMLFormField {
 
                                $html .= ' ' . Html::rawElement(
                                        'div',
-                                       array( 'class' => 'mw-htmlform-flatlist-item' ),
+                                       array( 'class' => 'mw-htmlform-flatlist-item mw-ui-radio' ),
                                        $radio
                                );
                        }
index 1e7e969..f990ddf 100644 (file)
@@ -55,7 +55,7 @@ class SqliteInstaller extends DatabaseInstaller {
        public function checkPrerequisites() {
                $result = Status::newGood();
                // Bail out if SQLite is too old
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                if ( version_compare( $db->getServerVersion(), self::MINIMUM_VERSION, '<' ) ) {
                        $result->fatal( 'config-outdated-sqlite', $db->getServerVersion(), self::MINIMUM_VERSION );
                }
index 995b809..436fed8 100644 (file)
@@ -48,6 +48,10 @@ class BlockLogFormatter extends LogFormatter {
 
                $subtype = $this->entry->getSubtype();
                if ( $subtype === 'block' || $subtype === 'reblock' ) {
+                       if ( !isset( $params[4] ) ) {
+                               // Very old log entry without duration: means infinite
+                               $params[4] = 'infinite';
+                       }
                        // Localize the duration, and add a tooltip
                        // in English to help visitors from other wikis.
                        // The lrm is needed to make sure that the number
index b09fe76..9e06ee2 100644 (file)
@@ -25,7 +25,7 @@
  * @brief Set options of the Parser
  *
  * All member variables are supposed to be private in theory, although in
- * practise this is not the case.
+ * practice this is not the case.
  *
  * @ingroup Parser
  */
index 5b18e72..52e860c 100644 (file)
@@ -142,8 +142,8 @@ class ExtensionRegistry {
                foreach ( $info['globals'] as $key => $val ) {
                        if ( !isset( $GLOBALS[$key] ) || !$GLOBALS[$key] ) {
                                $GLOBALS[$key] = $val;
-                       } elseif ( $key === 'wgHooks' ) {
-                               // Special case $wgHooks, which requires a recursive merge.
+                       } elseif ( $key === 'wgHooks' || $key === 'wgExtensionCredits' ) {
+                               // Special case $wgHooks and $wgExtensionCredits, which require a recursive merge.
                                // Ideally it would have been taken care of in the first if block though.
                                $GLOBALS[$key] = array_merge_recursive( $GLOBALS[$key], $val );
                        } elseif ( $key === 'wgGroupPermissions' ) {
index 31d679a..f9d1e8a 100644 (file)
@@ -356,6 +356,7 @@ class SpecialPage {
                if ( $this->getConfig()->get( 'UseMediaWikiUIEverywhere' ) ) {
                        $out->addModuleStyles( array(
                                'mediawiki.ui.input',
+                               'mediawiki.ui.radio',
                                'mediawiki.ui.checkbox',
                        ) );
                }
index 08b8761..74b1f7b 100644 (file)
@@ -101,7 +101,10 @@ class SpecialAllPages extends IncludableSpecialPage {
                $t = $this->getPageTitle();
 
                $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
-               $out .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $this->getConfig()->get( 'Script' ) ) );
+               $out .= Xml::openElement(
+                       'form',
+                       array( 'method' => 'get', 'action' => $this->getConfig()->get( 'Script' ) )
+               );
                $out .= Html::hidden( 'title', $t->getPrefixedText() );
                $out .= Xml::openElement( 'fieldset' );
                $out .= Xml::element( 'legend', null, $this->msg( 'allpages' )->text() );
index 674cbc8..eca307d 100644 (file)
@@ -141,7 +141,8 @@ class SpecialChangeEmail extends FormSpecialPage {
                        # Notify user that a confirmation email has been sent...
                        $this->getOutput()->wrapWikiMsg( "<div class='error' style='clear: both;'>\n$1\n</div>",
                                'eauthentsent', $this->getUser()->getName() );
-                       $this->getOutput()->addReturnTo( $titleObj, wfCgiToArray( $query ) ); // just show the link to go back
+                       // just show the link to go back
+                       $this->getOutput()->addReturnTo( $titleObj, wfCgiToArray( $query ) );
                }
        }
 
index 7e3bd8f..e9639e1 100644 (file)
@@ -240,9 +240,13 @@ HTML;
                        'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false',
                ) );
 
-               $styles = $out->makeResourceLoaderLink( 'jquery.qunit', ResourceLoaderModule::TYPE_STYLES, false );
+               $styles = $out->makeResourceLoaderLink(
+                       'jquery.qunit', ResourceLoaderModule::TYPE_STYLES, false
+               );
                // Use 'raw' since this is a plain HTML page without ResourceLoader
-               $scripts = $out->makeResourceLoaderLink( 'jquery.qunit', ResourceLoaderModule::TYPE_SCRIPTS, false, array( 'raw' => 'true' ) );
+               $scripts = $out->makeResourceLoaderLink(
+                       'jquery.qunit', ResourceLoaderModule::TYPE_SCRIPTS, false, array( 'raw' => 'true' )
+               );
 
                $head = trim( $styles['html'] . $scripts['html'] );
                $html = <<<HTML
index 9315eb8..44a2c34 100644 (file)
@@ -97,7 +97,10 @@ class SpecialLog extends SpecialPage {
                        }
                } else {
                        // Allow extensions to add relations to their search types
-                       Hooks::run( 'SpecialLogAddLogSearchRelations', array( $opts->getValue( 'type' ), $this->getRequest(), &$qc ) );
+                       Hooks::run(
+                               'SpecialLogAddLogSearchRelations',
+                               array( $opts->getValue( 'type' ), $this->getRequest(), &$qc )
+                       );
                }
 
                # Some log types are only for a 'User:' title but we might have been given
index 2e67e2b..5a67d92 100644 (file)
@@ -102,7 +102,10 @@ class SpecialPrefixindex extends SpecialAllPages {
         */
        protected function namespacePrefixForm( $namespace = NS_MAIN, $from = '' ) {
                $out = Xml::openElement( 'div', array( 'class' => 'namespaceoptions' ) );
-               $out .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $this->getConfig()->get( 'Script' ) ) );
+               $out .= Xml::openElement(
+                       'form',
+                       array( 'method' => 'get', 'action' => $this->getConfig()->get( 'Script' ) )
+               );
                $out .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
                $out .= Xml::openElement( 'fieldset' );
                $out .= Xml::element( 'legend', null, $this->msg( 'allpages' )->text() );
index efb870b..64b0eca 100644 (file)
@@ -252,7 +252,9 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                return $rows;
        }
 
-       protected function runMainQueryHook( &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) {
+       protected function runMainQueryHook( &$tables, &$fields, &$conds,
+               &$query_options, &$join_conds, $opts
+       ) {
                return parent::runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts )
                        && Hooks::run(
                                'SpecialRecentChangesQuery',
@@ -311,7 +313,9 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                        $rc = RecentChange::newFromRow( $obj );
                        $rc->counter = $counter++;
                        # Check if the page has been updated since the last visit
-                       if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) && !empty( $obj->wl_notificationtimestamp ) ) {
+                       if ( $this->getConfig()->get( 'ShowUpdatedMarker' )
+                               && !empty( $obj->wl_notificationtimestamp )
+                       ) {
                                $rc->notificationtimestamp = ( $obj->rc_timestamp >= $obj->wl_notificationtimestamp );
                        } else {
                                $rc->notificationtimestamp = false; // Default
@@ -732,7 +736,8 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
                        $link = $this->makeOptionsLink( $linkMessage->text(),
                                array( $key => 1 - $options[$key] ), $nondefaults );
-                       $links[] = "<span class=\"$msg rcshowhideoption\">" . $this->msg( $msg )->rawParams( $link )->escaped() . '</span>';
+                       $links[] = "<span class=\"$msg rcshowhideoption\">"
+                               . $this->msg( $msg )->rawParams( $link )->escaped() . '</span>';
                }
 
                // show from this onward link
index 1bafc61..0d44d34 100644 (file)
@@ -61,10 +61,11 @@ class SpecialRunJobs extends UnlistedSpecialPage {
 
                $squery = $params;
                unset( $squery['signature'] );
-               $cSig = self::getQuerySignature( $squery, $this->getConfig()->get( 'SecretKey' ) ); // correct signature
-               $rSig = $params['signature']; // provided signature
+               $correctSignature = self::getQuerySignature( $squery, $this->getConfig()->get( 'SecretKey' ) );
+               $providedSignature = $params['signature'];
 
-               $verified = is_string( $rSig ) && hash_equals( $cSig, $rSig );
+               $verified = is_string( $providedSignature )
+                       && hash_equals( $correctSignature, $providedSignature );
                if ( !$verified || $params['sigexpiry'] < time() ) {
                        header( "HTTP/1.0 400 Bad Request" );
                        print 'Invalid or stale signature provided';
index 4a92bb9..87e7063 100644 (file)
@@ -250,7 +250,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
                // make a curl call to the scaler to create a thumbnail
                $httpOptions = array(
                        'method' => 'GET',
-                       'timeout' => 'default'
+                       'timeout' => 5 // T90599 attempt to time out cleanly
                );
                $req = MWHttpRequest::factory( $scalerThumbUrl, $httpOptions, __METHOD__ );
                $status = $req->execute();
index a7365bb..c1a9593 100644 (file)
@@ -515,7 +515,10 @@ class SpecialVersion extends SpecialPage {
                        array( 'id' => 'mw-version-libraries' ),
                        $this->msg( 'version-libraries' )->text()
                );
-               $out .= Html::openElement( 'table', array( 'class' => 'wikitable plainlinks', 'id' => 'sv-libraries' ) );
+               $out .= Html::openElement(
+                       'table',
+                       array( 'class' => 'wikitable plainlinks', 'id' => 'sv-libraries' )
+               );
                $out .= Html::openElement( 'tr' )
                        . Html::element( 'th', array(), $this->msg( 'version-libraries-library' )->text() )
                        . Html::element( 'th', array(), $this->msg( 'version-libraries-version' )->text() )
@@ -528,7 +531,11 @@ class SpecialVersion extends SpecialPage {
                                continue;
                        }
                        $out .= Html::openElement( 'tr' )
-                               . Html::rawElement( 'td', array(), Linker::makeExternalLink( "https://packagist.org/packages/$name", $name ) )
+                               . Html::rawElement(
+                                       'td',
+                                       array(),
+                                       Linker::makeExternalLink( "https://packagist.org/packages/$name", $name )
+                               )
                                . Html::element( 'td', array(), $info['version'] )
                                . Html::closeElement( 'tr' );
                }
@@ -588,11 +595,15 @@ class SpecialVersion extends SpecialPage {
 
                $fhooks = $wgParser->getFunctionHooks();
                if ( count( $fhooks ) ) {
-                       $out = Html::rawElement( 'h2', array( 'class' => 'mw-headline plainlinks' ), Linker::makeExternalLink(
-                               '//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Parser_functions',
-                               $this->msg( 'version-parser-function-hooks' )->parse(),
-                               false /* msg()->parse() already escapes */
-                       ) );
+                       $out = Html::rawElement(
+                               'h2',
+                               array( 'class' => 'mw-headline plainlinks' ),
+                               Linker::makeExternalLink(
+                                       '//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Parser_functions',
+                                       $this->msg( 'version-parser-function-hooks' )->parse(),
+                                       false /* msg()->parse() already escapes */
+                               )
+                       );
 
                        $out .= $this->listToText( $fhooks );
                } else {
index 28be790..40cce5e 100644 (file)
@@ -152,7 +152,9 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        $conds['pagelinks'][] = 'rd_from is NOT NULL';
                }
 
-               $queryFunc = function ( $dbr, $table, $fromCol ) use ( $conds, $target, $limit, $useLinkNamespaceDBFields ) {
+               $queryFunc = function ( $dbr, $table, $fromCol ) use (
+                       $conds, $target, $limit, $useLinkNamespaceDBFields
+               ) {
                        // Read an extra row as an at-end check
                        $queryLimit = $limit + 1;
                        $on = array(
@@ -278,7 +280,11 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
 
                        if ( $row->rd_from && $level < 2 ) {
                                $out->addHTML( $this->listItem( $row, $nt, $target, true ) );
-                               $this->showIndirectLinks( $level + 1, $nt, $this->getConfig()->get( 'MaxRedirectLinksRetrieved' ) );
+                               $this->showIndirectLinks(
+                                       $level + 1,
+                                       $nt,
+                                       $this->getConfig()->get( 'MaxRedirectLinksRetrieved' )
+                               );
                                $out->addHTML( Xml::closeElement( 'li' ) );
                        } else {
                                $out->addHTML( $this->listItem( $row, $nt, $target ) );
index 1f639fc..9cf8cab 100644 (file)
@@ -167,7 +167,7 @@ class AutoloadGenerator {
                        <<<EOD
 <?php
 // This file is generated by $commandName, do not adjust manually
-
+// @codingStandardsIgnoreFile
 global \${$this->variableName};
 
 \${$this->variableName} {$op} array(
index 424ec85..b202e20 100644 (file)
@@ -13,7 +13,7 @@
        "tog-newpageshidepatrolled": "خبي الباجات المعسوسه اللي في ليستت الباجات الجدد",
        "tog-extendwatchlist": "دلّي الليستة تاع التتباع باش تورّي كامل التبديلات، ماشي برك غير التوالا",
        "tog-usenewrc": "جمّع الـتبدالات بل صفحة فل تبدالات الـجديدة و الـليستة تاع الـعسّة",
-       "tog-numberheadings": "رÙ\82Ù\85 Ø§Ù\84Ù\8aا Ø¹Ù\86اÙ\88Ù\8aÙ\86 Ø§Ù\84سÙ\83سÙ\8aÙ\88",
+       "tog-numberheadings": "رÙ\82Ù\91Ù\85 Ø§Ù\84عÙ\84اÙ\88Ù\86 ØªØ§Ø¹ Ø§Ù\84Ù\82سÙ\8aÙ\85ات",
        "tog-showtoolbar": "بيّن البارّة تاع دوزان‘ الكتبة",
        "tog-editondblclick": "آكتيفي التبدال تاع الباجات بل زوج ضركات تاع الفارة",
        "tog-editsectiononrightclick": "آكتيفي التبدال تاع السكسيوّات بل ضريك بل ليمنة على العلاوين نتاعهم",
        "showpreview": "بين معاينة",
        "showdiff": "عرض التبديلات",
        "anoneditwarning": "'''توله:''' راك ما دخلتش.\nغادي يتسجل لادراس آيبي نتاعك في تاريخ هذه الباجه.",
+       "loginreqlink": "اتكونيكتا",
        "newarticle": "(جديد)",
        "newarticletext": "راك تبعت وصيلة لباجه لم ما تخدمتش بعد.\nباش تصنع هاذ الباجه ابدا الكتبه فالصندوق التحت (شوف في [$1  زياده باجه المساعده] لمعلومات).\nإذا كانت زيارتك لهاذ الباجه غلطه، ادرك على بوطون''ولى'' في نافيقاتور الإنترنت نتاعك.",
        "noarticletext": "لحد الساعه ما كانش حتى نص في هاذ الباجه.\nتقدرو [[Special:Search/{{PAGENAME}}|ترميو تفتيشه على هاذ العنوان]] فالباجات لخرين,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} فتش فالعمليات المربوطه]\nو إلا[{{fullurl:{{FULLPAGENAME}}|action=edit}} أصنع هاذ الباجه]</span>.",
        "newuserlogpage": "ريجيستر صنعة حسابات المستخدمين",
        "action-edit": "عدل هاذ الباجه",
        "nchanges": "$1 تبديله{{PLURAL:$1||s}}",
+       "enhancedrc-history": "تاريخ",
        "recentchanges": "تبديلات توالا",
        "recentchanges-legend": "ابسيون التبديلات التواله",
        "recentchanges-feed-description": "تبع التبديلات الجدد للويكي في هاذ التيار .",
        "rcnotefrom": "هاهي التبديلات  من'''$2''' (ل'''$1''' معروضه).",
        "rclistfrom": "بين التبديلات البديه من $3 $2",
        "rcshowhideminor": "$1 التبديلات الصغير",
+       "rcshowhideminor-hide": "خبّي",
        "rcshowhidebots": "$1 البوتات",
+       "rcshowhidebots-show": "ورّي",
        "rcshowhideliu": "$1 المستخدمين المسجلين",
+       "rcshowhideliu-hide": "خبّي",
        "rcshowhideanons": "$1 المستخدمين المجهولين",
+       "rcshowhideanons-hide": "خبّي",
        "rcshowhidepatr": "$1 التبديلات المعسوسه",
        "rcshowhidemine": "$1 تبديلات نتاعي",
+       "rcshowhidemine-hide": "خبّي",
        "rclinks": "بين آخر $1 تبديل في آخر $2 يوم<br />$3",
        "diff": "إختلاف",
        "hist": "تاريخ",
        "minoreditletter": "ط",
        "newpageletter": "ج‌",
        "boteditletter": "ب",
-       "rc-change-size-new": "$1 {{PLURAL:$1|بايت|بايت}} بعد التبديله",
+       "rc-change-size-new": "$1 {{PLURAL:$1|octet|octets}} مورا التبدال",
        "rc-enhanced-expand": "بين التفاصيل (يلزمها جافاسكريبت)",
        "rc-enhanced-hide": "خبي التفاصيل",
        "recentchangeslinked": "تبديلات مربوطه",
        "linkstoimage": "{{PLURAL:$1|الباجة توصل|ال$1 باجات يوصلو}} لهاذ الملف :",
        "nolinkstoimage": "ما كانش باجات موصوله لهاذ الفيشي.",
        "sharedupload-desc-here": "هاذ الملف جاي من $1. يمكن يكون مستعمل من بروجيات وحد أخرين.\nالتوصيف نتاعو في [$2 باجت الصفات] محطوطه هنا لتحت.",
+       "upload-disallowed-here": "ما تنحمش تعدّل هاد التصويرة",
        "randompage": "باجة على الزهر",
        "statistics": "إحصاويّات",
        "nbytes": "{{PLURAL:$1|بايت 1|$1 بايت}}",
index 280bcd7..f8e0831 100644 (file)
        "createaccounterror": "Немагчыма стварыць рахунак: $1",
        "nocookiesnew": "Рахунак быў створаны, але ў сыстэму Вы не ўвайшлі.\n{{SITENAME}} выкарыстоўвае файлы-кукі для ўваходу ў сыстэму.\nУ Вашым браўзэры файлы-кукі адключаныя.\nКалі ласка, дазвольце іх, а потым ўвайдзіце з новым іменем удзельніка і паролем.",
        "nocookieslogin": "{{SITENAME}} выкарыстоўвае файлы-кукі для ўваходу ў сыстэму.\nУ Вашым браўзэры файлы-кукі адключаныя.\nКалі ласка, уключыце іх і паспрабуйце яшчэ раз.",
-       "nocookiesfornew": "Рахунак удзельніка ня быў створаны, таму што мы не змаглі пацьвердзіць яго крыніцу. \nУпэўніце, што ў Вас уключаныя закладкі (cookies), перазагрузіце гэтую старонку і паспрабуйце зноў.",
+       "nocookiesfornew": "Рахунак удзельніка ня быў створаны, таму што мы не змаглі пацьвердзіць яго крыніцу. \nУпэўніцеся, што ў Вас уключаныя файлы-кукі, перазагрузіце гэтую старонку і паспрабуйце зноў.",
        "noname": "Вы пазначылі няслушнае імя ўдзельніка.",
        "loginsuccesstitle": "Пасьпяховы ўваход у сыстэму",
        "loginsuccess": "'''Цяпер Вы ўвайшлі ў {{GRAMMAR:вінавальны|{{SITENAME}}}} як «$1».'''",
index 3e7f22c..c13ccd3 100644 (file)
@@ -46,7 +46,8 @@
                        "ESM",
                        "Loupeter",
                        "Macofe",
-                       "Gerardduenas"
+                       "Gerardduenas",
+                       "Medol"
                ]
        },
        "tog-underline": "Subratlla els enllaços:",
index 51dc29a..31ada1b 100644 (file)
@@ -95,7 +95,7 @@
        "tog-watchrollback": "Seiten, bei denen ich eine Zurücksetzung durchgeführt habe, automatisch beobachten",
        "tog-minordefault": "Eigene Änderungen standardmäßig als geringfügig markieren",
        "tog-previewontop": "Vorschau oberhalb des Bearbeitungsfensters anzeigen",
-       "tog-previewonfirst": "Beim ersten Bearbeiten immer die Vorschau anzeigen",
+       "tog-previewonfirst": "Vorschau beim ersten Bearbeiten immer anzeigen",
        "tog-enotifwatchlistpages": "Bei Änderungen an beobachteten Seiten oder Dateien E-Mails senden",
        "tog-enotifusertalkpages": "Bei Änderungen an meiner Benutzer-Diskussionsseite E-Mails senden",
        "tog-enotifminoredits": "Auch bei kleinen Änderungen an Seiten und Dateien E-Mails senden",
index ac57a2d..888ce8b 100644 (file)
        "page_last": "últimas",
        "histlegend": "Selección de diferencias: marca las casillas correspondientes a las versiones a comparar y pulsa Intro o el botón de abajo.<br />\nLeyenda: <strong>(act)</strong> = diferencias con la versión actual,\n<strong>(ant)</strong> = diferencias con la versión anterior, <strong>m</strong> = edición menor",
        "history-fieldset-title": "Buscar en el historial",
-       "history-show-deleted": "Solo ediciones ocultadas",
+       "history-show-deleted": "Solo eliminadas",
        "histfirst": "primeras",
        "histlast": "últimas",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
        "prefs-editwatchlist-edit": "Ver y quitar los títulos de tu lista de seguimiento",
        "prefs-editwatchlist-raw": "Editar tu lista de seguimiento en modo texto",
        "prefs-editwatchlist-clear": "Limpiar tu lista de seguimiento",
-       "prefs-watchlist-days": "Número de días a mostrar en la lista de seguimiento:",
+       "prefs-watchlist-days": "Número de días que mostrar en la lista de seguimiento:",
        "prefs-watchlist-days-max": "Máximo $1 {{PLURAL:$1|día|días}}",
        "prefs-watchlist-edits": "Número máximo de ediciones que mostrar en la lista expandida:",
        "prefs-watchlist-edits-max": "Cantidad máxima: 1000",
        "prefs-email": "Opciones de correo electrónico",
        "prefs-rendering": "Apariencia",
        "saveprefs": "Guardar",
-       "restoreprefs": "Restaurar la configuración predeterminada",
+       "restoreprefs": "Restaurar la configuración predeterminada (en todas las secciones)",
        "prefs-editing": "Edición",
        "rows": "Filas:",
        "columns": "Columnas:",
        "searchresultshead": "Búsquedas",
        "stub-threshold": "Límite para cambiar a formato de <a href=\"#\" class=\"stub\">enlace a esbozo</a> (en bytes):",
        "stub-threshold-disabled": "Desactivado",
-       "recentchangesdays": "Días que mostrar en Cambios recientes:",
-       "recentchangesdays-max": "(máximo {{PLURAL:$1|un día|$1 días}})",
+       "recentchangesdays": "Días que mostrar en los cambios recientes:",
+       "recentchangesdays-max": "Máximo {{PLURAL:$1|un día|$1 días}}",
        "recentchangescount": "N.º de ediciones que mostrar de manera predeterminada:",
-       "prefs-help-recentchangescount": "Esto incluye cambios recientes, historiales de página, y registros.",
+       "prefs-help-recentchangescount": "Esto incluye cambios recientes, historiales de páginas y registros.",
        "prefs-help-watchlist-token2": "Esta es la clave secreta del canal de suscripción de tu lista de seguimiento.\nCualquier persona que la conozca podría leer tu lista, así que no la compartas.\n[[Special:ResetTokens|Pulsa aquí si necesitas restablecerla]].",
        "savedprefs": "Se han guardado tus preferencias.",
        "timezonelegend": "Huso horario:",
        "feedback-bugornote": "Si estás preparado para describir en detalle un problema técnico, [$1 informa de un bug] por favor.\n\nEn otro caso, puedes usar el siguiente formulario. Tu comentario será añadido a la página [$3 $2], junto con tu nombre de usuario y el navegador que usas.",
        "feedback-cancel": "Cancelar",
        "feedback-close": "Hecho",
+       "feedback-external-bug-report-button": "Enviar una tarea técnica",
        "feedback-dialog-title": "Enviar comentarios",
+       "feedback-dialog-intro": "Puedes usar el formulario sencillo debajo para enviar tus comentarios. Ellos se agregarán a la página \"$1\", junto con tu nombre de usuario.",
        "feedback-error-title": "Error",
        "feedback-error1": "Error: No se reconoce resultado de API",
        "feedback-error2": "Error: Falló la edición",
        "feedback-message": "Mensaje:",
        "feedback-subject": "Asunto:",
        "feedback-submit": "Enviar",
+       "feedback-terms": "Entiendo que la información de mi agente de usuario incluye información sobre la versión exacta de mi navegador y mi sistema operativo y serán compartidos públicamente junto a mis comentarios.",
+       "feedback-termsofuse": "Acepto proporcionar comentarios de acuerdo con los Términos de uso.",
        "feedback-thanks": "¡Gracias! Su comentario ha sido anotado en la página [$2  $1].",
        "feedback-thanks-title": "¡Muchas gracias!",
+       "feedback-useragent": "Agente de usuario:",
        "searchsuggest-search": "Buscar",
        "searchsuggest-containing": "que contiene...",
        "api-error-badaccess-groups": "No puedes cargar archivos en este wiki.",
index 52b97a4..8557f6a 100644 (file)
        "ipblocklist-localblock": "Kohalik blokeering",
        "ipblocklist-otherblocks": "{{PLURAL:$1|Muu blokeering|Muud blokeeringud}}",
        "infiniteblock": "igavene",
-       "expiringblock": "aegub $1 $2",
+       "expiringblock": "aegumistähtaeg $1, $2",
        "anononlyblock": "ainult nimetuna",
        "noautoblockblock": "IP-aadressi ei blokita automaatselt",
        "createaccountblock": "kontode loomine keelatud",
index 39bdfe7..8ab187f 100644 (file)
        "revdelete-uname-unhid": "käyttäjätunnus palautettu näkyviin",
        "revdelete-restricted": "asetti rajoitukset ylläpitäjille",
        "revdelete-unrestricted": "poisti rajoitukset ylläpitäjiltä",
-       "logentry-block-block": "$1 {{GENDER:$2|esti}} kohteen {{GENDER:$4|$3}}. Eston kesto on $5 $6",
+       "logentry-block-block": "$1 {{GENDER:$2|esti}} käyttäjän {{GENDER:$4|$3}}. Eston kesto on $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|poisti muokkauseston}} käyttäjältä {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|muutti}} eston asetuksia kohteessa {{GENDER:$4|$3}}. Eston kesto on $5 $6",
-       "logentry-suppress-block": "$1 {{GENDER:$2|esti}} kohteen {{GENDER:$4|$3}}. Eston kesto on $5 $6",
+       "logentry-suppress-block": "$1 {{GENDER:$2|esti}} käyttäjän {{GENDER:$4|$3}}. Eston kesto on $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|muutti}} eston asetuksia kohteessa {{GENDER:$4|$3}}. Eston kesto on $5 $6",
        "logentry-merge-merge": "$1 {{GENDER:$2|yhdisti}} sivun $3 sivuun $4 (versiot $5 saakka)",
        "logentry-move-move": "$1 {{GENDER:$2|siirsi}} sivun $3 uudelle nimelle $4",
index 27e5925..fb8da8a 100644 (file)
@@ -56,7 +56,8 @@
                        "रोहित रावत",
                        "아라",
                        "संजीव कुमार",
-                       "बिप्लब आनन्द"
+                       "बिप्लब आनन्द",
+                       "Phoenix303"
                ]
        },
        "tog-underline": "कड़ियाँ अधोरेखन:",
        "disclaimers": "अस्वीकरण",
        "disclaimerpage": "Project:साधारण अस्वीकरण",
        "edithelp": "सम्पादन सहायता",
+       "helppage-top-gethelp": "सहायता",
        "mainpage": "मुखपृष्ठ",
        "mainpage-description": "मुखपृष्ठ",
        "policy-url": "Project:नीति",
index cd0f35a..fe0e5ae 100644 (file)
        "mergehistory-reason": "Պատճառ՝",
        "revertmerge": "Անջատել",
        "history-title": "«$1» էջի փոփոխումների պատմություն",
-       "difference-title": "$1: Խմբագրումների տարբերություն",
+       "difference-title": "«$1»–ի խմբագրումների տարբերություն",
        "difference-title-multipage": "$1 և $2: Խմբագրումների տարբերություն",
        "difference-multipage": "(Էջերի տարերություն)",
        "lineno": "Տող  $1.",
        "file-info-size": "$1 × $2 փիքսել, նիշքի չափը՝ $3, MIME-տեսակը՝ $4",
        "file-nohires": "Ավելի բարձր կետաչափով տարբերակ չկա։",
        "svg-long-desc": "SVG-նիշք, անվանապես $1 × $2 փիքսել, նիշքի չափը՝ $3",
-       "show-big-image": "Լրիվ թույլատվությամբ",
+       "show-big-image": "Սկզբնական նիշք",
        "show-big-image-preview": "Նախադիտման չափ՝ $1։",
        "show-big-image-size": "$1 × $2 պիքսել",
        "newimages": "Նոր նիշքերի սրահ",
        "metadata-fields": "EXIF մետատվյալների այն դաշտերը, որոնք նշված ենք այս ուղերձի մեջ, կցուցադրվեն պատկերի էջուն լռությամբ։ Այլ տվյալները լռությամբ կթաքցվեն։\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "Լայնք",
        "exif-imagelength": "Բարձրություն",
+       "exif-orientation": "Դիրք",
+       "exif-xresolution": "Հորիզոնական կետաչափ",
+       "exif-yresolution": "Ուղղահայաց կետաչափ",
        "exif-make": "Խցիկի արտադրող",
        "exif-model": "Խցիկի մոդել",
        "exif-software": "Օգտագործված ծրագիր",
        "exif-artist": "Հեղինակ",
        "exif-exifversion": "Էքսիֆի տարբերակ (Exif)",
+       "exif-colorspace": "Գունային տիրույթ",
        "exif-datetimeoriginal": "Ստեղծման ամսաթիվ",
        "exif-datetimedigitized": "Թվայնացման ամսաթիվ",
        "exif-flash": "Ֆլեշ տարբ.",
        "specialpages-group-spam": "Սպամի գործիքներ",
        "blankpage": "Դատարկ էջ",
        "intentionallyblankpage": "Այս էջը միտումնավոր դատարկ է թողված։",
+       "tag-filter": "[[Special:Tags|Պիտակների]] զտիչ՝",
        "tag-filter-submit": "Ֆիլտրել",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Պիտակ}}]]: $2)",
        "tags-source-header": "Աղբյուր",
index cf8bb2f..8bd80fe 100644 (file)
        "edit-gone-missing": "Gat ekki uppfært síðu.\nSvo virðist sem henni hafi verið eytt.",
        "edit-conflict": "Breytingaárekstur.",
        "edit-no-change": "Breyting þín var hunsuð, því engin breyting var á textanum.",
-       "postedit-confirmation-saved": "Breytingin þín var vistuð.",
+       "postedit-confirmation-saved": "Breyting þín hefur verið vistuð.",
        "edit-already-exists": "Gat ekki skapað nýja síðu.\nHún er nú þegar til.",
        "defaultmessagetext": "Sjálfgefinn skilaboða texti",
        "content-failed-to-parse": "Gat ekki þáttað $2 efni samkvæmt $1 líkani: $3",
        "lineno": "Lína $1:",
        "compareselectedversions": "Bera saman valdar útgáfur",
        "showhideselectedversions": "Sýna/fela valdar breytingar",
-       "editundo": "Taka aftur þessa breytingu",
+       "editundo": "afturkalla þessa breytingu",
        "diff-empty": "(Enginn munur)",
        "diff-multi-sameuser": "($1 {{PLURAL:$1|millibreyting ekki sýnd|millibreytingar ekki sýndar}} frá sama notandanum)",
        "diff-multi-manyusers": "($1 {{PLURAL:$1|millibreyting ekki sýnd|millibreytingar ekki sýndar}} frá fleiri en $2 {{PLURAL:$2|notanda|notendum}}.)",
        "tooltip-recreate": "Endurvekja síðuna þó henni hafi verið eytt",
        "tooltip-upload": "Hefja innhleðslu",
        "tooltip-rollback": "\"taka aftur\" breytir greininni til síðasta höfundar með einum smelli",
-       "tooltip-undo": "\"Tek aftur þessa breytingu\" breytir aftur til síðustu breytingu og opnar breytinguna í forskoðun. Hægt er að bæta við ástæðu í breytingarávarpinu.",
+       "tooltip-undo": "„Afturkalla þessa breytingu“ breytir aftur til síðustu breytingu og opnar breytinguna í forskoðun. Hægt er að bæta við ástæðu í breytingarávarpinu.",
        "tooltip-preferences-save": "Vista stillingar",
        "tooltip-summary": "Bættu við stuttu ágripi",
        "common.css": "/* Allt CSS sem sett er hér mun virka á öllum þemum. */",
        "htmlform-int-toohigh": "Gildið sem þú tilgreindir er stærra en hámarkið $1",
        "htmlform-required": "Þú þarft að fylla út þetta gildi.",
        "htmlform-submit": "Senda",
-       "htmlform-reset": "Taka aftur breytingu",
+       "htmlform-reset": "Afturkalla breytingar",
        "htmlform-selectorother-other": "Annað",
        "htmlform-no": "Nei",
        "htmlform-yes": "Já",
index 339045a..4e889f4 100644 (file)
@@ -79,7 +79,8 @@
                        "Laurentius",
                        "Macofe",
                        "Ricordisamoa",
-                       "Horcrux92"
+                       "Horcrux92",
+                       "Toadino2"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "tags-create-invalid-chars": "I nomi dei tag non devono contenere virgole (<code>,</code>) o barre (<code>/</code>).",
        "tags-create-invalid-title-chars": "I nomi dei tag non devono contenere caratteri che non possono essere utilizzati nei titoli delle pagine.",
        "tags-create-already-exists": "Il tag \"$1\" esiste già.",
+       "tags-create-warnings-above": "{{PLURAl:$2|È stato rilevato il seguente pericolo|Sono stati rilevati i seguenti pericoli}} mentre si cercava di creare l'etichetta \"$1\":",
        "tags-create-warnings-below": "Desideri continuare a creare il tag?",
        "tags-delete-title": "Elimina tag",
        "tags-delete-explanation-initial": "Stai per eliminare il tag \"$1\" dal database.",
+       "tags-delete-explanation-in-use": "Verrà rimossa da {{PLURAL:$2|$2 versioni o voce di registro| tutte le $2 versioni e voci di registro}} dove si trova attualmente.",
        "tags-delete-explanation-warning": "Questa azione è <strong>irreversibile</strong> e <strong>non può essere annullata</strong>, nemmeno da amministratori di database. Accertati che questo sia davvero il tag che intendi eliminare.",
+       "tags-delete-explanation-active": "<strong> L'etichetta \"$1\" è ancora attiva, e lo resterà in futuro. </strong> Perché questo smetta, vai alle voci di registro dove l'etichetta è in uso, e disattivala manualmente.",
        "tags-delete-reason": "Motivo:",
        "tags-delete-submit": "Elimina irreversibilmente questo tag",
        "tags-delete-not-allowed": "I tag definiti da un'estensione non possono essere eliminati a meno che ciò non sia specificamente permesso dall'estensione.",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha caricato}} una nuova versione di $3.",
        "logentry-upload-revert": "$1 {{GENDER:$2|ha caricato}} $3",
        "log-name-managetags": "Registro gestione tag",
+       "log-description-managetags": "Questa pagina elenca le azioni di gestione relative alle [[Speciale:Etichette|etichette]]. Il registro contiene solo le azioni effettuate manualmente da un amministratore; le etichette potrebbero essere create o cancellate dal programma wiki senza che ciò venga registrato qui.",
        "logentry-managetags-create": "$1 {{GENERE:$2|ha creato}} il tag \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|ha rimosso}} l'etichetta \"$4\" (da $5 {{PLURAL:$5|versione o voce di registro|versioni o voci di registro}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|ha inserito}} l'etichetta \"$4\" per l'uso da parte d'utenti e bot",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|ha disattivato}} l'etichetta \"$4\" per l'uso da parte d'utenti e bot",
        "rightsnone": "(nessuno)",
        "revdelete-summary": "oggetto della modifica",
        "feedback-adding": "Inserimento del feedback nella pagina...",
        "feedback-bugornote": "Se si è in grado di descrivere il problema tecnico riscontrato in maniera precisa, [$1 segnalate il bug]. In alternativa, si può usare il modulo semplificato sottostante. Il commento inserito sarà aggiunto alla pagina \"[$3 $2]\", insieme al proprio nome utente e al browser in uso.",
        "feedback-cancel": "Annulla",
        "feedback-close": "Fatto",
+       "feedback-external-bug-report-button": "Documenta un problema tecnico",
+       "feedback-dialog-title": "Invia un feedback",
+       "feedback-dialog-intro": "Usa il modulo sottostante per inviare il tuo feedback. Il tuo commento apparirà nella pagina \"$1\", assieme al tuo nome utente.",
        "feedback-error-title": "Errore",
        "feedback-error1": "Errore: Dalla API è arrivato un risultato non riconosciuto",
        "feedback-error2": "Errore: Non è stato possibile eseguire la modifica",
        "feedback-message": "Messaggio:",
        "feedback-subject": "Oggetto:",
        "feedback-submit": "Invia",
+       "feedback-terms": "Sono al corrente del fatto che le mie informazioni sull'user agent includono informazioni riguardanti il mio esatto browser e versione del sistema operativo, che saranno condivise pubblicamente, assieme al mio feedback.",
+       "feedback-termsofuse": "Accetto di fornire feedback conformemente alle Condizioni d'Uso.",
        "feedback-thanks": "Grazie! Il tuo feedback è stato pubblicato alla pagina \"[$2 $1]\".",
        "feedback-thanks-title": "Grazie!",
        "feedback-useragent": "Agente utente:",
index bbb79dd..e7dfc62 100644 (file)
        "summary-preview": "Қысқаша түйіндемесін қарап шығу:",
        "subject-preview": "Тақырыбын/бас жолын қарап шығу:",
        "blockedtitle": "Қатысушы бұғатталған",
-       "blockedtext": "<strong>Қатысушы атыңыз не IP мекенжайыңыз бұғатталған.</strong>\n\n$1 деген әкімші бұғаттаған. \nКелтірілген себебі: <em>$2</em>.\n\n* Бұғаттаудың басталғаны: $8\n* Бұғаттаудың бітетіні: $6\n* Бұғаттау нысанасы: $7\n\nОсы бұғаттауды талқылау үшін $1 не өзге [[{{MediaWiki:Grouppage-sysop}}|әкімшімен]] байланыса аласыз.\n[[Special:Preferences|Тіркелгі бапталымдары]]ңызда жарамды е-пошта мекенжайын көрсетіп және де оны пайдаланудан бұғатталмаған жағдайда ғана «Қатысушыға хат жазу» қызметін қолдана аласыз.\nАғымдық IP мекенжайыңыз: $3, бұғатау нөмірі: #$5.\nСұраным жасағанда осының екеуін де кірістіруіңізді сұраймыз.",
+       "blockedtext": "<strong>Қатысушы атыңыз не IP мекенжайыңыз бұғатталған.</strong>\n\n$1 деген әкімші бұғаттаған. \nКелтірілген себебі: <em>$2</em>.\n\n* Бұғаттаған кезі: $8\n* Бұғаттаудың бітетін кезі: $6\n* Бұғаттау нысанасы: $7\n\nОсы бұғаттауды талқылау үшін $1 не өзге [[{{MediaWiki:Grouppage-sysop}}|әкімшімен]] байланыса аласыз.\n[[Special:Preferences|Тіркелгі бапталымдары]]ңызда жарамды е-пошта мекенжайын көрсетіп және де оны пайдаланудан бұғатталмаған жағдайда ғана «Қатысушыға хат жазу» қызметін қолдана аласыз.\nАғымдық IP мекенжайыңыз: $3, бұғатау нөмірі: #$5.\nСұраным жасағанда осының екеуін де кірістіруіңізді сұраймыз.",
        "autoblockedtext": "IP мекенжайыңыз автоматты бұғатталған, себебі оны басқа қатысушы пайдаланған. Оны $1 есімді әкімші бұғаттаған\n\nКелтірілген себебі: \n:<em>$2</em>\n\n* Бұғаттаудың басталғаны: $8\n* Бұғаттаудың бітетіні: $6\n* Бұғаттау нысанасы: $7\n\nОсы бұғаттауды талқылау үшін $1 не басқа [[{{MediaWiki:Grouppage-sysop}}|әкімшімен]] байланыса аласыз.\n[[Special:Preferences|Тіркелгі бапталымдары]]ңызда жарамды е-пошта мекенжайын көрсеткен болсаңыз және де оны пайдаланудан бұғатталмаған жағдайда ғана «Қатысушыға хат жазу» қызметін қолдана аласыз.\nАғымдық IP мекенжайыңыз: $3, бұғатау нөмірі: $5.\nСұраным жасағанда осының екеуін де кірістіруіңізді сұраймыз.",
        "blockednoreason": "еш себебі келтірілмеген",
        "whitelistedittext": "Беттерді өңдеу үшін $1.",
index e9e3917..3eb6f37 100644 (file)
        "rcshowhidemine-show": "aanzeije",
        "rcshowhidemine-hide": "verschteihsche",
        "rclinks": "Zeisch de läzde {{int:pipe-separator}}$1{{int:pipe-separator}} Änderonge us de läzde {{int:pipe-separator}}$2{{int:pipe-separator}} Däch, un dun {{int:pipe-separator}} $3.",
-       "diff": "Ungerscheid",
+       "diff": "Ongerscheid",
        "hist": "Versione",
        "hide": "Ußblände!",
        "show": "Zeije:",
index 53a2a49..f456f43 100644 (file)
        "undelete-show-file-submit": "Òc",
        "namespace": "Espaci de noms :",
        "invert": "Inversar la seleccion",
+       "tooltip-invert": "Marcatz aquesta casa per amagar las modificacions de las paginas dins l'espaci de noms seleccionat (e l'espaci de noms associat se marcat)",
        "namespace_association": "Espaci de nom associat",
+       "tooltip-namespace_association": "Marcatz aquesta casa per inclure tanben l'espaci de noms de discussion associat a l'espaci de noms seleccionat",
        "blanknamespace": "(Principal)",
        "contributions": "Contribucions de l'{{GENDER:$1|utilizaire|utilizaira}}",
        "contributions-title": "Lista de las contribucions de l’utilizaire $1",
        "thumbnail_gd-library": "Configuracion incompleta de la bibliotèca GD : foncion $1 introbabla",
        "thumbnail_image-missing": "Lo fichièr seguent es introbable : $1",
        "import": "Importar de paginas",
-       "importinterwiki": "Impòrt interwiki",
+       "importinterwiki": "Importar a partir d'un autre wiki",
        "import-interwiki-text": "Seleccionatz un wiki e un títol de pagina d'importar.\nLas datas de las versions e los noms dels editors seràn preservats.\nTotas las accions d’importacion interwiki son conservadas dins lo [[Special:Log/import|jornal d’impòrt]].",
        "import-interwiki-sourcewiki": "Wiki font :",
        "import-interwiki-sourcepage": "Pagina font :",
        "tooltip-pt-mycontris": "Lista de vòstras contribucions",
        "tooltip-pt-login": "Sètz convidat(ada) a vos identificar, mas es pas obligatòri.",
        "tooltip-pt-logout": "Se desconnectar",
+       "tooltip-pt-createaccount": "Vos es conselhat de crear un compte e de vos connectar ; pasmens, es pas obligatòri",
        "tooltip-ca-talk": "Discussion a prepaus d'aquesta pagina",
        "tooltip-ca-edit": "Podètz modificar aquesta pagina. Mercé de previsualizar abans d’enregistrar.",
        "tooltip-ca-addsection": "Començar una seccion novèla",
        "feedback-error3": "Error : pas cap de responsa de l'API",
        "feedback-message": "Messatge :",
        "feedback-subject": "Subjècte :",
-       "feedback-submit": "Mandar vòstres comentaris",
+       "feedback-submit": "Mandar",
        "feedback-thanks": "Mercé ! Vòstre comentari es estat publicat sus la pagina \"[$2 $1]\".",
        "searchsuggest-search": "Recercar",
        "searchsuggest-containing": "que conten...",
index d6bfe9b..8144095 100644 (file)
        "sp-contributions-newbies-sub": "Dla nowych użytkowników",
        "sp-contributions-newbies-title": "Wkład nowych użytkowników",
        "sp-contributions-blocklog": "blokady",
-       "sp-contributions-suppresslog": "stłumiony wkład użytkownika",
+       "sp-contributions-suppresslog": "utajniony wkład użytkownika",
        "sp-contributions-deleted": "usunięty wkład użytkownika",
        "sp-contributions-uploads": "przesłane pliki",
        "sp-contributions-logs": "rejestry",
index 5d4106b..846b3f7 100644 (file)
        "welcomeuser": "Bem-vindo, $1!",
        "welcomecreation-msg": "A sua conta foi criada.\nNão se esqueça de personalizar as suas [[Special:Preferences|preferências no wiki {{SITENAME}}]].",
        "yourname": "Nome de usuário:",
-       "userlogin-yourname": "Nome de usuário",
+       "userlogin-yourname": "Nome de usuário(a)",
        "userlogin-yourname-ph": "Escreva seu nome de usuário",
        "createacct-another-username-ph": "Forneça o nome de usuário",
        "yourpassword": "Senha:",
        "group-suppress": "Oversights",
        "group-all": "(todos)",
        "group-user-member": "{{GENDER:$1|usuário|usuária}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|usuário autoconfirmado|usuária autoconfirmada}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|usuário autoconfirmado|usuária autoconfirmada|usuário(a) autoconfirmado(a)}}",
        "group-bot-member": "robô",
        "group-sysop-member": "{{GENDER:$1|administrador|administradora|administrador(a)}}",
        "group-bureaucrat-member": "burocrata",
index 23cc20a..878be69 100644 (file)
@@ -14,7 +14,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Baba Tabita",
-                       "Rich Farmbrough"
+                       "Rich Farmbrough",
+                       "Kipala"
                ]
        },
        "tog-underline": "Wekea mstari viungo:",
        "rightsnone": "(hana)",
        "revdelete-summary": "muhtasari wa kuhariri",
        "feedback-adding": "Maoni yako yanaongezwa katika ukurasa...",
+       "feedback-back": "Rudi",
        "feedback-cancel": "Batilisha",
        "feedback-close": "Tayari",
+       "feedback-error-title": "Kosa",
        "feedback-error1": "Hitilafu: Matokeo ya API hayafahamiki",
        "feedback-error2": "Hitilafu: Hiririo halikufaulu",
        "feedback-error3": "Hitilafu: API ya wiki haiitiki",
        "feedback-message": "Ujumbe:",
        "feedback-subject": "Mada:",
-       "feedback-submit": "Tuma maoni yako",
+       "feedback-submit": "Wasilisha",
        "feedback-thanks": "Ahsante! Maoni yako yamewekwa kwenye ukurasa wa \"[$2 $1]\".",
+       "feedback-thanks-title": "Asante!",
        "searchsuggest-search": "Kutafuta",
        "searchsuggest-containing": "ya maneno...",
        "api-error-empty-file": "Faili ulilowasilisha ni tupu.",
index 368b6ea..72eb870 100644 (file)
@@ -68,7 +68,8 @@
                        "Aşilleus",
                        "BatuhanBensoy",
                        "Mavrikant",
-                       "Ayrıntılı Bilgi"
+                       "Ayrıntılı Bilgi",
+                       "Gokalpselamet"
                ]
        },
        "tog-underline": "Bağlantıların altını çiz:",
        "rightsnone": "(hiçbiri)",
        "revdelete-summary": "değişiklik özeti",
        "feedback-adding": "Sayfaya geribildirim ekleniyor...",
+       "feedback-back": "Geri",
        "feedback-bugcheck": "Harika! Sadece [bilinen $1 hatalarından] olmadığını kontrol et.",
        "feedback-bugnew": "Kontrol ettim. Yeni hata bildir",
        "feedback-bugornote": "Eğer teknik bir problemi detaylarıyla açıklamaya hazırsanız lütfen [$1 bir hata raporlayın]. Diğer taraftan, aşağıdaki kolay formu kullanabilirsiniz. Yorumunuz, kullanıcı adınızla beraber \"[$3 $2]\" sayfasına eklenecektir.",
index 878593c..43f4b6c 100644 (file)
@@ -33,37 +33,57 @@ class FixUserRegistration extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Fix the user_registration field";
+               $this->setBatchSize( 1000 );
        }
 
        public function execute() {
-               $dbr = wfGetDB( DB_SLAVE );
                $dbw = wfGetDB( DB_MASTER );
 
-               // Get user IDs which need fixing
-               $res = $dbr->select( 'user', 'user_id', 'user_registration IS NULL', __METHOD__ );
-               foreach ( $res as $row ) {
-                       $id = $row->user_id;
-                       // Get first edit time
-                       $timestamp = $dbr->selectField(
-                               'revision',
-                               'MIN(rev_timestamp)',
-                               array( 'rev_user' => $id ),
-                               __METHOD__
+               $lastId = 0;
+               do {
+                       // Get user IDs which need fixing
+                       $res = $dbw->select(
+                               'user',
+                               'user_id',
+                               array(
+                                       'user_id >' . $dbw->addQuotes( $lastId ),
+                                       'user_registration IS NULL'
+                               ),
+                               __METHOD__,
+                               array(
+                                       'LIMIT' => $this->mBatchSize,
+                                       'ORDER BY user_id ASC',
+                               )
                        );
-                       // Update
-                       if ( !empty( $timestamp ) ) {
-                               $dbw->update(
-                                       'user',
-                                       array( 'user_registration' => $timestamp ),
-                                       array( 'user_id' => $id ),
+                       foreach ( $res as $row ) {
+                               $id = $row->user_id;
+                               $lastId = $id;
+                               // Get first edit time
+                               $timestamp = $dbw->selectField(
+                                       'revision',
+                                       'MIN(rev_timestamp)',
+                                       array( 'rev_user' => $id ),
                                        __METHOD__
                                );
-                               $this->output( "$id $timestamp\n" );
-                       } else {
-                               $this->output( "$id NULL\n" );
+                               // Update
+                               if ( $timestamp !== null ) {
+                                       $dbw->update(
+                                               'user',
+                                               array( 'user_registration' => $timestamp ),
+                                               array( 'user_id' => $id ),
+                                               __METHOD__
+                                       );
+                                       $user = User::newFromId( $id );
+                                       $user->invalidateCache();
+                                       $this->output( "Set registration for #$id to $timestamp\n" );
+                               } else {
+                                       $this->output( "Could not find registration for #$id NULL\n" );
+                               }
                        }
-               }
-               $this->output( "\n" );
+                       $this->output( "Waiting for slaves..." );
+                       wfWaitForSlaves();
+                       $this->output( " done.\n" );
+               } while ( $res->numRows() >= $this->mBatchSize );
        }
 }
 
index 5c0fd07..e173190 100644 (file)
@@ -59,7 +59,7 @@ class Sqlite {
                        'blob', // NULL type is omitted intentionally
                ) );
 
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                try {
                        foreach ( $files as $file ) {
                                $err = $db->sourceFile( $file );
index edc9e14..7e02a4b 100644 (file)
@@ -81,7 +81,7 @@ class SqliteMaintenance extends Maintenance {
        }
 
        private function vacuum() {
-               $prevSize = filesize( $this->db->mDatabaseFile );
+               $prevSize = filesize( $this->db->getDbFilePath() );
                if ( $prevSize == 0 ) {
                        $this->error( "Can't vacuum an empty database.\n", true );
                }
@@ -89,7 +89,7 @@ class SqliteMaintenance extends Maintenance {
                $this->output( 'VACUUM: ' );
                if ( $this->db->query( 'VACUUM' ) ) {
                        clearstatcache();
-                       $newSize = filesize( $this->db->mDatabaseFile );
+                       $newSize = filesize( $this->db->getDbFilePath() );
                        $this->output( sprintf( "Database size was %d, now %d (%.1f%% reduction).\n",
                                $prevSize, $newSize, ( $prevSize - $newSize ) * 100.0 / $prevSize ) );
                } else {
@@ -115,7 +115,7 @@ class SqliteMaintenance extends Maintenance {
        private function backup( $fileName ) {
                $this->output( "Backing up database:\n   Locking..." );
                $this->db->query( 'BEGIN IMMEDIATE TRANSACTION', __METHOD__ );
-               $ourFile = $this->db->mDatabaseFile;
+               $ourFile = $this->db->getDbFilePath();
                $this->output( "   Copying database file $ourFile to $fileName... " );
                wfSuppressWarnings( false );
                if ( !copy( $ourFile, $fileName ) ) {
index 182a2c4..6e93011 100755 (executable)
@@ -151,7 +151,7 @@ class UpdateMediaWiki extends Maintenance {
 
                $this->output( "Going to run database updates for " . wfWikiID() . "\n" );
                if ( $db->getType() === 'sqlite' ) {
-                       $this->output( "Using SQLite file: '{$db->mDatabaseFile}'\n" );
+                       $this->output( "Using SQLite file: '{$db->getDbFilePath()}'\n" );
                }
                $this->output( "Depending on the size of your database this may take a while!\n" );
 
index b410898..b0f29d5 100644 (file)
@@ -47,6 +47,9 @@ $wgAutoloadClasses += array(
        'TestUser' => "$testDir/phpunit/includes/TestUser.php",
        'LessFileCompilationTest' => "$testDir/phpunit/LessFileCompilationTest.php",
 
+       # tests/phpunit/includes
+       'TestingAccessWrapper' => "$testDir/phpunit/includes/TestingAccessWrapper.php",
+
        # tests/phpunit/includes/api
        'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php",
        'ApiQueryTestBase' => "$testDir/phpunit/includes/api/query/ApiQueryTestBase.php",
index 17769ad..e18c22b 100644 (file)
@@ -593,6 +593,14 @@ class ParserTest {
                        }
                }
 
+               if ( isset( $opts['tidy'] ) ) {
+                       if ( !$this->tidySupport->isEnabled() ) {
+                               return $this->showSkipped();
+                       } else {
+                               $options->setTidy( true );
+                       }
+               }
+
                if ( isset( $opts['title'] ) ) {
                        $titleText = $opts['title'];
                } else {
@@ -624,10 +632,6 @@ class ParserTest {
                        $output->setTOCEnabled( !isset( $opts['notoc'] ) );
                        $out = $output->getText();
                        if ( isset( $opts['tidy'] ) ) {
-                               if ( !$this->tidySupport->isEnabled() ) {
-                                       return $this->showSkipped();
-                               }
-                               $out = MWTidy::tidy( $out );
                                $out = preg_replace( '/\s+$/', '', $out );
                        }
 
@@ -877,10 +881,7 @@ class ParserTest {
                        'wgDisableLangConversion' => false,
                        'wgDisableTitleConversion' => false,
                        // Tidy options.
-                       // We always set 'wgUseTidy' to false when parsing, but certain
-                       // test-running modes still use tidy if available, so ensure
-                       // that the tidy-related options are all set to their defaults.
-                       'wgUseTidy' => false,
+                       'wgUseTidy' => isset( $opts['tidy'] ),
                        'wgAlwaysUseTidy' => false,
                        'wgDebugTidy' => false,
                        'wgTidyConf' => $IP . '/includes/tidy.conf',
index 966b666..36a7872 100644 (file)
@@ -69,6 +69,12 @@ Template:pipe
 |
 !! endarticle
 
+!! article
+Template:=
+!! text
+<nowiki>=</nowiki>
+!! endarticle
+
 !!article
 MediaWiki:bad image list
 !!text
@@ -126,6 +132,19 @@ Template:table_attribs_2
 |Bar||Baz
 !! endarticle
 
+!! article
+Template:table_attribs_3
+!! text
+<noinclude>
+|</noinclude>style{{=}}"background:&#35;f9f9f9;"|Foo
+!! endarticle
+
+!! article
+Template:table_attribs_4
+!! text
+| style="background-color:#DC241f;" width="10px" |
+!! endarticle
+
 !! article
 Template:table_header_cells
 !! text
@@ -154,6 +173,13 @@ style="color:red;" title="T48811"
 |foo
 !! endarticle
 
+!! article
+Template:definition_list
+!! text
+one
+::two
+!! endarticle
+
 !! article
 A?b
 !! text
@@ -1209,6 +1235,8 @@ Ruby markup (W3C-style)
 !! test
 Non-word characters don't terminate tag names (bug 17663, 40670, 52022)
 !! wikitext
+<blockquote|>a</blockquote>
+
 <b→> doesn't terminate </b→>
 
 <bä> doesn't terminate </bä>
@@ -1219,7 +1247,8 @@ Non-word characters don't terminate tag names (bug 17663, 40670, 52022)
 
 <sub-ID#1>
 !! html
-<p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;
+<p>&lt;blockquote|&gt;a&lt;/blockquote&gt;
+</p><p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;
 </p><p>&lt;bä&gt; doesn't terminate &lt;/bä&gt;
 </p><p>&lt;boo&gt; doesn't terminate &lt;/boo&gt;
 </p><p>&lt;s.foo&gt; doesn't terminate &lt;/s.foo&gt;
@@ -1228,9 +1257,13 @@ Non-word characters don't terminate tag names (bug 17663, 40670, 52022)
 !! end
 
 # There is a tidy bug here: http://sourceforge.net/p/tidy/bugs/946/
+# If the non-word-character tag made it through the sanitizer, tidy
+# would munge it up.
 !! test
 Non-word characters don't terminate tag names + tidy
 !! wikitext
+<blockquote|>a</blockquote>
+
 <b→> doesn't terminate </b→>
 
 <bä> doesn't terminate </bä>
@@ -1241,6 +1274,7 @@ Non-word characters don't terminate tag names + tidy
 
 <sub-ID#1>
 !! html+tidy
+<p>&lt;blockquote|&gt;a</p>
 <p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;</p>
 <p>&lt;bä&gt; doesn't terminate &lt;/bä&gt;</p>
 <p>&lt;boo&gt; doesn't terminate &lt;/boo&gt;</p>
@@ -1248,16 +1282,33 @@ Non-word characters don't terminate tag names + tidy
 <p>&lt;sub-ID#1&gt;</p>
 !! end
 
+###
+### See tests/parser/parserTestsParserHook.php for the <tåg> extension)
+### This checks that HTML5 tags (with non-word characters in the tag
+### name) make it safely through the parser -- the Sanitizer will
+### munge them later, as it should.
+###
+!! test
+Non-word characters are valid in extension tags (T19663)
+!! wikitext
+<tåg>tåg</tåg>
+!! html
+<pre>
+'tåg'
+array (
+)
+</pre>
+
+!! end
+
 !! test
 Isolated close tags should be treated as literal text (bug 52760)
 !! wikitext
 </b>
 
 <s.foo>s</s>
-!! html
-<p>&lt;/b&gt;
-</p><p>&lt;s.foo&gt;s&lt;/s&gt;
-</p>
+!! html+tidy
+<p>&lt;s.foo&gt;s</p>
 !! end
 
 ###
@@ -1366,6 +1417,64 @@ parsoid=html2wt
 <nowiki>* &lt;/nowiki&gt;</nowiki> tag
 !! end
 
+!! test
+T71950: 1. Put nowiki as close to cause as possible, even with non-quote escapable chars
+!! options
+parsoid=html2wt
+!! html
+<p>This text: L'<a rel="mw:WikiLink" href="./Foo">Foo</a>
+This text: L''<a rel="mw:WikiLink" href="./Foo">Foo</a>
+This text: L'''<a rel="mw:WikiLink" href="./Foo">Foo</a>''</p>
+!! wikitext
+This text: L'[[Foo]]
+This text: L<nowiki>''</nowiki>[[Foo]]
+This text: L<nowiki>'''</nowiki>[[Foo]]<nowiki>''</nowiki>
+!! end
+
+# This test fails because wikitext whitespace is not normalized before comparing.
+!! test
+T71950: 2. Put nowiki as close to cause as possible, after ' :'
+!! options
+parsoid=html2wt
+!! html
+<p>This text : L''<a rel="mw:WikiLink" href="./Foo">Foo</a>
+</p>
+!! wikitext
+This text : L<nowiki>''</nowiki>[[Foo]]
+!! end
+
+# This test and the next one are html2wt only as they test that incorrect wikitext
+# passed in template arguments gets escaped or wrapped in nowikis where required.
+!! test
+T71482: Use {{!}} instead of nowiki for single pipe in template argument
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo|bar&quot;}},&quot;i&quot;:0}}]}" about="#mwt1"></span>
+<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo|bar |[[&quot;}},&quot;i&quot;:0}}]}" about="#mwt2"></p>
+!! wikitext
+{{echo|foo{{!}}bar}}
+{{echo|<nowiki>foo|bar |[[</nowiki>}}
+!! end
+
+!! test
+T53961: Output correct nowikis in template arguments
+!! options
+parsoid=html2wt
+!! html/parsoid
+<p><span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;a [ b&quot;}},&quot;i&quot;:0}}]}" about="#mwt1"></span>
+<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;a }} b&quot;}},&quot;i&quot;:0}}]}" about="#mwt2"></span>
+<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;a [[ b&quot;}},&quot;i&quot;:0}}]}" about="#mwt3"></span>
+<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;a | {{ ]]&quot;}},&quot;i&quot;:0}}]}" about="#mwt4"></span>
+<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;a }&quot;}},&quot;i&quot;:0}}]}" about="#mwt5"></span></p>
+!! wikitext
+{{echo|a [ b}}
+{{echo|a <nowiki>}}</nowiki> b}}
+{{echo|<nowiki>a [[ b</nowiki>}}
+{{echo|a {{!}} <nowiki>{{ ]]</nowiki>}}
+{{echo|a <nowiki>}</nowiki>}}
+!! end
+
 ###
 ### Comments
 ###
@@ -1745,7 +1854,6 @@ b
 !! end
 
 ## PHP parser emits output which is broken
-## XXX The parsoid output doesn't match the tidy output.
 !! test
 Unclosed HTML p-tags should be handled properly
 !! wikitext
@@ -1755,9 +1863,10 @@ a
 b
 !! html/php+tidy
 <div>
-<p>foo&lt;/div&gt;</p>
+<p>foo</p>
+</div>
 <p>a</p>
-b</div>
+<p>b</p>
 !! html/parsoid
 <div data-parsoid='{"stx":"html"}'><p data-parsoid='{"stx":"html", "autoInsertedEnd":true}'>foo</p></div>
 <p>a</p>
@@ -4039,6 +4148,28 @@ Definition Lists: colons and tables 2
 </td></tr></table></dd></dl>
 !! end
 
+!! test
+Definition Lists: template interaction
+!! wikitext
+::{{definition_list}}
+
+:one
+::{{definition_list}}
+:::two
+:::three
+::four
+!! html/parsoid
+<dl><dd><dl data-parsoid='{}'><dd about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[]]}' data-mw='{"parts":[":",{"template":{"target":{"wt":"definition_list","href":"./Template:Definition_list"},"params":{},"i":0}}]}'>one</dd><span about="#mwt1">
+</span><dd about="#mwt1">two</dd></dl></dd></dl>
+
+<dl><dd data-parsoid='{}'>one
+<dl><dd about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"pi":[[]]}' data-mw='{"parts":["::",{"template":{"target":{"wt":"definition_list","href":"./Template:Definition_list"},"params":{},"i":0}},"\n:::two\n:::three"]}'>one</dd><span about="#mwt2">
+</span><dd about="#mwt2">two
+<dl><dd>two</dd>
+<dd>three</dd></dl></dd>
+<dd data-parsoid='{}'>four</dd></dl></dd></dl>
+!! end
+
 
 ###
 ### External links
@@ -6077,6 +6208,28 @@ parsoid=wt2html,html2html
 </table>
 !! end
 
+!! test
+Table cells not properly parsed in an implicit-td context
+!! wikitext
+{|
+|-
+{{table_attribs_4}} || a || b
+|}
+!! html/php+tidy
+<table>
+<tr>
+<td style="background-color:#DC241f;" width="10px"></td>
+<td>a</td>
+<td>b</td>
+</tr>
+</table>
+!! html/parsoid
+<table>
+<tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
+<td style="background-color:#DC241f;" width="10px" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["",{"template":{"target":{"wt":"table_attribs_4","href":"./Template:Table_attribs_4"},"params":{},"i":0}}," "]}'> </td><td data-parsoid='{"stx_v":"row","autoInsertedEnd":true}'> a </td><td data-parsoid='{"stx_v":"row","autoInsertedEnd":true}'> b</td></tr>
+</tbody></table>
+!! end
+
 !! test
 Parsoid: Round-trip tables directly followed by content (bug 51219)
 !! options
@@ -7690,9 +7843,6 @@ Broken br tag sanitization
 !! end
 
 # TODO: Fix html2html mode (bug 51055)!
-# This </br> handling was added as part of bug 50831; but it
-# differs from how PHP+tidy handles this.  We should investigate
-# this.
 !! test
 Parsoid: Broken br tag recognition
 !! options
@@ -7701,12 +7851,9 @@ parsoid=wt2html
 </br>
 
 <br/ >
-!! html/php+tidy
-<p>&lt;/br&gt;</p>
+!! html+tidy
+<p><br /></p>
 <p><br /></p>
-!! html/parsoid
-<p><br></p>
-<p><br/></p>
 !! end
 
 !! test
@@ -8010,6 +8157,16 @@ Nested lists 8 (multiple nesting transitions)
 
 !! end
 
+!! test
+Nested lists 9 (extension interaction)
+!! options
+parsoid
+!! wikitext
+*<references />
+!! html/parsoid
+<ul><li data-parsoid='{}'><ol class="references" typeof="mw:Extension/references" about="#mwt2" data-parsoid='{}' data-mw='{"name":"references","attrs":{}}'></ol></li></ul>
+!! end
+
 !! test
 1. Lists with start-of-line-transparent tokens before bullets: Comments
 !! wikitext
@@ -8282,11 +8439,9 @@ parsoid=wt2html,wt2wt,html2html
 <li><s> b </s></li></ol>
 !! end
 
-# Parsoid fails this test, but it might be tricky to support properly.
 # See bug 68395.
 !!test
-List embedded in a non-block tag
-(Ugly Parsoid output -- worth fixing; PHP parser relies on Tidy)
+1. List embedded in a formatting tag
 !! wikitext
 <small>
 * foo
@@ -8303,6 +8458,49 @@ List embedded in a non-block tag
 </small>
 !!end
 
+## Ugly Parsoid output here
+## Not sure what the right output is.
+!!test
+2. List embedded in a formatting tag
+!! wikitext
+<small>
+*a
+*b</small>
+!! html/php+tidy
+<ul>
+<li><small>a</small></li>
+<li><small>b</small></li>
+</ul>
+!! html/parsoid
+<small></small>
+<ul><small>
+<li>a</li>
+</small>
+<li><small>b</small></li>
+</ul>
+!!end
+
+# Ugly Parsoid and PHP parser output here
+# Not sure if we want to make this a test!
+#
+## !!test
+## 3. Unclosed formatting tags in list elements
+## !! wikitext
+## *<small>a
+## *<small>b
+## !! html/php+tidy
+## <ul>
+## <li><small>a</small></li>
+## <li><small><small>b</small></small></li>
+## </ul>
+## !! html/parsoid
+## <ul>
+## <li><small>a</small></li>
+## <small>
+## <li><small>b</small></li>
+## </small></ul>
+## !!end
+
 # This is a bug in the PHP parser + tidy combination.
 # (The </tr> tag gets parsed as text and html-escaped by PHP,
 # and then fostered out of the table by tidy.)
@@ -8316,14 +8514,7 @@ parsoid=wt2html,wt2wt
 <td>foo</td>
 </tr>
 </table>
-!! html/php+tidy
-<p>&lt;/tr&gt;</p>
-<table>
-<tr>
-<td>foo</td>
-</tr>
-</table>
-!! html/parsoid
+!! html+tidy
 <table>
 <tr>
 <td>foo</td>
@@ -10388,6 +10579,35 @@ Templates: Support for templates generating attributes and content
 </tbody></table>
 !!end
 
+!! test
+1. Entities and nowikis inside templated attributes should be handled correctly
+!! wikitext
+<div {{echo|style{{=}}"background:&#35;f9f9f9;"}}>foo</div>
+!! html/php
+<div style="background:#f9f9f9;">foo</div>
+
+!! html/parsoid
+<div style="background:#f9f9f9;" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html"}' data-mw='{"attribs":[[{"txt":"style","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]],&amp;quot;dsr&amp;quot;:[5,49,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;style{{=}}\\&amp;quot;background:&amp;amp;#35;f9f9f9;\\&amp;quot;&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">style&lt;/span>&lt;span typeof=\"mw:Nowiki\" about=\"#mwt1\" data-parsoid=\"{}\">=&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">\"background:&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=\"{&amp;quot;src&amp;quot;:&amp;quot;&amp;amp;#35;&amp;quot;,&amp;quot;srcContent&amp;quot;:&amp;quot;#&amp;quot;}\">#&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">f9f9f9;\"&lt;/span>"},{"html":""}]]}'>foo</div>
+!! end
+
+!! test
+2. Entities and nowikis inside templated attributes should be handled correctly
+!! wikitext
+{|
+|{{table_attribs_3}}
+|}
+!! html/php
+<table>
+<tr>
+<td style="background:#f9f9f9;">Foo
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_3","href":"./Template:Table_attribs_3"},"params":{},"i":0}}]}'>Foo</td></tr>
+</tbody></table>
+!! end
+
 !!test
 Templates: HTML Tables: 1. Generating start of a HTML table
 !! wikitext
@@ -12021,6 +12241,17 @@ parsoid=wt2html,wt2wt,html2html
 <p><span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></span></p>
 !! end
 
+!! test
+Alt image option should handle most kinds of wikitext without barfing
+!! wikitext
+[[Image:Foobar.jpg|thumb|This is the image caption|alt=This is a [[link]] and a {{echo|''bold template''}}.]]
+!! html/php
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="This is a link and a bold template." src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is the image caption</div></div></div>
+
+!! html/parsoid
+<figure class="mw-default-size" typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"This is the image caption"},{"ck":"alt","ak":"alt=This is a [[link]] and a {{echo|&#39;&#39;bold template&#39;&#39;}}."}]}' data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["alt",{"html":"alt=This is a &lt;a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid=\"{&amp;quot;stx&amp;quot;:&amp;quot;simple&amp;quot;,&amp;quot;a&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;./Link&amp;quot;},&amp;quot;sa&amp;quot;:{&amp;quot;href&amp;quot;:&amp;quot;link&amp;quot;},&amp;quot;dsr&amp;quot;:[65,73,2,2]}\">link&lt;/a> and a &lt;i about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[80,106,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;&#39;&#39;bold template&#39;&#39;&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\">bold template&lt;/i>."}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img alt="This is a link and a bold template." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" height="25" width="220" data-parsoid='{"a":{"alt":"This is a link and a bold template.","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=This is a [[link]] and a {{echo|&#39;&#39;bold template&#39;&#39;}}.","resource":"Image:Foobar.jpg"}}'/></a><figcaption>This is the image caption</figcaption></figure>
+!! end
+
 ###################
 # Conflicting image format options.
 # First option specified should 'win'.
@@ -13413,7 +13644,7 @@ Handling of sections up to level 6 and beyond
 !! end
 
 !! test
-TOC regression (bug 9764)
+TOC regression (T11764)
 !! wikitext
 == title 1 ==
 === title 1.1 ===
@@ -13585,7 +13816,7 @@ Link inside a section heading
 !! end
 
 !! test
-TOC regression (bug 12077)
+TOC regression (T14077)
 !! wikitext
 __TOC__
 == title 1 ==
@@ -14210,16 +14441,17 @@ Media link with text
 !! end
 
 # FIXME: this is still bad HTML tag nesting
+# FIXME: doBlockLevels won't wrap this in a paragraph because it contains a div
 !! test
 Media link with nasty text
-fixme: doBlockLevels won't wrap this in a paragraph because it contains a div
 !! wikitext
 [[Media:Foobar.jpg|Safe Link<div style=display:none>" onmouseover="alert(document.cookie)" onfoo="</div>]]
 !! html
 <a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a>
 
 !! html+tidy
-<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a></p>
+<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link</a></p>
+<div style="display:none">" onmouseover="alert(document.cookie)" onfoo="</div>
 !! end
 
 !! test
@@ -15433,6 +15665,7 @@ http://<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
 <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
 </ul>
 </div>
+<p></p>
 !! end
 
 !! test
@@ -19205,6 +19438,7 @@ __TOC__
 <h2><a href="#Quote" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="Quote"><blockquote>Quote</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 
 !! html+tidy
+<p></p>
 <div id="toc" class="toc">
 <div id="toctitle">
 <h2>Contents</h2>
@@ -19213,6 +19447,7 @@ __TOC__
 <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li>
 </ul>
 </div>
+<p></p>
 <h2><a href="#Quote" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="Quote"></span></h2>
 <blockquote>
 <p><span class="mw-headline" id="Quote">Quote</span></p>
@@ -19261,6 +19496,7 @@ __TOC__
 <h2><a href="#Foo_Bar_2" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote>Bar</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 
 !! html+tidy
+<p></p>
 <div id="toc" class="toc">
 <div id="toctitle">
 <h2>Contents</h2>
@@ -19270,6 +19506,7 @@ __TOC__
 <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li>
 </ul>
 </div>
+<p></p>
 <h2><a href="#Foo_Bar" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="Foo_Bar"><i>Foo</i> <b>Bar</b></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><a href="#Foo_Bar_2" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i></span></h2>
 <blockquote>
@@ -19346,6 +19583,37 @@ __TOC__
 
 !! end
 
+# Note that the html output does not have the <p></p>, but the
+# html+tidy output *does*.  This is because the empty <p></p> is
+# removed by the sanitizer, but only when tidy is *not* enabled (!).
+!! test
+Empty <p> tag in TOC, removed by Sanitizer (T92892)
+!! wikitext
+__TOC__
+== x ==
+!! html
+<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#x"><span class="tocnumber">1</span> <span class="toctext">x</span></a></li>
+</ul>
+</div>
+
+<h2><a href="#x" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="x">x</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: x">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+
+!! html+tidy
+<p></p>
+<div id="toc" class="toc">
+<div id="toctitle">
+<h2>Contents</h2>
+</div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#x"><span class="tocnumber">1</span> <span class="toctext">x</span></a></li>
+</ul>
+</div>
+<p></p>
+<h2><a href="#x" class="mw-headline-anchor" aria-hidden="true" title="Link to this section">§</a><span class="mw-headline" id="x">x</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: x">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! end
+
 !! article
 MediaWiki:Bug32057
 !! text
@@ -20338,6 +20606,22 @@ foo
 foo<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'></ol>
 !! end
 
+#### ----------------------------------------------------------------
+#### Parsoid-only testing of Parsoid's impl of LST
+#### Not implemented yet, see
+#### https://www.mediawiki.org/wiki/Parsoid/HTML_based_LST
+#### ----------------------------------------------------------------
+
+!!test
+LST Sections: 1. Simple section start and end
+!! wikitext
+<section begin="2011-05-16" />
+<section end="2014-04-10 (MW 1.23wmf22)" />
+!! html/parsoid
+<p><meta typeof="mw:Extension/LabeledSectionTransclusion/begin" content="2011-05-16"/>
+<meta typeof="mw:Extension/LabeledSectionTransclusion/end" content="2014-04-10 (MW 1.23wmf22)"/></p>
+!! end
+
 #--------- Test stripping of empty nodes in template content ----------
 !!test
 Empty LI and TR nodes should be stripped from template content
@@ -21892,18 +22176,6 @@ a>b
 </p>
 !! end
 
-
-# This was a bug in the PHP parser (see bug 17663 and its dups,
-# https://bugzilla.wikimedia.org/show_bug.cgi?id=17663)
-!! test
-Tag names followed by punctuation should not be recognized as tags
-!! wikitext
-<s.ome> text
-!! html
-<p>&lt;s.ome&gt; text
-</p>
-!! end
-
 !! test
 HTML tag with necessary entities in attributes
 !! wikitext
@@ -23138,6 +23410,22 @@ parsoid=html2wt
 [[Foo''bar''baz]]
 !! end
 
+!! test
+Enforce single-line context in the serializer
+!! options
+parsoid=html2wt
+!! html
+<h2>testing
+123</h2>
+
+<ul><li>asd
+sdf</li></ul>
+!! wikitext
+== testing 123 ==
+
+* asd sdf
+!! end
+
 #-----------------------------
 # I/B quote minimization tests
 #-----------------------------
@@ -23421,6 +23709,56 @@ parsoid=html2wt
 <foo />
 !! end
 
+# Note that the <p> wrapping isn't present in PHP parser output
+# The important thing for this test is that P-wrapping doesn't
+# interfere with the <nowiki> protection for leading - in <td>
+# (which isn't necessary for <th>).
+!! test
+T88318: p-wrapped dash in table.
+!! options
+parsoid=html2wt,wt2wt
+!! html/parsoid
+<table><tbody>
+<tr><th><p>-</p></th><th><p>- </p></th></tr>
+<tr><td><p>-</p></td><td><p>- </p></td></tr>
+<tr><td><small>-</small></td><td><br/><p>-</p></td><td><br/>-</td></tr>
+</tbody></table>
+!! wikitext
+{|
+!-
+!- 
+|-
+|<nowiki>-</nowiki>
+|<nowiki>- </nowiki>
+|-
+|<small>-</small>
+|<br>
+-
+|<br>
+-
+|}
+!! html/php+tidy
+<table>
+<tr>
+<th>-</th>
+<th>-</th>
+</tr>
+<tr>
+<td>-</td>
+<td>-</td>
+</tr>
+<tr>
+<td><small>-</small></td>
+<td><br />
+<p>-</p>
+</td>
+<td><br />
+<p>-</p>
+</td>
+</tr>
+</table>
+!! end
+
 # -----------------------------------------------------------------
 # End of section for Parsoid-only html2wt tests for serialization
 # of new content
index c8b3e89..221fc79 100644 (file)
@@ -29,6 +29,7 @@ class ParserTestParserHook {
 
        static function setup( &$parser ) {
                $parser->setHook( 'tag', array( __CLASS__, 'dumpHook' ) );
+               $parser->setHook( 'tåg', array( __CLASS__, 'dumpHook' ) );
                $parser->setHook( 'statictag', array( __CLASS__, 'staticTagHook' ) );
                return true;
        }
diff --git a/tests/phpunit/data/helpers/WellProtectedClass.php b/tests/phpunit/data/helpers/WellProtectedClass.php
new file mode 100644 (file)
index 0000000..7114cc9
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+class WellProtectedClass {
+       protected $property;
+
+       public function __construct() {
+               $this->property = 1;
+       }
+
+       protected function incrementPropertyValue() {
+               $this->property++;
+       }
+
+       public function getProperty() {
+               return $this->property;
+       }
+}
diff --git a/tests/phpunit/includes/TestingAccessWrapper.php b/tests/phpunit/includes/TestingAccessWrapper.php
new file mode 100644 (file)
index 0000000..d4ad363
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Circumvent access restrictions on object internals
+ *
+ * This can be helpful for writing tests that can probe object internals,
+ * without having to modify the class under test to accomodate.
+ *
+ * Wrap an object with private methods as follows:
+ *    $title = TestingAccessWrapper::newFromObject( Title::newFromDBkey( $key ) );
+ *
+ * You can access private and protected instance methods and variables:
+ *    $formatter = $title->getTitleFormatter();
+ *
+ * TODO:
+ * - Provide access to static methods and properties.
+ * - Organize other helper classes in tests/testHelpers.inc into a directory.
+ */
+class TestingAccessWrapper {
+       public $object;
+
+       /**
+        * Return the same object, without access restrictions.
+        */
+       public static function newFromObject( $object ) {
+               $wrapper = new TestingAccessWrapper();
+               $wrapper->object = $object;
+               return $wrapper;
+       }
+
+       public function __call( $method, $args ) {
+               $classReflection = new ReflectionClass( $this->object );
+               $methodReflection = $classReflection->getMethod( $method );
+               $methodReflection->setAccessible( true );
+               return $methodReflection->invoke( $this->object, $args );
+       }
+
+       public function __set( $name, $value ) {
+               $classReflection = new ReflectionClass( $this->object );
+               $propertyReflection = $classReflection->getProperty( $name );
+               $propertyReflection->setAccessible( true );
+               $propertyReflection->setValue( $this->object, $value );
+       }
+
+       public function __get( $name ) {
+               $classReflection = new ReflectionClass( $this->object );
+               $propertyReflection = $classReflection->getProperty( $name );
+               $propertyReflection->setAccessible( true );
+               return $propertyReflection->getValue( $this->object );
+       }
+}
diff --git a/tests/phpunit/includes/TestingAccessWrapperTest.php b/tests/phpunit/includes/TestingAccessWrapperTest.php
new file mode 100644 (file)
index 0000000..8da8e42
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+class TestingAccessWrapperTest extends MediaWikiTestCase {
+       protected $raw;
+       protected $wrapped;
+
+       function setUp() {
+               parent::setUp();
+
+               require_once __DIR__ . '/../data/helpers/WellProtectedClass.php';
+               $this->raw = new WellProtectedClass();
+               $this->wrapped = TestingAccessWrapper::newFromObject( $this->raw );
+       }
+
+       function testGetProperty() {
+               $this->assertSame( 1, $this->wrapped->property );
+       }
+
+       function testSetProperty() {
+               $this->wrapped->property = 10;
+               $this->assertSame( 10, $this->wrapped->property );
+               $this->assertSame( 10, $this->raw->getProperty() );
+       }
+
+       function testCallMethod() {
+               $this->wrapped->incrementPropertyValue();
+               $this->assertSame( 2, $this->wrapped->property );
+               $this->assertSame( 2, $this->raw->getProperty() );
+       }
+}
index 1220bb4..dabf72e 100644 (file)
@@ -88,9 +88,13 @@ STR;
        /**
         * Checks that the request's result matches the expected results.
         * @param array $values Array is a two element array( request, expected_results )
-        * @throws Exception
+        * @param array $session
+        * @param bool $appendModule
+        * @param User $user
         */
-       protected function check( $values ) {
+       protected function check( $values, array $session = null,
+               $appendModule = false, User $user = null
+       ) {
                list( $req, $exp ) = $this->validateRequestExpectedPair( $values );
                if ( !array_key_exists( 'action', $req ) ) {
                        $req['action'] = 'query';
@@ -103,7 +107,7 @@ STR;
                                $val = implode( '|', array_unique( $val ) );
                        }
                }
-               $result = $this->doApiRequest( $req );
+               $result = $this->doApiRequest( $req, $session, $appendModule, $user );
                $this->assertResult( array( 'query' => $exp ), $result[0], $req );
        }
 
@@ -116,9 +120,16 @@ STR;
                        if ( is_array( $message ) ) {
                                $message = http_build_query( $message );
                        }
+
+                       // FIXME: once we migrate to phpunit 4.1+, hardcode ComparisonFailure exception use
+                       $compEx = 'SebastianBergmann\Comparator\ComparisonFailure';
+                       if ( !class_exists( $compEx ) ) {
+                               $compEx = 'PHPUnit_Framework_ComparisonFailure';
+                       }
+
                        throw new PHPUnit_Framework_ExpectationFailedException(
                                $e->getMessage() . "\nRequest: $message",
-                               new PHPUnit_Framework_ComparisonFailure(
+                               new $compEx(
                                        $exp,
                                        $result,
                                        print_r( $exp, true ),
index d32c1a6..645baf1 100644 (file)
@@ -1,10 +1,12 @@
 <?php
 
-class MockDatabaseSqlite extends DatabaseSqliteStandalone {
+class MockDatabaseSqlite extends DatabaseSqlite {
        private $lastQuery;
 
-       function __construct() {
-               parent::__construct( ':memory:' );
+       public static function newInstance( array $p = array() ) {
+               $p['dbFilePath'] = ':memory:';
+
+               return new self( $p );
        }
 
        function query( $sql, $fname = '', $tempIgnore = false ) {
@@ -36,7 +38,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                if ( !Sqlite::isPresent() ) {
                        $this->markTestSkipped( 'No SQLite support detected' );
                }
-               $this->db = new MockDatabaseSqlite();
+               $this->db = MockDatabaseSqlite::newInstance();
                if ( version_compare( $this->db->getServerVersion(), '3.6.0', '<' ) ) {
                        $this->markTestSkipped( "SQLite at least 3.6 required, {$this->db->getServerVersion()} found" );
                }
@@ -89,7 +91,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         */
        public function testAddQuotes( $value, $expected ) {
                // check quoting
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $this->assertEquals( $expected, $db->addQuotes( $value ), 'string not quoted as expected' );
 
                // ok, quoting works as expected, now try a round trip.
@@ -172,7 +174,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         */
        public function testTableName() {
                // @todo Moar!
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $this->assertEquals( 'foo', $db->tableName( 'foo' ) );
                $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) );
                $db->tablePrefix( 'foo' );
@@ -184,7 +186,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         * @covers DatabaseSqlite::duplicateTableStructure
         */
        public function testDuplicateTableStructure() {
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $db->query( 'CREATE TABLE foo(foo, barfoo)' );
 
                $db->duplicateTableStructure( 'foo', 'bar' );
@@ -208,7 +210,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         * @covers DatabaseSqlite::duplicateTableStructure
         */
        public function testDuplicateTableStructureVirtual() {
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                if ( $db->getFulltextSearchModule() != 'FTS3' ) {
                        $this->markTestSkipped( 'FTS3 not supported, cannot create virtual tables' );
                }
@@ -231,7 +233,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         * @covers DatabaseSqlite::deleteJoin
         */
        public function testDeleteJoin() {
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $db->query( 'CREATE TABLE a (a_1)', __METHOD__ );
                $db->query( 'CREATE TABLE b (b_1, b_2)', __METHOD__ );
                $db->insert( 'a', array(
@@ -289,7 +291,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                        'user_newtalk.user_last_timestamp', // r84185
                );
 
-               $currentDB = new DatabaseSqliteStandalone( ':memory:' );
+               $currentDB = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $currentDB->sourceFile( "$IP/maintenance/tables.sql" );
 
                $profileToDb = false;
@@ -357,7 +359,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         * @covers DatabaseSqlite::insertId
         */
        public function testInsertIdType() {
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
 
                $databaseCreation = $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ );
                $this->assertInstanceOf( 'ResultWrapper', $databaseCreation, "Database creation" );
@@ -377,7 +379,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                }
 
                global $IP;
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $db->sourceFile( "$IP/tests/phpunit/data/db/sqlite/tables-$version.sql" );
                $updater = DatabaseUpdater::newForDB( $db, false, $maint );
                $updater->doUpdates( array( 'core' ) );
@@ -440,7 +442,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
 
        public function testCaseInsensitiveLike() {
                // TODO: Test this for all databases
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $res = $db->query( 'SELECT "a" LIKE "A" AS a' );
                $row = $res->fetchRow();
                $this->assertFalse( (bool)$row['a'] );
@@ -450,7 +452,7 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
         * @covers DatabaseSqlite::numFields
         */
        public function testNumFields() {
-               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
 
                $databaseCreation = $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ );
                $this->assertInstanceOf( 'ResultWrapper', $databaseCreation, "Failed to create table a" );
index 3ce3e1f..ccd7f96 100644 (file)
@@ -160,9 +160,6 @@ class NewParserTest extends MediaWikiTestCase {
                $this->djVuSupport = new DjVuSupport();
                // Tidy support
                $this->tidySupport = new TidySupport();
-               // We always set 'wgUseTidy' to false when parsing, but certain
-               // test-running modes still use tidy if available, so ensure
-               // that the tidy-related options are all set to their defaults.
                $tmpGlobals['wgUseTidy'] = false;
                $tmpGlobals['wgAlwaysUseTidy'] = false;
                $tmpGlobals['wgDebugTidy'] = false;
@@ -419,6 +416,7 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgMathDirectory' => $uploadDir . '/math',
                        'wgDefaultLanguageVariant' => $variant,
                        'wgLinkHolderBatchSize' => $linkHolderBatchSize,
+                       'wgUseTidy' => isset( $opts['tidy'] ),
                );
 
                if ( $config ) {
@@ -727,12 +725,21 @@ class NewParserTest extends MediaWikiTestCase {
                                        . "Current configuration is:\n\$wgTexvc = '$wgTexvc'" );
                        }
                }
+
                if ( isset( $opts['djvu'] ) ) {
                        if ( !$this->djVuSupport->isEnabled() ) {
                                $this->markTestSkipped( "SKIPPED: djvu binaries do not exist or are not executable.\n" );
                        }
                }
 
+               if ( isset( $opts['tidy'] ) ) {
+                       if ( !$this->tidySupport->isEnabled() ) {
+                               $this->markTestSkipped( "SKIPPED: tidy extension is not installed.\n" );
+                       } else {
+                               $options->setTidy( true );
+                       }
+               }
+
                if ( isset( $opts['pst'] ) ) {
                        $out = $parser->preSaveTransform( $input, $title, $user, $options );
                } elseif ( isset( $opts['msg'] ) ) {
@@ -753,12 +760,7 @@ class NewParserTest extends MediaWikiTestCase {
                        $output->setTOCEnabled( !isset( $opts['notoc'] ) );
                        $out = $output->getText();
                        if ( isset( $opts['tidy'] ) ) {
-                               if ( !$this->tidySupport->isEnabled() ) {
-                                       $this->markTestSkipped( "SKIPPED: tidy extension is not installed.\n" );
-                               } else {
-                                       $out = MWTidy::tidy( $out );
-                                       $out = preg_replace( '/\s+$/', '', $out );
-                               }
+                               $out = preg_replace( '/\s+$/', '', $out );
                        }
 
                        if ( isset( $opts['showtitle'] ) ) {
diff --git a/tests/phpunit/structure/AvailableRightsTest.php b/tests/phpunit/structure/AvailableRightsTest.php
new file mode 100644 (file)
index 0000000..51d31aa
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Try to make sure that extensions register all rights in $wgAvailableRights
+ * or via the 'UserGetAllRights' hook.
+ *
+ * @author Marius Hoch < hoo@online.de >
+ */
+class AvailableRightsTest extends PHPUnit_Framework_TestCase {
+
+       /**
+        * Returns all rights that should be in $wgAvailableRights + all rights
+        * registered via the 'UserGetAllRights' hook + all "core" rights.
+        *
+        * @return string[]
+        */
+       private function getAllVisibleRights() {
+               global $wgGroupPermissions, $wgRevokePermissions;
+
+               $rights = User::getAllRights();
+
+               foreach( $wgGroupPermissions as $permissions ) {
+                       $rights = array_merge( $rights, array_keys( $permissions ) );
+               }
+
+               foreach( $wgRevokePermissions as $permissions ) {
+                       $rights = array_merge( $rights, array_keys( $permissions ) );
+               }
+
+               $rights = array_unique( $rights );
+               sort( $rights );
+
+               return $rights;
+       }
+
+       public function testAvailableRights() {
+               $missingRights = array_diff(
+                       $this->getAllVisibleRights(),
+                       User::getAllRights()
+               );
+
+               $this->assertEquals(
+                       array(),
+                       // Re-index to produce nicer output, keys are meaningless.
+                       array_values( $missingRights ),
+                       'Additional user rights need to be added to $wgAvailableRights or ' .
+                       'via the "UserGetAllRights" hook. See the instructions at: ' .
+                       'https://www.mediawiki.org/wiki/Manual:User_rights#Adding_new_rights'
+               );
+       }
+}