Merge "SECURITY: Disable <html> tag on system messages despite $wgRawHtml = true;"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 31 Mar 2017 05:10:22 +0000 (05:10 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 31 Mar 2017 05:10:22 +0000 (05:10 +0000)
340 files changed:
RELEASE-NOTES-1.29
autoload.php
composer.json
docs/hooks.txt
includes/Block.php
includes/CategoryFinder.php
includes/Defines.php
includes/EditPage.php
includes/Linker.php
includes/MediaWiki.php
includes/MergeHistory.php
includes/Revision.php
includes/RevisionList.php
includes/SiteStats.php
includes/Title.php
includes/WatchedItemQueryService.php
includes/WatchedItemQueryServiceExtension.php
includes/WatchedItemStore.php
includes/actions/PurgeAction.php
includes/actions/ViewAction.php
includes/api/ApiBase.php
includes/api/ApiPageSet.php
includes/api/ApiPurge.php
includes/api/ApiQueryAllImages.php
includes/api/i18n/fr.json
includes/api/i18n/ko.json
includes/api/i18n/pt-br.json
includes/api/i18n/sv.json
includes/cache/BacklinkCache.php
includes/cache/LinkBatch.php
includes/cache/LinkCache.php
includes/cache/localisation/LCStoreDB.php
includes/changes/ChangesListBooleanFilter.php
includes/changes/ChangesListStringOptionsFilterGroup.php
includes/changetags/ChangeTagsList.php
includes/changetags/ChangeTagsLogList.php
includes/changetags/ChangeTagsRevisionList.php
includes/db/CloneDatabase.php
includes/db/ORAResult.php
includes/deferred/AtomicSectionUpdate.php
includes/deferred/AutoCommitUpdate.php
includes/deferred/DeferredUpdates.php
includes/deferred/LinksDeletionUpdate.php
includes/deferred/LinksUpdate.php
includes/deferred/MWCallableUpdate.php
includes/deferred/SiteStatsUpdate.php
includes/deferred/SqlDataUpdate.php
includes/deferred/WANCacheReapUpdate.php
includes/export/WikiExporter.php
includes/externalstore/ExternalStoreDB.php
includes/filebackend/filejournal/DBFileJournal.php
includes/filebackend/lockmanager/MySqlLockManager.php
includes/filerepo/FileBackendDBRepoWrapper.php
includes/filerepo/ForeignDBRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/LocalFile.php
includes/http/MWHttpRequest.php
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/i18n/br.json
includes/jobqueue/JobQueueDB.php
includes/jobqueue/utils/PurgeJobUtils.php
includes/libs/lockmanager/DBLockManager.php
includes/libs/rdbms/connectionmanager/ConnectionManager.php
includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/IMaintainableDatabase.php
includes/libs/rdbms/database/MaintainableDBConnRef.php
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/libs/rdbms/defines.php
includes/libs/rdbms/exception/DBConnectionError.php
includes/libs/rdbms/exception/DBError.php
includes/libs/rdbms/exception/DBExpectedError.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/lbfactory/LBFactoryMulti.php
includes/libs/rdbms/lbfactory/LBFactorySimple.php
includes/libs/rdbms/lbfactory/LBFactorySingle.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/libs/rdbms/loadmonitor/LoadMonitor.php
includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php
includes/logging/LogEntry.php
includes/logging/LogEventsList.php
includes/media/IPTC.php
includes/objectcache/SqlBagOStuff.php
includes/page/Article.php
includes/page/PageArchive.php
includes/page/WikiFilePage.php
includes/page/WikiPage.php
includes/pager/IndexPager.php
includes/resourceloader/ResourceLoaderImage.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelArchiveList.php
includes/revisiondelete/RevDelArchivedFileList.php
includes/revisiondelete/RevDelFileItem.php
includes/revisiondelete/RevDelFileList.php
includes/revisiondelete/RevDelLogList.php
includes/revisiondelete/RevDelRevisionList.php
includes/revisiondelete/RevisionDeleteUser.php
includes/search/SearchDatabase.php
includes/search/SearchEngineFactory.php
includes/specialpage/ChangesListSpecialPage.php
includes/specialpage/ImageQueryPage.php
includes/specialpage/PageQueryPage.php
includes/specialpage/QueryPage.php
includes/specialpage/WantedQueryPage.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListDuplicatedFiles.php
includes/specials/SpecialListredirects.php
includes/specials/SpecialMediaStatistics.php
includes/specials/SpecialMostcategories.php
includes/specials/SpecialMostinterwikis.php
includes/specials/SpecialMostlinked.php
includes/specials/SpecialMostlinkedcategories.php
includes/specials/SpecialMostlinkedtemplates.php
includes/specials/SpecialNewimages.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialShortpages.php
includes/specials/SpecialUnwatchedpages.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/ImageListPager.php
includes/specials/pagers/NewFilesPager.php
includes/user/UserGroupMembership.php
includes/user/UserRightsProxy.php
includes/utils/BatchRowIterator.php
includes/utils/BatchRowWriter.php
includes/widget/search/InterwikiSearchResultSetWidget.php
languages/i18n/ar.json
languages/i18n/arz.json
languages/i18n/atj.json
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frc.json
languages/i18n/frr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/it.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/olo.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sl.json
languages/i18n/sv.json
languages/i18n/tl.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/Maintenance.php
maintenance/backup.inc
maintenance/cleanupRemovedModules.php
maintenance/purgeModuleDeps.php
maintenance/refreshLinks.php
maintenance/runBatchedQuery.php
maintenance/sql.php
package.json
resources/Resources.php
resources/lib/oojs-ui/i18n/bqi.json
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/icons-alerts.json
resources/lib/oojs-ui/themes/apex/icons-content.json
resources/lib/oojs-ui/themes/apex/icons-interactions.json
resources/lib/oojs-ui/themes/apex/icons-layout.json [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/icons-movement.json
resources/lib/oojs-ui/themes/apex/icons.json
resources/lib/oojs-ui/themes/apex/images/icons/add-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/add-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/search.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/search.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/icons-alerts.json
resources/lib/oojs-ui/themes/mediawiki/icons-content.json
resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json
resources/lib/oojs-ui/themes/mediawiki/icons-layout.json
resources/lib/oojs-ui/themes/mediawiki/icons-location.json
resources/lib/oojs-ui/themes/mediawiki/icons-movement.json
resources/lib/oojs-ui/themes/mediawiki/icons.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.svg [deleted file]
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.special/mediawiki.special.search.interwikiwidget.styles.less
resources/src/mediawiki.special/mediawiki.special.userlogin.common.css
resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js [deleted file]
resources/src/mediawiki.widgets/mw.widgets.ComplexNamespaceInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.ComplexTitleInputWidget.js
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js
resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
resources/src/mediawiki/mediawiki.util.js
resources/src/moment-locale-overrides.js
tests/parser/DbTestPreviewer.php
tests/parser/DbTestRecorder.php
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phpunit/includes/auth/AuthManagerTest.php
tests/phpunit/includes/db/DatabaseTest.php
tests/phpunit/includes/http/HttpTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderWikiModuleTest.php
tests/phpunit/includes/title/NaiveImportTitleFactoryTest.php
tests/phpunit/includes/title/NamespaceImportTitleFactoryTest.php
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js
tests/selenium/wdio.conf.jenkins.js
tests/selenium/wdio.conf.js

index bb57a9e..2ced8a5 100644 (file)
@@ -269,6 +269,16 @@ changes to languages because of Phabricator reports.
 * WikiRevision::$fileIsTemp was deprecated.
 * WikiRevision::$importer was deprecated.
 * WikiRevision::$user was deprecated.
+* Article::getLastPurgeTimestamp(), WikiPage::getLastPurgeTimestamp(), and the
+  WikiPage::PURGE_* constants are deprecated, and the functions will always
+  return false. They were a hack for an issue that has since been fixed.
+* Hook 'EditPageBeforeEditChecks' is now deprecated. Instead use the new hook
+  'EditPageGetCheckboxesDefinition', or 'EditPage::showStandardInputs:options'
+  if you don't actually care about checkboxes and just want to add some HTML
+  to the page.
+* Selflinks are now rendered as href-less <a> tags with the class mw-selflink
+  rather than <strong> tags. The old class name, "selflink", was deprecated
+  and will be removed in a future release. (T160480)
 
 == Compatibility ==
 
index 4ffaa11..956d504 100644 (file)
@@ -1591,14 +1591,17 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\Blob' => __DIR__ . '/includes/libs/rdbms/encasing/Blob.php',
        'Wikimedia\\Rdbms\\ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php',
        'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
+       'Wikimedia\\Rdbms\\DBConnRef' => __DIR__ . '/includes/libs/rdbms/database/DBConnRef.php',
        'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBMasterPos.php',
        'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
        'Wikimedia\\Rdbms\\FakeResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php',
        'Wikimedia\\Rdbms\\Field' => __DIR__ . '/includes/libs/rdbms/field/Field.php',
        'Wikimedia\\Rdbms\\IBlob' => __DIR__ . '/includes/libs/rdbms/encasing/IBlob.php',
+       'Wikimedia\\Rdbms\\IDatabase' => __DIR__ . '/includes/libs/rdbms/database/IDatabase.php',
        'Wikimedia\\Rdbms\\ILBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/ILBFactory.php',
        'Wikimedia\\Rdbms\\ILoadBalancer' => __DIR__ . '/includes/libs/rdbms/loadbalancer/ILoadBalancer.php',
        'Wikimedia\\Rdbms\\ILoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/ILoadMonitor.php',
+       'Wikimedia\\Rdbms\\IMaintainableDatabase' => __DIR__ . '/includes/libs/rdbms/database/IMaintainableDatabase.php',
        'Wikimedia\\Rdbms\\IResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/IResultWrapper.php',
        'Wikimedia\\Rdbms\\LBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactory.php',
        'Wikimedia\\Rdbms\\LBFactoryMulti' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactoryMulti.php',
@@ -1610,6 +1613,7 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\LoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitor.php',
        'Wikimedia\\Rdbms\\LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php',
        'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php',
+       'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
        'Wikimedia\\Rdbms\\MssqlBlob' => __DIR__ . '/includes/libs/rdbms/encasing/MssqlBlob.php',
        'Wikimedia\\Rdbms\\MssqlField' => __DIR__ . '/includes/libs/rdbms/field/MssqlField.php',
        'Wikimedia\\Rdbms\\MssqlResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php',
index cd8f310..ece725c 100644 (file)
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.20.0",
+               "oojs/oojs-ui": "0.20.2",
                "oyejorge/less.php": "1.7.0.13",
                "php": ">=5.5.9",
                "psr/log": "1.0.2",
                "monolog/monolog": "~1.18.2",
                "nikic/php-parser": "2.1.0",
                "nmred/kafka-php": "0.1.5",
-               "phpunit/phpunit": "4.8.31",
+               "phpunit/phpunit": "4.8.35",
                "wikimedia/avro": "1.7.7",
                "hamcrest/hamcrest-php": "^2.0",
                "wmde/hamcrest-html-matchers": "^0.1.0",
-               "psy/psysh": "0.8.1"
+               "psy/psysh": "0.8.3"
        },
        "suggest": {
                "ext-apc": "Local data and opcode cache",
index 3a57563..a38f9bb 100644 (file)
@@ -1404,10 +1404,12 @@ textarea in the edit form.
 &$buttons: Array of edit buttons "Save", "Preview", "Live", and "Diff"
 &$tabindex: HTML tabindex of the last edit check/button
 
-'EditPageBeforeEditChecks': Allows modifying the edit checks below the textarea
-in the edit form.
+'EditPageBeforeEditChecks': DEPRECATED! Use 'EditPageGetCheckboxesDefinition' instead,
+or 'EditPage::showStandardInputs:options' if you don't actually care about checkboxes
+and just want to add some HTML to the page.
+Allows modifying the edit checks below the textarea in the edit form.
 &$editpage: The current EditPage object
-&$checks: Array of edit checks like "watch this page"/"minor edit"
+&$checks: Array of the HTML for edit checks like "watch this page"/"minor edit"
 &$tabindex: HTML tabindex of the last edit check/button
 
 'EditPageBeforeEditToolbar': Allows modifying the edit toolbar above the
@@ -1420,6 +1422,12 @@ $title: title of page being edited
 &$msg: localization message name, overridable. Default is either
   'copyrightwarning' or 'copyrightwarning2'.
 
+'EditPageGetCheckboxesDefinition': Allows modifying the edit checkboxes
+below the textarea in the edit form.
+$editpage: The current EditPage object
+&$checkboxes: Array of checkbox definitions. See EditPage::getCheckboxesDefinition()
+for the format.
+
 'EditPageGetDiffContent': Allow modifying the wikitext that will be used in
 "Show changes". Note that it is preferable to implement diff handling for
 different data types using the ContentHandler facility.
index cf6642a..b6b3ae0 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 
 class Block {
index 504b35f..595cf95 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * The "CategoryFinder" class takes a list of articles, creates an internal
  * representation of all their parent categories (as well as parents of
index bd92ff0..6bc70ed 100644 (file)
@@ -24,6 +24,8 @@ require_once __DIR__ . '/libs/mime/defines.php';
 require_once __DIR__ . '/libs/rdbms/defines.php';
 require_once __DIR__ . '/compat/normal/UtfNormalDefines.php';
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * @defgroup Constants MediaWiki constants
  */
index ac62e3f..e4d217c 100644 (file)
@@ -2421,7 +2421,7 @@ class EditPage {
                # Show log extract when the user is currently blocked
                if ( $namespace == NS_USER || $namespace == NS_USER_TALK ) {
                        $username = explode( '/', $this->mTitle->getText(), 2 )[0];
-                       $user = User::newFromName( $username, false /* allow IP users*/ );
+                       $user = User::newFromName( $username, false /* allow IP users */ );
                        $ip = User::isIP( $username );
                        $block = Block::newFromTarget( $user, $user );
                        if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
@@ -4005,70 +4005,114 @@ HTML
                return $toolbar;
        }
 
+       /**
+        * Return an array of checkbox definitions.
+        *
+        * Array keys correspond to the `<input>` 'name' attribute to use for each checkbox.
+        *
+        * Array values are associative arrays with the following keys:
+        *  - 'label-message' (required): message for label text
+        *  - 'id' (required): 'id' attribute for the `<input>`
+        *  - 'default' (required): default checkedness (true or false)
+        *  - 'title-message' (optional): used to generate 'title' attribute for the `<label>`
+        *  - 'tooltip' (optional): used to generate 'title' and 'accesskey' attributes
+        *    from messages like 'tooltip-foo', 'accesskey-foo'
+        *  - 'label-id' (optional): 'id' attribute for the `<label>`
+        *  - 'legacy-name' (optional): short name for backwards-compatibility
+        * @param array $checked Array of checkbox name (matching the 'legacy-name') => bool,
+        *   where bool indicates the checked status of the checkbox
+        * @return array
+        */
+       protected function getCheckboxesDefinition( $checked ) {
+               global $wgUser;
+               $checkboxes = [];
+
+               // don't show the minor edit checkbox if it's a new page or section
+               if ( !$this->isNew && $wgUser->isAllowed( 'minoredit' ) ) {
+                       $checkboxes['wpMinoredit'] = [
+                               'id' => 'wpMinoredit',
+                               'label-message' => 'minoredit',
+                               // Uses messages: tooltip-minoredit, accesskey-minoredit
+                               'tooltip' => 'minoredit',
+                               'label-id' => 'mw-editpage-minoredit',
+                               'legacy-name' => 'minor',
+                               'default' => $checked['minor'],
+                       ];
+               }
+
+               if ( $wgUser->isLoggedIn() ) {
+                       $checkboxes['wpWatchthis'] = [
+                               'id' => 'wpWatchthis',
+                               'label-message' => 'watchthis',
+                               // Uses messages: tooltip-watch, accesskey-watch
+                               'tooltip' => 'watch',
+                               'label-id' => 'mw-editpage-watch',
+                               'legacy-name' => 'watch',
+                               'default' => $checked['watch'],
+                       ];
+               }
+
+               $editPage = $this;
+               Hooks::run( 'EditPageGetCheckboxesDefinition', [ $editPage, &$checkboxes ] );
+
+               return $checkboxes;
+       }
+
        /**
         * Returns an array of html code of the following checkboxes:
         * minor and watch
         *
         * @param int $tabindex Current tabindex
-        * @param array $checked Array of checkbox => bool, where bool indicates the checked
-        *                 status of the checkbox
-        *
+        * @param array $checked See getCheckboxesDefinition()
         * @return array
         */
        public function getCheckboxes( &$tabindex, $checked ) {
-               global $wgUser, $wgUseMediaWikiUIEverywhere;
+               global $wgUseMediaWikiUIEverywhere;
 
                $checkboxes = [];
+               $checkboxesDef = $this->getCheckboxesDefinition( $checked );
 
-               // don't show the minor edit checkbox if it's a new page or section
+               // Backwards-compatibility for the EditPageBeforeEditChecks hook
                if ( !$this->isNew ) {
                        $checkboxes['minor'] = '';
-                       $minorLabel = $this->context->msg( 'minoredit' )->parse();
-                       if ( $wgUser->isAllowed( 'minoredit' ) ) {
-                               $attribs = [
-                                       'tabindex' => ++$tabindex,
-                                       'accesskey' => $this->context->msg( 'accesskey-minoredit' )->text(),
-                                       'id' => 'wpMinoredit',
-                               ];
-                               $minorEditHtml =
-                                       Xml::check( 'wpMinoredit', $checked['minor'], $attribs ) .
-                                       "&#160;<label for='wpMinoredit' id='mw-editpage-minoredit'" .
-                                       Xml::expandAttributes( [ 'title' => Linker::titleAttrib( 'minoredit', 'withaccess' ) ] ) .
-                                       ">{$minorLabel}</label>";
-
-                               if ( $wgUseMediaWikiUIEverywhere ) {
-                                       $checkboxes['minor'] =
-                                               Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $minorEditHtml );
-                               } else {
-                                       $checkboxes['minor'] = $minorEditHtml;
-                               }
-                       }
                }
-
-               $watchLabel = $this->context->msg( 'watchthis' )->parse();
                $checkboxes['watch'] = '';
-               if ( $wgUser->isLoggedIn() ) {
+
+               foreach ( $checkboxesDef as $name => $options ) {
+                       $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
+                       $label = $this->context->msg( $options['label-message'] )->parse();
                        $attribs = [
                                'tabindex' => ++$tabindex,
-                               'accesskey' => $this->context->msg( 'accesskey-watch' )->text(),
-                               'id' => 'wpWatchthis',
+                               'id' => $options['id'],
+                       ];
+                       $labelAttribs = [
+                               'for' => $options['id'],
                        ];
-                       $watchThisHtml =
-                               Xml::check( 'wpWatchthis', $checked['watch'], $attribs ) .
-                               "&#160;<label for='wpWatchthis' id='mw-editpage-watch'" .
-                               Xml::expandAttributes( [ 'title' => Linker::titleAttrib( 'watch', 'withaccess' ) ] ) .
-                               ">{$watchLabel}</label>";
+                       if ( isset( $options['tooltip'] ) ) {
+                               $attribs['accesskey'] = $this->context->msg( "accesskey-{$options['tooltip']}" )->text();
+                               $labelAttribs['title'] = Linker::titleAttrib( $options['tooltip'], 'withaccess' );
+                       }
+                       if ( isset( $options['title-message'] ) ) {
+                               $labelAttribs['title'] = $this->context->msg( $options['title-message'] )->text();
+                       }
+                       if ( isset( $options['label-id'] ) ) {
+                               $labelAttribs['id'] = $options['label-id'];
+                       }
+                       $checkboxHtml =
+                               Xml::check( $name, $options['default'], $attribs ) .
+                               '&#160;' .
+                               Xml::tags( 'label', $labelAttribs, $label );
+
                        if ( $wgUseMediaWikiUIEverywhere ) {
-                               $checkboxes['watch'] =
-                                       Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $watchThisHtml );
-                       } else {
-                               $checkboxes['watch'] = $watchThisHtml;
+                               $checkboxHtml = Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $checkboxHtml );
                        }
+
+                       $checkboxes[ $legacyName ] = $checkboxHtml;
                }
 
                // Avoid PHP 7.1 warning of passing $this by reference
                $editPage = $this;
-               Hooks::run( 'EditPageBeforeEditChecks', [ &$editPage, &$checkboxes, &$tabindex ] );
+               Hooks::run( 'EditPageBeforeEditChecks', [ &$editPage, &$checkboxes, &$tabindex ], '1.29' );
                return $checkboxes;
        }
 
index 0c8d1c6..816271f 100644 (file)
@@ -164,10 +164,10 @@ class Linker {
        }
 
        /**
-        * Make appropriate markup for a link to the current article. This is
-        * currently rendered as the bold link text. The calling sequence is the
-        * same as the other make*LinkObj static functions, despite $query not
-        * being used.
+        * Make appropriate markup for a link to the current article. This is since
+        * MediaWiki 1.29.0 rendered as an <a> tag without an href and with a class
+        * showing the link text. The calling sequence is the same as for the other
+        * make*LinkObj static functions, but $query is not used.
         *
         * @since 1.16.3
         * @param Title $nt
@@ -179,7 +179,7 @@ class Linker {
         * @return string
         */
        public static function makeSelfLinkObj( $nt, $html = '', $query = '', $trail = '', $prefix = '' ) {
-               $ret = "<strong class=\"selflink\">{$prefix}{$html}</strong>{$trail}";
+               $ret = "<a class=\"mw-selflink selflink\">{$prefix}{$html}</a>{$trail}";
                if ( !Hooks::run( 'SelfLinkBegin', [ $nt, &$html, &$trail, &$prefix, &$ret ] ) ) {
                        return $ret;
                }
@@ -188,7 +188,7 @@ class Linker {
                        $html = htmlspecialchars( $nt->getPrefixedText() );
                }
                list( $inside, $trail ) = self::splitTrail( $trail );
-               return "<strong class=\"selflink\">{$prefix}{$html}{$inside}</strong>{$trail}";
+               return "<a class=\"mw-selflink selflink\">{$prefix}{$html}{$inside}</a>{$trail}";
        }
 
        /**
index 521c02c..ef0563e 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use Psr\Log\LoggerInterface;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ChronologyProtector;
 use Wikimedia\Rdbms\LBFactory;
@@ -942,24 +943,45 @@ class MediaWiki {
                        $n = intval( $jobRunRate );
                }
 
-               $runJobsLogger = LoggerFactory::getInstance( 'runJobs' );
+               $logger = LoggerFactory::getInstance( 'runJobs' );
 
-               // Fall back to running the job(s) while the user waits if needed
-               if ( !$this->config->get( 'RunJobsAsync' ) ) {
-                       $runner = new JobRunner( $runJobsLogger );
-                       $runner->run( [ 'maxJobs' => $n ] );
-                       return;
-               }
-
-               // Do not send request if there are probably no jobs
                try {
-                       $group = JobQueueGroup::singleton();
-                       if ( !$group->queuesHaveJobs( JobQueueGroup::TYPE_DEFAULT ) ) {
-                               return;
+                       if ( $this->config->get( 'RunJobsAsync' ) ) {
+                               // Send an HTTP request to the job RPC entry point if possible
+                               $invokedWithSuccess = $this->triggerAsyncJobs( $n, $logger );
+                               if ( !$invokedWithSuccess ) {
+                                       // Fall back to blocking on running the job(s)
+                                       $logger->warning( "Jobs switched to blocking; Special:RunJobs disabled" );
+                                       $this->triggerSyncJobs( $n, $logger );
+                               }
+                       } else {
+                               $this->triggerSyncJobs( $n, $logger );
                        }
                } catch ( JobQueueError $e ) {
+                       // Do not make the site unavailable (T88312)
                        MWExceptionHandler::logException( $e );
-                       return; // do not make the site unavailable
+               }
+       }
+
+       /**
+        * @param integer $n Number of jobs to try to run
+        * @param LoggerInterface $runJobsLogger
+        */
+       private function triggerSyncJobs( $n, LoggerInterface $runJobsLogger ) {
+               $runner = new JobRunner( $runJobsLogger );
+               $runner->run( [ 'maxJobs' => $n ] );
+       }
+
+       /**
+        * @param integer $n Number of jobs to try to run
+        * @param LoggerInterface $runJobsLogger
+        * @return bool Success
+        */
+       private function triggerAsyncJobs( $n, LoggerInterface $runJobsLogger ) {
+               // Do not send request if there are probably no jobs
+               $group = JobQueueGroup::singleton();
+               if ( !$group->queuesHaveJobs( JobQueueGroup::TYPE_DEFAULT ) ) {
+                       return true;
                }
 
                $query = [ 'title' => 'Special:RunJobs',
@@ -1026,12 +1048,6 @@ class MediaWiki {
                        $runJobsLogger->error( "Failed to start cron API (socket error $errno): $errstr" );
                }
 
-               // Fall back to running the job(s) while the user waits if needed
-               if ( !$invokedWithSuccess ) {
-                       $runJobsLogger->warning( "Jobs switched to blocking; Special:RunJobs disabled" );
-
-                       $runner = new JobRunner( $runJobsLogger );
-                       $runner->run( [ 'maxJobs'  => $n ] );
-               }
+               return $invokedWithSuccess;
        }
 }
index 8cf3af1..cc589c9 100644 (file)
@@ -25,6 +25,7 @@
  * @file
  */
 use Wikimedia\Timestamp\TimestampException;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Handles the backend logic of merging the histories of two
index 486abd8..bae974f 100644 (file)
@@ -19,6 +19,8 @@
  *
  * @file
  */
+
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
index d909a65..ccdedb8 100644 (file)
@@ -22,6 +22,7 @@
 
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * List for revision table items for a single page
@@ -36,7 +37,7 @@ abstract class RevisionListBase extends ContextSource implements Iterator {
        /** @var ResultWrapper|bool */
        protected $res;
 
-       /** @var bool|object */
+       /** @var bool|Revision */
        protected $current;
 
        /**
index 105a581..bc6b842 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Static accessor class for site_stats and related things
  */
index e45994c..f16f0c5 100644 (file)
@@ -21,6 +21,8 @@
  *
  * @file
  */
+
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\Interwiki\InterwikiLookup;
 use MediaWiki\MediaWikiServices;
@@ -4028,7 +4030,10 @@ class Title implements LinkTarget {
                        $row = $db->selectRow( 'revision', Revision::selectFields(),
                                [ 'rev_page' => $pageId ],
                                __METHOD__,
-                               [ 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ]
+                               [
+                                       'ORDER BY' => 'rev_timestamp ASC',
+                                       'IGNORE INDEX' => 'rev_timestamp'
+                               ]
                        );
                        if ( $row ) {
                                return new Revision( $row );
index bc57049..ba77074 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\LoadBalancer;
index 6301576..93d5033 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Extension mechanism for WatchedItemQueryService
index caa3fdb..70fdbf1 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
index 942b731..b2002ff 100644 (file)
@@ -42,7 +42,7 @@ class PurgeAction extends FormAction {
        }
 
        public function onSubmit( $data ) {
-               return $this->page->doPurge( WikiPage::PURGE_ALL );
+               return $this->page->doPurge();
        }
 
        public function show() {
index 0ba964f..134b8a4 100644 (file)
@@ -58,9 +58,6 @@ class ViewAction extends FormlessAction {
                                $touched = null;
                        }
 
-                       // If a page was purged on HTTP GET, relect that timestamp to avoid sending 304s
-                       $touched = max( $touched, $this->page->getLastPurgeTimestamp() );
-
                        // Send HTTP 304 if the IMS matches or otherwise set expiry/last-modified headers
                        if ( $touched && $this->getOutput()->checkLastModified( $touched ) ) {
                                wfDebug( __METHOD__ . ": done 304\n" );
index c03faf0..fec4234 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * This abstract class implements many basic API functions, and is the base of
  * all API classes.
index 7d16af8..85c6860 100644 (file)
@@ -25,6 +25,7 @@
  */
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * This class contains a list of pages that the client has requested.
index 3124638..407497e 100644 (file)
@@ -56,7 +56,7 @@ class ApiPurge extends ApiBase {
                        $page = WikiPage::factory( $title );
                        if ( !$user->pingLimiter( 'purge' ) ) {
                                // Directly purge and skip the UI part of purge()
-                               $page->doPurge( WikiPage::PURGE_ALL );
+                               $page->doPurge();
                                $r['purged'] = true;
                        } else {
                                $this->addWarning( 'apierror-ratelimited' );
index ef6bb6a..8ce122c 100644 (file)
@@ -26,6 +26,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Query module to enumerate all available pages.
  *
@@ -85,6 +87,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                $db = $this->getDB();
 
                $params = $this->extractRequestParams();
+               $userId = !is_null( $params['user'] ) ? User::idFromName( $params['user'] ) : null;
 
                // Table and return fields
                $this->addTables( 'image' );
@@ -189,7 +192,11 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
 
                        // Image filters
                        if ( !is_null( $params['user'] ) ) {
-                               $this->addWhereFld( 'img_user_text', $params['user'] );
+                               if ( $userId ) {
+                                       $this->addWhereFld( 'img_user', $userId );
+                               } else {
+                                       $this->addWhereFld( 'img_user_text', $params['user'] );
+                               }
                        }
                        if ( $params['filterbots'] != 'all' ) {
                                $this->addTables( 'user_groups' );
@@ -269,7 +276,11 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                if ( $params['sort'] == 'timestamp' ) {
                        $this->addOption( 'ORDER BY', 'img_timestamp' . $sortFlag );
                        if ( !is_null( $params['user'] ) ) {
-                               $this->addOption( 'USE INDEX', [ 'image' => 'img_usertext_timestamp' ] );
+                               if ( $userId ) {
+                                       $this->addOption( 'USE INDEX', [ 'image' => 'img_user_timestamp' ] );
+                               } else {
+                                       $this->addOption( 'USE INDEX', [ 'image' => 'img_usertext_timestamp' ] );
+                               }
                        } else {
                                $this->addOption( 'USE INDEX', [ 'image' => 'img_timestamp' ] );
                        }
index 262b5eb..97d487b 100644 (file)
        "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Ajoute l’horodatage de la modification.",
        "apihelp-query+recentchanges-paramvalue-prop-title": "Ajoute le titre de la page modifiée.",
        "apihelp-query+recentchanges-paramvalue-prop-ids": "Ajoute l’ID de la page, l’ID des modifications récentes et l’ID de l’ancienne et la nouvelle révisions.",
-       "apihelp-query+recentchanges-paramvalue-prop-sizes": "Ajoute l’ancienne et la nouvelle tailles de la page en octets.",
+       "apihelp-query+recentchanges-paramvalue-prop-sizes": "Ajoute l’ancienne et la nouvelle taille de la page en octets.",
        "apihelp-query+recentchanges-paramvalue-prop-redirect": "Marque la modification si la page est une redirection.",
        "apihelp-query+recentchanges-paramvalue-prop-patrolled": "Marque les modifications patrouillables comme patrouillées ou non.",
        "apihelp-query+recentchanges-paramvalue-prop-loginfo": "Ajoute les informations du journal (Id du journal, type de trace, etc.) aux entrées du journal.",
index ec20f8a..eb19ede 100644 (file)
        "apihelp-delete-param-watch": "문서를 현재 사용자의 주시문서 목록에 추가합니다.",
        "apihelp-delete-param-unwatch": "문서를 현재 사용자의 주시문서 목록에서 제거합니다.",
        "apihelp-delete-example-simple": "<kbd>Main Page</kbd>를 삭제합니다.",
+       "apihelp-delete-example-reason": "<kbd>Preparing for move</kbd> 라는 이유로 <kbd>Main Page</kbd>를 삭제하기.",
        "apihelp-disabled-description": "이 모듈은 해제되었습니다.",
        "apihelp-edit-description": "문서를 만들고 편집합니다.",
+       "apihelp-edit-param-title": "편집할 문서의 제목. <var>$1pageid</var>과 같이 사용할 수 없습니다.",
        "apihelp-edit-param-section": "문단 번호입니다. <kbd>0</kbd>은 최상위 문단, <kbd>new</kbd>는 새 문단입니다.",
        "apihelp-edit-param-sectiontitle": "새 문단을 위한 제목.",
        "apihelp-edit-param-text": "문서 내용.",
index c340d4a..7d5f7ea 100644 (file)
@@ -11,7 +11,8 @@
                        "Caçador de Palavras",
                        "LucyDiniz",
                        "Eduardo Addad de Oliveira",
-                       "Warley Felipe C."
+                       "Warley Felipe C.",
+                       "TheEduGobi"
                ]
        },
        "apihelp-main-param-action": "Qual ação executar.",
@@ -22,6 +23,7 @@
        "apihelp-main-param-requestid": "Qualquer valor dado aqui será incluído na resposta. Pode ser usado para distinguir requisições.",
        "apihelp-main-param-servedby": "Inclua o nome de host que atendeu a solicitação nos resultados.",
        "apihelp-main-param-curtimestamp": "Inclui a data atual no resultado.",
+       "apihelp-main-param-origin": "Ao acessar a API usando uma solicitação AJAX por domínio cruzado (CORS), defina isto como o domínio de origem. Isto deve estar incluso em toda solicitação ''pre-flight'', sendo portanto parte do URI da solicitação (ao invés do corpo do POST).\n\nPara solicitações autenticadas, isto deve corresponder a uma das origens no cabeçalho <code>Origin</code>, para que seja algo como <kbd>https://pt.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Se este parâmetro não corresponder ao cabeçalho <code>Origin</code>, uma resposta 403 será retornada. Se este parâmetro corresponder ao cabeçalho <code>Origin</code> e a origem for permitida (''whitelisted''), os cabeçalhos <code>Access-Control-Allow-Origin</code> e <code>Access-Control-Allow-Credentials</code> serão definidos.\n\nPara solicitações não autenticadas, especifique o valor <kbd>*</kbd>. Isto fará com que o cabeçalho <code>Access-Control-Allow-Origin</code> seja definido, porém o <code>Access-Control-Allow-Credentials</code> será <code>false</code> e todos os dados específicos para usuários tornar-se-ão restritos.",
        "apihelp-block-description": "Bloquear um usuário",
        "apihelp-block-param-user": "Nome de usuário, endereço IP ou faixa de IP para bloquear.",
        "apihelp-block-param-reason": "Razão do bloqueio.",
@@ -91,7 +93,7 @@
        "apihelp-feedcontributions-param-newonly": "Mostrar somente as edições que são criação de páginas.",
        "apihelp-feedcontributions-param-hideminor": "Ocultar edições menores.",
        "apihelp-feedcontributions-param-showsizediff": "Mostrar a diferença de tamanho entre as revisões.",
-       "apihelp-feedrecentchanges-description": "Retorna um feed de alterações recentes.",
+       "apihelp-feedrecentchanges-description": "Retorna um ''feed'' de mudanças recentes.",
        "apihelp-feedrecentchanges-param-feedformat": "O formato do feed.",
        "apihelp-feedrecentchanges-param-namespace": "Espaço nominal a partir do qual limitar resultados.",
        "apihelp-feedrecentchanges-param-invert": "Todos os espaços nominais, exceto o selecionado.",
        "apihelp-feedrecentchanges-param-hidecategorization": "Alterações de membros pertencentes à uma categoria.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por tag.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar as mudanças recentes.",
-       "apihelp-feedrecentchanges-example-30days": "Mostrar as alterações recentes por 30 dias.",
+       "apihelp-feedrecentchanges-example-30days": "Mostrar as mudanças recentes por 30 dias.",
        "apihelp-feedwatchlist-description": "Retornar um feed da lista de vigiados.",
        "apihelp-feedwatchlist-param-feedformat": "O formato do feed.",
        "apihelp-feedwatchlist-param-hours": "Lista páginas modificadas dentro dessa quantia de horas a partir de agora.",
index 1396458..e6a1c75 100644 (file)
        "apihelp-query+protectedtitles-example-simple": "Lista skyddade titlar.",
        "apihelp-query+recentchanges-example-simple": "Lista de senaste ändringarna.",
        "apihelp-query+revisions-example-first5-not-localhost": "Hämta första 5 revideringarna av \"huvudsidan\" och som inte gjorts av anonym användare \"127.0.0.1\"",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "Returnerar en lista över språkkoder som [[mw:LanguageConverter|LanguageConverter]] har aktiverat och de varianter som varje stöder.",
        "apihelp-query+siteinfo-example-simple": "Hämta information om webbplatsen.",
        "apihelp-query+stashimageinfo-description": "Returnerar filinformation för temporära filer.",
        "apihelp-query+stashimageinfo-param-filekey": "Nyckel som identifierar en tidigare uppladdning som lagrats temporärt.",
index 0a07a93..7215606 100644 (file)
@@ -28,6 +28,7 @@
 
 use Wikimedia\Rdbms\ResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class for fetching backlink lists, approximate backlink counts and
index 77ab2d5..57d4581 100644 (file)
@@ -23,6 +23,7 @@
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class representing a list of titles
index b720dec..57f66f1 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Cache
  */
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 
index e7e2d10..52611ec 100644 (file)
@@ -18,6 +18,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * LCStore implementation which uses the standard DB functions to store data.
  * This will work on any MediaWiki installation.
index b6be1f9..d0c4b77 100644 (file)
@@ -22,6 +22,8 @@
  * @author Matthew Flaschen
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * An individual filter in a boolean group
  *
index befc213..86ae33f 100644 (file)
@@ -22,6 +22,8 @@
  * @author Matthew Flaschen
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Represents a filter group with multiple string options. They are passed to the server as
  * a single form parameter separated by a delimiter.  The parameter name is the
index dd8bab9..a37f5f2 100644 (file)
@@ -49,8 +49,9 @@ abstract class ChangeTagsList extends RevisionListBase {
                                $className = 'ChangeTagsLogList';
                                break;
                        default:
-                               throw new Exception( "Class $className requested, but does not exist" );
+                               throw new Exception( "Class $typeName requested, but does not exist" );
                }
+
                return new $className( $context, $title, $ids );
        }
 
index 480aace..271005f 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup Change tagging
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Stores a list of taggable log entries.
  * @since 1.25
index 8eae238..a0248c6 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup Change tagging
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Stores a list of taggable revisions.
  * @since 1.25
index c4921e2..809b660 100644 (file)
@@ -24,6 +24,7 @@
  * @ingroup Database
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IMaintainableDatabase;
 
 class CloneDatabase {
        /** @var string Table prefix for cloning */
index 07c6fc7..fbbc962 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * The oci8 extension is fairly weak and doesn't support oci_num_rows, among
  * other things. We use a wrapper class to handle that and other
index 6585575..8b62989 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Deferrable Update for closure/callback updates via IDatabase::doAtomicSection()
  * @since 1.27
index d61dec2..f9297af 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Deferrable Update for closure/callback updates that should use auto-commit mode
  * @since 1.28
index 0a9755d..bbe8687 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\LBFactory;
 use Wikimedia\Rdbms\LoadBalancer;
index 7215696..ca29078 100644 (file)
@@ -21,6 +21,7 @@
  */
 use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Update object handling the cleanup of links tables after a page was deleted.
index 0133f19..5697960 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
 
index 5247e97..5b822af 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Deferrable Update for closure/callback
  */
index 7426624..aefa7f5 100644 (file)
@@ -19,6 +19,7 @@
  */
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class for handling updates to the site_stats table
index 25e8841..2411bef 100644 (file)
@@ -21,6 +21,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * @deprecated Since 1.28 Use DataUpdate directly, injecting the database
  */
index 33ddc59..b12af19 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use Psr\Log\LoggerInterface;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class for fixing stale WANObjectCache keys using a purge event source
index e41ab54..a307468 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * @ingroup SpecialPage Dump
index d907c30..6bb1618 100644 (file)
@@ -21,6 +21,9 @@
  */
 
 use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\MaintainableDBConnRef;
 
 /**
  * DB accessable external objects.
index 62e635d..d09c245 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Version of FileJournal that logs to a DB table
index 5936e7d..8510d0c 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * MySQL version of DBLockManager that supports shared locks.
  *
index 5bc60a0..856dc36 100644 (file)
@@ -23,6 +23,9 @@
  * @author Aaron Schulz
  */
 
+use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\MaintainableDBConnRef;
+
 /**
  * @brief Proxy backend that manages file layout rewriting for FileRepo.
  *
index 3e88508..29c017c 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup FileRepo
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * A foreign repository with an accessible MediaWiki database
  *
index d5e29ab..9c92bc0 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A repository that stores files in the local filesystem and registers them
index a633fd2..c109fba 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use \MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class to represent a local file in the wiki's own database
index 8d58ce5..88cc510 100644 (file)
@@ -609,19 +609,17 @@ class MWHttpRequest implements LoggerAwareInterface {
                                }
                        }
 
-                       if ( $foundRelativeURI ) {
-                               if ( $domain ) {
-                                       return $domain . $locations[$countLocations - 1];
-                               } else {
-                                       $url = parse_url( $this->url );
-                                       if ( isset( $url['host'] ) ) {
-                                               return $url['scheme'] . '://' . $url['host'] .
-                                                       $locations[$countLocations - 1];
-                                       }
-                               }
-                       } else {
+                       if ( !$foundRelativeURI ) {
                                return $locations[$countLocations - 1];
                        }
+                       if ( $domain ) {
+                               return $domain . $locations[$countLocations - 1];
+                       }
+                       $url = parse_url( $this->url );
+                       if ( isset( $url['host'] ) ) {
+                               return $url['scheme'] . '://' . $url['host'] .
+                                       $locations[$countLocations - 1];
+                       }
                }
 
                return $this->url;
index 0305535..22717fc 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Deployment
  */
 use Wikimedia\Rdbms\LBFactorySingle;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Base class for DBMS-specific installation helper classes.
index 98d354c..8913c77 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Deployment
  */
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 
 require_once __DIR__ . '/../../maintenance/Maintenance.php';
index 9aa9572..74033ab 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "Skoret eo ar reizhiadoù diaz titouroù da-heul gant MediaWiki :\n\n$1\n\nMa ne welit ket amañ dindan ar reizhiad diaz titouroù a fell deoc'h ober ganti, heuilhit an titouroù a-us (s.o. al liammoù) evit gweredekaat ar skorañ.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] eo an dibab kentañ evit MediaWiki hag an hini skoret ar gwellañ. Mont a ra MediaWiki en-dro gant [{{int:version-db-mariadb-url}} MariaDB] ha [{{int:version-db-percona-url}} Percona Server] ivez, kenglotus o-daou gant MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Penaos kempunañ PHP gant skor MySQL])",
-       "config-dbsupport-postgres": "* Ur reizhiad diaz titouroù brudet ha digor eo $1. Gallout a ra ober evit MySQL ([http://www.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL]). Gallout a ra bezañ un nebeud drein bihan enni ha n'eo ket erbedet he implijout en un endro produiñ.",
-       "config-dbsupport-sqlite": "* $1 zo ur reizhiad diaz titouroù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] zo anezhi ur reizhiad diaz roadennoù frank a wirioù brudet-mat a c'haller ober gantañ e plas MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] zo anezhi ur reizhiad diaz roadennoù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
        "config-dbsupport-oracle": "* $1 zo un diaz titouroù kenwerzhel. ([http://www.php.net/manual/en/oci8.installation.php Penaos kempunañ PHP gant skor OCI8])",
        "config-header-mysql": "Arventennoù MySQL",
        "config-header-postgres": "Arventennoù PostgreSQL",
index 2f58947..540b8c5 100644 (file)
  * @file
  * @author Aaron Schulz
  */
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
+use Wikimedia\Rdbms\DBConnRef;
 
 /**
  * Class to handle job queues stored in the DB
index d76d866..ba80c8e 100644 (file)
@@ -20,6 +20,7 @@
  *
  * @file
  */
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 
 class PurgeJobUtils {
index b17b1a0..8ef8196 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup LockManager
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Version of LockManager based on using named/row DB locks.
  *
index fc00965..49b2fe6 100644 (file)
@@ -3,8 +3,6 @@
 namespace Wikimedia\Rdbms;
 
 use Database;
-use DBConnRef;
-use IDatabase;
 use InvalidArgumentException;
 
 /**
index fc3ebe0..0d5fbf5 100644 (file)
@@ -1,8 +1,9 @@
 <?php
 
-use Wikimedia\Rdbms\DatabaseDomain;
-use Wikimedia\Rdbms\ILoadBalancer;
-use Wikimedia\Rdbms\DBMasterPos;
+namespace Wikimedia\Rdbms;
+
+use Database;
+use InvalidArgumentException;
 
 /**
  * Helper class to handle automatically marking connections as reusable (via RAII pattern)
@@ -603,3 +604,5 @@ class DBConnRef implements IDatabase {
                }
        }
 }
+
+class_alias( 'Wikimedia\Rdbms\DBConnRef', 'DBConnRef' );
index 92adaf9..fbfd899 100644 (file)
@@ -33,6 +33,8 @@ use Wikimedia\Rdbms\ResultWrapper;
 use Wikimedia\Rdbms\DBMasterPos;
 use Wikimedia\Rdbms\Blob;
 use Wikimedia\Timestamp\ConvertibleTimestamp;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\IMaintainableDatabase;
 
 /**
  * Relational database abstraction object
@@ -366,7 +368,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                $class = 'Database' . ucfirst( $driver );
-               if ( class_exists( $class ) && is_subclass_of( $class, 'IDatabase' ) ) {
+               if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
                        // Resolve some defaults for b/c
                        $p['host'] = isset( $p['host'] ) ? $p['host'] : false;
                        $p['user'] = isset( $p['user'] ) ? $p['user'] : false;
@@ -1955,7 +1957,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return string
         */
        protected function indexName( $index ) {
-               return $index;
+               // Backwards-compatibility hack
+               $renamed = [
+                       'ar_usertext_timestamp' => 'usertext_timestamp',
+                       'un_user_id' => 'user_id',
+                       'un_user_ip' => 'user_ip',
+               ];
+
+               if ( isset( $renamed[$index] ) ) {
+                       return $renamed[$index];
+               } else {
+                       return $index;
+               }
        }
 
        public function addQuotes( $s ) {
index 090ce8e..2a5deb6 100644 (file)
@@ -430,6 +430,16 @@ class DatabaseSqlite extends Database {
                return str_replace( '"', '', parent::tableName( $name, $format ) );
        }
 
+       /**
+        * Index names have DB scope
+        *
+        * @param string $index
+        * @return string
+        */
+       protected function indexName( $index ) {
+               return $index;
+       }
+
        /**
         * This must be called after nextSequenceVal
         *
index 6bc870b..0b146cd 100644 (file)
  * @file
  * @ingroup Database
  */
+namespace Wikimedia\Rdbms;
+
 use Wikimedia\ScopedCallback;
-use Wikimedia\Rdbms\Blob;
-use Wikimedia\Rdbms\LikeMatch;
-use Wikimedia\Rdbms\DBMasterPos;
-use Wikimedia\Rdbms\Field;
-use Wikimedia\Rdbms\IResultWrapper;
+use DBError;
+use DBConnectionError;
+use DBUnexpectedError;
+use DBQueryError;
+use Exception;
+use RuntimeException;
+use UnexpectedValueException;
+use stdClass;
 
 /**
  * Basic database interface for live and lazy-loaded relation database handles
@@ -1802,3 +1807,5 @@ interface IDatabase {
         */
        public function setTableAliases( array $aliases );
 }
+
+class_alias( 'Wikimedia\Rdbms\IDatabase', 'IDatabase' );
index 43cec28..138cf2d 100644 (file)
  * @file
  * @ingroup Database
  */
+namespace Wikimedia\Rdbms;
+
+use Exception;
+use RuntimeException;
+use DBUnexpectedError;
 
 /**
  * Advanced database interface for IDatabase handles that include maintenance methods
@@ -206,3 +211,5 @@ interface IMaintainableDatabase extends IDatabase {
                $oldName, $newName, $temporary = false, $fname = __METHOD__
        );
 }
+
+class_alias( 'Wikimedia\Rdbms\IMaintainableDatabase', 'IMaintainableDatabase' );
index fa3ddf9..30c62de 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+namespace Wikimedia\Rdbms;
+
 /**
  * Helper class to handle automatically marking connections as reusable (via RAII pattern)
  * as well handling deferring the actual network connection until the handle is used
@@ -66,3 +69,5 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 }
+
+class_alias( 'Wikimedia\Rdbms\MaintainableDBConnRef', 'MaintainableDBConnRef' );
index c3367e7..cbc8ca3 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use Wikimedia\Rdbms\ILoadBalancer;
+use Wikimedia\Rdbms\IDatabase;
 
 /**@{
  * Database related constants
index 47f8c96..dca1302 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Database
  */
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * @ingroup Database
index 526596d..226c675 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Database
  */
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Database error base class
index 7d303b1..57538a8 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Database
  */
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Base class for the more common types of database errors. These are known to occur
index 002d253..b4c3d52 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Database
  */
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * @ingroup Database
index f05dabc..86547b9 100644 (file)
@@ -30,7 +30,6 @@ use EmptyBagOStuff;
 use WANObjectCache;
 use Exception;
 use RuntimeException;
-use IDatabase;
 use DBTransactionError;
 use DBReplicationWaitError;
 
@@ -508,7 +507,8 @@ abstract class LBFactory implements ILBFactory {
                        'errorLogger' => $this->errorLogger,
                        'hostname' => $this->hostname,
                        'cliMode' => $this->cliMode,
-                       'agent' => $this->agent
+                       'agent' => $this->agent,
+                       'chronologyProtector' => $this->getChronologyProtector()
                ];
        }
 
index 447b96f..0384588 100644 (file)
@@ -23,7 +23,6 @@
 
 namespace Wikimedia\Rdbms;
 
-use IDatabase;
 use InvalidArgumentException;
 
 /**
@@ -252,9 +251,7 @@ class LBFactoryMulti extends LBFactory {
        public function getMainLB( $domain = false ) {
                $section = $this->getSectionForDomain( $domain );
                if ( !isset( $this->mainLBs[$section] ) ) {
-                       $lb = $this->newMainLB( $domain );
-                       $this->getChronologyProtector()->initLB( $lb );
-                       $this->mainLBs[$section] = $lb;
+                       $this->mainLBs[$section] = $this->newMainLB( $domain );
                }
 
                return $this->mainLBs[$section];
@@ -283,7 +280,6 @@ class LBFactoryMulti extends LBFactory {
        public function getExternalLB( $cluster ) {
                if ( !isset( $this->extLBs[$cluster] ) ) {
                        $this->extLBs[$cluster] = $this->newExternalLB( $cluster );
-                       $this->getChronologyProtector()->initLB( $this->extLBs[$cluster] );
                }
 
                return $this->extLBs[$cluster];
index 15cd508..df0a806 100644 (file)
@@ -89,7 +89,6 @@ class LBFactorySimple extends LBFactory {
        public function getMainLB( $domain = false ) {
                if ( !isset( $this->mainLB ) ) {
                        $this->mainLB = $this->newMainLB( $domain );
-                       $this->getChronologyProtector()->initLB( $this->mainLB );
                }
 
                return $this->mainLB;
@@ -106,7 +105,6 @@ class LBFactorySimple extends LBFactory {
        public function getExternalLB( $cluster ) {
                if ( !isset( $this->extLBs[$cluster] ) ) {
                        $this->extLBs[$cluster] = $this->newExternalLB( $cluster );
-                       $this->getChronologyProtector()->initLB( $this->extLBs[$cluster] );
                }
 
                return $this->extLBs[$cluster];
index 5931d80..cd998c3 100644 (file)
@@ -23,7 +23,6 @@
 
 namespace Wikimedia\Rdbms;
 
-use IDatabase;
 use InvalidArgumentException;
 use BadMethodCallException;
 
index 4c277ff..2ea0e4e 100644 (file)
  */
 namespace Wikimedia\Rdbms;
 
-use IDatabase;
 use Database;
-use DBConnRef;
-use MaintainableDBConnRef;
 use DBError;
 use DBAccessError;
 use DBTransactionError;
@@ -105,6 +102,7 @@ interface ILoadBalancer {
         *  - srvCache : BagOStuff object for server cache [optional]
         *  - memCache : BagOStuff object for cluster memory cache [optional]
         *  - wanCache : WANObjectCache object [optional]
+        *  - chronologyProtector: ChronologyProtector object [optional]
         *  - hostname : The name of the current server [optional]
         *  - cliMode: Whether the execution context is a CLI script. [optional]
         *  - profiler : Class name or instance with profileIn()/profileOut() methods. [optional]
@@ -138,7 +136,7 @@ interface ILoadBalancer {
         * If a DB_REPLICA connection has been opened already, then wait immediately.
         * Otherwise sets a variable telling it to wait if such a connection is opened.
         *
-        * @param DBMasterPos $pos
+        * @param DBMasterPos|bool $pos Master position or false
         */
        public function waitFor( $pos );
 
@@ -147,7 +145,7 @@ interface ILoadBalancer {
         *
         * This can be used a faster proxy for waitForAll()
         *
-        * @param DBMasterPos $pos
+        * @param DBMasterPos|bool $pos Master position or false
         * @param int $timeout Max seconds to wait; default is mWaitTimeout
         * @return bool Success (able to connect and no timeouts reached)
         */
@@ -156,7 +154,7 @@ interface ILoadBalancer {
        /**
         * Set the master wait position and wait for ALL replica DBs to catch up to it
         *
-        * @param DBMasterPos $pos
+        * @param DBMasterPos|bool $pos Master position or false
         * @param int $timeout Max seconds to wait; default is mWaitTimeout
         * @return bool Success (able to connect and no timeouts reached)
         */
index 6878712..d178657 100644 (file)
@@ -25,10 +25,7 @@ namespace Wikimedia\Rdbms;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
 use Wikimedia\ScopedCallback;
-use IDatabase;
 use Database;
-use DBConnRef;
-use MaintainableDBConnRef;
 use BagOStuff;
 use EmptyBagOStuff;
 use WANObjectCache;
@@ -69,6 +66,8 @@ class LoadBalancer implements ILoadBalancer {
 
        /** @var ILoadMonitor */
        private $loadMonitor;
+       /** @var ChronologyProtector|null */
+       private $chronProt;
        /** @var BagOStuff */
        private $srvCache;
        /** @var BagOStuff */
@@ -124,6 +123,8 @@ class LoadBalancer implements ILoadBalancer {
 
        /** @var boolean */
        private $disabled = false;
+       /** @var boolean */
+       private $chronProtInitialized = false;
 
        /** @var integer Warn when this many connection are held */
        const CONN_HELD_WARN_THRESHOLD = 10;
@@ -222,6 +223,10 @@ class LoadBalancer implements ILoadBalancer {
                        : ( gethostname() ?: 'unknown' );
                $this->cliMode = isset( $params['cliMode'] ) ? $params['cliMode'] : PHP_SAPI === 'cli';
                $this->agent = isset( $params['agent'] ) ? $params['agent'] : '';
+
+               if ( isset( $params['chronologyProtector'] ) ) {
+                       $this->chronProt = $params['chronologyProtector'];
+               }
        }
 
        /**
@@ -424,21 +429,24 @@ class LoadBalancer implements ILoadBalancer {
                return $i;
        }
 
-       /**
-        * @param DBMasterPos|false $pos
-        */
        public function waitFor( $pos ) {
+               $oldPos = $this->mWaitForPos;
                $this->mWaitForPos = $pos;
-               $i = $this->mReadIndex;
 
+               // If a generic reader connection was already established, then wait now
+               $i = $this->mReadIndex;
                if ( $i > 0 ) {
                        if ( !$this->doWait( $i ) ) {
                                $this->laggedReplicaMode = true;
                        }
                }
+
+               // Restore the older position if it was higher
+               $this->setWaitForPositionIfHigher( $oldPos );
        }
 
        public function waitForOne( $pos, $timeout = null ) {
+               $oldPos = $this->mWaitForPos;
                $this->mWaitForPos = $pos;
 
                $i = $this->mReadIndex;
@@ -456,10 +464,14 @@ class LoadBalancer implements ILoadBalancer {
                        $ok = true; // no applicable loads
                }
 
+               // Restore the older position if it was higher
+               $this->setWaitForPositionIfHigher( $oldPos );
+
                return $ok;
        }
 
        public function waitForAll( $pos, $timeout = null ) {
+               $oldPos = $this->mWaitForPos;
                $this->mWaitForPos = $pos;
                $serverCount = count( $this->mServers );
 
@@ -470,9 +482,25 @@ class LoadBalancer implements ILoadBalancer {
                        }
                }
 
+               // Restore the older position if it was higher
+               $this->setWaitForPositionIfHigher( $oldPos );
+
                return $ok;
        }
 
+       /**
+        * @param DBMasterPos|bool $pos
+        */
+       private function setWaitForPositionIfHigher( $pos ) {
+               if ( !$pos ) {
+                       return;
+               }
+
+               if ( !$this->mWaitForPos || $pos->hasReached( $this->mWaitForPos ) ) {
+                       $this->mWaitForPos = $pos;
+               }
+       }
+
        /**
         * @param int $i
         * @return IDatabase|bool
@@ -718,6 +746,13 @@ class LoadBalancer implements ILoadBalancer {
                        $domain = false; // local connection requested
                }
 
+               if ( !$this->chronProtInitialized && $this->chronProt ) {
+                       $this->connLogger->debug( __METHOD__ . ': calling initLB() before first connection.' );
+                       // Load CP positions before connecting so that doWait() triggers later if needed
+                       $this->chronProtInitialized = true;
+                       $this->chronProt->initLB( $this );
+               }
+
                if ( $domain !== false ) {
                        $conn = $this->openForeignConnection( $i, $domain );
                } elseif ( isset( $this->mConns['local'][$i][0] ) ) {
index 5e92c33..d120b6f 100644 (file)
@@ -24,7 +24,6 @@ namespace Wikimedia\Rdbms;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
 use Wikimedia\ScopedCallback;
-use IDatabase;
 use BagOStuff;
 
 /**
index c9f1345..1c5899b 100644 (file)
@@ -28,6 +28,8 @@
  * @since 1.19
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Interface for log entries. Every log entry has these methods.
  *
index 4382910..317652a 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 class LogEventsList extends ContextSource {
        const NO_ACTION_LINK = 1;
index f93b1b5..b7ebfc9 100644 (file)
@@ -97,7 +97,7 @@ class IPTC {
                                case '2#025': /* keywords */
                                        $data['Keywords'] = self::convIPTC( $val, $c );
                                        break;
-                               case '2#101': /* Country (shown)*/
+                               case '2#101': /* Country (shown) */
                                        $data['CountryDest'] = self::convIPTC( $val, $c );
                                        break;
                                case '2#095': /* state/province (shown) */
@@ -115,7 +115,7 @@ class IPTC {
                                case '2#040': /* special instructions */
                                        $data['SpecialInstructions'] = self::convIPTC( $val, $c );
                                        break;
-                               case '2#105': /* headline*/
+                               case '2#105': /* headline */
                                        $data['Headline'] = self::convIPTC( $val, $c );
                                        break;
                                case '2#110': /* credit */
index 07581d7..8f94374 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Cache
  */
 
+use Wikimedia\Rdbms\IDatabase;
 use \MediaWiki\MediaWikiServices;
 use \Wikimedia\WaitConditionLoop;
 use \Wikimedia\Rdbms\TransactionProfiler;
index cb97126..ee0ff22 100644 (file)
@@ -1133,7 +1133,7 @@ class Article implements Page {
                        || $title->getNamespace() == NS_USER_TALK
                ) {
                        $rootPart = explode( '/', $title->getText() )[0];
-                       $user = User::newFromName( $rootPart, false /* allow IP users*/ );
+                       $user = User::newFromName( $rootPart, false /* allow IP users */ );
                        $ip = User::isIP( $rootPart );
                        $block = Block::newFromTarget( $user, $user );
 
@@ -2043,16 +2043,20 @@ class Article implements Page {
        /**
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::doPurge
+        * @note In 1.28 (and only 1.28), this took a $flags parameter that
+        *  controlled how much purging was done.
         */
-       public function doPurge( $flags = WikiPage::PURGE_ALL ) {
-               return $this->mPage->doPurge( $flags );
+       public function doPurge() {
+               return $this->mPage->doPurge();
        }
 
        /**
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::getLastPurgeTimestamp
+        * @deprecated since 1.29
         */
        public function getLastPurgeTimestamp() {
+               wfDeprecated( __METHOD__, '1.29' );
                return $this->mPage->getLastPurgeTimestamp();
        }
 
index 388e693..c2bfb07 100644 (file)
@@ -20,6 +20,7 @@
 
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Used to show archived pages and eventually restore them.
index e4b524b..66fadf5 100644 (file)
@@ -164,9 +164,12 @@ class WikiFilePage extends WikiPage {
                return $this->mDupes;
        }
 
-       public function doPurge( $flags = self::PURGE_ALL ) {
+       /**
+        * Override handling of action=purge
+        * @return bool
+        */
+       public function doPurge() {
                $this->loadFile();
-
                if ( $this->mFile->exists() ) {
                        wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
                        DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ) );
@@ -182,8 +185,7 @@ class WikiFilePage extends WikiPage {
                        // Purge redirect cache
                        $this->mRepo->invalidateImageRedirect( $this->mTitle );
                }
-
-               return parent::doPurge( $flags );
+               return parent::doPurge();
        }
 
        /**
index 4bc8ad6..7044e6a 100644 (file)
@@ -23,6 +23,7 @@
 use \MediaWiki\Logger\LoggerFactory;
 use \MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class representing a MediaWiki article and history.
@@ -84,9 +85,10 @@ class WikiPage implements Page, IDBAccessObject {
         */
        protected $mLinksUpdated = '19700101000000';
 
-       const PURGE_CDN_CACHE = 1; // purge CDN cache for page variant URLs
-       const PURGE_CLUSTER_PCACHE = 2; // purge parser cache in the local datacenter
-       const PURGE_GLOBAL_PCACHE = 4; // set page_touched to clear parser cache in all datacenters
+       /** @deprecated since 1.29. Added in 1.28 for partial purging, no longer used. */
+       const PURGE_CDN_CACHE = 1;
+       const PURGE_CLUSTER_PCACHE = 2;
+       const PURGE_GLOBAL_PCACHE = 4;
        const PURGE_ALL = 7;
 
        /**
@@ -574,35 +576,12 @@ class WikiPage implements Page, IDBAccessObject {
         * @return Revision|null
         */
        public function getOldestRevision() {
-
                // Try using the replica DB first, then try the master
-               $continue = 2;
-               $db = wfGetDB( DB_REPLICA );
-               $revSelectFields = Revision::selectFields();
-
-               $row = null;
-               while ( $continue ) {
-                       $row = $db->selectRow(
-                               [ 'revision' ],
-                               $revSelectFields,
-                               [
-                                       'rev_page' => $this->getId()
-                               ],
-                               __METHOD__,
-                               [
-                                       'ORDER BY' => 'rev_timestamp ASC'
-                               ]
-                       );
-
-                       if ( $row ) {
-                               $continue = 0;
-                       } else {
-                               $db = wfGetDB( DB_MASTER );
-                               $continue--;
-                       }
+               $rev = $this->mTitle->getFirstRevision();
+               if ( !$rev ) {
+                       $rev = $this->mTitle->getFirstRevision( Title::GAID_FOR_UPDATE );
                }
-
-               return $row ? Revision::newFromRow( $row ) : null;
+               return $rev;
        }
 
        /**
@@ -1119,10 +1098,11 @@ class WikiPage implements Page, IDBAccessObject {
 
        /**
         * Perform the actions of a page purging
-        * @param integer $flags Bitfield of WikiPage::PURGE_* constants
         * @return bool
+        * @note In 1.28 (and only 1.28), this took a $flags parameter that
+        *  controlled how much purging was done.
         */
-       public function doPurge( $flags = self::PURGE_ALL ) {
+       public function doPurge() {
                // Avoid PHP 7.1 warning of passing $this by reference
                $wikiPage = $this;
 
@@ -1130,30 +1110,15 @@ class WikiPage implements Page, IDBAccessObject {
                        return false;
                }
 
-               if ( ( $flags & self::PURGE_GLOBAL_PCACHE ) == self::PURGE_GLOBAL_PCACHE ) {
-                       // Set page_touched in the database to invalidate all DC caches
-                       $this->mTitle->invalidateCache();
-               } elseif ( ( $flags & self::PURGE_CLUSTER_PCACHE ) == self::PURGE_CLUSTER_PCACHE ) {
-                       // Delete the parser options key in the local cluster to invalidate the DC cache
-                       ParserCache::singleton()->deleteOptionsKey( $this );
-                       // Avoid sending HTTP 304s in ViewAction to the client who just issued the purge
-                       $cache = ObjectCache::getLocalClusterInstance();
-                       $cache->set(
-                               $cache->makeKey( 'page', 'last-dc-purge', $this->getId() ),
-                               wfTimestamp( TS_MW ),
-                               $cache::TTL_HOUR
-                       );
-               }
+               $this->mTitle->invalidateCache();
 
-               if ( ( $flags & self::PURGE_CDN_CACHE ) == self::PURGE_CDN_CACHE ) {
-                       // Clear any HTML file cache
-                       HTMLFileCache::clearFileCache( $this->getTitle() );
-                       // Send purge after any page_touched above update was committed
-                       DeferredUpdates::addUpdate(
-                               new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
-                               DeferredUpdates::PRESEND
-                       );
-               }
+               // Clear file cache
+               HTMLFileCache::clearFileCache( $this->getTitle() );
+               // Send purge after above page_touched update was committed
+               DeferredUpdates::addUpdate(
+                       new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
+                       DeferredUpdates::PRESEND
+               );
 
                if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
                        $messageCache = MessageCache::singleton();
@@ -1168,11 +1133,11 @@ class WikiPage implements Page, IDBAccessObject {
         *
         * @return string|bool TS_MW timestamp or false
         * @since 1.28
+        * @deprecated since 1.29. It will always return false.
         */
        public function getLastPurgeTimestamp() {
-               $cache = ObjectCache::getLocalClusterInstance();
-
-               return $cache->get( $cache->makeKey( 'page', 'last-dc-purge', $this->getId() ) );
+               wfDeprecated( __METHOD__, '1.29' );
+               return false;
        }
 
        /**
index 4694890..0b867ef 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * IndexPager is an efficient pager which uses a (roughly unique) index in the
index 6a6a3c2..19d5471 100644 (file)
@@ -67,23 +67,27 @@ class ResourceLoaderImage {
                                }
                        }
                }
+               // Remove 'deprecated' key
+               if ( is_array( $this->descriptor ) ) {
+                       unset( $this->descriptor[ 'deprecated' ] );
+               }
 
                // Ensure that all files have common extension.
                $extensions = [];
-               $descriptor = (array)$descriptor;
+               $descriptor = (array)$this->descriptor;
                array_walk_recursive( $descriptor, function ( $path ) use ( &$extensions ) {
                        $extensions[] = pathinfo( $path, PATHINFO_EXTENSION );
                } );
                $extensions = array_unique( $extensions );
                if ( count( $extensions ) !== 1 ) {
                        throw new InvalidArgumentException(
-                               "File type for different image files of '$name' not the same"
+                               "File type for different image files of '$name' not the same in module '$module'"
                        );
                }
                $ext = $extensions[0];
                if ( !isset( self::$fileTypes[$ext] ) ) {
                        throw new InvalidArgumentException(
-                               "Invalid file type for image files of '$name' (valid: svg, png, gif, jpg)"
+                               "Invalid file type for image files of '$name' (valid: svg, png, gif, jpg) in module '$module'"
                        );
                }
                $this->extension = $ext;
index 91e63e7..d72b3af 100644 (file)
@@ -23,8 +23,6 @@
 
 class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
 
-       /* Methods */
-
        /**
         * @param ResourceLoaderContext $context
         * @return array
@@ -77,13 +75,12 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
                return false;
        }
 
-       /**
-        * @param ResourceLoaderContext $context
-        * @return string: Hash
-        */
-       public function getModifiedHash( ResourceLoaderContext $context ) {
-               $logo = $this->getConfig()->get( 'Logo' );
-               $logoHD = $this->getConfig()->get( 'LogoHD' );
-               return md5( parent::getModifiedHash( $context ) . $logo . json_encode( $logoHD ) );
+       public function getDefinitionSummary( ResourceLoaderContext $context ) {
+               $summary = parent::getDefinitionSummary( $context );
+               $summary[] = [
+                       'logo' => $this->getConfig()->get( 'Logo' ),
+                       'logoHD' => $this->getConfig()->get( 'LogoHD' ),
+               ];
+               return $summary;
        }
 }
index f6f14b3..92095f7 100644 (file)
@@ -22,6 +22,8 @@
  * @author Roan Kattouw
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Abstraction for ResourceLoader modules which pull from wiki pages
  *
index ad9259b..9afaf40 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * List for archive table items, i.e. revisions deleted via action=delete
  */
index afee637..1d80d86 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * List for filearchive table items
  */
index 9beafc9..62bafe9 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Item class for an oldimage table row
  */
index 00cb2e1..77cf976 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * List for oldimage table items
  */
index ff1d2ed..1932778 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * List for logging table items
  */
index 453c6cc..1ea6a38 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * List for revision table items
index 7f41eb2..7812fb9 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup RevisionDelete
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Backend functions for suppressing and unsuppressing all references to a given user,
  * used when blocking with HideUser enabled.  This was spun out of SpecialBlockip.php
index 38c60d0..d51e525 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Search
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Base search engine base class for database-backed searches
  * @ingroup Search
index a767bc3..613d33c 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Factory class for SearchEngine.
  * Allows to create engine of the specific type.
index 1832233..2ece5aa 100644 (file)
@@ -22,6 +22,7 @@
  */
 use MediaWiki\Logger\LoggerFactory;
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Special page which uses a ChangesList to show query results.
@@ -426,6 +427,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                if ( $rows === false ) {
                        if ( !$this->including() ) {
                                $this->doHeader( $opts, 0 );
+                               $this->outputNoResults();
                                $this->getOutput()->setStatusCode( 404 );
                        }
 
@@ -445,7 +447,6 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        }
                }
                $batch->execute();
-
                $this->webOutput( $rows, $opts );
 
                $rows->free();
@@ -459,6 +460,17 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                }
        }
 
+       /**
+        * Add the "no results" message to the output
+        */
+       protected function outputNoResults() {
+               $this->getOutput()->addHTML(
+                       '<div class="mw-changeslist-empty">' .
+                       $this->msg( 'recentchanges-noresult' )->parse() .
+                       '</div>'
+               );
+       }
+
        /**
         * Get the database result for this special page instance. Used by ApiFeedRecentChanges.
         *
index bafee65..59abefd 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Variant of QueryPage which uses a gallery to output results, thus
index 45cef2b..76b1535 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Variant of QueryPage which formats the result as a simple link to the page
index 7bc2dfa..68d2d30 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * This is a class for doing query pages; since they're almost all the same,
index e7bc496..d788f2b 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Class definition for a wanted query page like
index 9aba41e..cd9345d 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page listing redirects to non existent page. Those should be
index 59351dc..d7e99db 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page listing redirects to redirecting page.
index a1f5efa..dae6074 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Special:LinkSearch to search the external-links table.
index 52c710d..d5fb001 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Special:ListDuplicatedFiles Lists all files where the current version is
index b2d6a33..5f38629 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Special:Listredirects - Lists all the redirects on the wiki.
index a88767a..7c4b490 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * @ingroup SpecialPage
index 0776eec..bebed12 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page that list pages that have highest category count
index 8560dca..c140ee9 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page that listed pages that have highest interwiki count
index ff8550d..fbfaa73 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page to show pages ordered by the number of pages linking to them.
index 699940b..956207f 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A querypage to show categories ordered in descending order by the pages in them
index f5c2c5f..dee1c8e 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Special page lists templates with a large number of
index 9e3a750..12dae8b 100644 (file)
@@ -39,6 +39,7 @@ class SpecialNewFiles extends IncludableSpecialPage {
                $opts = new FormOptions();
 
                $opts->add( 'like', '' );
+               $opts->add( 'user', '' );
                $opts->add( 'showbots', false );
                $opts->add( 'hidepatrolled', false );
                $opts->add( 'limit', 50 );
@@ -75,6 +76,12 @@ class SpecialNewFiles extends IncludableSpecialPage {
                                'name' => 'like',
                        ],
 
+                       'user' => [
+                               'type' => 'text',
+                               'label-message' => 'newimages-user',
+                               'name' => 'user',
+                       ],
+
                        'showbots' => [
                                'type' => 'check',
                                'label-message' => 'newimages-showbots',
index 205f7cf..3e7971a 100644 (file)
@@ -398,11 +398,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $rclistOutput .= $list->endRecentChangesList();
 
                if ( $rows->numRows() === 0 ) {
-                       $this->getOutput()->addHTML(
-                               '<div class="mw-changeslist-empty">' .
-                               $this->msg( 'recentchanges-noresult' )->parse() .
-                               '</div>'
-                       );
+                       $this->outputNoResults();
                        if ( !$this->including() ) {
                                $this->getOutput()->setStatusCode( 404 );
                        }
index a5e5113..3282a7a 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * SpecialShortpages extends QueryPage. It is used to return the shortest
index e82279e..fea7e21 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page that displays a list of pages that are not on anyones watchlist.
index 4a17533..9066148 100644 (file)
@@ -23,6 +23,7 @@
 
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * A special page that lists last changes made to the wiki,
index 439b6ab..6f91c46 100644 (file)
@@ -21,6 +21,8 @@
  * @todo Use some variant of Pager or something; the pagination here is lousy.
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Implements Special:Whatlinkshere
  *
index 5126bad..1133625 100644 (file)
@@ -26,6 +26,7 @@
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\ResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 class ContribsPager extends ReverseChronologicalPager {
 
index 3789dfa..47b059b 100644 (file)
@@ -193,7 +193,8 @@ class ImageListPager extends TablePager {
                }
                $sortable = [ 'img_timestamp', 'img_name', 'img_size' ];
                /* For reference, the indicies we can use for sorting are:
-                * On the image table: img_usertext_timestamp, img_size, img_timestamp
+                * On the image table: img_user_timestamp, img_usertext_timestamp,
+                * img_size, img_timestamp
                 * On oldimage: oi_usertext_timestamp, oi_name_timestamp
                 *
                 * In particular that means we cannot sort by timestamp when not filtering
index 4bf5dff..b781930 100644 (file)
@@ -55,6 +55,16 @@ class NewFilesPager extends ReverseChronologicalPager {
                $fields = [ 'img_name', 'img_user', 'img_timestamp' ];
                $options = [];
 
+               $user = $opts->getValue( 'user' );
+               if ( $user !== '' ) {
+                       $userId = User::idFromName( $user );
+                       if ( $userId ) {
+                               $conds['img_user'] = $userId;
+                       } else {
+                               $conds['img_user_text'] = $user;
+                       }
+               }
+
                if ( !$opts->getValue( 'showbots' ) ) {
                        $groupsWithBotPermission = User::getGroupsWithPermission( 'bot' );
 
index 59ca31c..81a4083 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Represents a "user group membership" -- a specific instance of a user belonging
  * to a group. For example, the fact that user Mary belongs to the sysop group is a
index d801fa0..4df73f7 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Cut-down copy of User interface for local-interwiki-database
  * user rights manipulation.
index 43bccba..e107fb1 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Allows iterating a large number of rows in batches transparently.
  * By default when iterated over returns the full query result as an
index a6e47c8..70afb91 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Maintenance
  */
+use Wikimedia\Rdbms\IDatabase;
 use \MediaWiki\MediaWikiServices;
 
 class BatchRowWriter {
index b1b8c73..1911c79 100644 (file)
@@ -131,7 +131,7 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                        : "";
 
                if ( isset( $this->customCaptions[$iwPrefix] ) ) {
-                       /* customCaptions composed by loadCustomCaptions() with pre-escaped content.*/
+                       /* customCaptions composed by loadCustomCaptions() with pre-escaped content. */
                        $caption = $this->customCaptions[$iwPrefix];
                } else {
                        $interwiki = $this->iwLookup->fetch( $iwPrefix );
index b4a66a0..51c69e6 100644 (file)
        "post-expand-template-argument-warning": "'''تحذير:''' هذه الصفحة تحتوي على عامل قالب واحد على الأقل له حجم تمدد كبير جدا.\nهذه العوامل تم حذفها.",
        "post-expand-template-argument-category": "تجاوزات معطيات القوالب",
        "parser-template-loop-warning": "تم كشف حلقة قالب: [[$1]]",
+       "template-loop-category": "الصفحات بحلقات قالب",
+       "template-loop-category-desc": "الصفحة تحتوي على حلقة قالب، أي أن القالب يستدعي نفسه.",
        "parser-template-recursion-depth-warning": "تم تجاوز حد عمق فرد القوالب ($1)",
        "language-converter-depth-warning": "تم تخطي حد عمق محول اللغة ($1)",
        "node-count-exceeded-category": "تجاوزات تعداد العقد",
        "newimages-summary": "هذه الصفحة الخاصة تعرض آخر الملفات المرفوعة.",
        "newimages-legend": "المرشح",
        "newimages-label": "اسم الملف (أو جزء منه):",
+       "newimages-user": "عنوان الأيبي أو اسم المستخدم",
        "newimages-showbots": "أظهر التحميلات بواسطة البوتات",
        "newimages-hidepatrolled": "أخف المرفوعات المنظورة",
        "noimages": "لا شيء للعرض.",
index 0120e9b..9de4469 100644 (file)
@@ -10,7 +10,8 @@
                        "Ramsis II",
                        "아라",
                        "Oldstoneage",
-                       "Macofe"
+                       "Macofe",
+                       "Abdelrhaman Eid"
                ]
        },
        "tog-underline": "حط خط تحت اللينكات:",
        "externaldberror": "يا إما فى حاجة غلط فى الدخول على قاعدة البيانات الخارجية أو انت مش مسموح لك تعمل تحديث لحسابك الخارجي.",
        "login": "دخول",
        "nav-login-createaccount": "تسجيل دخول / فتح حساب",
-       "userlogin": "دخول / فتح حساب",
-       "userloginnocreate": "دخول",
        "logout": "خروج",
        "userlogout": "خروج",
        "notloggedin": "انت مش مسجل دخولك",
        "userlogin-noaccount": "معندكش حساب؟",
        "userlogin-joinproject": "انضم ل {{SITENAME}}",
-       "nologin": "معندكش حساب؟ '''$1'''.",
-       "nologinlink": "افتح حساب",
        "createaccount": "افتح حساب",
-       "gotaccount": "عندك حساب؟ '''$1'''.",
-       "gotaccountlink": "دخول",
-       "userlogin-resetlink": "نسيت تفاصيل الدخول؟",
        "userlogin-helplink2": "مساعده ف الدخول",
        "createacct-email-ph": "أكتب عنوان الإيميل بتاعك",
        "createaccountmail": "استخدم باسورد مؤقته و إبعتها ع الايميل المحدد ده",
-       "createaccountreason": "السبب:",
        "createacct-reason": "سبب:",
        "createacct-submit": "افتح حسابك",
        "createacct-benefit-body1": "$1 {{PLURAL:$1|تعديل|تعديلات}}",
        "logentry-newusers-create": "تم فتح حساب {{GENDER:$2|اليوزر|اليوزره}} $1",
        "logentry-upload-upload": " {{GENDER:$2|رفع|اترفعت}} $1 $3",
        "rightsnone": "(فاضى)",
-       "revdelete-summary": "ملخص التعديل",
        "searchsuggest-search": "تدوير",
        "searchsuggest-containing": "جوّاه...",
        "expandtemplates": "تكبير القوالب",
index 2baf6af..6c90b1f 100644 (file)
        "nstab-special": "Ka ici wectakaniok",
        "nstab-project": "nohwe ma",
        "nstab-image": "Masinhikan",
+       "nstab-template": "Tapapitcikan",
        "nstab-category": "Ka ici arimotcikatek",
        "mainpage-nstab": "Otitikowin",
        "error": "Oniparin",
        "databaseerror-error": "Oniparin: $1",
        "badtitle": "nama mia icinikatew",
+       "badtitletext": "Nama takon nohwe e icinikatek paskickwemikan ,cikoctew,kekotc nama mia ki otci icinikatcikatew e itectamakaniwok nte arimwewinik kekotc nte otamirowinik.\nPotc osam nipira aitisinihikana actetikena nama tca ki actakaniwona tan e icinikatcikateki kekwan.",
        "viewsource": "Nte ici nta kanawapata e otciparik",
        "yourname": "Icinikasowin:",
        "userlogin-yourname": "Icinikasowin",
        "login": "Posi",
        "logout": "Piskeapikenakan",
        "userlogout": "Piskeapikenakan",
+       "userlogin-noaccount": " Nama takon ki mockinesinihikan?",
+       "userlogin-joinproject": "Pe natcipicta {{ohwe itipiwin}}",
        "createaccount": "Masinahotiso",
        "userlogin-resetpassword-link": "Ki onikan kipitakesinihikan?",
+       "userlogin-helplink2": "Witcihewin kata pitakeapikecinaniwok",
        "createacct-emailrequired": "Pamikicikwepitcikan matcetcicihikan",
        "createacct-emailoptional": "Pamikicikwepitcikan matcetcicihikan (kir kotc)",
        "createacct-email-ph": "Pitakesinaha ki pamikicikwepitcikan matcetcicihikan",
        "botpasswords-label-cancel": "Ponipita",
        "botpasswords-label-delete": "Wepina",
        "resetpass-submit-cancel": "Ponipita",
+       "passwordreset": "Ka ocehikaniin itewin koski masinaha",
        "passwordreset-username": "Icinikasowin:",
        "passwordreset-email": "Pamikicikwepitcikan matcetcicihikan:",
        "bold_sample": "Atisokesinahikan e makatewasinatek",
        "templatesused": "{{PLURAL:$1|tapapitcikan ka apatak |tapapitcikan ka apatak}} nta paskickwemakanik:",
        "template-protected": "(nakatweritcikatew)",
        "template-semiprotected": "(apita nakatoweritakon)",
+       "moveddeleted-notice": "Paskickwemakan ka ki wepinikatek.\nOhwe wapatcikan nitc ici nokon  paskickwemakanik ka ki wepinikateki acit ka ki atcipitcikateki .",
        "content-model-javascript": "JavaScript",
        "viewpagelogs": "Kinawapta kekwan kaki isparik ota masinhikanik",
        "revisionasof": "Kiwe wapata $1",
        "enhancedrc-history": "isparik",
        "recentchanges": "Ka ki meckotcitakanioki",
        "recentchanges-legend": " Ka meckotcitain matcenikana",
+       "recentchanges-summary": "Paskickwemikan ke ici nosanetain ka ki ocki meckotcisinihikatekai wikik.",
        "recentchanges-label-newpage": "Ocki paskickwemikan ki ocitamakan",
        "recentchanges-label-minor": "Apicic meckotciparin",
        "recentchanges-label-bot": "Icike ki meckotciparin",
        "historyaction-submit": "Wapata",
        "dellogpage": " Nesitc ka wepinikatek kanaweritcikan",
        "rollbacklink": "e maninikatek",
+       "protectlogpage": "Nanakatisiwina wapatcikan",
        "restriction-edit": "Meckotcita",
        "undeleteviewlink": "tapwatcike",
        "undelete-search-submit": "Nantokaskeritcikatek",
        "tooltip-t-whatlinkshere": "Ka masinateti ite e ici itohikemakak",
        "tooltip-t-recentchangeslinked": "Ka masinateki anihi kaki atcitakaniwok",
        "tooltip-feed-atom": "Atom itapihikan ohwe otci paskickwemikan",
+       "tooltip-t-contributions": "Ka masinasotcik ka witcihiwetcik{{GENDER:$1|ka ntotcitatc}}",
        "tooltip-t-upload": "Matceticiha masinhikan",
        "tooltip-t-specialpages": "Kotahaki masinhikana",
        "tooltip-t-print": "Matci keki orowipitaman kitci masinatekipan",
        "tooltip-ca-nstab-special": "Ohowe kitcickwemakinikan,nama actew kitci meckotcitaparik.",
        "tooltip-ca-nstab-project": "Kitci wapataman nehe masinihikan ocki otamirowinik otci",
        "tooltip-ca-nstab-image": "Kitci wapitaman nehe masinhikan",
+       "tooltip-ca-nstab-template": "kanawapata orictawisinihikan",
        "tooltip-ca-nstab-category": "Kitci wapitaman nehe mia ka ici arimotcikatek",
        "tooltip-save": "Kinokepita ka meckotcisinihaman",
        "tooltip-preview": "Mikwetc pitaman e kanawapataman kaki meckotcitain, e pwamici actain pamikicikwepitcikanik.",
        "tooltip-diff": "Nokota nohwe ka ki meckotcisinihaham  masinihikanik",
+       "tooltip-rollback": "\"Nakaha\" nikanikatew kotc peikwa e makohotc nohwe makonakan kaskina ka ki meckotcisinihikateki nta paskickwemakanik nohwe ka ki orisinihiketc mamitcit",
+       "tooltip-undo": "\"Nama ntowatc\"nihictamikan nictam meckotcisinihikan minawatc cepirihomikon taci e ici meckotcisinihikaniwok ke ici kanawapataman.Matci kaie ki ka acotcitan kekwan espirik  nta nosem masinihikanik.",
        "tooltip-summary": "Acta e arimotaman masinihikan apicic",
        "simpleantispam-label": "Ntokiskeritcike piciriwe masinihikan \n\nNte nota <strong>nama kekwan</strong> masinaha ota!",
        "pageinfo-toolboxlink": "Tipatcimo masinahikan",
        "pageinfo-contentpage-yes": "Ehe",
        "pageinfo-protect-cascading-yes": "Ehe",
        "confirm-markpatrolled-button": "OK",
+       "nextdiff": "Tec meckotcisinihikan",
        "show-big-image": "E otciparik masinahikaniwoc",
        "show-big-image-preview": "E irikweckwemikisitc$1",
        "show-big-image-size": "$1 x $2 pixels",
        "saturday-at": "mari kicikaw $1",
        "sunday-at": "manactakaniwon $1",
        "metadata": "E ici tipatcitcikatek",
+       "metadata-fields": "Nohwe e aitotwakaniwitc masinasowin nta kata ici actew paskickwemakanik ka ici tipatcimonaniwok ickwa atciwonikateke nta kitci tipatcimoniwocik. Minawatc kotakahi kata katcictakaniwona.\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-orientation": "Itactamictew",
        "exif-datetime": "Apitc ka meckotcitakaniwok",
        "exif-make": "Ka ki ocitatatc masinapiskihikaniw",
        "exif-model": "E icinakok masinapiskohewin",
+       "exif-software": "Tipatcimocikimiwesinikan ka totcikatek",
+       "exif-colorspace": "Icipekihikanik",
        "exif-datetimeoriginal": "E tato piponikak nictam ka masinohaniwok",
        "exif-datetimedigitized": "e tato konekisit pisimw ka capwapiskipitcikatek",
        "exif-source": "Ite wetciparik",
index bc6a601..4630658 100644 (file)
        "userrights-nodatabase": "$1 базаһы юҡ йәки урындағы (локаль) база түгел.",
        "userrights-changeable-col": "Һеҙ үҙгәртә алған төркөмдәр",
        "userrights-unchangeable-col": "Һеҙ үҙгәртә алмаған төркөмдәр",
+       "userrights-expiry-options": "1 көн:1 day,1 аҙна:1 week,1 ай:1 mopnth, 3 ай:3 months,6 ай:6 months,1 йыл:1 year",
        "userrights-conflict": "Ҡатнашыусының хоҡуҡтарын үҙгәртеү яраманы! Зинһар, үҙгәрештәрҙе тикшерегеҙ һәм яңынан индерегеҙ.",
        "group": "Төркөм:",
        "group-user": "Ҡулланыусылар",
index 9602673..83c9c56 100644 (file)
        "post-expand-template-argument-warning": "<strong>Увага</strong>: гэтая старонка ўтрымлівае прынамсі адзін парамэтар шаблёну, які мае занадта вялікі выгляд у разгорнутым выглядзе.\nГэтыя парамэтры былі прапушчаныя.",
        "post-expand-template-argument-category": "Старонкі, у якіх прапушчаныя парамэтры шаблёнаў",
        "parser-template-loop-warning": "Выяўлены цыкль у шаблёнах: [[$1]]",
+       "template-loop-category": "Старонкі з цыклямі шаблёнаў",
+       "template-loop-category-desc": "Старонка ўтрымлівае цыкль шаблёну, г. зн., шаблён уключае сам сябе рэкурсіўна.",
        "parser-template-recursion-depth-warning": "Перавышаны ліміт глыбіні рэкурсіі шаблёну ($1)",
        "language-converter-depth-warning": "Перавышанае абмежаваньне глыбіні канвэртару варыянтаў мовы ($1)",
        "node-count-exceeded-category": "Старонкі зь перавышанай колькасьцю вузлоў",
index acc2b37..d076f51 100644 (file)
        "default-skin-not-found-no-skins": "Упс! Прадвызначаная вокладка для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code>, недаступна.\n\nВы не ўстанавілі вокладкі.\n\n; Калі вы толькі што ўстанавілі ці абнавілі MediaWiki:\n: Магчыма, вы ўстанавілі з git, ці наўпрост з зыходнага коду, выкарыстаўшы іншы метад. Гэта нармальна. MediaWiki 1.24 і навейшыя не ўключаюць вокладкі ў асноўнае сховішча. Паспрабуйце ўстанавіць некалькі вокладак з [https://www.mediawiki.org/wiki/Category:All_skins каталога вокладак mediawiki.org], такім чынам:\n:* Узяўшы [https://www.mediawiki.org/wiki/Download tarball-інсталятар], які ўтрымлівае некалькі вокладак і прыставак. Вы можаце скапіяваць і ўставіць каталог <code>skins/</code> адтуль.\n:* Зрабіўшы клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталог <code>skins/</code> вашай інсталяцыі MediaWiki.\n: Калі вы распрацоўшчык MediaWiki, гэта не павінна адбіцца на вашым git-сховішчы. Гл. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя: Настройка вокладак] дзеля інфармацыі па ўключэнні вокладак і выбары прадвызначэння.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (уключана)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>выключана</strong>)",
+       "mediastatistics-table-extensions": "Магчымыя прыстаўкі",
        "mediastatistics-table-count": "Колькасць файлаў",
        "mediastatistics-table-totalbytes": "Агульны памер",
        "mediastatistics-header-unknown": "Невядомыя",
index ee3e58f..29d49bc 100644 (file)
        "jumptosearch": "অনুসন্ধান",
        "view-pool-error": "দুঃখিত, সার্ভারে এ মূহুর্তে অতিরিক্ত চাপ রয়েছে।\nঅনেক বেশি সংখ্যক ব্যবহারকারী এই পাতাটি দেখার চেষ্টা করছেন।\nনতুন করে এ পাতাটি দেখার চেষ্টা করার আগে কিছুক্ষণ অপেক্ষা করুন।\n\n$1",
        "generic-pool-error": "দুঃখিত, সার্ভারে এ মূহুর্তে অতিরিক্ত চাপ রয়েছে।\nঅনেক বেশি সংখ্যক ব্যবহারকারী এই পাতাটি দেখার চেষ্টা করছেন।\nনতুন করে এ পাতাটি দেখার চেষ্টা করার আগে কিছুক্ষণ অপেক্ষা করুন।",
-       "pool-timeout": "সময় à¦\89তà§\8dতিরà§\8dণ à¦²à¦\95-à¦\8fর à¦\9cনà§\8dয à¦\85পà§\87à¦\95à§\8dষারত",
+       "pool-timeout": "à¦\85বরà§\8bধà§\87র à¦\9cনà§\8dয à¦\85পà§\87à¦\95à§\8dষা à¦\95রতà§\87 à¦\97িয়à§\87 à¦¸à¦®à¦¯à¦¼ à¦\89তà§\8dতà§\80রà§\8dণ",
        "pool-queuefull": "পুলের লাইন পূর্ণ",
        "pool-errorunknown": "অজানা ত্রুটি",
        "pool-servererror": "পুল কাউন্টার সার্ভিস নিষ্ক্রিয় ($1)।",
        "editsectionhint": "অনুচ্ছেদ সম্পাদনা: $1",
        "toc": "পরিচ্ছেদসমূহ",
        "showtoc": "দেখাও",
-       "hidetoc": "লà§\81à¦\95িয়à§\87 à¦°à¦¾à¦\96া à¦¹à§\8bà¦\95",
+       "hidetoc": "লà§\81à¦\95িয়à§\87 à¦°à¦¾à¦\96à§\81ন",
        "collapsible-collapse": "সংকোচন",
        "collapsible-expand": "প্রসারণ",
        "confirmable-confirm": "{{GENDER:$1|আপনি}} কি নিশ্চিত?",
        "transaction-duration-limit-exceeded": "দীর্ঘ পুনঃসৃষ্টি বিলম্ব এড়ানোর জন্য এই ট্রানজাকশনটি বাতিল করা হল, কারণ লিখনের স্থায়িত্ব ($1) $2 সেকেন্ড সীমাটিকে অতিক্রম করে গিয়েছিল। \nযদি আপনি অনেকগুলি আইটেম একসাথে পরিবর্তন করতে চান, তাহলে একাধিক ক্ষুদ্রতর অপারেশন সম্পন্ন করার চেষ্টা করুন।",
        "laggedslavemode": "<strong>সতর্ক বার্তা:</strong> পাতাটি সম্ভবত সম্প্রতি হালনাগাদ করা হয়নি।",
        "readonly": "ডাটাবেজ অবরুদ্ধ",
-       "enterlockreason": "তালাবদà§\8dধ à¦\95রার à¦\95ারণ à¦\95ি à¦¤à¦¾ à¦¬à¦²à§\81ন, à¦¸à¦¾à¦¥à§\87 à¦\95à¦\96ন à¦¤à¦¾à¦²à¦¾ খুলবেন তার আনুমানিক সময় উল্লেখ করুন",
+       "enterlockreason": "à¦\85বরà§\81দà§\8dধ à¦\95রার à¦\95ারণ à¦\95à§\80 à¦¤à¦¾ à¦¬à¦²à§\81ন, à¦¸à¦¾à¦¥à§\87 à¦\95à¦\96ন à¦\85বরà§\8bধ খুলবেন তার আনুমানিক সময় উল্লেখ করুন",
        "readonlytext": "নতুন ভুক্তি এবং অন্যান্য সম্পাদনার জন্য ডাটাবেজ বর্তমানে অবরুদ্ধ করা আছে। সম্ভবত ডাটাবেজ রক্ষণাবেক্ষণের নিয়মিত কাজ চলছে। কাজ শেষ হলে এটি স্বাভাবিক অবস্থায় ফিরে আসবে।\n\nযে সিস্টেম প্রশাসক এটি অবরুদ্ধ করেছেন, তিনি এই ব্যাখ্যা দিয়েছেন: $1",
        "missing-article": "\"$1\" পাতাটির $2 লেখাটি ডাটাবেজ খুঁজে পায়নি, যদিও খুঁজে পাওয়ার কথা ছিল।\n\nসাধারণত কোন মেয়াদোত্তীর্ণ সংশোধন পার্থক্য অনুসরণ করলে অথবা  \nমুছে ফেলা কোন পাতার ইতিহাসের সংযোগ অনুসরণ করলে এমনটি ঘটে।\n\nযদি এমনটি না হয়, তাহলে আপনি হয়ত সফটওয়্যারে কোন ত্রুটি খুঁজে পেয়েছেন।\n\nঅনুগ্রহ করে ইউআরএল-টি উল্লেখ করে এ ব্যাপারে কোন [[Special:ListUsers/sysop|প্রশাসককে]] অবহিত করুন।",
        "missingarticle-rev": "(সংস্করণ#: $1)",
        "resettokens-token-label": "$1 (বর্তমান: $2)",
        "resettokens-watchlist-token": "[[Special:Watchlist|নজরতালিকায় থাকা পাতাগুলোতে পরিবর্তন]] সংক্রান্ত ওয়েব ফিডের (Atom বা RSS) টোকেন",
        "resettokens-done": "টোকেনগুলি সফলভাবে পুনঃনির্ধারিত হয়েছে।",
-       "resettokens-resetbutton": "নিরà§\8dবাà¦\9aিত à¦\9fà§\8bà¦\95à§\87নà¦\97à§\81লি à¦ªà§\81নà¦\83নিরà§\8dধারণ à¦\95রা à¦¹à§\8bà¦\95",
+       "resettokens-resetbutton": "নিরà§\8dবাà¦\9aিত à¦\9fà§\8bà¦\95à§\87নà¦\97à§\81লি à¦ªà§\81নà¦\83নিরà§\8dধারণ à¦\95রà§\81ন",
        "bold_sample": "গাঢ় লেখা",
        "bold_tip": "গাঢ় লেখা",
        "italic_sample": "তির্যক লেখা",
        "headline_sample": "শিরোনাম",
        "headline_tip": "২য় স্তরের শিরোনাম",
        "nowiki_sample": "অবিন্যাসকৃত পাঠ্য এখানে যোগ করুন",
-       "nowiki_tip": "à¦\89à¦\87à¦\95ি à¦«à¦°à¦®à§\8dযাà¦\9fিà¦\82 উপেক্ষা করা হোক",
+       "nowiki_tip": "à¦\89à¦\87à¦\95ি à¦¬à¦¿à¦¨à§\8dযাসন উপেক্ষা করা হোক",
        "image_sample": "উদাহরণ.jpg",
        "image_tip": "গ্রথিত ফাইল",
        "media_tip": "ফাইল সংযোগ",
        "sectioneditnotsupported-text": "এই সম্পাদনা পাতায় অনুচ্ছেদ সম্পাদনা সমর্থন করে না",
        "permissionserrors": "অনুমতি ত্রুটিসমূহ",
        "permissionserrorstext": "নিন্মলিখিত {{PLURAL:$1|কারণটির|কারণগুলির}} জন্য আপনার এটা করার অনুমতি নেই:",
-       "permissionserrorstext-withaction": "আপনার $2 অনুমতি নেই, যার {{PLURAL:$1|কারণ|কারণসমূহ}} হল:",
+       "permissionserrorstext-withaction": "আপনার $2 অনুমতি নেই, যার {{PLURAL:$1|কারণটি|কারণগুলি}} হল:",
        "contentmodelediterror": "আপনি এই পুনর্বিবেচনা সম্পাদনা করতে পারবেন না কারণ এর বিষয়বস্তু মডেল <code>$1</code>, যা বর্তমান বিষয়বস্তু মডেল <code>$2</code>-এর থেকে ভিন্ন।",
        "recreate-moveddeleted-warn": "'''সতর্কীকরণ: আপনি এমন একটি পাতা পুনরায় তৈরি করছেন যা পূর্বে অপসারণ করা হয়েছিল।'''\n\nআপনি পাতাটি সম্পাদনা চালিয়ে যাওয়া ঠিক হবে কিনা, তা বিবেচনা করুন।\nআপনার সুবিধার্থে পাতাটির অপলুপ্তি লগ এখানে দেয়া হলো:",
        "moveddeleted-notice": "এই পাতাটি অপসারণ করা হয়েছে।\nসূত্র হিসেবে নিচে এ পাতার অবলুপ্তি লগ দেওয়া হলো।",
        "mergehistory-list": "একীকরণযোগ্য সম্পাদনা ইতিহাস",
        "mergehistory-merge": "[[:$1]]-এর নিচের সংশোধনগুলি [[:$2]]-এর সাথে একত্র করা যাবে। রেডিও বোতাম কলামটি ব্যবহার করে কেবলমাত্র নির্দেশিত সময় ও তার আগের সমস্ত সংশোধন একত্র করুন। লক্ষ্য করুন, পরিভ্রমণ সংযোগ ব্যবহার করলে কলামটি আদি অবস্থায় ফেরত যাবে।",
        "mergehistory-go": "একত্রীকরণযোগ্য সম্পাদনাগুলি দেখানো হোক",
-       "mergehistory-submit": "সংশোধনগুলি একত্র করা হোক",
+       "mergehistory-submit": "সংশোধনগুলি একত্রীত করুন",
        "mergehistory-empty": "কোন সংশোধন একত্র করা যাবে না.",
        "mergehistory-done": "$1-এর $3{{PLURAL:$3|টি সংশোধন}} [[:$2]]-এর সাথে একত্রিত করা হয়েছে।",
        "mergehistory-fail": "ইতিহাস একত্র করা গেল না। অনুগ্রহ করে পাতাটি ও সময়ের প্যারামিটারগুলি আবার পরীক্ষা করে দেখুন।",
        "action-autocreateaccount": "স্বয়ংক্রিয়ভাবে এই বাহ্যিক ব্যবহারকারী অ্যাকাউন্ট তৈরি করার",
        "action-history": "এই পাতার ইতিহাস দেখার",
        "action-minoredit": "এই সম্পাদনাটি অনুল্লেখ্য হিসেবে চিহ্নিত করার",
-       "action-move": "পাতাà¦\9fি à¦¸à¦°à¦¿à¦¯à¦¼à§\87 à¦«à§\87লà§\81ন",
-       "action-move-subpages": "পাতাà¦\9fি à¦\8fবà¦\82 à¦\8fর à¦\89পপাতাà¦\97à§\81লà§\8b à¦¸à¦°à¦¿à¦¯à¦¼à§\87 à¦«à§\87লà§\81ন",
+       "action-move": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦¸à§\8dথানানà§\8dতর à¦\95রার",
+       "action-move-subpages": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\8fবà¦\82 à¦\8fর à¦\89পপাতাà¦\97à§\81লি à¦¸à§\8dথানানà§\8dতর à¦\95রার",
        "action-move-rootuserpages": "root ব্যবহারকারীর পাতাগুলো সরিয়ে ফেলুন",
-       "action-move-categorypages": "বিষয়শ্রেণী পাতা স্থানান্তর করা",
+       "action-move-categorypages": "বিষয়শ্রেণীর পাতা স্থানান্তর করার",
        "action-movefile": "এই ফাইল স্থানান্তর করার",
        "action-upload": "এই ফাইল আপলোড করার",
-       "action-reupload": "বিদà§\8dযমান à¦«à¦¾à¦\87ল à¦ªà§\8dরতিসà§\8dথাপন à¦\95রà§\8b",
+       "action-reupload": "à¦\8fà¦\87 à¦¬à¦¿à¦¦à§\8dযমান à¦«à¦¾à¦\87ল à¦ªà§\8dরতিসà§\8dথাপন à¦\95রার",
        "action-reupload-shared": "শেয়ার্ড রিপোজিটরীতে এই ফাইলটি হালনাগাদ করার",
-       "action-upload_by_url": "à¦\95à§\8bন à¦\87à¦\89à¦\86রà¦\8fল à¦¥à§\87à¦\95à§\87 à¦«à¦¾à¦\87লà¦\9fি à¦\86পলà§\8bড à¦\95রà§\8b",
-       "action-writeapi": "রাà¦\87à¦\9f à¦\8fপিà¦\86à¦\87 à¦¬à§\8dযবহার à¦\95রà§\81ন",
-       "action-delete": "পাতাà¦\9fি à¦®à§\81à¦\9bà§\87 à¦«à§\87লà§\8b",
+       "action-upload_by_url": "à¦\8fà¦\95à¦\9fি à¦\87à¦\89à¦\86রà¦\8fল à¦¥à§\87à¦\95à§\87 à¦\8fà¦\87 à¦«à¦¾à¦\87লà¦\9fি à¦\86পলà§\8bড à¦\95রার",
+       "action-writeapi": "à¦\8fপিà¦\86à¦\87 à¦²à§\87à¦\96া à¦¬à§\8dযবহার à¦\95রার",
+       "action-delete": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\85পসারণ à¦\95রার",
        "action-deleterevision": "সংশোধনটি মুছে ফেলার",
        "action-deletelogentry": "লগের ভুক্তি অপসারণ করার",
        "action-deletedhistory": "পাতার অপসারিত ইতিহাস দেখার",
        "action-deletedtext": "অপসারিত সংশোধনের লেখা দেখার",
-       "action-browsearchive": "অপসারিত পাতায় অনুসন্ধান করুন",
+       "action-browsearchive": "অপসারিত পাতা অনুসন্ধান করার",
        "action-undelete": "পাতাটি পুনরুদ্ধার করার",
        "action-suppressrevision": "লুকানো সংস্করণগুলো পর্যালোচনা এবং পুনঃস্থাপন করার",
        "action-suppressionlog": "এই ব্যক্তিগত লগ দেখার",
        "action-protect": "এই পাতার সুরক্ষার মাত্রা পরিবর্তন করার",
        "action-rollback": "একটি নির্দিষ্ট পাতার সর্বশেষ ব্যবহারকারীর সম্পদনা পূর্বাবস্থায় ফিরিয়ে আনুন",
        "action-import": "অন্য উইকি থেকে পাতা আমদানি করার",
-       "action-importupload": "ফাà¦\87ল à¦\86পলà§\8bড à¦¥à§\87à¦\95à§\87 à¦ªà¦¾à¦¤à¦¾ à¦\86মদানà§\80 à¦\95রà§\8b",
-       "action-patrol": "à¦\85নà§\8dযদà§\87র à¦¸à¦®à§\8dপাদনা à¦ªà¦°à§\80à¦\95à§\8dষিত à¦¬à¦²à§\87 à¦\9aিহà§\8dনিত à¦\95রà§\8b",
+       "action-importupload": "ফাà¦\87ল à¦\86পলà§\8bড à¦¥à§\87à¦\95à§\87 à¦ªà¦¾à¦¤à¦¾ à¦\86মদানি à¦\95রার",
+       "action-patrol": "à¦\85নà§\8dযদà§\87র à¦¸à¦®à§\8dপাদনা à¦ªà¦°à§\80à¦\95à§\8dষিত à¦¬à¦²à§\87 à¦\9aিহà§\8dনিত à¦\95রার",
        "action-autopatrol": "পরীক্ষিত বলে চিহ্নিত কি আপনি সম্পাদনা করেছেন",
-       "action-unwatchedpages": "নà¦\9cরতালিà¦\95া à¦¬à¦¹à¦¿à¦°à§\8dভà§\82ত à¦ªà¦¾à¦¤à¦¾à¦\97à§\81লির à¦¤à¦¾à¦²à¦¿à¦\95া à¦¦à§\87à¦\96াà¦\93",
+       "action-unwatchedpages": "নà¦\9cরতালিà¦\95া à¦¬à¦¹à¦¿à¦°à§\8dভà§\82ত à¦ªà¦¾à¦¤à¦¾à¦\97à§\81লির à¦¤à¦¾à¦²à¦¿à¦\95া à¦¦à§\87à¦\96ার",
        "action-mergehistory": "এই পাতার ইতিহাস একত্রিত করার",
-       "action-userrights": "সà¦\95ল à¦¬à§\8dযবহারà¦\95ারà§\80র à¦\85ধিà¦\95ার à¦¸à¦®à§\8dপাদনা à¦\95রà§\81ন",
-       "action-userrights-interwiki": "অন্যান্য উইকির ব্যবহারকারীদের অধিকারসমূহ সম্পাদনা করুন",
-       "action-siteadmin": "ডাটাবেজ অবরুদ্ধ করা অথবা খোলা",
+       "action-userrights": "সà¦\95ল à¦¬à§\8dযবহারà¦\95ারà§\80র à¦\85ধিà¦\95ার à¦¸à¦®à§\8dপাদনা à¦\95রার",
+       "action-userrights-interwiki": "অন্য উইকিতে ব্যবহারকারীদের অধিকার সম্পাদনা করার",
+       "action-siteadmin": "ডাটাবেজ অবরুদ্ধ করার অথবা খোলার",
        "action-sendemail": "ই-মেইল পাঠাও",
        "action-editmyoptions": "নিজের পছন্দসমূহ সম্পাদনা করার",
        "action-editmywatchlist": "আপনার নজরতালিকা পরিবর্তন করুন",
        "recentchanges-submit": "দেখাও",
        "rcfilters-activefilters": "সক্রিয় ফিল্টার",
        "rcfilters-restore-default-filters": "পূর্বনির্ধারিত ছাঁকনি পুনরুদ্ধার করুন",
-       "rcfilters-clear-all-filters": "সমসà§\8dত à¦«à¦¿à¦²à§\8dà¦\9fার à¦\85পসারণ",
+       "rcfilters-clear-all-filters": "সব à¦\9bাà¦\81à¦\95নি à¦ªà¦°à¦¿à¦·à§\8dà¦\95ার à¦\95রà§\81ন",
        "rcfilters-search-placeholder": "সাম্প্রতিক পরিবর্তনসমূহ ছাঁকুন (ব্রাউজ বা টাইপ করা শুরু করুন)",
-       "rcfilters-invalid-filter": "à¦\85à¦\95ারà§\8dযà¦\95র à¦«à¦¿à¦²à§\8dà¦\9fার",
+       "rcfilters-invalid-filter": "à¦\85à¦\95ারà§\8dযà¦\95র à¦\9bাà¦\81à¦\95নি",
        "rcfilters-empty-filter": "কোনো সক্রিয় ফিল্টার নেই। সমস্ত অবদান দেখানো হয়েছে।",
        "rcfilters-filterlist-title": "ছাঁকনি",
        "rcfilters-filterlist-whatsthis": "এটি কী?",
        "rcfilters-filterlist-feedbacklink": "নতুন (বিটা) ছাঁকনির উপর মতামত প্রদান করুন",
-       "rcfilters-highlightbutton-title": "ফলাফল আলোকপাত করুন",
+       "rcfilters-highlightbutton-title": "ফলাফল আলোকপাত করুন",
        "rcfilters-highlightmenu-title": "একটি রং নির্বাচন করুন",
-       "rcfilters-highlightmenu-help": "এই বৈশিষ্ট্য আলোকপাত করতে একটি রঙ নির্বাচন করুন",
-       "rcfilters-filterlist-noresults": "à¦\95à§\8bনà¦\93 à¦«à¦¿à¦²à§\8dà¦\9fার পাওয়া যায়নি",
+       "rcfilters-highlightmenu-help": "এই বৈশিষ্ট্যটিতে আলোকপাত করতে একটি রঙ নির্বাচন করুন",
+       "rcfilters-filterlist-noresults": "à¦\95à§\8bনà¦\93 à¦\9bাà¦\81à¦\95নি পাওয়া যায়নি",
        "rcfilters-noresults-conflict": "কোনও ফলাফল পাওয়া যায়নি কারণ অনুসন্ধানের মাপকাঠিগুলির মধ্যে সংঘর্ষ আছে",
-       "rcfilters-state-message-subset": "এই ছাঁকনিটির কোন প্রভাব নেই কারণ এর ফলাফলগুলি নিম্নোক্ত বৃহত্তর পরিধির {{PLURAL:$2|ছাঁকনির|ছাঁকনিগুলির}} মধ্যে অন্তর্ভুক্ত আছে (আলোকপাত করে এটিকে আলাদা করে দেখার চেষ্টা করুন): $1",
+       "rcfilters-state-message-subset": "à¦\8fà¦\87 à¦\9bাà¦\81à¦\95নিà¦\9fির à¦\95à§\8bন à¦ªà§\8dরভাব à¦¨à§\87à¦\87 à¦\95ারণ à¦\8fর à¦«à¦²à¦¾à¦«à¦²à¦\97à§\81লি à¦¨à¦¿à¦®à§\8dনà§\8bà¦\95à§\8dত à¦¬à§\83হতà§\8dতর à¦ªà¦°à¦¿à¦§à¦¿à¦° {{PLURAL:$2|à¦\9bাà¦\81à¦\95নিà¦\9fির|à¦\9bাà¦\81à¦\95নিà¦\97à§\81লির}} à¦®à¦§à§\8dযà§\87 à¦\85নà§\8dতরà§\8dভà§\81à¦\95à§\8dত à¦\86à¦\9bà§\87 (à¦\86লà§\8bà¦\95পাত à¦\95রà§\87 à¦\8fà¦\9fিà¦\95à§\87 à¦\86লাদা à¦\95রà§\87 à¦¦à§\87à¦\96ার à¦\9aà§\87ষà§\8dà¦\9fা à¦\95রà§\81ন): $1",
        "rcfilters-state-message-fullcoverage": "কোন দলের সমস্ত ছাঁকনি নির্বাচন করা এবং কোন ছাঁকনিই নির্বাচন না করা একই কথা, তাই এই ছাঁকনিটির কোন প্রভাব নেই। এই দলে অন্তর্ভুক্ত ছাঁকনিগুলি হল: $1",
        "rcfilters-filtergroup-registration": "ব্যবহারকারী নিবন্ধন",
        "rcfilters-filter-registered-label": "নিবন্ধিত",
        "rcfilters-filter-registered-description": "প্রবেশকৃত সম্পাদকবৃন্দ।",
        "rcfilters-filter-unregistered-label": "অনিবন্ধিত",
-       "rcfilters-filter-unregistered-description": "সমà§\8dপাদà¦\95 à¦¯à¦¾à¦°à¦¾ à¦ªà§\8dরবà§\87শ à¦\95রà§\87ন নি।",
-       "rcfilters-filter-unregistered-conflicts-user-experience-level": "এই ছাঁকনিটির সাথে নিম্নোক্ত ব্যবহারকারী অভিজ্ঞতা{{PLURAL:$2|ছাঁকনির|ছাঁকনিগুলির}} সংঘর্ষ আছে; যা কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে: $1",
-       "rcfilters-filtergroup-authorship": "à¦\95à§\83তি à¦¸à¦®à§\8dপাদনা",
+       "rcfilters-filter-unregistered-description": "যà§\87সব à¦¸à¦®à§\8dপাদà¦\95 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà§\87 à¦ªà§\8dরবà§\87শ à¦\95রà§\87ননি।",
+       "rcfilters-filter-unregistered-conflicts-user-experience-level": "এই ছাঁকনিটির সাথে নিম্নোক্ত ব্যবহারকারী অভিজ্ঞতা {{PLURAL:$2|ছাঁকনিটির|ছাঁকনিগুলির}} সংঘর্ষ আছে; যা কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে: $1",
+       "rcfilters-filtergroup-authorship": "à¦\95ার à¦¦à§\8dবারা à¦¸à¦®à§\8dপাদিত",
        "rcfilters-filter-editsbyself-label": "আপনার নিজস্ব সম্পাদনা",
-       "rcfilters-filter-editsbyself-description": "à¦\86পনার à¦¦à§\8dবারা à¦¸à¦®à§\8dপাদনা।",
-       "rcfilters-filter-editsbyother-label": "à¦\85নà§\8dযদà§\87র à¦¦à§\8dবারা à¦¸à¦®à§\8dপাদনা",
-       "rcfilters-filter-editsbyother-description": "à¦\85নà§\8dয à¦¬à§\8dযবহারà¦\95ারà§\80দà§\87র à¦¦à§\8dবারা à¦\95রা à¦¸à¦®à§\8dপাদনা (à¦\86পনার à¦¨à¦¾)।",
+       "rcfilters-filter-editsbyself-description": "à¦\86পনার à¦¸à¦®à§\8dপাদনাà¦\97à§\81লি।",
+       "rcfilters-filter-editsbyother-label": "à¦\85নà§\8dযদà§\87র à¦¸à¦®à§\8dপাদনাà¦\97à§\81লি",
+       "rcfilters-filter-editsbyother-description": "à¦\85নà§\8dয à¦¬à§\8dযবহারà¦\95ারà§\80দà§\87র à¦\95রা à¦¸à¦®à§\8dপাদনাà¦\97à§\81লি (à¦\86পনার à¦\95রা à¦¨à¦¯à¦¼)।",
        "rcfilters-filtergroup-userExpLevel": "অভিজ্ঞতার স্তর (শুধু মাত্র নিবন্ধিত ব্যবহারকারীর জন্য)",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "অভিজ্ঞতা ছাঁকনিগুলি কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে, তাই এই ছাঁকনিটি \"অনিবন্ধিত\" ছাঁকনিটির সাথে সংঘর্ষে আছে।",
        "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "\"অনিবন্ধিত\" ছাঁকনিটি এক বা তার অধিক অভিজ্ঞতা ছাঁকনির সাথে সংঘর্ষে আছে, যে ছাঁকনিগুলি কেবলমাত্র নিবন্ধিত ব্যবহারকারীদের খুঁজে বের করে। সংঘর্ষরত ছাঁকনিগুলিকে উপরের \"সক্রিয় ছাঁকনিসমূহ\" এলাকাতে চিহ্নিত করা হয়েছে।",
        "rcfilters-filter-user-experience-level-newcomer-label": "নতুন আগত",
-       "rcfilters-filter-user-experience-level-newcomer-description": "১০টি সম্পাদনার কম ও ৪ দিনের কার্যকলাপ।",
+       "rcfilters-filter-user-experience-level-newcomer-description": "১০টির কমসংখ্যক সম্পাদনা করেছেন ও ৪ দিনের কম সময় ধরে সক্রিয় আছেন।",
        "rcfilters-filter-user-experience-level-learner-label": "শিক্ষার্থী",
        "rcfilters-filter-user-experience-level-learner-description": "যারা \"নবাগত\" ব্যবহারকারীদের চেয়ে বেশিসংখ্যক দিন ও বেশিবার সম্পাদনা করেছেন, কিন্তু \"অভিজ্ঞ ব্যবহারকারীদের\" চেয়ে কম করেছেন।",
        "rcfilters-filter-user-experience-level-experienced-label": "অভিজ্ঞ ব্যবহারকারী",
-       "rcfilters-filter-user-experience-level-experienced-description": "৩০ à¦¦à¦¿à¦¨à§\87র à¦¬à§\87শà§\80 à¦\95ারà§\8dযà¦\95লাপ à¦\93 à§«à§¦à§¦à¦\9fি à¦¸à¦®à§\8dপাদনা।",
+       "rcfilters-filter-user-experience-level-experienced-description": "৩০ à¦¦à¦¿à¦¨à§\87র à¦¬à§\87শি à¦¸à¦\95à§\8dরিয় à¦\86à¦\9bà§\87ন à¦\93 à§«à§¦à§¦à¦\9fির à¦¬à§\87শি à¦¸à¦®à§\8dপাদনা à¦\95রà§\87à¦\9bà§\87ন।",
        "rcfilters-filtergroup-automated": "স্বয়ংক্রিয় অবদান",
        "rcfilters-filter-bots-label": "বট",
        "rcfilters-filter-bots-description": "স্বয়ংক্রিয় সরঞ্জাম দিয়ে করা সম্পাদনা।",
        "rcfilters-filter-humans-label": "মানুষ (বট নয়)",
-       "rcfilters-filter-humans-description": "মানব à¦¸à¦®à§\8dপাদà¦\95 à¦¦à§\8dবারা করা সম্পাদনা।",
+       "rcfilters-filter-humans-description": "মানà§\81ষà§\87র করা সম্পাদনা।",
        "rcfilters-filtergroup-reviewstatus": "পর্যালোচনার অবস্থা",
        "rcfilters-filter-patrolled-label": "পরীক্ষিত",
        "rcfilters-filter-patrolled-description": "সম্পাদনা পরীক্ষিত হিসেবে চিহ্নিত করা হয়েছে।",
        "rcfilters-filtergroup-significance": "তাৎপর্য",
        "rcfilters-filter-minor-label": "অনুল্লেখ্য সম্পাদনা",
        "rcfilters-filter-minor-description": "যেসব সম্পাদনাকে লেখক অনুল্লেখ্য হিসেবে চিহ্নিত করেছেন।",
-       "rcfilters-filter-major-label": "অ-অনুল্লেখ্য সম্পাদনা",
+       "rcfilters-filter-major-label": "অনুল্লেখ্য নয়, এমন সম্পাদনা",
        "rcfilters-filter-major-description": "যেসব সম্পাদনাকে অনুল্লেখ্য হিসেবে চিহ্নিত করা হয়নি।",
        "rcfilters-filtergroup-changetype": "পরিবর্তনের ধরন",
        "rcfilters-filter-pageedits-label": "পাতার সম্পাদনা",
        "rcfilters-filter-pageedits-description": "উইকি বিষয়বস্তু, আলোচনা, বিষয়শ্রেণীর বিবরণ.... ইত্যাদিতে সম্পাদনা",
-       "rcfilters-filter-newpages-label": "পাতার সৃষ্টিকরণ",
+       "rcfilters-filter-newpages-label": "পাতা তৈরিকরণ",
        "rcfilters-filter-newpages-description": "সম্পাদনা যা নতুন পাতা তৈরি করেছে।",
        "rcfilters-filter-categorization-label": "বিষয়শ্রেণীর পরিবর্তন",
        "rcfilters-filter-categorization-description": "বিষয়শ্রেণী পাতা সংযোজন বা অপসারণের তালিকা",
        "lockmanager-fail-releaselock": "\"$1\" লক করা ফাইলটি ছাড়া যাচ্ছে না।",
        "lockmanager-fail-db-bucket": "$1 বাকেটটিতে যথেষ্ট সংখ্যক অবরোধ ডাটাবেজের সাথে যোগাযোগ করা যাচ্ছে না।",
        "lockmanager-fail-db-release": "$1 ডাটাবেজের লক খোলা যাচ্ছে না।",
-       "lockmanager-fail-svr-acquire": "$1 à¦¸à¦¾à¦°à§\8dভারà§\87 à¦¤à¦¾à¦²à¦¾ পাওয়া যায়নি।",
+       "lockmanager-fail-svr-acquire": "$1 à¦¸à¦¾à¦°à§\8dভারà§\87 à¦\85বরà§\8bধà¦\97à§\81লি পাওয়া যায়নি।",
        "lockmanager-fail-svr-release": "$1 ডাটাবেজের লক খোলা যাচ্ছে না।",
        "zip-file-open-error": "ফাইলটির জিপ পরীক্ষা করার সময় একটি ত্রুটি দেখা দিয়েছে।",
        "zip-wrong-format": "চিহ্নিত ফাইলটি কোনো জিপ ফাইল নয়।",
        "shared-repo-from": "$1 থেকে",
        "shared-repo": "শেয়ার্ড রিপোজিটরী",
        "shared-repo-name-wikimediacommons": "উইকিমিডিয়া কমন্স",
+       "filepage.css": "/* এখানে সন্নিবেশিত সিএসএস ফাইলের বিবরণ পৃষ্ঠায় অন্তর্ভুক্ত হবে, এছাড়া বিদেশী ক্লায়েন্ট উইকিতেও অন্তর্ভুক্ত হবে */",
        "upload-disallowed-here": "আপনি এই ফাইলটি প্রতিস্থাপন করতে পারবেন না।",
        "filerevert": "$1 পূর্বাবস্থায় ফেরত নিন",
        "filerevert-legend": "ফাইল পূর্বাবস্থায় ফেরত নিন",
        "filerevert-success": "'''[[Media:$1|$1]]''' ফাইলটি  [$3, $2-এর $4 সংস্করণে] ফেরত নেওয়া হয়েছে।",
        "filerevert-badversion": "প্রদত্ত তারিখ ও সময়ের জন্য এই ফাইলটির কোন স্থানীয় সংস্করণ নেই।",
        "filerevert-identical": "ফাইলটির বর্তমান সংস্করণের সাথে নির্বাচিত সংস্করণটির হুবহু মিল রয়েছে।",
-       "filedelete": "$1 à¦®à§\81à¦\9bà§\87 à¦«à§\87লা à¦¹à§\8bà¦\95",
-       "filedelete-legend": "ফাà¦\87ল à¦®à§\81à¦\9bà§\87 à¦«à§\87লা à¦¹à§\8bà¦\95",
+       "filedelete": "$1 à¦\85পসারণ à¦\95রà§\81ন",
+       "filedelete-legend": "ফাà¦\87ল à¦\85পসারণ à¦\95রà§\81ন",
        "filedelete-intro": "আপনি '''[[Media:$1|$1]]''' ফাইলটি এর সমস্ত ইতিহাসহ অপসারণ করছেন।",
        "filedelete-intro-old": "আপনি '''[[Media:$1|$1]]''' ফাইলটির [$4 $3, $2] সংস্করণটি মুছে ফেলছেন।",
        "filedelete-comment": "কারণ:",
        "apisandbox-multivalue-all-namespaces": "$1 (সব নামস্থান)",
        "apisandbox-multivalue-all-values": "$1 (সব মান)",
        "booksources": "বইয়ের উৎস",
-       "booksources-search-legend": "বà¦\87য়à§\87র à¦\89à§\8eসà§\87র à¦\9cনà§\8dয à¦\85নà§\81সনà§\8dধান à¦\95রা à¦¹à§\8bà¦\95",
+       "booksources-search-legend": "বà¦\87য়à§\87র à¦\89à§\8eসà§\87র à¦\9cনà§\8dয à¦\85নà§\81সনà§\8dধান à¦\95রà§\81ন",
        "booksources-isbn": "আইএসবিএন:",
        "booksources-search": "অনুসন্ধান",
        "booksources-text": "নতুন ও পুরাতন ব্যবহৃত বই বিক্রি করে, এমন কতগুলি সাইটের সংযোগের তালিকা নিচে দেওয়া হল, যে সাইটগুলিতে আপনার অনুসন্ধানকৃত বইগুলির উপর আরও তথ্য থাকতে পারে:",
        "block": "ব্যবহারকারীকে বাধা দাও",
        "unblock": "ব্যবহারকারীর উপর থেকে বাধা অপসারণ",
        "blockip": "{{GENDER:$1|ব্যবহারকারীকে}} বাধা দাও",
-       "blockip-legend": "বà§\8dযবহারà¦\95ারà§\80à¦\95à§\87 à¦¬à¦¾à¦§à¦¾ à¦¦à§\87à¦\93য়া à¦¹à§\8bà¦\95",
+       "blockip-legend": "বà§\8dযবহারà¦\95ারà§\80à¦\95à§\87 à¦¬à¦¾à¦§à¦¾ à¦¦à¦¿à¦¨",
        "blockiptext": "কোন নির্দিষ্ট আইপি ঠিকানা বা ব্যবহারকারীর লেখার অধিকারে বাধা দিতে নিচের ফর্মটি ব্যবহার করুন।\nএটি কেবলমাত্র ধ্বংসপ্রবণতা প্রতিরোধে ও [[{{MediaWiki:Policy-url}}|নীতিমালা]] মেনে সম্পাদন করা উচিত।\nনিচে একটি নির্দিষ্ট কারণ দিন (উদাহরণস্বরূপ, যেসব পাতার ধ্বংসসাধন করা হয়েছে, সেগুলি উল্লেখ করতে পারেন)।\nআপনি একটি নির্দিষ্ট সীমার অন্তর্গত একাধিক আইপি ঠিকানাকে বাধা দিতে পারেন; এজন্য [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] সিনট্যাক্স বা পদবিন্যাসবিধি ব্যবহার করুন; এরকম বৃহত্তম অনুমোদিত সীমা হচ্ছে IPv4-এর ক্ষেত্রে /$1 এবং IPv6-এর ক্ষেত্রে /$2।",
        "ipaddressorusername": "আইপি ঠিকানা বা ব্যবহারকারীর নাম:",
        "ipbexpiry": "যখন মেয়াদোত্তীর্ণ হবে:",
        "ipb-hardblock": "এই আইপি ঠিকানা থেকে লগ-ইনকৃত ব্যবহারকারীদেরকে সম্পাদনায় বাধা দাও",
        "ipbcreateaccount": "অ্যাকাউন্ট সৃষ্টিতে বাধা দেওয়া হোক",
        "ipbemailban": "ব্যবহারকারীকে ই-মেইল পাঠাতে বাধা দেওয়া হোক",
-       "ipbenableautoblock": "এই ব্যবহারকারীর ব্যবহার করা সর্বশেষ আইপি ঠিকানা, এবং পরবর্তী যেসব আইপি ঠিকানা থেকে সম্পাদনার চেষ্টা করা হবে, সেগুলিকেও স্বয়ংক্রিয়ভাবে বাধা দেয়া হোক",
+       "ipbenableautoblock": "এই ব্যবহারকারীর ব্যবহার করা সর্বশেষ আইপি ঠিকানা, এবং পরবর্তী যেসব আইপি ঠিকানা থেকে সম্পাদনার চেষ্টা করা হবে, সেগুলিকেও স্বয়ংক্রিয়ভাবে বাধা দেয়া হোক",
        "ipbsubmit": "এই ব্যবহারকারীকে বাধা দেয়া হোক",
        "ipbother": "অন্য সময়:",
        "ipboptions": "২ ঘণ্টা:2 hours,১ দিন:1 day,৩ দিন:3 days,১ সপ্তাহ:1 week,২ সপ্তাহ:2 weeks,১ মাস:1 month,৩ মাস:3 months,৬ মাস:6 months,১ বছর:1 year,অসীম:infinite",
        "ipb-confirmhideuser": "\"hide user\" ক্ষমতার মাধ্যমে আপনি একজন ব্যবহারকারীকে বাধা দিতে যাচ্ছেন। এর মাধ্যমে এই ব্যবহারকারীর নাম সকল লিস্ট এবং লগএন্ট্রি থেকে সরিয়ে ফেলা হবে। আপনি কি নিশ্চিতভাবে এটি করতে চান?",
        "ipb-confirmaction": "আপনি যদি নিশ্চিত হন আপনি এটি সত্যিকার অর্থেই করতে চান তাহলে অনুগ্রহ করে উপরের \"{{int:ipb-confirm}}\" ঘরটি দেখুন।",
        "ipb-edit-dropdown": "বাধাদানের কারণ সম্পাদনা করুন",
-       "ipb-unblock-addr": "$1-à¦\8fর à¦\89পর à¦¥à§\87à¦\95à§\87 à¦¬à¦¾à¦§à¦¾ à¦¤à§\81লà§\87 à¦¨à§\87à¦\93য়া à¦¹à§\8bà¦\95",
+       "ipb-unblock-addr": "$1-à¦\8fর à¦¬à¦¾à¦§à¦¾ à¦¤à§\81লà§\87 à¦¨à¦¿à¦¨",
        "ipb-unblock": "ব্যবহারকারী বা আইপি ঠিকানার উপর থেকে বাধা তুলে নেওয়া হোক",
        "ipb-blocklist": "বিদ্যমান বাধাগুলি দেখুন",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}}-এর অবদানসমূহ",
        "ipb-blocklist-duration-left": "$1 বাকি",
        "unblockip": "ব্যবহারকারীর উপর থেকে বাধা তুলে নেওয়া হোক",
        "unblockiptext": "নিচের ফর্মটি ব্যবহার করে পূর্বে বাধা দেওয়া কোন আইপি ঠিকানা বা ব্যবহারকারীর সাইটে লেখার অধিকার পুনঃপ্রতিষ্ঠা করুন।",
-       "ipusubmit": "বাধা à¦¤à§\81লà§\87 à¦¨à§\87à¦\93য়া à¦¹à§\8bà¦\95",
+       "ipusubmit": "à¦\8fà¦\87 à¦¬à¦¾à¦§à¦¾ à¦¤à§\81লà§\87 à¦¨à¦¿à¦¨",
        "unblocked": "[[User:$1|$1]]-এর উপর বাধা তুলে নেওয়া হয়েছে",
        "unblocked-range": "$1 -এর থেকে বাধা সরিয়ে নেওয়া হয়েছে",
        "unblocked-id": "$1 বাধাটি তুলে নেওয়া হয়েছে",
        "ipblocklist-empty": "বাধাতালিকা খালি।",
        "ipblocklist-no-results": "অনুরুদ্ধ আইপি ঠিকানা বা ব্যবহারকারী নামটির উপর কোন বাধা নেই।",
        "blocklink": "বাধা দাও",
-       "unblocklink": "বাধা à¦¤à§\81লà§\87 à¦¨à§\87à¦\93য়া à¦¹à§\8bà¦\95",
+       "unblocklink": "বাধা à¦¤à§\81লà§\81ন",
        "change-blocklink": "বাধা পরিবর্তন করুন",
        "contribslink": "অবদান",
        "emaillink": "ই-মেইল পাঠাও",
        "cant-see-hidden-user": "আপনি যে ব্যবহারকারীকে ব্লক বা লুকিয়ে রাখতে চাচ্ছেন তাকে আগে থেকেই ব্লক বা লুকিয়ে রাখা হয়েছে। এছাড়া আপনার Hideuser অধিকার নেই, তাই আপনি ব্যবহারকারীর অবস্থা পরিবর্তন করতে পারবেন না।",
        "ipbblocked": "আপনি অন্য কোন ব্যবহারকরীকে ব্লক বা আনব্লক করতে পারবেন না, কারণ আপনি নিজেই ব্লক রয়েছেন",
        "ipbnounblockself": "আপনি নিজেকে আনব্লক করতে পারবেন না",
-       "lockdb": "ডাà¦\9fাবà§\87à¦\9c à¦\85বরà§\81দà§\8dধ à¦\95রà§\87 à¦¦à§\87à¦\93য়া à¦¹à§\8bà¦\95",
+       "lockdb": "ডাটাবেজ অবরুদ্ধ করা হোক",
        "unlockdb": "ডাটাবেজ খুলে দেওয়া হোক",
        "lockdbtext": "ডাটাবেজ অবরুদ্ধ করে দিলে কোনো ব্যবহারকারীই পাতা সম্পাদনা করতে, তাদের পছন্দ পরিবর্তন করতে, তাদের নজরতালিকা সম্পাদনা করতে এবং ডাটাবেজে পরিবর্তন আনে এমন কোন কিছু করতে পারবেন না।\nঅনুগ্রহ করে নিশ্চিত করুন যে আপনি এটাই করতে চান, এবং আপনার রক্ষণাবেক্ষণ শেষ হবার পর ডাটাবেজ আবার খুলে দেবেন।",
        "unlockdbtext": "ডাটাবেজ খুলে দিলে সব ব্যবহারকারী পাতা সম্পাদনা করতে, তাদের পছন্দ পরিবর্তন করতে, তাদের নজরতালিকা সম্পাদনা করতে, এবং ডাটাবেজে পরিবর্তন সাধন করে, এমন অন্যান্য কাজ করতে পারবেন।\nঅনুগ্রহ করে নিশ্চিত করুন যে আপনি এটাই করতে চান।",
        "locknoconfirm": "আপনি নিশ্চিতকরণ বাক্সে টিক দেননি।",
        "lockdbsuccesssub": "ডাটাবেজ সফলভাবে অবরুদ্ধ করে দেওয়া হয়েছে",
        "unlockdbsuccesssub": "ডাটাবেজ খুলে দেওয়া হয়েছে",
-       "lockdbsuccesstext": "ডাটাবেজ অবরুদ্ধ করা হয়েছে\n<br />আপনার রক্ষণাবেক্ষণ সম্পন্ন হবার পর [[Special:UnlockDB|ডাটাবেজ খুলে দিতে]] ভুলবেন না।",
+       "lockdbsuccesstext": "ডাটাবেজ অবরুদ্ধ করা হয়েছে।<br />\nআপনার রক্ষণাবেক্ষণ সম্পন্ন হবার পর [[Special:UnlockDB|ডাটাবেজ খুলে দিতে]] ভুলবেন না।",
        "unlockdbsuccesstext": "ডাটাবেজ খুলে দেওয়া হয়েছে।",
        "lockfilenotwritable": "ডাটাবেজ অবরোধনির্দেশক ফাইলটি লিখনযোগ্য নয়। ডাটাবেজ অবরুদ্ধ করতে বা খুলতে চাইলে ফাইলটিকে ওয়েব সার্ভার কর্তৃক লিখনযোগ্য হতে হবে।",
        "databaselocked": "ডাটাবেজটি ইতিমধ্যেই অবরুদ্ধ।",
        "import-interwiki-sourcewiki": "উত্স উইকি:",
        "import-interwiki-sourcepage": "উৎস পাতা:",
        "import-interwiki-history": "এই পাতার ইতিহাসের সমস্ত সংস্করণের প্রতিলিপি করা হোক",
-       "import-interwiki-templates": "সà¦\95ল à¦\9fà§\87মà§\8dপলà§\87à¦\9f à¦\85নà§\8dতরà§\8dভà§\81à¦\95à§\8dত",
+       "import-interwiki-templates": "সà¦\95ল à¦\9fà§\87মপà§\8dলà§\87à¦\9f à¦\85নà§\8dতরà§\8dভà§\81à¦\95à§\8dত à¦\95রà§\81ন",
        "import-interwiki-submit": "আমদানি",
        "import-mapping-default": "পূর্বনির্ধারিত অবস্থানে আমদানি করুন",
        "import-mapping-namespace": "একটি নামস্থানে আমদানি করুন:",
        "tooltip-ca-protect": "এই পাতাকে সুরক্ষিত করো",
        "tooltip-ca-unprotect": "এই পাতার সুরক্ষা পরিবর্তন করো",
        "tooltip-ca-delete": "পাতাটি মুছে ফেলো",
-       "tooltip-ca-undelete": "পাতাà¦\9fি à¦®à§\81à¦\9bà§\87 à¦«à§\87লার à¦\86à¦\97à§\87 à¦¯à§\87 à¦¸à¦®à§\8dপাদনাà¦\97à§\81লি à¦\95রা à¦¹à¦¯à¦¼à§\87à¦\9bিল, à¦¸à§\87à¦\97à§\81লি à¦\89দà§\8dধার à¦\95রা à¦¹à§\8bà¦\95।",
+       "tooltip-ca-undelete": "পাতাà¦\9fি à¦\85পসারণà§\87র à¦\86à¦\97à§\87 à¦¯à§\87 à¦¸à¦®à§\8dপাদনাà¦\97à§\81লি à¦\95রা à¦¹à¦¯à¦¼à§\87à¦\9bিল à¦¸à§\87à¦\97à§\81লি à¦\89দà§\8dধার à¦\95রা à¦¹à§\8bà¦\95",
        "tooltip-ca-move": "পাতাটি স্থানান্তর করুন",
        "tooltip-ca-watch": "এই পাতাটি আপনার নজরতালিকায় যোগ করুন",
        "tooltip-ca-unwatch": "এই পাতাটি আপনার নজরতালিকা থেকে সরিয়ে ফেলুন",
        "tooltip-search": "{{SITENAME}} অনুসন্ধান",
        "tooltip-search-go": "যদি থাকে, তবে ঠিক এই নামের পাতায় চলো",
-       "tooltip-search-fulltext": "à¦\8fà¦\87 à¦\9fà§\87à¦\95à§\8dসà¦\9fà§\87র à¦\9cনà§\8dয à¦ªà¦¾à¦¤à¦¾à¦\97à§\81লিতà§\87 à¦\85নà§\81সনà§\8dধান à¦\95রা à¦¹à§\8bà¦\95",
+       "tooltip-search-fulltext": "à¦\8fà¦\87 à¦²à§\87à¦\96ার à¦\9cনà§\8dয à¦ªà¦¾à¦¤à¦¾à¦\97à§\81লিতà§\87 à¦\85নà§\81সনà§\8dধান à¦\95রà§\81ন",
        "tooltip-p-logo": "প্রধান পাতা পরিদর্শন করুন",
        "tooltip-n-mainpage": "প্রধান পাতায় যান",
        "tooltip-n-mainpage-description": "প্রধান পাতা পরিদর্শন করুন",
        "tooltip-preferences-save": "পছন্দ সংরক্ষণ",
        "tooltip-summary": "একটি সংক্ষিপ্ত সারাংশ দিন",
        "interlanguage-link-title": "$1 - $2",
-       "common.css": "/* এখানে সিএসএস নিবেশিত করা হলে তা সব স্কিনে প্রয়োগ করা হবে */",
+       "common.css": "/* এখানে সন্নিবেশিত সিএসএস সব আবরণে প্রয়োগ করা হবে */",
+       "print.css": "/* এখানে সন্নিবেশিত সিএসএস মুদ্রণের আউটপুটকে প্রভাবিত করবে */",
+       "noscript.css": "/* এখানে সন্নিবেশিত সিএসএস জাভাস্ক্রিপ্ট নিষ্ক্রিয় করা ব্যবহারকারীদের প্রভাবিত করবে */",
+       "group-autoconfirmed.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু স্বয়ংনিশ্চিতকৃত ব্যবহারকারীদের প্রভাবিত করবে */",
+       "group-user.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু নিবন্ধিত ব্যবহারকারীদের প্রভাবিত করবে */",
+       "group-bot.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু বটকে প্রভাবিত করবে */",
+       "group-sysop.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু প্রশাসকদের প্রভাবিত করবে */",
+       "group-bureaucrat.css": "/* এখানে সন্নিবেশিত সিএসএস শুধু ব্যুরোক্র্যাটদের প্রভাবিত করবে */",
+       "common.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট সকল ব্যবহারকারীর জন্য সকল পাতায় লোড হবে। */",
+       "group-autoconfirmed.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু স্বয়ংনিশ্চিতকৃত ব্যবহারকারীদের জন্য লোড হবে */",
+       "group-user.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু নিবন্ধিত ব্যবহারকারীদের জন্য লোড হবে */",
+       "group-bot.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু বটের জন্য লোড হবে */",
+       "group-sysop.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু প্রশাসকদের জন্য লোড হবে */",
+       "group-bureaucrat.js": "/* এখানে সন্নিবেশিত জাভাস্ক্রিপ্ট শুধু ব্যুরোক্র্যাটদের জন্য লোড হবে */",
        "anonymous": "{{SITENAME}} এর বেনামী {{PLURAL:$1|ব্যবহারকারী|ব্যবহারকারীবৃন্দ}}",
        "siteuser": "{{SITENAME}} ব্যবহারকারী $1",
        "anonuser": "{{SITENAME}} বেনামী ব্যবহারকারী $1",
        "newimages-summary": "এই বিশেষ পাতা সর্বশেষ আপলোডকৃত ফাইল দেখাবে।",
        "newimages-legend": "ছাঁকনি",
        "newimages-label": "ফাইলের নাম (অথবা এর কোন অংশ):",
+       "newimages-user": "আইপি ঠিকানা বা ব্যবহারকারী নাম",
        "newimages-showbots": "বটের আপলোড গুলো দেখাও।",
        "newimages-hidepatrolled": "টহলকৃত আপলোড লুকানো হোক",
        "noimages": "দেখার মত কিছু নেই।",
        "exif-copyrighted-false": "কপিরাইট সংক্রান্ত তথ্য নেই",
        "exif-photometricinterpretation-0": "কালো এবং সাদা (সাদা হল 0)",
        "exif-photometricinterpretation-1": "কালো এবং সাদা (কালো হল 0)",
+       "exif-photometricinterpretation-3": "প্যালেট",
+       "exif-photometricinterpretation-4": "স্বচ্ছতা মাস্ক",
+       "exif-photometricinterpretation-5": "পৃথকীকৃত (সম্ভবত CMYK)",
        "exif-unknowndate": "অজানা তারিখ",
        "exif-orientation-1": "সাধারণ",
        "exif-orientation-2": "অনুভূমিকভাবে উল্টানো",
        "watchlistedit-normal-title": "নজরতালিকা সম্পাদনা করো",
        "watchlistedit-normal-legend": "নজর তালিকা থেকে শিরোনামসমূহ মুছে ফেলো",
        "watchlistedit-normal-explain": "আপনার নজরতালিকায় রাখা পাতার শিরোনামগুলি নিচে দেখানো হয়েছে।\nকোন শিরোনাম সরিয়ে নিতে চাইলে পাশের বাক্সে টিক দিন এবং \"{{int:Watchlistedit-normal-submit}}\"-এ ক্লিক করুন।\nআপনি [[Special:EditWatchlist/raw|মূল তালিকাটিও]] সম্পাদনা করতে পারেন।",
-       "watchlistedit-normal-submit": "শিরà§\8bনামà¦\97à§\81লি à¦¸à¦°à¦¿à¦¯à¦¼à§\87 à¦«à§\87লা à¦¹à§\8bà¦\95",
+       "watchlistedit-normal-submit": "শিরà§\8bনামà¦\97à§\81লি à¦¸à¦°à¦¾à¦¨",
        "watchlistedit-normal-done": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} আপনার নজর তালিকা থেকে মুছে ফেলা হয়েছে:",
        "watchlistedit-raw-title": "অশোধিত নজর তালিকা সম্পাদনা করুন",
        "watchlistedit-raw-legend": "অশোধিত নজরতালিকা সম্পাদনা করুন",
        "watchlistedit-raw-explain": "আপনার নজরতালিকায় রাখা পাতার শিরোনামগুলি নিচে দেখানো হয়েছে, এই তালিকাতে নতুন শিরোনাম যোগ করা যাবে বা শিরোনাম সরিয়ে নেওয়া যাবে;\nপ্রতিটি লাইনে একটি করে শিরনাম দেখানো হচ্ছে।\nশেষ হলে \"{{int:Watchlistedit-raw-submit}}\"-এ ক্লিক করুন।\nআপনি [[Special:EditWatchlist|আদর্শ সম্পাদনা সরঞ্জাম]]-ও ব্যবহার করতে পারেন।",
        "watchlistedit-raw-titles": "শিরোনাম:",
-       "watchlistedit-raw-submit": "নà¦\9cরতালিà¦\95া à¦¹à¦¾à¦²à¦¨à¦¾à¦\97াদ à¦\95রা à¦¹à§\8bà¦\95",
+       "watchlistedit-raw-submit": "নà¦\9cরতালিà¦\95া à¦¹à¦¾à¦²à¦¨à¦¾à¦\97াদ à¦\95রà§\81ন",
        "watchlistedit-raw-done": "আপনার নজর তালিকা হালনাগাদ করা হয়েছে।",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} যোগ করা হয়েছে:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 শিরোনাম|$1 শিরোনামসমূহ}} মুছে ফেলা হয়েছে:",
index 4e28666..5e5bd57 100644 (file)
        "newimages-summary": "Diskouez a ra ar bajenn dibar-mañ roll ar restroù diwezhañ bet enporzhiet.",
        "newimages-legend": "Sil",
        "newimages-label": "Anv ar restr (pe darn anezhi) :",
+       "newimages-user": "Chomlec'h IP pe anv implijer",
        "newimages-showbots": "Diskouez an ezporzhiadennoù graet gant robotoù",
        "newimages-hidepatrolled": "Kuzhat ar enporzhiadennoù gwiriet",
        "noimages": "Netra da welet.",
index f14b874..93640a7 100644 (file)
        "post-expand-template-argument-warning": "Varování: Tato stránka obsahuje alespoň jeden argument šablony, který je po rozbalení příliš velký.\nTyto argumenty byly vynechány.",
        "post-expand-template-argument-category": "Stránky obsahující vynechané argumenty šablon",
        "parser-template-loop-warning": "Nalezena smyčka šablon: [[$1]]",
+       "template-loop-category": "Stránky se smyčkami šablon",
+       "template-loop-category-desc": "Stránka obsahuje smyčku šablon, tj. šablonu, která je vložená sama do sebe.",
        "parser-template-recursion-depth-warning": "Překročen limit hloubky rekurzivního vkládání šablon ($1)",
        "language-converter-depth-warning": "Překročen limit vnoření u jazykové konverze ($1)",
        "node-count-exceeded-category": "Stránky překračující počet uzlů",
index c348aab..571b764 100644 (file)
        "newimages-summary": "Diese Spezialseite zeigt die zuletzt hochgeladenen Dateien an.",
        "newimages-legend": "Filter",
        "newimages-label": "Dateiname (oder ein Teil davon):",
+       "newimages-user": "IP-Adresse oder Benutzername",
        "newimages-showbots": "Von Bots hochgeladene Dateien anzeigen",
        "newimages-hidepatrolled": "Kontrollierte Dateien ausblenden",
        "noimages": "Keine Dateien gefunden.",
index fa5b0c1..0b78599 100644 (file)
        "watchthis": "Şıma bewnê ena perre",
        "savearticle": "Perre qeyd ke",
        "savechanges": "Vırnayışan qeyd kerê",
-       "publishpage": "Perer bıhesırne",
-       "publishchanges": "Vurnayışa vıla ke",
+       "publishpage": "Riperri bare ke",
+       "publishchanges": "Vırnayışan aşkera ke",
        "preview": "Verqayt",
        "showpreview": "Verasayışi bımocne",
        "showdiff": "Vurnayışan bımotne",
        "tooltip-ca-nstab-category": "Pela kategoriye bıvêne",
        "tooltip-minoredit": "Ney vırnayışo werdi nışan bıkerê",
        "tooltip-save": "Vurnayışanê xo qeyd ke",
-       "tooltip-publish": "Vurnayışê xo vıla kı",
+       "tooltip-publish": "Vırnayışê xo aşkera ke",
        "tooltip-preview": "Vurnayışanê xo çım ra bıviyarnê. Qeydkerdış ra ver bıgurê cı!",
        "tooltip-diff": "Kamci vırnayışê ke şıma nuştey sero kerdê, inan bıvênê.",
        "tooltip-compareselectedversions": "Ena per de ferqê rewziyonan de dı weçinaya bıvinê",
index f9fbfd0..e87b6fb 100644 (file)
        "newimages-summary": "This special page shows the last uploaded files.",
        "newimages-legend": "Filter",
        "newimages-label": "Filename (or a part of it):",
+       "newimages-user": "IP address or username",
        "newimages-showbots": "Show uploads by bots",
        "newimages-hidepatrolled": "Hide patrolled uploads",
        "noimages": "Nothing to see.",
index 6b8fe3c..c36e363 100644 (file)
        "logentry-newusers-autocreate": "Se ha {{GENDER:$2|creado}} automáticamente la cuenta de {{GENDER:$4|usuario|usuaria}} $1",
        "logentry-protect-move_prot": "$1 {{GENDER:$2|trasladó}} las preferencias de protección de $4 a $3",
        "logentry-protect-unprotect": "$1 {{GENDER:$2|eliminó}} la protección de $3",
-       "logentry-protect-protect": "$1 {{GENDER:$2|protegió}} $3 $4",
-       "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegió}} a $3 $4 [en cascada]",
+       "logentry-protect-protect": "$1 {{GENDER:$2|protegió}} la página $3 $4",
+       "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegió}} la página $3 $4 [en cascada]",
        "logentry-protect-modify": "$1 {{GENDER:$2|cambió}} el nivel de protección de $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|cambió}} el nivel de protección de $3 $4 [en cascada]",
        "logentry-rights-rights": "$1 {{GENDER:$2|modificó}} los grupos a los que pertenece {{GENDER:$6|$3}}: de $4 a $5",
index 2c8fecf..9daa40e 100644 (file)
        "right-createpage": "Luua lehekülgi (mis pole aruteluleheküljed)",
        "right-createtalk": "Luua arutelulehekülgi",
        "right-createaccount": "Luua uusi kasutajakontosid",
+       "right-autocreateaccount": "Automaatselt välise kasutajakontoga sisse logida",
        "right-minoredit": "Märkida muudatusi pisimuudatusteks",
        "right-move": "Teisaldada lehekülgi",
        "right-move-subpages": "Teisaldada lehekülgi koos nende alamlehtedega",
        "action-createpage": "seda lehekülge luua",
        "action-createtalk": "seda arutelulehekülge luua",
        "action-createaccount": "seda kasutajakontot luua",
+       "action-autocreateaccount": "välise kasutajakontoga automaatselt sisse logida",
        "action-history": "vaadata selle lehekülje ajalugu",
        "action-minoredit": "seda muudatust pisimuudatuseks märkida",
        "action-move": "seda lehekülge teisaldada",
        "newimages-summary": "Sellel erilehel on viimati üles laaditud failid.",
        "newimages-legend": "Filter",
        "newimages-label": "Failinimi (või selle osa):",
+       "newimages-user": "IP-aadress või kasutajanimi",
        "newimages-showbots": "Näita robotite üles laaditud faile",
        "newimages-hidepatrolled": "Peida kontrollitud failid",
        "noimages": "Uusi pilte ei ole.",
        "authform-wrongtoken": "Vale luba",
        "specialpage-securitylevel-not-allowed-title": "Pole lubatud",
        "specialpage-securitylevel-not-allowed": "Kahjuks ei lubata sul seda lehekülge kasutada, kuna sinu identiteeti ei õnnestunud tõestada.",
+       "authpage-cannot-login": "Sisselogimisega ei õnnestu alustada.",
+       "authpage-cannot-login-continue": "Sisselogimisega ei õnnestu jätkata. Suure tõenäosusega on sinu seansi ajalõpp möödunud.",
+       "authpage-cannot-create": "Konto loomisega ei õnnestu alustada.",
+       "authpage-cannot-create-continue": "Konto loomisega ei õnnestu jätkata. Suure tõenäosusega on sinu seansi ajalõpp möödunud.",
+       "authpage-cannot-link": "Konto linkimisega ei õnnestu alustada.",
+       "authpage-cannot-link-continue": "Konto linkimisega ei õnnestu jätkata. Suure tõenäosusega on sinu seansi ajalõpp möödunud.",
        "changecredentials": "Autentimisandmete muutmine",
        "changecredentials-submit": "Muuda autentimisandmed",
        "changecredentials-success": "Sinu autentimisandmed on muudetud.",
        "removecredentials-success": "Sinu autentimisandmed on eemaldatud.",
        "credentialsform-provider": "Andmete tüüp:",
        "credentialsform-account": "Konto nimi:",
+       "authenticationdatachange-ignored": "Autentimisandmete muutmine jäi rahuldamata. Võimalik, et ühtegi pakkujat polnud häälestatud.",
        "userjsispublic": "Pea silmas, et JavaScripti alamleheküljed ei tohiks sisaldada konfidentsiaalseid andmeid, kuna neid näevad teised kasutajad.",
        "usercssispublic": "Palun pane tähele: CSS-alamleheküljel ei peaks olema konfidentsiaalseid andmeid, kuna teised kasutajad näevad seda.",
        "restrictionsfield-badip": "Vigane IP-aadress või -aadressivahemik: $1",
index 26c372b..5d3ca4f 100644 (file)
        "mediastatistics-table-count": "Tiedostojen lukumäärä",
        "mediastatistics-table-totalbytes": "Yhteenlaskettu koko",
        "mediastatistics-header-unknown": "Tuntematon",
-       "mediastatistics-header-bitmap": "Bitmap-kuvat",
+       "mediastatistics-header-bitmap": "Bittikarttakuvat",
        "mediastatistics-header-drawing": "Piirrokset (vektorikuvat)",
        "mediastatistics-header-audio": "Audio",
        "mediastatistics-header-video": "Videot",
index fd8f66a..d206d68 100644 (file)
        "post-expand-template-argument-category": "Pages contenant des paramètres de modèle non évalués",
        "parser-template-loop-warning": "Modèle en boucle détecté : [[$1]]",
        "template-loop-category": "Pages avec des boucles de modèle",
-       "template-loop-category-desc": "La page contient une boucle de modèle, c.à.d. un modèle qui s’appelle lui-même récursivement.",
+       "template-loop-category-desc": "La page contient une boucle dans le modèle, c.à.d. un modèle qui s’appelle lui-même récursivement.",
        "parser-template-recursion-depth-warning": "Limite de profondeur des appels récursifs de modèles dépassée ($1)",
        "language-converter-depth-warning": "Limite de profondeur du convertisseur de langue dépassée ($1)",
        "node-count-exceeded-category": "Pages dépassant le nombre de nœuds maximal",
        "newimages-summary": "Cette page spéciale affiche les derniers fichiers importés.",
        "newimages-legend": "Filtre",
        "newimages-label": "Nom du fichier (ou une partie de celui-ci) :",
+       "newimages-user": "Adresse IP ou nom d'utilisateur",
        "newimages-showbots": "Afficher les imports faits par des robots",
        "newimages-hidepatrolled": "Masquer les téléchargements patrouillés",
        "noimages": "Aucune image à afficher.",
        "confirmemail_sendfailed": "{{SITENAME}} n’a pas pu vous envoyer le courriel de confirmation.\nVeuillez vérifiez que votre adresse de courriel ne comprend aucun caractère incorrect.\n\nLe programme d’envoi de courriel a retourné l’indication suivante : $1",
        "confirmemail_invalid": "Code de confirmation incorrect.\nCelui-ci a peut-être expiré.",
        "confirmemail_needlogin": "Vous devez vous $1 pour confirmer votre adresse de courriel.",
-       "confirmemail_success": "Votre adresse de courriel a été confirmée.\nVous pouvez maintenant vous [[Special:UserLogin|{{MediaWiki:Loginreqlink}}]] et profiter du wiki.",
+       "confirmemail_success": "Votre adresse de courriel a été confirmée.\nVous pouvez maintenant vous [[Special:UserLogin|{{MediaWiki:Loginreqlink/fr}}]] et profiter du wiki.",
        "confirmemail_loggedin": "Votre adresse de courriel est maintenant confirmée.",
        "confirmemail_subject": "Confirmation d’adresse de courriel pour {{SITENAME}}",
        "confirmemail_body": "Quelqu’un, probablement vous, à partir de l’adresse IP $1,\na créé un compte « $2 » avec cette adresse de courriel sur le site {{SITENAME}}.\n\nPour confirmer que ce compte vous appartient vraiment et afin\nd’activer les fonctions de messagerie sur {{SITENAME}},\nveuillez suivre ce lien dans votre navigateur :\n\n$3\n\nSi vous n’avez *pas* créé ce compte, suivez le lien ci-dessous \npour annuler la confirmation de votre adresse courriel :\n\n$5\n\nCe code de confirmation expirera le $4.",
index 3ae9648..c809c76 100644 (file)
        "externaldberror": "Soit y avait une erreur avec la base d'information de certification extérieur, soit vous avez pas la permission de renouveler votre compte extérieur.",
        "login": "Connecter",
        "nav-login-createaccount": "Connecter / créer un compte",
-       "userlogin": "Connecter / créer un compte",
        "logout": "Déconnecter",
        "userlogout": "Déconnecter",
        "notloggedin": "Pas connecté",
-       "nologin": "Vous avez pas de compte? '''$1'''.",
-       "nologinlink": "Créez un compte",
        "createaccount": "Créer un compte",
-       "gotaccount": "Vous avez un compte déjà? '''$1'''.",
-       "gotaccountlink": "Connectez",
-       "userlogin-resetlink": "Oublié vôtre détailes de log in?",
        "createacct-emailrequired": "Adresse d'email",
        "createacct-emailoptional": "Adresse d'email (optional)",
        "createacct-email-ph": "Entres t'adresse d'email",
        "createacct-another-email-ph": "Entres adresse d'email",
        "createaccountmail": "par e-mail",
-       "createaccountreason": "Raison:",
        "createacct-reason": "Raison",
        "createacct-reason-ph": "Pourquoi crées-tu un autre compte",
        "badretype": "Les mots de passe que vous avez mis sont pas pareils.",
        "resetpass-temp-password": "Mot de passe temporaire:",
        "passwordreset-username": "Nom d'useur:",
        "passwordreset-domain": "Domaine:",
-       "passwordreset-capture": "Regarder l'email résultant?",
        "passwordreset-email": "Adresse d'email:",
        "changeemail-none": "(aucun)",
        "changeemail-password": "Ton mot de passe sur {{SITENAME}}:",
index 280b124..db9be6f 100644 (file)
        "userjsyoucanpreview": "'''Tip:''' Brük di „{{int:showpreview}}“-knoop, am din nei JavaScript föör det seekrin tu testin.",
        "usercsspreview": "'''Seenk diaram, dat det bluas en föörskau faan din CSS as.'''\n'''Det as noch ei seekert wurden!'''",
        "userjspreview": "'''Seenk diaram, dat det bluas en föörskau faan din JavaScript as.'''\n'''Det as noch ei seekert wurden!'''",
-       "sitecsspreview": "'''Påås aw dåt dü jüdeer CSS bloot forbekiikest.'''\n'''Dåt as nuch ai spiikerd!'''",
-       "sitejspreview": "'''Påås aw dåt dü jüdeer JavaScript code bloot forbekiikest.'''\n'''Dåt as nuch ai spiikerd!'''",
+       "sitecsspreview": "<strong>Paase üüb! Det as bluas en föörskau faan't CSS. Det as noch ei seekert wurden!</strong>",
+       "sitejspreview": "<strong>Paase üüb! Det as bluas en föörskau faan di JavaScript code. Det as noch ei seekert wurden!</strong>",
        "userinvalidcssjstitle": "''Paase üüb:''' Skak \"$1\" jaft at ei.\nSeenk diaram, dat faan en brüker iinracht .css- an .js-sidjen mä en letjen buksteew began skel. Bispal:\n''{{ns:user}}:Münsterkjarl/vector.css'' uunsteed faan ''{{ns:user}}:Münsterkjarl/Vector.css''.",
        "updated": "(Feranert)",
        "note": "'''Paase üüb:'''",
index 2382292..8856b37 100644 (file)
        "post-expand-template-argument-warning": "'''Aviso:''' Esta páxina contén, polo menos, un argumento de modelo que ten un tamaño e expansión moi grande.\nEstes argumentos foron omitidos.",
        "post-expand-template-argument-category": "Páxinas que conteñen argumentos de modelo omitidos",
        "parser-template-loop-warning": "Detectouse un modelo en bucle: [[$1]]",
+       "template-loop-category": "Páxinas con bucles de modelo",
+       "template-loop-category-desc": "A páxina contén un bucle de modelo, por exemplo, un modelo que se chama a si mesmo recursivamente.",
        "parser-template-recursion-depth-warning": "Excedeuse o límite de profundidade de recursión do modelo ($1)",
        "language-converter-depth-warning": "Excedeuse o límite de profundidade do convertedor de lingua ($1)",
        "node-count-exceeded-category": "Páxinas nas que se supera o número de nodos",
        "newimages-summary": "Esta páxina especial mostra os últimos ficheiros cargados.",
        "newimages-legend": "Filtro",
        "newimages-label": "Nome do ficheiro (ou parte del):",
+       "newimages-user": "Enderezo IP ou nome de usuario",
        "newimages-showbots": "Mostrar as cargas feitas por bots",
        "newimages-hidepatrolled": "Agochar as subidas patrulladas",
        "noimages": "Non hai imaxes que mostrar.",
index 864b0d7..0d78299 100644 (file)
        "newimages-summary": "דף מיוחד זה מציג את הקבצים האחרונים שהועלו.",
        "newimages-legend": "מסנן",
        "newimages-label": "שם הקובץ (או חלק ממנו):",
+       "newimages-user": "כתובת IP או שם משתמש",
        "newimages-showbots": "הצגת העלאות שבוצעו על־ידי בוטים",
        "newimages-hidepatrolled": "הסתרת העלאות בדוקות",
        "noimages": "אין קבצים.",
index a560d24..0dd667e 100644 (file)
        "post-expand-template-argument-warning": "'''चेतावनी:''' इस पृष्ठ पर किसी साँचे में कम-से-कम एक ऐसा प्राचल है जो बढ़ाने पर बहुत बड़ा हो जायेगा।\nऐसे प्राचलों को छोड़ दिया गया है।",
        "post-expand-template-argument-category": "ऐसे पृष्ठ जिनमें प्राचल छोड़े गये हैं",
        "parser-template-loop-warning": "साँचा चक्र मिला: [[$1]]",
+       "template-loop-category": "टेम्पलेट लूप वाले पेज",
+       "template-loop-category-desc": "पृष्ठ में एक टेम्पलेट लूप है, अर्थात। एक टेम्पलेट जो स्वयं को पुनरावर्ती रूप से कॉल करता है",
        "parser-template-recursion-depth-warning": "साँचा पुनरावर्ती गहराई सीमा पार ($1)",
        "language-converter-depth-warning": "भाषा कन्वर्टर गहराई सीमा से बाहर गया ( $1 )",
        "node-count-exceeded-category": "पृष्ठ जिनमें नोड-संख्या सीमा पार की गई है",
        "prefs-help-recentchangescount": "इसमें हाल के बदलाव, पृष्ठ इतिहास व लॉग शामिल हैं।",
        "prefs-help-watchlist-token2": "यह आपकी ध्यानसूची की वेब फ़ीड की गोपनीय चाबी है।\nयह जिसके भी पास होगी वह आपकी ध्यानसूची पढ़ सकेगा, इसिलए इसे किसी के साथ बांटियेगा नहीं।\n[[Special:ResetTokens|इसे रीसेट करने के लिए यहाँ क्लिक करें]]।",
        "savedprefs": "आपकी वरीयताएँ संजोई गई हैं।",
-       "savedrights": "पà¥\8dरयà¥\8bà¤\95à¥\8dता {{GENDER:$1|$1}} का सदस्य अधिकार सहेजा गया।",
+       "savedrights": "सदसà¥\8dय {{GENDER:$1|$1}} का सदस्य अधिकार सहेजा गया।",
        "timezonelegend": "समयमंडल:",
        "localtime": "स्थानीय समय:",
        "timezoneuseserverdefault": "विकि मूल का उपयोग करें ($1)",
        "userrights-user-editname": "सदस्यनाम दें:",
        "editusergroup": "सदस्य समूह दिखायें",
        "editinguser": "सदस्य '''[[User:$1|$1]]''' $2 के अधिकार बदलें\n{{GENDER:$1|सदस्य}} के सदस्य अधिकार बदले जा रहे हैं <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "{{GENDER:$1|user}} के उपयोगकर्ता अधिकारों को देखना <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "सदस्य समूहों का संपादन करें",
-       "userrights-viewusergroup": "सदस्य समूह देखें",
+       "userrights-viewusergroup": "{{GENDER:$1|सदस्य}} समूह देखें",
        "saveusergroups": "{{GENDER:$1|सदस्य}} समूह सहेजें",
        "userrights-groupsmember": "निम्न {{PLURAL:$1|समूह|समूहों}} का सदस्य:",
        "userrights-groupsmember-auto": "निम्न {{PLURAL:$1|समूह|समूहों}} का अंतर्निहित सदस्य:",
-       "userrights-groups-help": "आप इस सदस्य की समूह-सदस्यता बदल सकते हैं:\n* बक्से पर सही का निशान लगे होने का अर्थ है कि सदस्य उस समूह में है।\n* बक्से पर सही का निशान न लगे होने का अर्थ है कि सदस्य उस समूह में नहीं है।\n* एक * का अर्थ है कि एक बार जोड़ने के बाद वह समूह हटा नहीं सकते हैं, और हटाने के बाद जोड़ नहीं सकते हैं।",
+       "userrights-groups-help": "आप इस सदस्य की समूह-सदस्यता बदल सकते हैं:\n* बक्से पर सही का निशान लगे होने का अर्थ है कि सदस्य उस समूह में है।\n* बक्से पर सही का निशान न लगे होने का अर्थ है कि सदस्य उस समूह में नहीं है।\n* एक * का अर्थ है कि एक बार जोड़ने के बाद वह समूह हटा नहीं सकते हैं, और हटाने के बाद जोड़ नहीं सकते हैं।\n* एक # सूचित करता है कि आप केवल इस समूह के समाप्ति समय को वापस रख सकते हैं; आप इसे आगे नहीं बढ़ा सकते हैं",
        "userrights-reason": "कारण:",
        "userrights-no-interwiki": "आपको अन्य विकियों पर सदस्य अधिकार बदलने की अनुमति नहीं हैं।",
        "userrights-nodatabase": "डाटाबेस $1 या तो मौजूद नहीं है या फिर स्थानीय नहीं है।",
        "userrights-expiry-options": "एक दिन:1 day,एक सप्ताह:1 week,एक महीना:1 month,तीन महीने:3 months,छः महीने:6 months,एक वर्ष:1 year",
        "userrights-invalid-expiry": "\"$1\" समूह के लिए समाप्ती तिथि अमान्य है।",
        "userrights-expiry-in-past": "\"$1\" समूह हेतु समाप्ती का समय पहले ही बीत चुका है।",
+       "userrights-cannot-shorten-expiry": "आप \"$1\" समूह की समाप्ति को आगे नहीं बढ़ा सकते हैं। केवल इस समूह को जोड़ने और निकालने की अनुमति वाले उपयोगकर्ता आगे समाप्ति समय ला सकते हैं।",
        "userrights-conflict": "सदस्य अधिकार बदलावों में अंतर्विरोध! कृपया अपने बदलाव जाँचें और पुनः सुनिश्चित करें।",
        "group": "समूह:",
        "group-user": "सदस्य",
        "action-delete": "इस पृष्ठ को हटाने",
        "action-deleterevision": "अवतरण हटायें",
        "action-deletelogentry": "लॉग प्रविष्टियाँ को हटाए",
-       "action-deletedhistory": "à¤\87स à¤ªà¥\83षà¥\8dठ à¤\95à¥\87 à¤®à¤¿à¤\9fà¥\87 à¤\87तिहास à¤\95à¥\8b à¤¦à¥\87à¤\96नà¥\87",
+       "action-deletedhistory": "पà¥\83षà¥\8dठ à¤\95à¥\87 à¤®à¤¿à¤\9fà¥\87 à¤\87तिहास à¤\95à¥\8b à¤¦à¥\87à¤\96ना",
        "action-deletedtext": "हटाये गए अवतरण का पाठ देखें",
        "action-browsearchive": "हटाएँ गए पृष्ठों में खोजने",
-       "action-undelete": "à¤\87स à¤ªà¥\83षà¥\8dठ à¤\95à¥\8b à¤ªà¥\81नरà¥\8dसà¥\8dथापित à¤\95रनà¥\87",
-       "action-suppressrevision": "à¤\87स à¤\9bिपà¥\87 à¤\85वतरण को देखने और पुनर्स्थापित करने",
+       "action-undelete": "पृष्ठ को पुनर्स्थापित करने",
+       "action-suppressrevision": "à¤\9bिपà¥\87 à¤\85वतरणà¥\8bà¤\82 को देखने और पुनर्स्थापित करने",
        "action-suppressionlog": "इस निजी लॉग को देखने",
        "action-block": "इस सदस्य को संपादन करने से ब्लॉक करने",
        "action-protect": "इस पृष्ठ के सुरक्षा स्तर बदलने",
        "rcfilters-empty-filter": "कोई सक्रिय फिल्टर नहीं। सभी योगदान दिखाए गए है।",
        "rcfilters-filterlist-title": "फिल्टर",
        "rcfilters-filterlist-whatsthis": "यह क्या है?",
+       "rcfilters-filterlist-feedbacklink": "नए (बीटा) फिल्टर पर प्रतिक्रिया दें",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "रंग चुनें",
+       "rcfilters-highlightmenu-help": "इस गुण को हाइलाइट करने के लिए एक रंग चुनें",
        "rcfilters-filterlist-noresults": "कोई फिल्टर नहीं पाया",
+       "rcfilters-noresults-conflict": "कोई भी परिणाम नहीं मिला क्योंकि खोज मापदंड संघर्ष में है",
+       "rcfilters-state-message-subset": "इस फिल्टर का कोई प्रभाव नहीं है क्योंकि इसका परिणाम निम्न, व्यापक {{PLURAL: $2 |फ़िल्टर|फिल्टर}} के साथ शामिल है (इसे भेद करने के लिए हाइलाइट करने की कोशिश करें): $1",
+       "rcfilters-state-message-fullcoverage": "किसी समूह में सभी फ़िल्टर चुनना कोई भी नहीं चुनने के समान है इसलिए इस फ़िल्टर का कोई प्रभाव नहीं है समूह में शामिल हैं: $1",
        "rcfilters-filtergroup-registration": "उपयोगकर्ता पंजीकरण",
        "rcfilters-filter-registered-label": "पंजीकृत:",
        "rcfilters-filter-registered-description": "लॉग-इन संपादक।",
        "rcfilters-filter-unregistered-label": "अपंजीकृत",
        "rcfilters-filter-unregistered-description": "संपादक जो लॉग इन नहीं हैं।",
+       "rcfilters-filtergroup-authorship": "लेखकों को संपादित करें",
        "rcfilters-filter-editsbyself-label": "आपके अपने संपादन",
        "rcfilters-filter-editsbyself-description": "आपके द्वारा संपादित",
        "rcfilters-filter-editsbyother-label": "दूसरों के द्वारा संपादित",
+       "rcfilters-filter-editsbyother-description": "अन्य उपयोगकर्ताओं द्वारा बनाई गए संपादन (आपके द्वारा नहीं)",
+       "rcfilters-filtergroup-userExpLevel": "अनुभवी स्तर (केवल पंजीकृत सदस्यों के लिए)",
+       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "अनुभव फ़िल्टर केवल पंजीकृत उपयोगकर्ता पाते हैं इसलिए यह फ़िल्टर \"अपंजीकृत\" फ़िल्टर के साथ संघर्ष करता है।",
        "rcfilters-filter-user-experience-level-newcomer-label": "अपरिचित",
        "rcfilters-filter-user-experience-level-newcomer-description": "4 दिनों की गतिविधि और 10 सम्पादन से कम।",
        "rcfilters-filter-user-experience-level-learner-label": "शिक्षार्थियों",
        "rcfilters-filter-unpatrolled-description": "परीक्षित चिन्हित न किए सम्पादन।",
        "rcfilters-filtergroup-significance": "महत्व",
        "rcfilters-filter-minor-label": "छोटा संपादन",
+       "rcfilters-filter-minor-description": "लेखक का संपादन छोटा संपादन के रूप में लेबल किया गया है।",
        "rcfilters-filter-major-label": "गैर-मामूली संपादन",
        "rcfilters-filtergroup-changetype": "बदलाव के प्रकार:",
        "rcfilters-filter-pageedits-label": "पृष्ठ संपादन",
+       "rcfilters-filter-pageedits-description": "विकि सामग्री, चर्चा, श्रेणी विवरणों के संपादन ....",
        "rcfilters-filter-newpages-label": "पृष्ठ कृतियों",
        "rcfilters-filter-newpages-description": "संपादन जिससे नया पृष्ट बना",
        "rcfilters-filter-categorization-label": "श्रेणी परिवर्तन",
+       "rcfilters-filter-categorization-description": "श्रेणियों से पृष्ठों के रिकॉर्ड्स को जोड़ा या निकाला जा सकता है",
+       "rcfilters-filter-logactions-label": "लॉग की गई कार्रवाई",
+       "rcfilters-filter-logactions-description": "प्रशासनिक कार्रवाई, खाता निर्माण, पृष्ठ विलोपन, अपलोड ....",
        "rcnotefrom": "नीचे <strong>$2</strong> के बाद से (<strong>$1</strong> तक) {{PLURAL:$5|हुआ बदलाव दर्शाया गया है|हुए बदलाव दर्शाए गये हैं}}।",
        "rclistfrom": "$3 $2 से नये बदलाव दिखाएँ",
        "rcshowhideminor": "छोटे बदलाव $1",
        "feedback-thanks": "धन्यवाद! आपकी प्रतिक्रिया पृष्ठ में नियुक्त किया गया है \"[ $2  $1 ]\"।",
        "feedback-thanks-title": "धन्यवाद!",
        "feedback-useragent": "सदस्य कर्ता:",
-       "searchsuggest-search": "खोजें {{SITENAME}}",
+       "searchsuggest-search": "{{SITENAME}} में खोजें",
        "searchsuggest-containing": "...से युक्त",
        "api-error-badtoken": "आंतरिक त्रुटि: बुरी टोकन।",
        "api-error-emptypage": "नए खाली पृष्ठ बनाने की अनुमति नहीं है।",
index a24bed7..c90633e 100644 (file)
        "htmlform-time-invalid": "Unesena vrijednost nije prepoznati format vremena. Pokušajte koristiti format HH:MM:SS.",
        "htmlform-datetime-toohigh": "Uneseni datum i vrijeme su veći od $1",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
-       "logentry-delete-delete_redir": "$1 je premještanjem {{GENDER:$2|pobrisao|pobrisala}} preusmjeravanje $3",
+       "logentry-delete-delete_redir": "$1 premještanjem je {{GENDER:$2|pobrisao|pobrisala}} preusmjeravanje $3",
        "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
        "logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|zapisa u evidenciji|$5 zapisa u evidenciji}} na $3: $4",
        "logentry-delete-revision": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|uređivanja|$5 uređivanja}} na stranici $3: $4",
index 1fcdedb..6b2c293 100644 (file)
        "newimages-summary": "Questa pagina speciale mostra i file caricati più di recente.",
        "newimages-legend": "Filtra",
        "newimages-label": "Nome file (o una parte di esso):",
+       "newimages-user": "Indirizzo IP o nome utente",
        "newimages-showbots": "Mostra caricamenti di bot",
        "newimages-hidepatrolled": "Nascondi caricamenti verificati",
        "noimages": "Non c'è nulla da vedere.",
index 2442f52..4e4f70c 100644 (file)
        "yourrealname": "실명:",
        "yourlanguage": "언어:",
        "yourvariant": "언어 변종:",
-       "prefs-help-variant": "이 위키 내용을 볼 때 사용할 언어 변종이나 철자 체계를 선택하세요.",
+       "prefs-help-variant": "이 위키 내용을 표시하기 위해 사용할 언어 변종이나 철자 체계를 선택하세요.",
        "yournick": "새 서명:",
        "prefs-help-signature": "토론 문서에 글을 쓴 후에는 마지막에 서명을 해야 합니다.  “<nowiki>~~~~</nowiki>” 기호를 추가하면 서명과 글 작성 시각이 자동으로 입력됩니다.",
        "badsig": "서명이 잘못되었습니다.\nHTML 태그를 확인하세요.",
        "upload_directory_read_only": "파일 저장 디렉터리($1)에 쓰기 권한이 없습니다.",
        "uploaderror": "올리기 오류",
        "upload-recreate-warning": "<strong>경고: 해당 이름으로 된 파일이 삭제되었거나 이동되었습니다.</strong>\n\n편의를 위해 이 문서에 대한 삭제와 이동 기록을 다음과 같이 제공합니다:",
-       "uploadtext": "파일을 올리기 위해서는 아래의 양식을 채워주세요.\n[[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 검색할 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.\n\n문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 너비를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할 때",
+       "uploadtext": "파일을 올리기 위해서는 아래의 양식을 채워주세요.\n[[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 검색할 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.\n\n문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong> 파일의 온전한 모양을 사용하고자 할 때\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code></strong> 파일의 너비를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> 파일을 직접 표시하지 않고 파일로 바로 링크할 때",
        "upload-permitted": "허용된 파일 {{PLURAL:$2|형식}}: $1",
        "upload-preferred": "권장 파일 {{PLURAL:$2|형식}}: $1",
        "upload-prohibited": "금지된 파일 {{PLURAL:$2|형식}}: $1",
        "log": "기록 목록",
        "logeventslist-submit": "보기",
        "all-logs-page": "모든 공개 기록",
-       "alllogstext": "{{SITENAME}}ì\97\90ì\84\9cì\9d\98 ê¸°ë¡\9dì\9d´ ëª¨ë\91\90 ë\82\98ì\99\80 ì\9e\88ì\8aµë\8b\88ë\8b¤.\n기ë¡\9d ì¢\85ë¥\98, ì\82¬ì\9a©ì\9e\90 ì\9d´ë¦\84, ë¬¸ì\84\9c ì\9d´ë¦\84ì\9d\84 ì\84 í\83\9dí\95´서 볼 수 있습니다. (대소문자를 구별합니다.)",
+       "alllogstext": "{{SITENAME}}ì\9d\98 ì\82¬ì\9a©í\95  ì\88\98 ì\9e\88ë\8a\94 ê¸°ë¡\9dì\9d´ ëª¨ë\91\90 í\91\9cì\8b\9cë\90\98ì\96´ ì\9e\88ì\8aµë\8b\88ë\8b¤.\n기ë¡\9d ì¢\85ë¥\98, ì\82¬ì\9a©ì\9e\90 ì\9d´ë¦\84, ì\98\81í\96¥ì\9d\84 ë°\9bë\8a\94 ë¬¸ì\84\9cì\9d\84 ì\84 í\83\9dí\95´ì\84\9c ë²\94ì\9c\84를 ì¢\81í\98\80서 볼 수 있습니다. (대소문자를 구별합니다.)",
        "logempty": "일치하는 항목이 없습니다.",
        "log-title-wildcard": "다음 글로 시작하는 제목 검색",
        "showhideselectedlogentries": "선택한 기록 항목 보이기/숨기기",
        "newimages-summary": "이 특수 문서는 최근에 올라온 파일을 나열하고 있습니다.",
        "newimages-legend": "필터",
        "newimages-label": "파일 이름 (또는 그 일부분):",
+       "newimages-user": "IP 주소 또는 사용자 이름",
        "newimages-showbots": "봇이 올린 것 보기",
        "newimages-hidepatrolled": "점검한 업로드 숨기기",
        "noimages": "그림이 없습니다.",
        "metadata-help": "이 파일은 카메라나 스캐너가 파일을 만들거나 디지털화하는 데 사용하기위해 기록한 부가 정보를 포함하고 있습니다.\n프로그램에서 파일을 편집한 경우, 새로 저장한 파일에 일부 부가 정보가 빠질 수 있습니다.",
        "metadata-expand": "자세한 정보 보이기",
        "metadata-collapse": "자세한 정보 숨기기",
-       "metadata-fields": "파일 메타데이터 표가 접혀 있을 때, 이 메시지에 올라와 있는 다음 속성값만이 기본적으로 보이게 됩니다.\n나머지 값은 자동적으로 숨겨집니다.\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",
+       "metadata-fields": "그림 메타데이터 표가 접혀 있을 때, 이 메시지에 나열되어 있는 다음 메타데이터 필드가 그림 문서 표시에 포함됩니다.\n나머지는 기본적으로 숨겨집니다.\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-bitspersample": "픽셀당 비트 수",
        "authprovider-confirmlink-request-label": "연결할 계정",
        "authprovider-confirmlink-success-line": "$1: 연결을 성공했습니다.",
        "authprovider-confirmlink-failed": "계정 연결을 완전히 성공하지 못했습니다: $1",
-       "authprovider-confirmlink-ok-help": "연결 실패 메시지를 보여준 뒤에도 계속합니다.",
+       "authprovider-confirmlink-ok-help": "연결 실패 메시지를 표시한 뒤에도 계속합니다.",
        "authprovider-resetpass-skip-label": "건너뛰기",
        "authprovider-resetpass-skip-help": "비밀번호 재설정을 건너뜁니다.",
        "authform-nosession-login": "인증은 성공했으나 사용자의 브라우저가 로그인 상태를 저장하지 못했습니다.\n\n$1",
index ae8a516..9706c1a 100644 (file)
        "newimages-summary": "Dës Spezialsäit weist eng Lëscht mat de Fichieren déi als lescht eropgeluede goufen.",
        "newimages-legend": "Filter",
        "newimages-label": "Numm vum Fichier (oder en Deel dovun):",
+       "newimages-user": "IP-Adress oder Benotzernumm",
        "newimages-showbots": "Vu Botten eropgeluede Fichiere weisen",
        "newimages-hidepatrolled": "Nogekuckt Fichiere verstoppen",
        "noimages": "Keng Biller fonnt.",
index 5ca5204..3e868c3 100644 (file)
        "watchthis": "Stebėti šį puslapį",
        "savearticle": "Išsaugoti puslapį",
        "savechanges": "Išsaugoti pakeitimus",
-       "publishpage": "Skelbti puslapį",
-       "publishchanges": "Skelbti pakeitimus",
+       "publishpage": "Išsaugoti puslapį",
+       "publishchanges": "Išsaugoti pakeitimus",
        "preview": "Peržiūra",
        "showpreview": "Rodyti peržiūrą",
        "showdiff": "Rodyti skirtumus",
index b77db9d..e195566 100644 (file)
        "editlink": "kohendele",
        "viewsourcelink": "Kačo algukoodu",
        "editsectionhint": "Kohendele tädä kohtua: $1",
-       "toc": "Sizäldö",
+       "toc": "Syväindö",
        "showtoc": "ozuttua",
-       "hidetoc": "peittiä",
+       "hidetoc": "peitä",
        "collapsible-collapse": "Peitä",
        "collapsible-expand": "Levitä",
        "confirmable-confirm": "{{GENDER:$1|Oletgo}} varmu?",
        "password-change-forbidden": "Et voi vaihtua peittosanoi täs wikis.",
        "login": "Kirjuttai",
        "nav-login-createaccount": "Kirjuttai libo registriiruiččei",
-       "userlogin": "Kirjuttai libo registriiruiččei",
-       "userloginnocreate": "Kirjuttai",
        "logout": "Kirjuttai ullos",
        "userlogout": "Kirjuttai ullos",
        "notloggedin": "Ei kirjutannuhes",
        "userlogin-noaccount": "Ei ole tilii?",
        "userlogin-joinproject": "Yhty {{SITENAME}}",
-       "nologin": "Ei ole tilii? $1",
-       "nologinlink": "Luaji tili",
        "createaccount": "Registriiruiččei",
-       "gotaccount": "Ollou sinul jo tunnus? $1",
-       "gotaccountlink": "Kirjuttai",
-       "userlogin-resetlink": "Unohtitgo sinun käyttäinimen/peittosanan?",
        "userlogin-resetpassword-link": "Unohtitgo sinun peittosanan?",
        "userlogin-helplink2": "Abuu kirjuttamizeh",
        "userlogin-loggedin": "Olet jo kirjutannuhes nimel {{GENDER:$1|$1}}.\nKäytä al olijua ankiettua ku kirjuttuakseh eri käyttäjänny.",
        "createacct-email-ph": "Kirjuta sinun sähköpoštuadressu",
        "createacct-another-email-ph": "Kirjuta sinun sähköpoštuadressu",
        "createacct-realname": "Tovelline nimi (omatahtoine tiedo)",
-       "createaccountreason": "Syy:",
        "createacct-reason": "Syy",
        "createacct-reason-ph": "Mindäh olet luadimas tostu käyttäitilii",
        "createacct-submit": "Luaji tili",
        "prefs-changeemail": "Vaihta libo ota iäre sähköpoštuadressu",
        "prefs-setemail": "Kirjuta sähköpoštuadressu",
        "saveprefs": "Tallenda",
-       "rows": "Riädyy:",
        "searchresultshead": "Eččie",
        "timezoneregion-africa": "Afriekku",
        "timezoneregion-america": "Ameriekku",
        "rcshowhideanons-show": "Ozuta",
        "rcshowhideanons-hide": "Peitä",
        "rcshowhidepatr-show": "Ozuttua",
-       "rcshowhidepatr-hide": "Peittiä",
+       "rcshowhidepatr-hide": "Peitä",
        "rcshowhidemine": "$1 minun kohendukset",
        "rcshowhidemine-show": "Ozuta",
        "rcshowhidemine-hide": "Peitä",
index 64a046e..d8f3b30 100644 (file)
        "newimages-summary": "Na tej stronie specjalnej prezentowane są ostatnio przesłane pliki.",
        "newimages-legend": "Filtruj",
        "newimages-label": "Nazwa pliku (lub jej fragment):",
+       "newimages-user": "Adres IP lub nazwa użytkownika",
        "newimages-showbots": "Pokaż pliki przesłane przez boty",
        "newimages-hidepatrolled": "Ukryj sprawdzone pliki",
        "noimages": "Brak plików do pokazania.",
index 2250b88..1d0e54a 100644 (file)
                        "!Silent",
                        "Joao Xavier",
                        "Nahime2015",
-                       "Alex Great"
+                       "Alex Great",
+                       "EVinente"
                ]
        },
        "tog-underline": "Sublinhar links:",
        "login": "Autenticar-se",
        "login-security": "Verificar sua identidade",
        "nav-login-createaccount": "Entrar / criar conta",
-       "userlogin": "Entrar / criar conta",
-       "userloginnocreate": "Entrar",
        "logout": "Sair",
        "userlogout": "Sair",
        "notloggedin": "Não autenticado(a)",
        "userlogin-noaccount": "Não possui uma conta?",
        "userlogin-joinproject": "Junte-se ao projeto {{SITENAME}}",
-       "nologin": "Não possui uma conta? $1.",
-       "nologinlink": "Criar uma conta",
        "createaccount": "Criar conta",
-       "gotaccount": "Já possui uma conta? '''$1'''.",
-       "gotaccountlink": "Autenticar-se",
-       "userlogin-resetlink": "Esqueceu-se do seu nome de usuário ou da senha?",
        "userlogin-resetpassword-link": "Esqueceu sua senha?",
        "userlogin-helplink2": "Ajuda com o login",
        "userlogin-loggedin": "Você já está conectado como {{GENDER:$1|$1}}.\nUse o formulário abaixo para iniciar sessão como outro usuário.",
        "createaccountmail": "Usar uma senha aleatória e temporária que será enviada ao endereço de e-mail especificado a seguir",
        "createaccountmail-help": "Pode ser utilizado para criar uma conta para outra pessoa sem saber a senha.",
        "createacct-realname": "Nome real (opcional)",
-       "createaccountreason": "Motivo:",
        "createacct-reason": "Motivo",
        "createacct-reason-ph": "Por que você está criando outra conta",
        "createacct-reason-help": "Mensagem mostrada no registro de criação de conta",
        "rcfilters-activefilters": "Filtros ativos",
        "rcfilters-restore-default-filters": "Restaurar filtros padrão",
        "rcfilters-clear-all-filters": "Limpar todos os filtros",
-       "rcfilters-search-placeholder": "Filtrar alterações recentes (procurar ou começar a digitar)",
+       "rcfilters-search-placeholder": "Filtrar mudanças recentes (procurar ou começar a digitar)",
        "rcfilters-invalid-filter": "Filtro inválido",
        "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filter-editsbyother-label": "Edições de outros",
        "rcfilters-filter-editsbyother-description": "Edições criadas por outros usuários (não você.)",
        "rcfilters-filtergroup-userExpLevel": "Nível de experiência (apenas para usuário registados)",
-       "rcfilters-filter-userExpLevel-newcomer-label": "Recém-chegados",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
-       "rcfilters-filter-userExpLevel-learner-label": "Aprendizes",
-       "rcfilters-filter-userExpLevel-learner-description": "Mais dias de atividade e edições do que \"Novatos\", mas menos do que \"Usuários experientes\".",
-       "rcfilters-filter-userExpLevel-experienced-label": "Usuários experientes",
-       "rcfilters-filter-userExpLevel-experienced-description": "Mais de 30 dias de atividade e 500 edições.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Recém-chegados",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
+       "rcfilters-filter-user-experience-level-learner-label": "Aprendizes",
+       "rcfilters-filter-user-experience-level-learner-description": "Mais dias de atividade e edições do que \"Novatos\", mas menos do que \"Usuários experientes\".",
+       "rcfilters-filter-user-experience-level-experienced-label": "Usuários experientes",
+       "rcfilters-filter-user-experience-level-experienced-description": "Mais de 30 dias de atividade e 500 edições.",
        "rcfilters-filtergroup-automated": "Contribuições automatizadas",
        "rcfilters-filter-bots-label": "Robô",
        "rcfilters-filter-bots-description": "Edições feitas por ferramentas automatizadas.",
        "rcshowhidecategorization": "$1 categorização de páginas",
        "rcshowhidecategorization-show": "Exibir",
        "rcshowhidecategorization-hide": "Esconder",
-       "rclinks": "Exibir as $1 alterações recentes feitas nos últimos $2 dias<br />$3",
+       "rclinks": "Exibir as $1 mudanças recentes feitas nos últimos $2 dias<br />$3",
        "diff": "dif",
        "hist": "his",
        "hide": "Ocultar",
        "newimages-summary": "Esta página especial mostra os arquivos mais recentemente enviados",
        "newimages-legend": "Filtrar",
        "newimages-label": "Nome de arquivo (ou parte dele):",
+       "newimages-user": "Endereço IP ou nome do usuário:",
        "newimages-showbots": "Mostrar uploads realizados por robôs",
        "newimages-hidepatrolled": "Ocultar os carregamentos patrulhados.",
        "noimages": "Nada para ver.",
        "autosumm-newblank": "Criar página em branco",
        "size-kilobytes": "$1 kB",
        "bitrate-kilobits": "$1&nbsp;kb/s",
-       "lag-warn-normal": "É possível que as alterações que sejam mais recentes do que $1 {{PLURAL:$1|segundo|segundos}} não sejam exibidas nesta lista.",
-       "lag-warn-high": "Devido a sérios problemas de latência no servidor do banco de dados, as alterações mais recentes que $1 {{PLURAL:$1|segundo|segundos}} poderão não ser exibidas nesta lista.",
+       "lag-warn-normal": "É possível que as mudanças que sejam mais recentes do que $1 {{PLURAL:$1|segundo|segundos}} não sejam exibidas nesta lista.",
+       "lag-warn-high": "Devido a sérios problemas de latência no servidor do banco de dados, as mudanças mais recentes que $1 {{PLURAL:$1|segundo|segundos}} poderão não ser exibidas nesta lista.",
        "watchlistedit-normal-title": "Editar lista de páginas vigiadas",
        "watchlistedit-normal-legend": "Remover títulos da lista de páginas vigiadas",
        "watchlistedit-normal-explain": "Os títulos das páginas de sua lista de vigiadas são exibidos abaixo.\nPara remover um título, marque a caixa ao lado do mesmo e clique \"{{int:Watchlistedit-normal-submit}}\".\nVocê pode também [[Special:EditWatchlist/raw|editar a lista de páginas vigiadas em forma de texto]].",
        "logentry-tag-update-revision": "$1 {{GENDER:$2|atualizou}} etiquetas em revisão $4 da página $3 ({{PLURAL:$7|adicionou}} $6; {{PLURAL:$9|removeu}} $8)",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|atualizou}} etiquetas na entrada de registro $5 da página $3 ({{PLURAL:$7|adicionou}} $6; {{PLURAL:$9|removeu}} $8)",
        "rightsnone": "(nenhum)",
-       "revdelete-summary": "resumo da edição",
        "rightslogentry-temporary-group": "$1 (temporário, até $2)",
        "feedback-adding": "Adicionando os comentários na página...",
        "feedback-back": "Voltar",
index 2793992..8905262 100644 (file)
        "page_first": "primeira",
        "page_last": "última",
        "histlegend": "Seleção de diferenças: use os botões de opção para marcar as versões que deseja comparar.\nPressione 'Enter' ou clique o botão \"{{int:compareselectedversions}}\".<br />\nLegenda: '''({{int:cur}})''' = diferenças para a versão atual,\n'''({{int:last}})''' = diferenças para a versão anterior,\n'''{{int:minoreditletter}}''' = edição menor",
-       "history-fieldset-title": "Navegar pelo histórico",
-       "history-show-deleted": "Somente eliminadas",
+       "history-fieldset-title": "Pesquisar revisões",
+       "history-show-deleted": "Somente revisões eliminadas",
        "histfirst": "Mais antigas",
        "histlast": "Mais novas",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
        "prefs-help-prefershttps": "Esta preferência terá efeito no seu próximo início de sessão.",
        "prefswarning-warning": "Fez alterações às suas preferências que não foram gravadas ainda.\nSe abandonar esta página sem clicar em \"$1\", as suas preferências não serão atualizadas.",
        "prefs-tabs-navigation-hint": "Dica: Pode usar as setas direita e esquerda do teclado para navegar entre os separadores.",
-       "userrights": "Gestão de privilégios {{GENDER:{{BASEPAGENAME}}|do utilizador|da utilizadora|de utilizador(a)}}",
+       "userrights": "Privilégios de utilizador",
        "userrights-lookup-user": "Selecionar um utilizador",
        "userrights-user-editname": "Introduza um nome de utilizador(a):",
        "editusergroup": "Carregar grupos do utilizador",
        "rcfilters-invalid-filter": "Filtro inválido",
        "rcfilters-empty-filter": "Não há filtros ativos. São mostradas todas as contribuições.",
        "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-filterlist-whatsthis": "O que é isto?",
        "rcfilters-filterlist-feedbacklink": "Dê-nos a sua opinião sobre os novos filtros (beta)",
        "rcfilters-highlightbutton-title": "Realçar resultados",
        "rcfilters-highlightmenu-title": "Selecionar uma cor",
+       "rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
        "rcfilters-filterlist-noresults": "Não foram encontrados filtros",
+       "rcfilters-noresults-conflict": "Não foram encontrados resultados porque os critérios de pesquisa estão em conflito",
        "rcfilters-filtergroup-registration": "Registo de utilizador",
        "rcfilters-filter-registered-label": "Registado",
        "rcfilters-filter-registered-description": "Editores autenticados.",
        "rcfilters-filter-bots-description": "Edições efectuadas por ferramentas automatizadas.",
        "rcfilters-filter-humans-label": "Ser humano (não robô)",
        "rcfilters-filter-humans-description": "Edições efectuadas por editores humanos.",
+       "rcfilters-filtergroup-reviewstatus": "Estado da revisão",
+       "rcfilters-filter-patrolled-label": "Patrulhadas",
+       "rcfilters-filter-patrolled-description": "Edições marcadas como patrulhadas.",
+       "rcfilters-filter-unpatrolled-label": "Não patrulhadas",
+       "rcfilters-filter-unpatrolled-description": "Edições não marcadas como patrulhadas.",
        "rcfilters-filtergroup-significance": "Significado",
        "rcfilters-filter-minor-label": "Edições menores",
        "rcfilters-filter-minor-description": "Edições marcadas pelo autor como menores.",
        "newimages-summary": "Esta página especial mostra os ficheiros mais recentemente enviados.",
        "newimages-legend": "Filtrar",
        "newimages-label": "Nome de ficheiro (ou parte dele):",
+       "newimages-user": "Endereço IP ou nome do utilizador",
        "newimages-showbots": "Mostrar carregamentos feitos por robôs",
        "newimages-hidepatrolled": "Ocultar carregamentos patrulhados",
        "noimages": "Nada para ver.",
index 75be7aa..f244431 100644 (file)
        "newimages-summary": "This message is displayed at the top of [[Special:NewImages]] to explain what is shown on that special page.",
        "newimages-legend": "Caption of the fieldset for the filter on [[Special:NewImages]]\n\n{{Identical|Filter}}",
        "newimages-label": "Caption of the filter editbox on [[Special:NewImages]]",
+       "newimages-user": "Caption of the username/IP address editbox on [[Special:NewImages]]",
        "newimages-showbots": "Used as label for a checkbox. When checked, [[Special:NewImages]] will also display uploads by users in the bots group.",
        "newimages-hidepatrolled": "Used as label for a checkbox. When checked, [[Special:NewImages]] will not display patrolled uploads.\n\nCf. {{msg-mw|tog-hidepatrolled}} and {{msg-mw|apihelp-feedrecentchanges-param-hidepatrolled}}.",
        "noimages": "This is shown on the special page [[Special:NewImages]], when there aren't any recently uploaded files.",
index c9e2ed9..3e799da 100644 (file)
        "newimages-summary": "На этой служебной странице показаны недавно загруженные файлы.",
        "newimages-legend": "Фильтр",
        "newimages-label": "Имя файла (или его часть):",
+       "newimages-user": "IP-адрес или имя участника",
        "newimages-showbots": "Показать загрузки ботов",
        "newimages-hidepatrolled": "Скрыть отпатрулированные загрузки",
        "noimages": "Изображения отсутствуют.",
index 9fe4e51..811f41d 100644 (file)
        "newimages-summary": "Ta posebna stran prikazuje najnovejše naložene datoteke.",
        "newimages-legend": "Filter",
        "newimages-label": "Ime datoteke (ali njen del):",
+       "newimages-user": "IP-naslov ali uporabniško ime",
        "newimages-showbots": "Prikaži nalaganja botov",
        "newimages-hidepatrolled": "Skrij nadzorovana nalaganja",
        "noimages": "Nič ni videti.",
index 2f24898..a8c7a30 100644 (file)
        "post-expand-template-argument-warning": "Varning: Sidan innehåller en eller flera mallparametrar som blir för långa när de expanderas.\nDessa parametrar har uteslutits.",
        "post-expand-template-argument-category": "Sidor med uteslutna mallparametrar",
        "parser-template-loop-warning": "Mall-loop upptäckt: [[$1]]",
+       "template-loop-category": "Sidor med loopade mallar",
+       "template-loop-category-desc": "Sidan innehåller en loopad mall, d.v.s. en mall som anropar sig själv rekursivt.",
        "parser-template-recursion-depth-warning": "Gräns för mallrekursionsdjup överskriden ($1)",
        "language-converter-depth-warning": "Gräns för språkkonverteringsdjup överskriden ($1)",
        "node-count-exceeded-category": "Sidor där antalet noder har överskridits",
        "newimages-summary": "Den här specialsidan visar de senast uppladdade filerna.",
        "newimages-legend": "Filter",
        "newimages-label": "Filnamn (eller en del av det):",
+       "newimages-user": "IP-adress eller användarnamn",
        "newimages-showbots": "Visa uppladdningar av botar",
        "newimages-hidepatrolled": "Dölj patrullerade uppladdningar",
        "noimages": "Ingenting att se.",
index 30fe744..043ab43 100644 (file)
        "externaldberror": "Maaaring may kamalian sa pagpapatotoo ng database o kaya hindi ka pinahintulutang isapanahon ng iyong panlabas na account.",
        "login": "Lumagda",
        "nav-login-createaccount": "Lumagda / lumikha ng account",
-       "userlogin": "Lumagda / lumikha ng account",
-       "userloginnocreate": "Lumagda",
        "logout": "Umalis sa pagkaka-login",
        "userlogout": "Umalis sa pagkaka-login",
        "notloggedin": "Hindi naka-login",
        "userlogin-noaccount": "Wala ka pa bang account?",
        "userlogin-joinproject": "Sumali sa {{SITENAME}}",
-       "nologin": "Wala ka pang account? $1.",
-       "nologinlink": "Lumikha ng account",
        "createaccount": "Lumikha ng account",
-       "gotaccount": "May account ka na ba? $1.",
-       "gotaccountlink": "Lumagda",
-       "userlogin-resetlink": "Nakalimutan mo ang iyong mga detalyeng pang-login?",
        "userlogin-resetpassword-link": "Nakalimutan ba ang iyong password?",
        "userlogin-helplink2": "Tulong sa pag-login",
        "userlogin-loggedin": "Naka-login ka na bilang {{GENDER:$1|$1}}. Gamitin ang form sa ibaba upang maka-login bilang ibang tagagamit o user.",
        "createacct-another-email-ph": "Ipasok ang email address",
        "createaccountmail": "Gumamit ng pansamantalang random na password at ipadala ito sa email na nakasaad sa ibaba",
        "createacct-realname": "Tunay na pangalan (maaaring wala)",
-       "createaccountreason": "Dahilan:",
        "createacct-reason": "Dahilan",
        "createacct-reason-ph": "Bakit ka gagawa ng isa pang account?",
        "createacct-submit": "Likhain ang iyong account",
        "post-expand-template-argument-warning": "Babala: Naglalamang ang pahinang ito ng kahit isang pagaalitan ng padron na napakalaki ng sukat ng paglawak.  Tinanggal ang mga alitang ito.",
        "post-expand-template-argument-category": "Mga pahinang naglalaman ng mga tinanggal na mga alitan ng padron",
        "parser-template-loop-warning": "Nadiskubreng silo ng suleras: [[$1]]",
+       "template-loop-category-desc": "Ang pahina ay naglalaman ng kodigong-makapanguulit, halimbawa. Isang kodigo na magpapahiwatig sa sarili ng paguulit.",
        "parser-template-recursion-depth-warning": "Lumabis na sa nakatakdang lalim ng rekursyon (pormula) ng suleras ($1)",
        "language-converter-depth-warning": "Lumampas sa ($1) ang hangganan ng lalim ng pampalit ng wika",
        "node-count-exceeded-category": "Mga pahina kung saan nalampasan ang bilang ng buko",
        "logentry-newusers-autocreate": "Automatikong {{GENDER:$2|inilikha}} ang account ng tagagamit na $1",
        "logentry-upload-upload": "{{GENDER:$2|Ikinarga}} ni $1 ang $3",
        "rightsnone": "(wala)",
-       "revdelete-summary": "buod ng pagbabago",
        "feedback-adding": "Idinaragdag ang pakaing-tugon sa pahina...",
        "feedback-back": "Magbalik",
        "feedback-bugcheck": "Mahusay! Suriin lang na hindi pa ito isa sa [$1 nalalamang mga depekto].",
index aeff357..d6be248 100644 (file)
        "newimages-summary": "本特殊页面展示最后上传的文件。",
        "newimages-legend": "过滤",
        "newimages-label": "文件名(或它的一部份):",
+       "newimages-user": "IP地址或用户名",
        "newimages-showbots": "显示机器人上传",
        "newimages-hidepatrolled": "隐藏已巡查的上传",
        "noimages": "无可查看文件。",
index f6cb76f..ee0db4d 100644 (file)
        "newimages-summary": "此特殊頁面中顯示最新上傳的檔案。",
        "newimages-legend": "搜尋",
        "newimages-label": "檔案名稱 (或部份檔名):",
+       "newimages-user": "IP 位址或使用者名稱",
        "newimages-showbots": "顯示由機器人上傳的檔案",
        "newimages-hidepatrolled": "隱藏己巡查上傳",
        "noimages": "無任何圖片。",
index 62dc36c..a8080c5 100644 (file)
@@ -36,6 +36,7 @@ define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless
 
 $maintClass = false;
 
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\LBFactory;
index 286fb58..60b8a7a 100644 (file)
@@ -28,6 +28,7 @@ require_once __DIR__ . '/Maintenance.php';
 require_once __DIR__ . '/../includes/export/DumpFilter.php';
 
 use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * @ingroup Dump Maintenance
index 83ab35c..dbaf643 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 require_once __DIR__ . '/Maintenance.php';
 
index 3088baa..feeeb65 100644 (file)
@@ -22,7 +22,7 @@
  * @author Timo Tijhof
  */
 
-use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 require_once __DIR__ . '/Maintenance.php';
 
index 06fcbaf..67f7780 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
index f8eedb3..b0a2b92 100644 (file)
@@ -25,6 +25,8 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * Maintenance script to run a database query in batches and wait for replica DBs.
  *
index 58472e9..b03620d 100644 (file)
@@ -25,6 +25,7 @@
 require_once __DIR__ . '/Maintenance.php';
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IDatabase;
 
 /**
  * Maintenance script that sends SQL queries from the specified file to the database.
index 2c22395..762c5e7 100644 (file)
@@ -11,7 +11,7 @@
     "eslint": "3.12.2",
     "eslint-config-wikimedia": "0.3.0",
     "grunt": "1.0.1",
-    "grunt-banana-checker": "0.5.0",
+    "grunt-banana-checker": "0.6.0",
     "grunt-contrib-copy": "1.0.0",
     "grunt-contrib-watch": "1.0.0",
     "grunt-eslint": "19.0.0",
index 631386a..ce52846 100644 (file)
@@ -1302,7 +1302,7 @@ return [
                'dependencies' => [
                        'mediawiki.ForeignStructuredUpload',
                        'mediawiki.Upload.BookletLayout',
-                       'mediawiki.widgets.CategorySelector',
+                       'mediawiki.widgets.CategoryMultiselectWidget',
                        'mediawiki.widgets.DateInputWidget',
                        'mediawiki.jqueryMsg',
                        'mediawiki.api.messages',
@@ -2357,9 +2357,15 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.widgets.CategorySelector' => [
+               'deprecated' => 'Use "mw.widgets.CategoryMultiselectWidget" instead. See T161285.',
+               'dependencies' => [
+                       'mediawiki.widgets.CategoryMultiselectWidget',
+               ],
+       ],
+       'mediawiki.widgets.CategoryMultiselectWidget' => [
                'scripts' => [
                        'resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js',
-                       'resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js',
+                       'resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js',
                ],
                'dependencies' => [
                        'oojs-ui-widgets',
@@ -2369,7 +2375,7 @@ return [
                ],
                'messages' => [
                        'red-link-title',
-                       'mw-widgets-categoryselector-add-category-placeholder'
+                       'mw-widgets-categoryselector-add-category-placeholder',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
index a84374a..a0e53b3 100644 (file)
@@ -4,14 +4,19 @@
                        "Mogoeilor"
                ]
        },
+       "ooui-outline-control-move-down": "ڤا دڤۈن بوردن آیتم",
+       "ooui-outline-control-move-up": "ڤارو بردن آیتم",
+       "ooui-outline-control-remove": "ڤورداشتن آیتم",
        "ooui-toolbar-more": "بیشتر",
        "ooui-toolgroup-expand": "بیشتر",
        "ooui-toolgroup-collapse": "کمتر",
        "ooui-dialog-message-accept": "خۈڤإ",
        "ooui-dialog-message-reject": "أنجومشيڤ کردن",
+       "ooui-dialog-process-error": "یأ چي ايچو إشتوا إ",
        "ooui-dialog-process-retry": "ز نۉ تلاش کونين",
        "ooui-dialog-process-continue": "ديندا گرهڌن",
        "ooui-selectfile-button-select": "گولإڤورچين کردن جانیا",
+       "ooui-selectfile-not-supported": "گول ڤورچی کردن جانیا کونشتکاری نڤابیڌ",
        "ooui-selectfile-placeholder": "هيژ جانيایي گولإ ڤورچين نڤابيڌإ",
        "ooui-selectfile-dragdrop-placeholder": "جانيانأ ڤأنين ايچو"
 }
index a13441b..f390b56 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
  */
 ( function ( OO ) {
 
index 382c13b..624cc57 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
 .oo-ui-element-hidden {
   display: none !important;
       -ms-user-select: none;
           user-select: none;
 }
+.oo-ui-buttonElement > .oo-ui-buttonElement-button::-moz-focus-inner {
+  border-color: transparent;
+  padding: 0;
+}
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   display: none;
@@ -1130,9 +1134,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-menuSelectWidget-invisible {
   display: none;
 }
-.oo-ui-menuOptionWidget {
-  position: relative;
-}
 .oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
   display: none;
 }
index c4fdf20..bff0f50 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
 .oo-ui-element-hidden {
   display: none !important;
       -ms-user-select: none;
           user-select: none;
 }
+.oo-ui-buttonElement > .oo-ui-buttonElement-button::-moz-focus-inner {
+  border-color: transparent;
+  padding: 0;
+}
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   display: none;
@@ -60,9 +64,6 @@
   border-radius: 2px;
   outline: 0;
 }
-.oo-ui-buttonElement > .oo-ui-buttonElement-button:focus::-moz-focus-inner {
-  border-color: transparent;
-}
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   margin-right: 0.25em;
   margin-left: 0.46875em;
@@ -670,7 +671,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-optionWidget {
   position: relative;
   display: block;
-  border: 0;
 }
 .oo-ui-optionWidget.oo-ui-widget-enabled {
   cursor: pointer;
@@ -1566,7 +1566,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   display: none;
 }
 .oo-ui-menuOptionWidget {
-  position: relative;
   padding: 0.5em 1em;
   -webkit-transition: background-color 100ms, color 100ms;
      -moz-transition: background-color 100ms, color 100ms;
index fe11d68..44b21ab 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
  */
 ( function ( OO ) {
 
@@ -90,7 +90,7 @@ OO.ui.isFocusableElement = function ( $element ) {
        // Check if the element is visible
        if ( !(
                // This is quicker than calling $element.is( ':visible' )
-               $.expr.filters.visible( element ) &&
+               $.expr.pseudos.visible( element ) &&
                // Check that all parents are visible
                !$element.parents().addBack().filter( function () {
                        return $.css( this, 'visibility' ) === 'hidden';
@@ -883,7 +883,7 @@ OO.ui.Element.static.getDocument = function ( obj ) {
                // Window
                obj.document ||
                // HTMLDocument
-               ( obj.nodeType === 9 && obj ) ||
+               ( obj.nodeType === Node.DOCUMENT_NODE && obj ) ||
                null;
 };
 
@@ -912,7 +912,7 @@ OO.ui.Element.static.getDir = function ( obj ) {
        if ( obj instanceof jQuery ) {
                obj = obj[ 0 ];
        }
-       isDoc = obj.nodeType === 9;
+       isDoc = obj.nodeType === Node.DOCUMENT_NODE;
        isWin = obj.document !== undefined;
        if ( isDoc || isWin ) {
                if ( isWin ) {
@@ -1140,17 +1140,18 @@ OO.ui.Element.static.getScrollLeft = ( function () {
 }() );
 
 /**
- * Get scrollable object parent
+ * Get the root scrollable element of given element's document.
  *
- * documentElement can't be used to get or set the scrollTop
- * property on Blink. Changing and testing its value lets us
- * use 'body' or 'documentElement' based on what is working.
+ * On Blink-based browsers (Chrome etc.), `document.documentElement` can't be used to get or set
+ * the scrollTop property; instead we have to use `document.body`. Changing and testing the value
+ * lets us use 'body' or 'documentElement' based on what is working.
  *
  * https://code.google.com/p/chromium/issues/detail?id=303131
  *
  * @static
- * @param {HTMLElement} el Element to find scrollable parent for
- * @return {HTMLElement} Scrollable parent
+ * @param {HTMLElement} el Element to find root scrollable parent for
+ * @return {HTMLElement} Scrollable parent, `document.body` or `document.documentElement`
+ *     depending on browser
  */
 OO.ui.Element.static.getRootScrollableElement = function ( el ) {
        var scrollTop, body;
@@ -1174,8 +1175,8 @@ OO.ui.Element.static.getRootScrollableElement = function ( el ) {
 /**
  * Get closest scrollable container.
  *
- * Traverses up until either a scrollable element or the root is reached, in which case the window
- * will be returned.
+ * Traverses up until either a scrollable element or the root is reached, in which case the root
+ * scrollable element will be returned (see #getRootScrollableElement).
  *
  * @static
  * @param {HTMLElement} el Element to find scrollable container for
@@ -1193,6 +1194,12 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension )
                props = [ 'overflow-' + dimension ];
        }
 
+       // Special case for the document root (which doesn't really have any scrollable container, since
+       // it is the ultimate scrollable container, but this is probably saner than null or exception)
+       if ( $( el ).is( 'html, body' ) ) {
+               return this.getRootScrollableElement( el );
+       }
+
        while ( $parent.length ) {
                if ( $parent[ 0 ] === this.getRootScrollableElement( el ) ) {
                        return $parent[ 0 ];
@@ -1211,7 +1218,8 @@ OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension )
                }
                $parent = $parent.parent();
        }
-       return this.getDocument( el ).body;
+       // The element is unattached... return something mostly sane
+       return this.getRootScrollableElement( el );
 };
 
 /**
@@ -2181,6 +2189,7 @@ OO.ui.mixin.ButtonElement.prototype.isActive = function () {
  * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Groups
  *
  * @abstract
+ * @mixins OO.EmitterList
  * @class
  *
  * @constructor
@@ -2192,15 +2201,20 @@ OO.ui.mixin.GroupElement = function OoUiMixinGroupElement( config ) {
        // Configuration initialization
        config = config || {};
 
+       // Mixin constructors
+       OO.EmitterList.call( this, config );
+
        // Properties
        this.$group = null;
-       this.items = [];
-       this.aggregateItemEvents = {};
 
        // Initialization
        this.setGroupElement( config.$group || $( '<div>' ) );
 };
 
+/* Setup */
+
+OO.mixinClass( OO.ui.mixin.GroupElement, OO.EmitterList );
+
 /* Events */
 
 /**
@@ -2229,28 +2243,6 @@ OO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) {
        }
 };
 
-/**
- * Check if a group contains no items.
- *
- * @return {boolean} Group is empty
- */
-OO.ui.mixin.GroupElement.prototype.isEmpty = function () {
-       return !this.items.length;
-};
-
-/**
- * Get all items in the group.
- *
- * The method returns an array of item references (e.g., [button1, button2, button3]) and is useful
- * when synchronizing groups of items, or whenever the references are required (e.g., when removing items
- * from a group).
- *
- * @return {OO.ui.Element[]} An array of items.
- */
-OO.ui.mixin.GroupElement.prototype.getItems = function () {
-       return this.items.slice( 0 );
-};
-
 /**
  * Get an item by its data.
  *
@@ -2297,62 +2289,6 @@ OO.ui.mixin.GroupElement.prototype.getItemsFromData = function ( data ) {
        return items;
 };
 
-/**
- * Aggregate the events emitted by the group.
- *
- * When events are aggregated, the group will listen to all contained items for the event,
- * and then emit the event under a new name. The new event will contain an additional leading
- * parameter containing the item that emitted the original event. Other arguments emitted from
- * the original event are passed through.
- *
- * @param {Object.<string,string|null>} events An object keyed by the name of the event that should be
- *  aggregated  (e.g., ‘click’) and the value of the new name to use (e.g., ‘groupClick’).
- *  A `null` value will remove aggregated events.
-
- * @throws {Error} An error is thrown if aggregation already exists.
- */
-OO.ui.mixin.GroupElement.prototype.aggregate = function ( events ) {
-       var i, len, item, add, remove, itemEvent, groupEvent;
-
-       for ( itemEvent in events ) {
-               groupEvent = events[ itemEvent ];
-
-               // Remove existing aggregated event
-               if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
-                       // Don't allow duplicate aggregations
-                       if ( groupEvent ) {
-                               throw new Error( 'Duplicate item event aggregation for ' + itemEvent );
-                       }
-                       // Remove event aggregation from existing items
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               item = this.items[ i ];
-                               if ( item.connect && item.disconnect ) {
-                                       remove = {};
-                                       remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                                       item.disconnect( this, remove );
-                               }
-                       }
-                       // Prevent future items from aggregating event
-                       delete this.aggregateItemEvents[ itemEvent ];
-               }
-
-               // Add new aggregate event
-               if ( groupEvent ) {
-                       // Make future items aggregate event
-                       this.aggregateItemEvents[ itemEvent ] = groupEvent;
-                       // Add event aggregation to existing items
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               item = this.items[ i ];
-                               if ( item.connect && item.disconnect ) {
-                                       add = {};
-                                       add[ itemEvent ] = [ 'emit', groupEvent, item ];
-                                       item.connect( this, add );
-                               }
-                       }
-               }
-       }
-};
-
 /**
  * Add items to the group.
  *
@@ -2364,46 +2300,54 @@ OO.ui.mixin.GroupElement.prototype.aggregate = function ( events ) {
  * @chainable
  */
 OO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {
-       var i, len, item, itemEvent, events, currentIndex,
-               itemElements = [];
+       // Mixin method
+       OO.EmitterList.prototype.addItems.call( this, items, index );
 
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
+       this.emit( 'change', this.getItems() );
+       return this;
+};
 
-               // Check if item exists then remove it first, effectively "moving" it
-               currentIndex = this.items.indexOf( item );
-               if ( currentIndex >= 0 ) {
-                       this.removeItems( [ item ] );
-                       // Adjust index to compensate for removal
-                       if ( currentIndex < index ) {
-                               index--;
-                       }
-               }
-               // Add the item
-               if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) {
-                       events = {};
-                       for ( itemEvent in this.aggregateItemEvents ) {
-                               events[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                       }
-                       item.connect( this, events );
-               }
-               item.setElementGroup( this );
-               itemElements.push( item.$element.get( 0 ) );
-       }
+/**
+ * @inheritdoc
+ */
+OO.ui.mixin.GroupElement.prototype.moveItem = function ( items, newIndex ) {
+       // insertItemElements expects this.items to not have been modified yet, so call before the mixin
+       this.insertItemElements( items, newIndex );
+
+       // Mixin method
+       newIndex = OO.EmitterList.prototype.moveItem.call( this, items, newIndex );
+
+       return newIndex;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.mixin.GroupElement.prototype.insertItem = function ( item, index ) {
+       item.setElementGroup( this );
+       this.insertItemElements( item, index );
 
+       // Mixin method
+       index = OO.EmitterList.prototype.insertItem.call( this, item, index );
+
+       return index;
+};
+
+/**
+ * Insert elements into the group
+ *
+ * @private
+ * @param {OO.ui.Element} itemWidget Item to insert
+ * @param {number} index Insertion index
+ */
+OO.ui.mixin.GroupElement.prototype.insertItemElements = function ( itemWidget, index ) {
        if ( index === undefined || index < 0 || index >= this.items.length ) {
-               this.$group.append( itemElements );
-               this.items.push.apply( this.items, items );
+               this.$group.append( itemWidget.$element );
        } else if ( index === 0 ) {
-               this.$group.prepend( itemElements );
-               this.items.unshift.apply( this.items, items );
+               this.$group.prepend( itemWidget.$element );
        } else {
-               this.items[ index ].$element.before( itemElements );
-               this.items.splice.apply( this.items, [ index, 0 ].concat( items ) );
+               this.items[ index ].$element.before( itemWidget.$element );
        }
-
-       this.emit( 'change', this.getItems() );
-       return this;
 };
 
 /**
@@ -2416,26 +2360,21 @@ OO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {
  * @chainable
  */
 OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {
-       var i, len, item, index, events, itemEvent;
+       var i, len, item, index;
 
-       // Remove specific items
+       // Remove specific items elements
        for ( i = 0, len = items.length; i < len; i++ ) {
                item = items[ i ];
                index = this.items.indexOf( item );
                if ( index !== -1 ) {
-                       if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) {
-                               events = {};
-                               for ( itemEvent in this.aggregateItemEvents ) {
-                                       events[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                               }
-                               item.disconnect( this, events );
-                       }
                        item.setElementGroup( null );
-                       this.items.splice( index, 1 );
                        item.$element.detach();
                }
        }
 
+       // Mixin method
+       OO.EmitterList.prototype.removeItems.call( this, items );
+
        this.emit( 'change', this.getItems() );
        return this;
 };
@@ -2449,27 +2388,18 @@ OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {
  * @chainable
  */
 OO.ui.mixin.GroupElement.prototype.clearItems = function () {
-       var i, len, item, remove, itemEvent;
+       var i, len;
 
-       // Remove all items
+       // Remove all item elements
        for ( i = 0, len = this.items.length; i < len; i++ ) {
-               item = this.items[ i ];
-               if (
-                       item.connect && item.disconnect &&
-                       !$.isEmptyObject( this.aggregateItemEvents )
-               ) {
-                       remove = {};
-                       if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
-                               remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                       }
-                       item.disconnect( this, remove );
-               }
-               item.setElementGroup( null );
-               item.$element.detach();
+               this.items[ i ].setElementGroup( null );
+               this.items[ i ].$element.detach();
        }
 
+       // Mixin method
+       OO.EmitterList.prototype.clearItems.call( this );
+
        this.emit( 'change', this.getItems() );
-       this.items = [];
        return this;
 };
 
@@ -4303,6 +4233,20 @@ OO.ui.mixin.FloatableElement.prototype.position = function () {
                return this;
        }
 
+       if ( !(
+               // To continue, some things need to be true:
+               // The element must actually be in the DOM
+               this.isElementAttached() && (
+                       // The closest scrollable is the current window
+                       this.$floatableClosestScrollable[ 0 ] === this.getElementWindow() ||
+                       // OR is an element in the element's DOM
+                       $.contains( this.getElementDocument(), this.$floatableClosestScrollable[ 0 ] )
+               )
+       ) ) {
+               // Abort early if important parts of the widget are no longer attached to the DOM
+               return this;
+       }
+
        if ( this.hideWhenOutOfView && !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable ) ) {
                this.$floatable.addClass( 'oo-ui-element-hidden' );
                return this;
@@ -4883,6 +4827,14 @@ OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.LabelElement );
 OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );
 OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.FloatableElement );
 
+/* Events */
+
+/**
+ * @event ready
+ *
+ * The popup is ready: it is visible and has been positioned and clipped.
+ */
+
 /* Methods */
 
 /**
@@ -5016,6 +4968,7 @@ OO.ui.PopupWidget.prototype.hasAnchor = function () {
  * Side-effects may include broken interface and exceptions being thrown. This wasn't always
  * strictly enforced, so currently it only generates a warning in the browser console.
  *
+ * @fires ready
  * @inheritdoc
  */
 OO.ui.PopupWidget.prototype.toggle = function ( show ) {
@@ -5046,6 +4999,7 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
                        }
                        this.updateDimensions();
                        this.toggleClipping( true );
+                       this.emit( 'ready' );
                } else {
                        this.toggleClipping( false );
                        if ( this.autoClose ) {
index b4a6392..8538b6e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
  */
 ( function ( OO ) {
 
index 479e2a5..983bc69 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
index df77684..502b7b1 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
 .oo-ui-tool.oo-ui-widget-enabled {
   -webkit-transition: background-color 100ms;
   height: 2.5em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-  width: 0.9375em;
-  height: 1.625em;
-  margin: 0.78125em 0.5em;
   top: 0;
   right: 0;
+  width: 0.9375em;
+  height: 100%;
+  margin: 0 0.5em;
   opacity: 0.3;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
index 7d09854..4cc0db1 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
  */
 ( function ( OO ) {
 
index 7f8389e..a9b31da 100644 (file)
@@ -1,22 +1,22 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
-.oo-ui-draggableElement-handle,
-.oo-ui-draggableElement-handle.oo-ui-widget {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ),
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
   cursor: url(images/grab.cur );
   cursor: -webkit-grab;
   cursor:    -moz-grab;
   cursor:         grab;
 }
-.oo-ui-draggableElement-handle:active {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ):active {
   cursor: url(images/grabbing.cur );
   cursor: -webkit-grabbing;
   cursor:    -moz-grabbing;
index c79dc85..8438a3d 100644 (file)
@@ -1,22 +1,22 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
-.oo-ui-draggableElement-handle,
-.oo-ui-draggableElement-handle.oo-ui-widget {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ),
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
   cursor: url(images/grab.cur );
   cursor: -webkit-grab;
   cursor:    -moz-grab;
   cursor:         grab;
 }
-.oo-ui-draggableElement-handle:active {
+.oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ):active {
   cursor: url(images/grabbing.cur );
   cursor: -webkit-grabbing;
   cursor:    -moz-grabbing;
 }
 .oo-ui-buttonOptionWidget {
   display: inline-block;
-  padding: 0;
 }
 .oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
   cursor: default;
   display: inline-block;
   vertical-align: middle;
 }
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
-  background-color: transparent;
-}
 .oo-ui-toggleButtonWidget {
   margin-right: 0.5em;
 }
index c2e62fd..3482256 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
  */
 ( function ( OO ) {
 
@@ -24,6 +24,9 @@
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {jQuery} [$handle] The part of the element which can be used for dragging, defaults to the whole element
+ * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable
+ *  but the draggable state should be called from the DraggableGroupElement, which updates
+ *  the whole group
  */
 OO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement( config ) {
        config = config || {};
@@ -32,6 +35,7 @@ OO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement( config ) {
        this.index = null;
        this.$handle = config.$handle || this.$element;
        this.wasHandleUsed = null;
+       this.draggable = config.draggable === undefined ? true : !!config.draggable;
 
        // Initialize and events
        this.$element.addClass( 'oo-ui-draggableElement' )
@@ -81,6 +85,32 @@ OO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;
 
 /* Methods */
 
+/**
+ * Change the draggable state of this widget.
+ * This allows users to temporarily halt the dragging operations.
+ *
+ * @param {boolean} isDraggable Widget supports draggable operations
+ * @fires draggable
+ */
+OO.ui.mixin.DraggableElement.prototype.toggleDraggable = function ( isDraggable ) {
+       isDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;
+
+       if ( this.draggable !== isDraggable ) {
+               this.draggable = isDraggable;
+
+               this.$element.toggleClass( 'oo-ui-draggableElement-undraggable', !this.draggable );
+       }
+};
+
+/**
+ * Check the draggable state of this widget
+ *
+ * @return {boolean} Widget supports draggable operations
+ */
+OO.ui.mixin.DraggableElement.prototype.isDraggable = function () {
+       return this.draggable;
+};
+
 /**
  * Respond to mousedown event.
  *
@@ -88,6 +118,10 @@ OO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;
  * @param {jQuery.Event} e Drag event
  */
 OO.ui.mixin.DraggableElement.prototype.onDragMouseDown = function ( e ) {
+       if ( !this.isDraggable() ) {
+               return;
+       }
+
        this.wasHandleUsed =
                // Optimization: if the handle is the whole element this is always true
                this.$handle[ 0 ] === this.$element[ 0 ] ||
@@ -107,7 +141,7 @@ OO.ui.mixin.DraggableElement.prototype.onDragStart = function ( e ) {
        var element = this,
                dataTransfer = e.originalEvent.dataTransfer;
 
-       if ( !this.wasHandleUsed ) {
+       if ( !this.wasHandleUsed || !this.isDraggable() ) {
                return false;
        }
 
@@ -208,6 +242,7 @@ OO.ui.mixin.DraggableElement.prototype.getIndex = function () {
  *  should match the layout of the items. Items displayed in a single row
  *  or in several rows should use horizontal orientation. The vertical orientation should only be
  *  used when the items are displayed in a single column. Defaults to 'vertical'
+ * @cfg {boolean} [draggable] The items are draggable. This can change with #toggleDraggable
  */
 OO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( config ) {
        // Configuration initialization
@@ -222,6 +257,7 @@ OO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( con
        this.itemKeys = {};
        this.dir = null;
        this.itemsOrder = null;
+       this.draggable = config.draggable === undefined ? true : !!config.draggable;
 
        // Events
        this.aggregate( {
@@ -260,15 +296,54 @@ OO.mixinClass( OO.ui.mixin.DraggableGroupElement, OO.ui.mixin.GroupElement );
  */
 
 /**
- * And item has been dropped at a new position.
+ * An item has been dropped at a new position.
  *
  * @event reorder
  * @param {OO.ui.mixin.DraggableElement} item Reordered item
  * @param {number} [newIndex] New index for the item
  */
 
+/**
+ * Draggable state of this widget has changed.
+ *
+ * @event draggable
+ * @param {boolean} [draggable] Widget is draggable
+ */
+
 /* Methods */
 
+/**
+ * Change the draggable state of this widget.
+ * This allows users to temporarily halt the dragging operations.
+ *
+ * @param {boolean} isDraggable Widget supports draggable operations
+ * @fires draggable
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.toggleDraggable = function ( isDraggable ) {
+       isDraggable = isDraggable !== undefined ? !!isDraggable : !this.draggable;
+
+       if ( this.draggable !== isDraggable ) {
+               this.draggable = isDraggable;
+
+               // Tell the items their draggable state changed
+               this.getItems().forEach( function ( item ) {
+                       item.toggleDraggable( this.draggable );
+               }.bind( this ) );
+
+               // Emit event
+               this.emit( 'draggable', this.draggable );
+       }
+};
+
+/**
+ * Check the draggable state of this widget
+ *
+ * @return {boolean} Widget supports draggable operations
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.isDraggable = function () {
+       return this.draggable;
+};
+
 /**
  * Respond to item drag start event
  *
@@ -276,6 +351,9 @@ OO.mixinClass( OO.ui.mixin.DraggableGroupElement, OO.ui.mixin.GroupElement );
  * @param {OO.ui.mixin.DraggableElement} item Dragged item
  */
 OO.ui.mixin.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {
+       if ( !this.isDraggable() ) {
+               return;
+       }
        // Make a shallow copy of this.items so we can re-order it during previews
        // without affecting the original array.
        this.itemsOrder = this.items.slice();
index 17caa33..4842a46 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
   background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
index 0530610..beca510 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:28Z
+ * Date: 2017-03-30T20:34:41Z
  */
 .oo-ui-window {
   background: transparent;
index ab78a4a..1cbec34 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.20.0
+ * OOjs UI v0.20.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2017-03-15T17:06:24Z
+ * Date: 2017-03-30T20:34:37Z
  */
 ( function ( OO ) {
 
@@ -1333,7 +1333,7 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
                                manager.toggleGlobalEvents( true );
                                manager.toggleAriaIsolation( true );
                        }
-                       manager.$returnFocusTo = data.$returnFocusTo || $( document.activeElement );
+                       manager.$returnFocusTo = data.$returnFocusTo !== undefined ? data.$returnFocusTo : $( document.activeElement );
                        manager.currentWindow = win;
                        manager.opening = opening;
                        manager.preparingToOpen = null;
index 892b8db..c3977eb 100644 (file)
@@ -2,17 +2,20 @@
        "prefix": "oo-ui-icon",
        "intro": "@import '../../../../src/styles/common';",
        "images": {
+               "alert": { "file": "images/icons/alert.svg" },
                "bell": { "file": "images/icons/bell.svg" },
                "bellOn": { "file": {
                        "ltr": "images/icons/bellOn-ltr.svg",
                        "rtl": "images/icons/bellOn-rtl.svg"
                } },
+               "comment": { "file": "images/icons/comment.svg" },
                "eye": { "file": "images/icons/eye.svg" },
                "eyeClosed": { "file": "images/icons/eyeClosed.svg" },
                "message": { "file": {
                        "ltr": "images/icons/message-ltr.svg",
                        "rtl": "images/icons/message-rtl.svg"
                } },
+               "notice": { "file": "images/icons/notice.svg" },
                "signature": { "file": {
                        "ltr": "images/icons/signature-ltr.svg",
                        "rtl": "images/icons/signature-rtl.svg"
index 0cd901f..a9db33f 100644 (file)
                        "ltr": "images/icons/articleRedirect-ltr.svg",
                        "rtl": "images/icons/articleRedirect-rtl.svg"
                } },
+               "history": { "file": "images/icons/history.svg" },
+               "info": { "file": "images/icons/info.svg" },
                "journal": { "file": {
                        "ltr": "images/icons/journal-ltr.svg",
                        "rtl": "images/icons/journal-rtl.svg"
                } },
+               "tag": { "file": "images/icons/tag.svg" },
                "upload": { "file": {
                        "ltr": "images/icons/upload-ltr.svg",
                        "rtl": "images/icons/upload-rtl.svg"
-               } }
+               } },
+               "window": { "file": "images/icons/window.svg" }
        }
 }
index 5b6ac3c..64651fc 100644 (file)
@@ -1,14 +1,9 @@
 {
        "prefix": "oo-ui-icon",
        "intro": "@import '../../../../src/styles/common';",
-       "variants": {
-               "invert": {
-                       "color": "#FFFFFF",
-                       "global": true
-               }
-       },
        "images": {
                "add": { "file": "images/icons/add.svg" },
+               "advanced": { "file": "images/icons/advanced.svg" },
                "bookmark": { "file": {
                        "ltr": "images/icons/bookmark-ltr.svg",
                        "rtl": "images/icons/bookmark-rtl.svg"
                        "ltr": "images/icons/browser-ltr.svg",
                        "rtl": "images/icons/browser-rtl.svg"
                } },
+               "cancel": { "file": "images/icons/cancel.svg" },
+               "check": { "file": "images/icons/check.svg" },
                "clear": { "file": "images/icons/clear.svg" },
                "clock": { "file": "images/icons/clock.svg" },
+               "close": { "file": "images/icons/close.svg" },
+               "ellipsis": { "file": "images/icons/ellipsis.svg" },
                "feedback": { "file": {
                        "ltr": "images/icons/feedback-ltr.svg",
                        "rtl": "images/icons/feedback-rtl.svg"
                        "rtl": "images/icons/funnel-rtl.svg"
                } },
                "heart": { "file": "images/icons/heart.svg" },
+               "help": { "file": {
+                       "ltr": "images/icons/help-ltr.svg",
+                       "rtl": "images/icons/help-rtl.svg",
+                       "lang": {
+                               "he,yi": "images/icons/help-ltr.svg"
+                       }
+               } },
                "key": { "file": {
                        "ltr": "images/icons/key-ltr.svg",
                        "rtl": "images/icons/key-rtl.svg"
                        "ltr": "images/icons/printer-ltr.svg",
                        "rtl": "images/icons/printer-rtl.svg"
                } },
+               "search": { "file": {
+                       "ltr": "images/icons/search-ltr.svg",
+                       "rtl": "images/icons/search-rtl.svg"
+                       }
+               },
+               "settings": { "file": "images/icons/settings.svg" },
                "subtract": { "file": "images/icons/subtract.svg" },
                "sun": { "file": {
                        "ltr": "images/icons/sun-ltr.svg",
diff --git a/resources/lib/oojs-ui/themes/apex/icons-layout.json b/resources/lib/oojs-ui/themes/apex/icons-layout.json
new file mode 100644 (file)
index 0000000..173b284
--- /dev/null
@@ -0,0 +1,25 @@
+{
+       "prefix": "oo-ui-icon",
+       "intro": "@import '../../../../src/styles/common';",
+       "images": {
+               "menu": { "file": "images/icons/menu.svg" },
+               "stripeFlow": { "file": {
+                       "ltr": "images/icons/stripeFlow-ltr.svg",
+                       "rtl": "images/icons/stripeFlow-rtl.svg"
+               } },
+               "stripeSideMenu": { "file": "images/icons/stripeSideMenu.svg" },
+               "stripeSummary": { "file": {
+                       "ltr": "images/icons/stripeSummary-ltr.svg",
+                       "rtl": "images/icons/stripeSummary-rtl.svg"
+               } },
+               "stripeToC": { "file": {
+                       "ltr": "images/icons/stripeToC-ltr.svg",
+                       "rtl": "images/icons/stripeToC-rtl.svg"
+               } },
+               "viewCompact": { "file": "images/icons/viewCompact.svg" },
+               "viewDetails": { "file": {
+                       "ltr": "images/icons/viewDetails-ltr.svg",
+                       "rtl": "images/icons/viewDetails-rtl.svg"
+               } }
+       }
+}
index 9aa1b80..7ab6eaa 100644 (file)
                } },
                "caretDown": { "file": "images/icons/caretDown.svg" },
                "caretUp": { "file": "images/icons/caretUp.svg" },
+               "collapse": { "file": "images/icons/collapse.svg" },
                "downTriangle": { "file": "images/icons/downTriangle.svg" },
+               "expand": { "file": "images/icons/expand.svg" },
                "move": { "file": "images/icons/move.svg" },
+               "next": { "file": {
+                       "ltr": "images/icons/move-ltr.svg",
+                       "rtl": "images/icons/move-rtl.svg"
+                       }
+               },
+               "previous": { "file": {
+                       "ltr": "images/icons/move-rtl.svg",
+                       "rtl": "images/icons/move-ltr.svg"
+                       }
+               },
                "upTriangle": { "file": "images/icons/upTriangle.svg" }
        }
 }
index f4a2dc9..c0ccb36 100644 (file)
@@ -2,49 +2,63 @@
        "prefix": "oo-ui-icon",
        "intro": "@import '../../../../src/styles/common';",
        "images": {
-               "add": { "file": "images/icons/add.svg", "deprecated": "Moved since v0.19.5, use from the 'interactive' pack instead." },
-               "advanced": { "file": "images/icons/advanced.svg" },
-               "alert": { "file": "images/icons/alert.svg" },
-               "cancel": { "file": "images/icons/cancel.svg" },
-               "check": { "file": "images/icons/check.svg" },
-               "circle": { "file": "images/icons/circle.svg" },
-               "close": { "file": "images/icons/close.svg" },
-               "code": { "file": "images/icons/code.svg" },
-               "collapse": { "file": "images/icons/collapse.svg" },
-               "comment": { "file": "images/icons/comment.svg" },
-               "ellipsis": { "file": "images/icons/ellipsis.svg" },
-               "expand": { "file": "images/icons/expand.svg" },
+               "add": { "file": "images/icons/add.svg", "deprecated": "Moved since v0.19.5, use from the 'interactions' pack instead." },
+               "advanced": { "file": "images/icons/advanced.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "alert": { "file": "images/icons/alert.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+               "cancel": { "file": "images/icons/cancel.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "check": { "file": "images/icons/check.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "circle": { "file": "images/icons/circle.svg", "deprecated": "Deprecated since v0.20.1, do not use." },
+               "close": { "file": "images/icons/close.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "code": { "file": "images/icons/code.svg", "deprecated": "Moved since v0.16.2, use from the 'editing-advanced' pack instead." },
+               "collapse": { "file": "images/icons/collapse.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
+               "comment": { "file": "images/icons/comment.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+               "ellipsis": { "file": "images/icons/ellipsis.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "expand": { "file": "images/icons/expand.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
                "help": { "file": {
                        "ltr": "images/icons/help-ltr.svg",
                        "rtl": "images/icons/help-rtl.svg",
                        "lang": {
                                "he,yi": "images/icons/help-ltr.svg"
-                       }
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
                } },
-               "history": { "file": "images/icons/history.svg" },
-               "info": { "file": "images/icons/info.svg" },
-               "menu": { "file": "images/icons/menu.svg" },
+               "history": { "file": "images/icons/history.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+               "info": { "file": "images/icons/info.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+               "menu": { "file": "images/icons/menu.svg", "deprecated": "Moved since v0.20.1, use from the 'layout' pack instead." },
                "next": { "file": {
                        "ltr": "images/icons/move-ltr.svg",
                        "rtl": "images/icons/move-rtl.svg"
-               } },
-               "notice": { "file": "images/icons/notice.svg" },
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+               },
+               "notice": { "file": "images/icons/notice.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
                "previous": { "file": {
                        "ltr": "images/icons/move-rtl.svg",
                        "rtl": "images/icons/move-ltr.svg"
-               } },
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+               },
                "redo": { "file": {
                        "ltr": "images/icons/arched-arrow-ltr.svg",
                        "rtl": "images/icons/arched-arrow-rtl.svg"
-               } },
-               "remove": { "file": "images/icons/trash.svg" },
-               "search": { "file": "images/icons/search.svg" },
-               "settings": { "file": "images/icons/settings.svg" },
-               "tag": { "file": "images/icons/tag.svg" },
+                       },
+                       "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+               },
+               "remove": { "file": "images/icons/trash.svg", "deprecated": "Replaced since v0.14.0, use 'trash' from the 'moderation' pack instead." },
+               "search": { "file": {
+                       "ltr": "images/icons/search-ltr.svg",
+                       "rtl": "images/icons/search-rtl.svg"
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
+               },
+               "settings": { "file": "images/icons/settings.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "tag": { "file": "images/icons/tag.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
                "undo": { "file": {
                        "ltr": "images/icons/arched-arrow-rtl.svg",
                        "rtl": "images/icons/arched-arrow-ltr.svg"
-               } },
-               "window": { "file": "images/icons/window.svg" }
+                       },
+                       "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+               },
+               "window": { "file": "images/icons/window.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." }
        }
 }
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/add-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/add-invert.png
deleted file mode 100644 (file)
index 8deeddf..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/add-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/add-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/add-invert.svg
deleted file mode 100644 (file)
index a2d49a1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <g id="add">
-        <path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
-    </g>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.png
deleted file mode 100644 (file)
index 084cbc7..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-ltr-invert.svg
deleted file mode 100644 (file)
index 8098166..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M15 5H8c-1.1 0-2 .9-2 2v3h3v11l4-3 4 3V7c0-1.1-.9-2-2-2zM9 9H7V7c0-.6.4-1 1-1h1v3z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.png
deleted file mode 100644 (file)
index 125fb74..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/bookmark-rtl-invert.svg
deleted file mode 100644 (file)
index bc3ef4e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M8 5h7c1.1 0 2 .9 2 2v3h-3v11l-4-3-4 3V7c0-1.1.9-2 2-2zm6 4h2V7c0-.6-.4-1-1-1h-1v3z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.png
deleted file mode 100644 (file)
index 027df2d..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/browser-ltr-invert.svg
deleted file mode 100644 (file)
index 792b4aa..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M3 6v11c0 1.7 1.3 3 3 3h15V6H3zm2.5 1C6.3 7 7 7.7 7 8.5S6.3 10 5.5 10 4 9.3 4 8.5 4.7 7 5.5 7zM20 19H6c-1.1 0-2-.9-2-2v-6h16v8z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.png
deleted file mode 100644 (file)
index 51937b7..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/browser-rtl-invert.svg
deleted file mode 100644 (file)
index 079a62c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M21 6v11c0 1.7-1.3 3-3 3H3V6h18zm-2.5 1c-.8 0-1.5.7-1.5 1.5s.7 1.5 1.5 1.5S20 9.3 20 8.5 19.3 7 18.5 7zM4 19h14c1.1 0 2-.9 2-2v-6H4v8z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.png
deleted file mode 100644 (file)
index ec90ed9..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/clear-invert.svg
deleted file mode 100644 (file)
index 09df1d3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <g id="clear">
-        <path id="circle-with-cross" d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 11l-1 1-3-3-3 3-1-1 3-3-3-3 1-1 3 3 3-3 1 1-3 3 3 3z"/>
-    </g>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.png
deleted file mode 100644 (file)
index fdd3e51..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/clock-invert.svg
deleted file mode 100644 (file)
index c11e11e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <g id="clock">
-        <path id="circle" d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm0 1.25a5.75 5.75 0 0 1 0 11.5 5.75 5.75 0 0 1 0-11.5z"/>
-        <path id="hands" d="M15.605 14.08s-1.674-1.36-2.81-2.15c.504-1.683 1.194-4.605 1.194-4.605s-3.057 3.765-3.427 4.703c-.325.82 1.024 1.55 1.647 1.178 1.335.387 3.394.873 3.394.873z"/>
-    </g>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png
deleted file mode 100644 (file)
index f49ebeb..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-ltr-invert.svg
deleted file mode 100644 (file)
index d32e478..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M8.202 15.834l.568 2.101c.198.765 1.06 1.22 1.8 1.016.698-.193 1.125-.983.926-1.747l-.38-1.37H20L17.229 5 4.155 12.652c-.427.762.088 2.748.823 3.182h3.224z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png
deleted file mode 100644 (file)
index efba220..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/feedback-rtl-invert.svg
deleted file mode 100644 (file)
index 14be7ff..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M15.798 15.834l-.568 2.101c-.198.765-1.06 1.22-1.8 1.016-.698-.193-1.125-.983-.926-1.747l.38-1.37H4L6.771 5l13.074 7.652c.427.762-.088 2.748-.823 3.182h-3.224z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.png
deleted file mode 100644 (file)
index 2949648..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/funnel-ltr-invert.svg
deleted file mode 100644 (file)
index d533779..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M11 13L5 6h15l-6 7v7c-1.7 0-3-1.3-3-3v-4z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.png
deleted file mode 100644 (file)
index c0f155a..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/funnel-rtl-invert.svg
deleted file mode 100644 (file)
index f99e338..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M14 13l6-7H5l6 7v7c1.7 0 3-1.3 3-3v-4z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.png
deleted file mode 100644 (file)
index 2070997..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/heart-invert.svg
deleted file mode 100644 (file)
index ab9e536..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M15 7c-2 0-3 2-3 2s-1-2-3-2c-2.5 0-4 2-4 4 0 4 5 5 7 8 2-3 7-4 7-8 0-2-1.5-4-4-4z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.png
deleted file mode 100644 (file)
index 265da14..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/key-ltr-invert.svg
deleted file mode 100644 (file)
index 454f6a9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M14.5 4C11.5 4 9 6.5 9 9.5c0 1 .3 1.9.7 2.8L4 18v2h4v-2h2v-2h2l1.2-1.2c.4.1.9.2 1.3.2 3 0 5.5-2.5 5.5-5.5S17.5 4 14.5 4zM16 9c-.8 0-1.5-.7-1.5-1.5S15.2 6 16 6s1.5.7 1.5 1.5S16.8 9 16 9z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.png
deleted file mode 100644 (file)
index a5f2904..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/key-rtl-invert.svg
deleted file mode 100644 (file)
index 6b7fd63..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M9.5 4c3 0 5.5 2.5 5.5 5.5 0 1-.3 1.9-.7 2.8L20 18v2h-4v-2h-2v-2h-2l-1.2-1.2c-.4.1-.9.2-1.3.2-3 0-5.5-2.5-5.5-5.5S6.5 4 9.5 4zM8 9c.8 0 1.5-.7 1.5-1.5S8.8 6 8 6s-1.5.7-1.5 1.5S7.2 9 8 9z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.png
deleted file mode 100644 (file)
index d7d1a0b..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-ltr-invert.svg
deleted file mode 100644 (file)
index d137db6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M3 7v9c0 1.7 1.3 3 3 3h15V7H3zm8 2h2v2h-2V9zm0 3h2v2h-2v-2zM8 9h2v2H8V9zm0 3h2v2H8v-2zm-1 5H6c-.6 0-1-.4-1-1v-1h2v2zm0-3H5v-2h2v2zm0-3H5V9h2v2zm9 6H8v-2h8v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2zm3 6h-2v-2h2v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.png
deleted file mode 100644 (file)
index 1b0275e..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/keyboard-rtl-invert.svg
deleted file mode 100644 (file)
index 792025b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M21 7v9c0 1.7-1.3 3-3 3H3V7h18zm-8 2h-2v2h2V9zm0 3h-2v2h2v-2zm3-3h-2v2h2V9zm0 3h-2v2h2v-2zm1 5h1c.6 0 1-.4 1-1v-1h-2v2zm0-3h2v-2h-2v2zm0-3h2V9h-2v2zm-9 6h8v-2H8v2zm0-3h2v-2H8v2zm0-3h2V9H8v2zm-3 6h2v-2H5v2zm0-3h2v-2H5v2zm0-3h2V9H5v2z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.png
deleted file mode 100644 (file)
index fb1bb0c..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/logOut-ltr-invert.svg
deleted file mode 100644 (file)
index 14f148a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M15 14v3l5-4.5L15 8v3H8c0 1.7 1.3 3 3 3h4zm-1-9H4v15h10v-2H6V7h8V5z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.png
deleted file mode 100644 (file)
index dcd2f15..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/logOut-rtl-invert.svg
deleted file mode 100644 (file)
index e3ce38b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M9 14v3l-5-4.5L9 8v3h7c0 1.7-1.3 3-3 3H9zm1-9h10v15H10v-2h8V7h-8V5z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.png
deleted file mode 100644 (file)
index 5e432b0..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-ltr-invert.svg
deleted file mode 100644 (file)
index f7a92e0..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M12 5l2.5 2.5L11 11c-1.2 1.2-1.2 2.8 0 4l5.5-5.5L19 12V5h-7zm5 12H8c-.6 0-1-.4-1-1V7h3L8 5H5v11c0 1.7 1.3 3 3 3h11v-3l-2-2v3z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.png
deleted file mode 100644 (file)
index f9a742e..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/newWindow-rtl-invert.svg
deleted file mode 100644 (file)
index ef51a66..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M12 5L9.5 7.5 13 11c1.2 1.2 1.2 2.8 0 4L7.5 9.5 5 12V5h7zM7 17h9c.6 0 1-.4 1-1V7h-3l2-2h3v11c0 1.7-1.3 3-3 3H5v-3l2-2v3z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.png
deleted file mode 100644 (file)
index ca07bcc..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/printer-ltr-invert.svg
deleted file mode 100644 (file)
index 1442004..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M18 8h-1V4H7v4H3v6c0 1.7 1.3 3 3 3h1v3h10v-3h4v-6c0-1.7-1.3-3-3-3zM8 5h8v3H8V5zm8 14H8v-6h8v6z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.png
deleted file mode 100644 (file)
index 95ef54a..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/printer-rtl-invert.svg
deleted file mode 100644 (file)
index 0d1cd83..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M6 8h1V4h10v4h4v6c0 1.7-1.3 3-3 3h-1v3H7v-3H3v-6c0-1.7 1.3-3 3-3zm10-3H8v3h8V5zM8 19h8v-6H8v6z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.png
new file mode 100644 (file)
index 0000000..e8e99f8
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/search-ltr.svg
new file mode 100644 (file)
index 0000000..ebc654a
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="search">
+        <path id="magnifying-glass" d="M10.5 4a6.5 6.5 0 1 0 2.844 12.344L16 19c1.4 1.4 2.5 1.5 4 0l-4.438-4.438A6.426 6.426 0 0 0 17 10.5 6.5 6.5 0 0 0 10.5 4zm0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.png
new file mode 100644 (file)
index 0000000..3ab96be
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/search-rtl.svg
new file mode 100644 (file)
index 0000000..c51d4cb
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="search">
+        <path id="magnifying-glass" d="M13.5 4a6.5 6.5 0 1 1-2.844 12.344L8 19c-1.4 1.4-2.5 1.5-4 0l4.438-4.438A6.426 6.426 0 0 1 7 10.5 6.5 6.5 0 0 1 13.5 4zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/search.png b/resources/lib/oojs-ui/themes/apex/images/icons/search.png
deleted file mode 100644 (file)
index 7b47539..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/search.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/search.svg b/resources/lib/oojs-ui/themes/apex/images/icons/search.svg
deleted file mode 100644 (file)
index 823ebf2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <g id="search">
-        <path id="magnifying-glass" d="M18.87 18.375l-3.987-3.99-.286-.17a5.774 5.774 0 0 0 1.082-3.372C15.67 7.616 13.06 5 9.84 5A5.843 5.843 0 0 0 4 10.844a5.84 5.84 0 0 0 5.842 5.842c1.26 0 2.423-.403 3.377-1.08l.16.286 3.99 3.987c.32.31.91.24 1.33-.18.41-.42.49-1.01.17-1.33zM9.837 14.56a3.72 3.72 0 0 1-3.718-3.717c0-2.05 1.67-3.72 3.72-3.72s3.72 1.668 3.72 3.72a3.722 3.722 0 0 1-3.72 3.718z"/>
-    </g>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.png
new file mode 100644 (file)
index 0000000..5423b36
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-ltr.svg
new file mode 100644 (file)
index 0000000..2112bb2
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M4 9h12v2H4V9zm0 3h8v2H4v-2zm0-7h16v3H4V5zm16 14H4v-3h16v3z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.png
new file mode 100644 (file)
index 0000000..0ff3d7c
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeFlow-rtl.svg
new file mode 100644 (file)
index 0000000..39790a9
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M20 9H8v2h12V9zm0 3h-8v2h8v-2zm0-7H4v3h16V5zM4 19h16v-3H4v3z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.png
new file mode 100644 (file)
index 0000000..e031527
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSideMenu.svg
new file mode 100644 (file)
index 0000000..e63a7d5
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M20 19H4v-2h16v2zM20 15H4v-2h16v2zM20 11H4V9h16v2z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.png
new file mode 100644 (file)
index 0000000..ce15bd8
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-ltr.svg
new file mode 100644 (file)
index 0000000..767d6cd
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M20 11H4V9h16v2zM4 12h8v2H4v-2z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.png
new file mode 100644 (file)
index 0000000..82ca2bf
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeSummary-rtl.svg
new file mode 100644 (file)
index 0000000..4d16337
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M4 11h16V9H4v2zm16 1h-8v2h8v-2z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.png
new file mode 100644 (file)
index 0000000..b482d3e
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-ltr.svg
new file mode 100644 (file)
index 0000000..d7c202e
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M17 13H4v-3h13v3zm-5 6H4v-3h8v3zM4 7V4h16v3H4z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.png
new file mode 100644 (file)
index 0000000..516bc2c
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/stripeToC-rtl.svg
new file mode 100644 (file)
index 0000000..0859be6
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M7 13h13v-3H7v3zm5 6h8v-3h-8v3zm8-12V4H4v3h16z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.png
deleted file mode 100644 (file)
index 4e58b70..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/subtract-invert.svg
deleted file mode 100644 (file)
index 9595ac6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-       <path d="M18 13H6v-2h12"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.png
deleted file mode 100644 (file)
index 2bc944a..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/sun-ltr-invert.svg
deleted file mode 100644 (file)
index f533999..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M18.1 5.1c0 .3-.1.6-.3.9l-1.4 1.4-.9-.8 2.2-2.2c.3.1.4.4.4.7zm-.5 5.3h3.2c0 .3-.1.6-.4.9s-.5.4-.8.4h-2v-1.3zm-6.2-5V2.2c.3 0 .6.1.9.4s.4.5.4.8v2h-1.3zm6.4 11.7c-.3 0-.6-.1-.8-.3l-1.4-1.4.8-.8 2.2 2.2c-.2.2-.5.3-.8.3zM6.2 4.9c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4s-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9s.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8s.1-.6.3-.8z"/>
-    <circle cx="12" cy="11" r="4"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.png
deleted file mode 100644 (file)
index 7ac54ff..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/sun-rtl-invert.svg
deleted file mode 100644 (file)
index 0e19566..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M5.9 5.1c0 .3.1.6.3.9l1.4 1.4.9-.8-2.2-2.2c-.3.1-.4.4-.4.7zm.5 5.3H3.2c0 .3.1.6.4.9.3.3.5.4.8.4h2v-1.3zm6.2-5V2.2c-.3 0-.6.1-.9.4-.3.3-.4.5-.4.8v2h1.3zM6.2 17.1c.3 0 .6-.1.8-.3l1.4-1.4-.8-.8-2.2 2.2c.2.2.5.3.8.3zM17.8 4.9c-.3 0-.6.1-.8.3l-1.4 1.4.8.9 2.2-2.3c-.2-.2-.5-.3-.8-.3zm-5.2 11.7h-1.2v3.2c.3 0 .6-.1.9-.4.3-.3.4-.5.4-.8l-.1-2zm7-6.2h-2v1.2h3.2c0-.3-.1-.6-.4-.9-.3-.3-.5-.3-.8-.3zM17.8 16l-1.4-1.4-.8.8 2.2 2.2c.2-.2.3-.5.3-.8 0-.3-.1-.6-.3-.8z"/>
-    <circle cx="12" cy="11" r="4" transform="matrix(-1 0 0 1 24 0)"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.png b/resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.png
new file mode 100644 (file)
index 0000000..13fe420
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.svg b/resources/lib/oojs-ui/themes/apex/images/icons/viewCompact.svg
new file mode 100644 (file)
index 0000000..d96a2e3
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="viewCompact">
+        <circle cx="6" cy="6" r="2"/>
+        <circle cx="12" cy="6" r="2"/>
+        <circle cx="18" cy="6" r="2"/>
+        <circle cx="6" cy="12" r="2"/>
+        <circle cx="12" cy="12" r="2"/>
+        <circle cx="18" cy="12" r="2"/>
+        <circle cx="6" cy="18" r="2"/>
+        <circle cx="12" cy="18" r="2"/>
+        <circle cx="18" cy="18" r="2"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.png
new file mode 100644 (file)
index 0000000..4341f0e
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-ltr.svg
new file mode 100644 (file)
index 0000000..1a5092a
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="viewDetails">
+        <circle cx="5.5" cy="8.5" r="2.5"/>
+        <path d="M10 6h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
+        <circle cx="5.5" cy="16.5" r="2.5"/>
+        <path d="M10 14h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.png
new file mode 100644 (file)
index 0000000..338294c
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/viewDetails-rtl.svg
new file mode 100644 (file)
index 0000000..f43b05f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <g id="viewDetails">
+        <circle cx="18.5" cy="8.5" r="2.5"/>
+        <path d="M14 6H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
+        <circle cx="18.5" cy="16.5" r="2.5"/>
+        <path d="M14 14H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
+    </g>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.png
deleted file mode 100644 (file)
index 7018968..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-ltr-invert.svg
deleted file mode 100644 (file)
index a6d466a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M13 14h5v1h-5v-1zm0 3h5v-1h-5v1zm0 1h5v1h-5v-1zm-1-5v3l-5 3 1-6-4-3 6-1 2-5s1.9 5 2 5l6 1-4 3h-4z"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.png
deleted file mode 100644 (file)
index 28008b5..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/watchlist-rtl-invert.svg
deleted file mode 100644 (file)
index 61a2866..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#FFFFFF">
-    <path d="M11 14H6v1h5v-1zm0 3H6v-1h5v1zm0 1H6v1h5v-1zm1-5v3l5 3-1-6 4-3-6-1-2-5s-1.9 5-2 5l-6 1 4 3h4z"/>
-</g></svg>
index e6fa863..c169b56 100644 (file)
                }
        },
        "images": {
+               "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] },
                "bell": { "file": "images/icons/bell.svg" },
                "bellOn": { "file": {
                        "ltr": "images/icons/bellOn-ltr.svg",
                        "rtl": "images/icons/bellOn-rtl.svg"
                } },
+               "comment": { "file": "images/icons/comment.svg" },
                "eye": { "file": "images/icons/eye.svg" },
                "eyeClosed": { "file": "images/icons/eyeClosed.svg" },
                "message": { "file": {
                        "ltr": "images/icons/message-ltr.svg",
                        "rtl": "images/icons/message-rtl.svg"
                } },
+               "notice": { "file": "images/icons/notice.svg" },
                "signature": { "file": {
                        "ltr": "images/icons/signature-ltr.svg",
                        "rtl": "images/icons/signature-rtl.svg"
index 80bbcaf..e952108 100644 (file)
@@ -62,6 +62,8 @@
                        "ltr": "images/icons/folderPlaceholder-ltr.svg",
                        "rtl": "images/icons/folderPlaceholder-rtl.svg"
                } },
+               "history": { "file": "images/icons/history.svg" },
+               "info": { "file": "images/icons/info.svg" },
                "journal": { "file": {
                        "ltr": "images/icons/journal-ltr.svg",
                        "rtl": "images/icons/journal-rtl.svg"
                        "ltr": "images/icons/newspaper-ltr.svg",
                        "rtl": "images/icons/newspaper-rtl.svg"
                } },
+               "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ] },
                "upload": { "file": {
                        "ltr": "images/icons/upload-ltr.svg",
                        "rtl": "images/icons/upload-rtl.svg"
-               } }
+               } },
+               "window": { "file": "images/icons/window.svg" }
        }
 }
index f693e3f..668173f 100644 (file)
@@ -23,6 +23,7 @@
        },
        "images": {
                "add": { "file": "images/icons/add.svg", "variants": [ "constructive", "progressive" ] },
+               "advanced": { "file": "images/icons/advanced.svg" },
                "bookmark": { "file": {
                        "ltr": "images/icons/bookmark-ltr.svg",
                        "rtl": "images/icons/bookmark-rtl.svg"
                        "ltr": "images/icons/browser-ltr.svg",
                        "rtl": "images/icons/browser-rtl.svg"
                } },
+               "cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ] },
+               "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ] },
                "clear": { "file": "images/icons/clear.svg" },
                "clock": { "file": "images/icons/clock.svg" },
+               "close": { "file": "images/icons/close.svg" },
+               "ellipsis": { "file": "images/icons/ellipsis.svg" },
                "feedback": {
                        "file": {
                                "ltr": "images/icons/feedback-ltr.svg",
                        "rtl": "images/icons/funnel-rtl.svg"
                } },
                "heart": { "file": "images/icons/heart.svg" },
+               "help": { "file": {
+                       "ltr": "images/icons/help-ltr.svg",
+                       "rtl": "images/icons/help-rtl.svg",
+                       "lang": {
+                               "he,yi": "images/icons/help-ltr.svg"
+                       }
+               } },
                "key": { "file": {
                        "ltr": "images/icons/key-ltr.svg",
                        "rtl": "images/icons/key-rtl.svg"
                        "ltr": "images/icons/printer-ltr.svg",
                        "rtl": "images/icons/printer-rtl.svg"
                } },
+               "search": { "file": {
+                       "ltr": "images/icons/search-ltr.svg",
+                       "rtl": "images/icons/search-rtl.svg"
+                       }
+               },
+               "settings": { "file": "images/icons/settings.svg" },
                "subtract": { "file": "images/icons/subtract.svg" },
                "sun": { "file": {
                        "ltr": "images/icons/sun-ltr.svg",
index 6ff4a0e..f720a25 100644 (file)
@@ -22,6 +22,7 @@
                }
        },
        "images": {
+               "menu": { "file": "images/icons/menu.svg" },
                "stripeFlow": { "file": {
                        "ltr": "images/icons/stripeFlow-ltr.svg",
                        "rtl": "images/icons/stripeFlow-rtl.svg"
index 7098f23..58feb23 100644 (file)
                        "ltr": "images/icons/mapPinAdd-ltr.svg",
                        "rtl": "images/icons/mapPinAdd-rtl.svg"
                } },
+               "mapTrail": { "file": {
+                       "ltr": "images/icons/mapTrail-ltr.svg",
+                       "rtl": "images/icons/mapTrail-rtl.svg"
+               } },
                "wikitrail": { "file": {
-                       "ltr": "images/icons/wikitrail-ltr.svg",
-                       "rtl": "images/icons/wikitrail-rtl.svg"
-               } }
+                       "ltr": "images/icons/mapTrail-ltr.svg",
+                       "rtl": "images/icons/mapTrail-rtl.svg"
+               }, "deprecated": "Renamed to 'mapTrail' since v0.20.1."
+               }
        }
 }
index 059073f..0dc88e3 100644 (file)
                } },
                "caretDown": { "file": "images/icons/caretDown.svg" },
                "caretUp": { "file": "images/icons/caretUp.svg" },
+               "collapse": { "file": "images/icons/collapse.svg" },
                "downTriangle": { "file": "images/icons/downTriangle.svg" },
+               "expand": { "file": "images/icons/expand.svg" },
                "move": { "file": "images/icons/move.svg" },
+               "next": { "file": {
+                       "ltr": "images/icons/move-ltr.svg",
+                       "rtl": "images/icons/move-rtl.svg"
+                       }
+               },
+               "previous": { "file": {
+                       "ltr": "images/icons/move-rtl.svg",
+                       "rtl": "images/icons/move-ltr.svg"
+                       }
+               },
                "upTriangle": { "file": "images/icons/upTriangle.svg" }
        }
 }
index 60c05f3..958e7e3 100644 (file)
                }
        },
        "images": {
-               "add": { "file": "images/icons/add.svg", "variants": [ "constructive", "progressive" ], "deprecated": "Moved since v0.19.5, use from the 'interactive' pack instead." },
-               "advanced": { "file": "images/icons/advanced.svg" },
-               "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] },
-               "cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ] },
-               "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ] },
-               "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive", "progressive" ] },
-               "close": { "file": "images/icons/close.svg" },
-               "code": { "file": "images/icons/code.svg" },
-               "collapse": { "file": "images/icons/collapse.svg" },
-               "comment": { "file": "images/icons/comment.svg" },
-               "ellipsis": { "file": "images/icons/ellipsis.svg" },
-               "expand": { "file": "images/icons/expand.svg" },
+               "add": { "file": "images/icons/add.svg", "variants": [ "constructive", "progressive" ], "deprecated": "Moved since v0.19.5, use from the 'interactions' pack instead." },
+               "advanced": { "file": "images/icons/advanced.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ], "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+               "cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ], "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ], "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+       "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive", "progressive" ], "deprecated": "Deprecated since v0.20.1, do not use." },
+               "close": { "file": "images/icons/close.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "code": { "file": "images/icons/code.svg", "deprecated": "Moved since v0.16.2, use from the 'editing-advanced' pack instead." },
+               "collapse": { "file": "images/icons/collapse.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
+               "comment": { "file": "images/icons/comment.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
+               "ellipsis": { "file": "images/icons/ellipsis.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "expand": { "file": "images/icons/expand.svg", "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead." },
                "help": { "file": {
                        "ltr": "images/icons/help-ltr.svg",
                        "rtl": "images/icons/help-rtl.svg",
                        "lang": {
                                "he,yi": "images/icons/help-ltr.svg"
-                       }
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
                } },
-               "history": { "file": "images/icons/history.svg" },
-               "info": { "file": "images/icons/info.svg" },
-               "menu": { "file": "images/icons/menu.svg" },
+               "history": { "file": "images/icons/history.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+               "info": { "file": "images/icons/info.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
+               "menu": { "file": "images/icons/menu.svg", "deprecated": "Moved since v0.20.1, use from the 'layout' pack instead." },
                "next": { "file": {
                        "ltr": "images/icons/move-ltr.svg",
                        "rtl": "images/icons/move-rtl.svg"
-               } },
-               "notice": { "file": "images/icons/notice.svg" },
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+               },
+               "notice": { "file": "images/icons/notice.svg", "deprecated": "Moved since v0.20.1, use from the 'alerts' pack instead." },
                "previous": { "file": {
                        "ltr": "images/icons/move-rtl.svg",
                        "rtl": "images/icons/move-ltr.svg"
-               } },
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'movement' pack instead."
+               },
                "redo": { "file": {
                        "ltr": "images/icons/arched-arrow-ltr.svg",
                        "rtl": "images/icons/arched-arrow-rtl.svg"
-               } },
-               "remove": { "file": "images/icons/trash.svg", "variants": [ "destructive" ] },
+                       },
+                       "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+               },
+               "remove": { "file": "images/icons/trash.svg", "variants": [ "destructive" ], "deprecated": "Replaced since v0.14.0, use 'trash' from the 'moderation' pack instead." },
                "search": { "file": {
                        "ltr": "images/icons/search-ltr.svg",
                        "rtl": "images/icons/search-rtl.svg"
-               } },
-               "settings": { "file": "images/icons/settings.svg" },
-               "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ] },
+                       },
+                       "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead."
+               },
+               "settings": { "file": "images/icons/settings.svg", "deprecated": "Moved since v0.20.1, use from the 'interactions' pack instead." },
+               "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ], "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." },
                "undo": { "file": {
                        "ltr": "images/icons/arched-arrow-rtl.svg",
                        "rtl": "images/icons/arched-arrow-ltr.svg"
-               } },
-               "window": { "file": "images/icons/window.svg" }
+                       },
+                       "deprecated": "Moved since v0.16.2, use from the 'editing-core' pack instead."
+               },
+               "window": { "file": "images/icons/window.svg", "deprecated": "Moved since v0.20.1, use from the 'content' pack instead." }
        }
 }
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.png
new file mode 100644 (file)
index 0000000..075f84e
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-invert.svg
new file mode 100644 (file)
index 0000000..17d3645
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+    <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+    <circle cx="8" cy="5" r="2"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.png
new file mode 100644 (file)
index 0000000..2b26e15
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr-progressive.svg
new file mode 100644 (file)
index 0000000..2b49b99
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+    <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+    <circle cx="8" cy="5" r="2"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.png
new file mode 100644 (file)
index 0000000..331fd59
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-ltr.svg
new file mode 100644 (file)
index 0000000..cb073b9
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+    <circle cx="8" cy="5" r="2"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.png
new file mode 100644 (file)
index 0000000..75c8dcf
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-invert.svg
new file mode 100644 (file)
index 0000000..fbb9cab
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
+    <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+    <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.png
new file mode 100644 (file)
index 0000000..fc0b2d9
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl-progressive.svg
new file mode 100644 (file)
index 0000000..a2f62ff
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
+    <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+    <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.png
new file mode 100644 (file)
index 0000000..62f1fe9
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/mapTrail-rtl.svg
new file mode 100644 (file)
index 0000000..e8b1a08
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+    <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.png
deleted file mode 100644 (file)
index 075f84e..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.svg
deleted file mode 100644 (file)
index 17d3645..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
-    <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
-    <circle cx="8" cy="5" r="2"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.png
deleted file mode 100644 (file)
index 2b26e15..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-progressive.svg
deleted file mode 100644 (file)
index 2b49b99..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
-    <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
-    <circle cx="8" cy="5" r="2"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.png
deleted file mode 100644 (file)
index 331fd59..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr.svg
deleted file mode 100644 (file)
index cb073b9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
-    <circle cx="8" cy="5" r="2"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.png
deleted file mode 100644 (file)
index 75c8dcf..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.svg
deleted file mode 100644 (file)
index fbb9cab..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#fff">
-    <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
-    <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.png
deleted file mode 100644 (file)
index fc0b2d9..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-progressive.svg
deleted file mode 100644 (file)
index a2f62ff..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="#36c">
-    <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
-    <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
-</g></svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.png
deleted file mode 100644 (file)
index 62f1fe9..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl.svg
deleted file mode 100644 (file)
index e8b1a08..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
-    <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
-</svg>
index 7c4dbb1..7b2d711 100644 (file)
@@ -459,4 +459,4 @@ html > body.rtl .mw-body ul#filetoc {
        display: block;
 }
 
-/* RTL specific CSS ends here **/
+/** RTL specific CSS ends here **/
index ff0c0e3..8d7a2a9 100644 (file)
@@ -322,6 +322,21 @@ a.new {
        color: #ba0000;
 }
 
+/* self links */
+a.mw-selflink {
+       color: inherit;
+       font-weight: bold;
+       text-decoration: inherit;
+}
+a.mw-selflink:hover {
+       cursor: inherit;
+       text-decoration: inherit;
+}
+a.mw-selflink:active,
+a.mw-selflink:visited {
+       color: inherit;
+}
+
 /* Plainlinks - this can be used to switch
  * off special external link styling */
 .plainlinks a.external {
index 0b0f912..d5e1c48 100644 (file)
@@ -148,7 +148,7 @@ to resemble a traditional dictionary definition */
        left: 0;
        text-align: center;
        color: #fff;
-       text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background*/
+       text-shadow: 0 0 10px rgba( 0, 0, 0, 0.4 ); /* improves legibility on white background */
        font-size: 0.8em;
        padding: 5px;
        background-color: rgba( 0, 0, 0, 0.5 );
@@ -183,7 +183,7 @@ to resemble a traditional dictionary definition */
 
        #mw-interwiki-results {
                width: 30%;
-               display: inline-block; /* used to align iw sidebar with the top of the main search results*/
+               display: inline-block; /* used to align iw sidebar with the top of the main search results */
                margin-left: 10%;
        }
        .searchresults .mw-search-createlink,
index 9da6c83..4a48f46 100644 (file)
@@ -29,7 +29,7 @@
        font-size: 0.8em;
 }
 
-/* Put some space under template's header, which may contain CAPTCHA HTML.*/
+/* Put some space under template's header, which may contain CAPTCHA HTML. */
 section.mw-form-header {
        margin-bottom: 10px;
 }
diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js b/resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js
new file mode 100644 (file)
index 0000000..ccc5c9d
--- /dev/null
@@ -0,0 +1,416 @@
+/*!
+ * MediaWiki Widgets - CategoryMultiselectWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function ( $, mw ) {
+       var NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
+
+       /**
+        * Category selector widget. Displays an OO.ui.CapsuleMultiselectWidget
+        * and autocompletes with available categories.
+        *
+        *     mw.loader.using( 'mediawiki.widgets.CategoryMultiselectWidget', function () {
+        *       var selector = new mw.widgets.CategoryMultiselectWidget( {
+        *         searchTypes: [
+        *           mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch,
+        *           mw.widgets.CategoryMultiselectWidget.SearchType.InternalSearch
+        *         ]
+        *       } );
+        *
+        *       $( 'body' ).append( selector.$element );
+        *
+        *       selector.setSearchTypes( [ mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories ] );
+        *     } );
+        *
+        * @class mw.widgets.CategoryMultiselectWidget
+        * @uses mw.Api
+        * @extends OO.ui.CapsuleMultiselectWidget
+        * @mixins OO.ui.mixin.PendingElement
+        *
+        * @constructor
+        * @param {Object} [config] Configuration options
+        * @cfg {mw.Api} [api] Instance of mw.Api (or subclass thereof) to use for queries
+        * @cfg {number} [limit=10] Maximum number of results to load
+        * @cfg {mw.widgets.CategoryMultiselectWidget.SearchType[]} [searchTypes=[mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch]]
+        *   Default search API to use when searching.
+        */
+       mw.widgets.CategoryMultiselectWidget = function MWCategoryMultiselectWidget( config ) {
+               // Config initialization
+               config = $.extend( {
+                       limit: 10,
+                       searchTypes: [ mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch ]
+               }, config );
+               this.limit = config.limit;
+               this.searchTypes = config.searchTypes;
+               this.validateSearchTypes();
+
+               // Parent constructor
+               mw.widgets.CategoryMultiselectWidget.parent.call( this, $.extend( true, {}, config, {
+                       menu: {
+                               filterFromInput: false
+                       },
+                       placeholder: mw.msg( 'mw-widgets-categoryselector-add-category-placeholder' ),
+                       // This allows the user to both select non-existent categories, and prevents the selector from
+                       // being wiped from #onMenuItemsChange when we change the available options in the dropdown
+                       allowArbitrary: true
+               } ) );
+
+               // Mixin constructors
+               OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) );
+
+               // Event handler to call the autocomplete methods
+               this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
+
+               // Initialize
+               this.api = config.api || new mw.Api();
+               this.searchCache = {};
+       };
+
+       /* Setup */
+
+       OO.inheritClass( mw.widgets.CategoryMultiselectWidget, OO.ui.CapsuleMultiselectWidget );
+       OO.mixinClass( mw.widgets.CategoryMultiselectWidget, OO.ui.mixin.PendingElement );
+
+       /* Methods */
+
+       /**
+        * Gets new items based on the input by calling
+        * {@link #getNewMenuItems getNewItems} and updates the menu
+        * after removing duplicates based on the data value.
+        *
+        * @private
+        * @method
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.updateMenuItems = function () {
+               this.getMenu().clearItems();
+               this.getNewMenuItems( this.$input.val() ).then( function ( items ) {
+                       var existingItems, filteredItems,
+                               menu = this.getMenu();
+
+                       // Never show the menu if the input lost focus in the meantime
+                       if ( !this.$input.is( ':focus' ) ) {
+                               return;
+                       }
+
+                       // Array of strings of the data of OO.ui.MenuOptionsWidgets
+                       existingItems = menu.getItems().map( function ( item ) {
+                               return item.data;
+                       } );
+
+                       // Remove if items' data already exists
+                       filteredItems = items.filter( function ( item ) {
+                               return existingItems.indexOf( item ) === -1;
+                       } );
+
+                       // Map to an array of OO.ui.MenuOptionWidgets
+                       filteredItems = filteredItems.map( function ( item ) {
+                               return new OO.ui.MenuOptionWidget( {
+                                       data: item,
+                                       label: item
+                               } );
+                       } );
+
+                       menu.addItems( filteredItems ).toggle( true );
+               }.bind( this ) );
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.clearInput = function () {
+               mw.widgets.CategoryMultiselectWidget.parent.prototype.clearInput.call( this );
+               // Abort all pending requests, we won't need their results
+               this.api.abort();
+       };
+
+       /**
+        * Searches for categories based on the input.
+        *
+        * @private
+        * @method
+        * @param {string} input The input used to prefix search categories
+        * @return {jQuery.Promise} Resolves with an array of categories
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.getNewMenuItems = function ( input ) {
+               var i,
+                       promises = [],
+                       deferred = $.Deferred();
+
+               if ( $.trim( input ) === '' ) {
+                       deferred.resolve( [] );
+                       return deferred.promise();
+               }
+
+               // Abort all pending requests, we won't need their results
+               this.api.abort();
+               for ( i = 0; i < this.searchTypes.length; i++ ) {
+                       promises.push( this.searchCategories( input, this.searchTypes[ i ] ) );
+               }
+
+               this.pushPending();
+
+               $.when.apply( $, promises ).done( function () {
+                       var categoryNames,
+                               allData = [],
+                               dataSets = Array.prototype.slice.apply( arguments );
+
+                       // Collect values from all results
+                       allData = allData.concat.apply( allData, dataSets );
+
+                       categoryNames = allData
+                               // Remove duplicates
+                               .filter( function ( value, index, self ) {
+                                       return self.indexOf( value ) === index;
+                               } )
+                               // Get Title objects
+                               .map( function ( name ) {
+                                       return mw.Title.newFromText( name );
+                               } )
+                               // Keep only titles from 'Category' namespace
+                               .filter( function ( title ) {
+                                       return title && title.getNamespaceId() === NS_CATEGORY;
+                               } )
+                               // Convert back to strings, strip 'Category:' prefix
+                               .map( function ( title ) {
+                                       return title.getMainText();
+                               } );
+
+                       deferred.resolve( categoryNames );
+
+               } ).always( this.popPending.bind( this ) );
+
+               return deferred.promise();
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.createItemWidget = function ( data ) {
+               var title = mw.Title.makeTitle( NS_CATEGORY, data );
+               if ( !title ) {
+                       return null;
+               }
+               return new mw.widgets.CategoryCapsuleItemWidget( {
+                       apiUrl: this.api.apiUrl || undefined,
+                       title: title
+               } );
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.getItemFromData = function ( data ) {
+               // This is a bit of a hack... We have to canonicalize the data in the same way that
+               // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
+               var title = mw.Title.makeTitle( NS_CATEGORY, data );
+               if ( !title ) {
+                       return null;
+               }
+               return OO.ui.mixin.GroupElement.prototype.getItemFromData.call( this, title.getMainText() );
+       };
+
+       /**
+        * Validates the values in `this.searchType`.
+        *
+        * @private
+        * @return {boolean}
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.validateSearchTypes = function () {
+               var validSearchTypes = false,
+                       searchTypeEnumCount = Object.keys( mw.widgets.CategoryMultiselectWidget.SearchType ).length;
+
+               // Check if all values are in the SearchType enum
+               validSearchTypes = this.searchTypes.every( function ( searchType ) {
+                       return searchType > -1 && searchType < searchTypeEnumCount;
+               } );
+
+               if ( validSearchTypes === false ) {
+                       throw new Error( 'Unknown searchType in searchTypes' );
+               }
+
+               // If the searchTypes has mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories
+               // it can be the only search type.
+               if ( this.searchTypes.indexOf( mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories ) > -1 &&
+                       this.searchTypes.length > 1
+               ) {
+                       throw new Error( 'Can\'t have additional search types with mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories' );
+               }
+
+               // If the searchTypes has mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories
+               // it can be the only search type.
+               if ( this.searchTypes.indexOf( mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories ) > -1 &&
+                       this.searchTypes.length > 1
+               ) {
+                       throw new Error( 'Can\'t have additional search types with mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories' );
+               }
+
+               return true;
+       };
+
+       /**
+        * Sets and validates the value of `this.searchType`.
+        *
+        * @param {mw.widgets.CategoryMultiselectWidget.SearchType[]} searchTypes
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.setSearchTypes = function ( searchTypes ) {
+               this.searchTypes = searchTypes;
+               this.validateSearchTypes();
+       };
+
+       /**
+        * Searches categories based on input and searchType.
+        *
+        * @private
+        * @method
+        * @param {string} input The input used to prefix search categories
+        * @param {mw.widgets.CategoryMultiselectWidget.SearchType} searchType
+        * @return {jQuery.Promise} Resolves with an array of categories
+        */
+       mw.widgets.CategoryMultiselectWidget.prototype.searchCategories = function ( input, searchType ) {
+               var deferred = $.Deferred(),
+                       cacheKey = input + searchType.toString();
+
+               // Check cache
+               if ( this.searchCache[ cacheKey ] !== undefined ) {
+                       return this.searchCache[ cacheKey ];
+               }
+
+               switch ( searchType ) {
+                       case mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch:
+                               this.api.get( {
+                                       formatversion: 2,
+                                       action: 'opensearch',
+                                       namespace: NS_CATEGORY,
+                                       limit: this.limit,
+                                       search: input
+                               } ).done( function ( res ) {
+                                       var categories = res[ 1 ];
+                                       deferred.resolve( categories );
+                               } ).fail( deferred.reject.bind( deferred ) );
+                               break;
+
+                       case mw.widgets.CategoryMultiselectWidget.SearchType.InternalSearch:
+                               this.api.get( {
+                                       formatversion: 2,
+                                       action: 'query',
+                                       list: 'allpages',
+                                       apnamespace: NS_CATEGORY,
+                                       aplimit: this.limit,
+                                       apfrom: input,
+                                       apprefix: input
+                               } ).done( function ( res ) {
+                                       var categories = res.query.allpages.map( function ( page ) {
+                                               return page.title;
+                                       } );
+                                       deferred.resolve( categories );
+                               } ).fail( deferred.reject.bind( deferred ) );
+                               break;
+
+                       case mw.widgets.CategoryMultiselectWidget.SearchType.Exists:
+                               if ( input.indexOf( '|' ) > -1 ) {
+                                       deferred.resolve( [] );
+                                       break;
+                               }
+
+                               this.api.get( {
+                                       formatversion: 2,
+                                       action: 'query',
+                                       prop: 'info',
+                                       titles: 'Category:' + input
+                               } ).done( function ( res ) {
+                                       var categories = [];
+
+                                       $.each( res.query.pages, function ( index, page ) {
+                                               if ( !page.missing ) {
+                                                       categories.push( page.title );
+                                               }
+                                       } );
+
+                                       deferred.resolve( categories );
+                               } ).fail( deferred.reject.bind( deferred ) );
+                               break;
+
+                       case mw.widgets.CategoryMultiselectWidget.SearchType.SubCategories:
+                               if ( input.indexOf( '|' ) > -1 ) {
+                                       deferred.resolve( [] );
+                                       break;
+                               }
+
+                               this.api.get( {
+                                       formatversion: 2,
+                                       action: 'query',
+                                       list: 'categorymembers',
+                                       cmtype: 'subcat',
+                                       cmlimit: this.limit,
+                                       cmtitle: 'Category:' + input
+                               } ).done( function ( res ) {
+                                       var categories = res.query.categorymembers.map( function ( category ) {
+                                               return category.title;
+                                       } );
+                                       deferred.resolve( categories );
+                               } ).fail( deferred.reject.bind( deferred ) );
+                               break;
+
+                       case mw.widgets.CategoryMultiselectWidget.SearchType.ParentCategories:
+                               if ( input.indexOf( '|' ) > -1 ) {
+                                       deferred.resolve( [] );
+                                       break;
+                               }
+
+                               this.api.get( {
+                                       formatversion: 2,
+                                       action: 'query',
+                                       prop: 'categories',
+                                       cllimit: this.limit,
+                                       titles: 'Category:' + input
+                               } ).done( function ( res ) {
+                                       var categories = [];
+
+                                       $.each( res.query.pages, function ( index, page ) {
+                                               if ( !page.missing && $.isArray( page.categories ) ) {
+                                                       categories.push.apply( categories, page.categories.map( function ( category ) {
+                                                               return category.title;
+                                                       } ) );
+                                               }
+                                       } );
+
+                                       deferred.resolve( categories );
+                               } ).fail( deferred.reject.bind( deferred ) );
+                               break;
+
+                       default:
+                               throw new Error( 'Unknown searchType' );
+               }
+
+               // Cache the result
+               this.searchCache[ cacheKey ] = deferred.promise();
+
+               return deferred.promise();
+       };
+
+       /**
+        * @enum mw.widgets.CategoryMultiselectWidget.SearchType
+        * Types of search available.
+        */
+       mw.widgets.CategoryMultiselectWidget.SearchType = {
+               /** Search using action=opensearch */
+               OpenSearch: 0,
+
+               /** Search using action=query */
+               InternalSearch: 1,
+
+               /** Search for existing categories with the exact title */
+               Exists: 2,
+
+               /** Search only subcategories  */
+               SubCategories: 3,
+
+               /** Search only parent categories */
+               ParentCategories: 4
+       };
+
+       // For backwards compatibility. See T161285.
+       mw.widgets.CategorySelector = mw.widgets.CategoryMultiselectWidget;
+}( jQuery, mediaWiki ) );
diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js b/resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js
deleted file mode 100644 (file)
index 422c048..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/*!
- * MediaWiki Widgets - CategorySelector class.
- *
- * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-( function ( $, mw ) {
-       var CSP,
-               NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
-
-       /**
-        * Category selector widget. Displays an OO.ui.CapsuleMultiselectWidget
-        * and autocompletes with available categories.
-        *
-        *     mw.loader.using( 'mediawiki.widgets.CategorySelector', function () {
-        *       var selector = new mw.widgets.CategorySelector( {
-        *         searchTypes: [
-        *           mw.widgets.CategorySelector.SearchType.OpenSearch,
-        *           mw.widgets.CategorySelector.SearchType.InternalSearch
-        *         ]
-        *       } );
-        *
-        *       $( 'body' ).append( selector.$element );
-        *
-        *       selector.setSearchTypes( [ mw.widgets.CategorySelector.SearchType.SubCategories ] );
-        *     } );
-        *
-        * @class mw.widgets.CategorySelector
-        * @uses mw.Api
-        * @extends OO.ui.CapsuleMultiselectWidget
-        * @mixins OO.ui.mixin.PendingElement
-        *
-        * @constructor
-        * @param {Object} [config] Configuration options
-        * @cfg {mw.Api} [api] Instance of mw.Api (or subclass thereof) to use for queries
-        * @cfg {number} [limit=10] Maximum number of results to load
-        * @cfg {mw.widgets.CategorySelector.SearchType[]} [searchTypes=[mw.widgets.CategorySelector.SearchType.OpenSearch]]
-        *   Default search API to use when searching.
-        */
-       function CategorySelector( config ) {
-               // Config initialization
-               config = $.extend( {
-                       limit: 10,
-                       searchTypes: [ CategorySelector.SearchType.OpenSearch ]
-               }, config );
-               this.limit = config.limit;
-               this.searchTypes = config.searchTypes;
-               this.validateSearchTypes();
-
-               // Parent constructor
-               mw.widgets.CategorySelector.parent.call( this, $.extend( true, {}, config, {
-                       menu: {
-                               filterFromInput: false
-                       },
-                       placeholder: mw.msg( 'mw-widgets-categoryselector-add-category-placeholder' ),
-                       // This allows the user to both select non-existent categories, and prevents the selector from
-                       // being wiped from #onMenuItemsChange when we change the available options in the dropdown
-                       allowArbitrary: true
-               } ) );
-
-               // Mixin constructors
-               OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) );
-
-               // Event handler to call the autocomplete methods
-               this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
-
-               // Initialize
-               this.api = config.api || new mw.Api();
-               this.searchCache = {};
-       }
-
-       /* Setup */
-
-       OO.inheritClass( CategorySelector, OO.ui.CapsuleMultiselectWidget );
-       OO.mixinClass( CategorySelector, OO.ui.mixin.PendingElement );
-       CSP = CategorySelector.prototype;
-
-       /* Methods */
-
-       /**
-        * Gets new items based on the input by calling
-        * {@link #getNewMenuItems getNewItems} and updates the menu
-        * after removing duplicates based on the data value.
-        *
-        * @private
-        * @method
-        */
-       CSP.updateMenuItems = function () {
-               this.getMenu().clearItems();
-               this.getNewMenuItems( this.$input.val() ).then( function ( items ) {
-                       var existingItems, filteredItems,
-                               menu = this.getMenu();
-
-                       // Never show the menu if the input lost focus in the meantime
-                       if ( !this.$input.is( ':focus' ) ) {
-                               return;
-                       }
-
-                       // Array of strings of the data of OO.ui.MenuOptionsWidgets
-                       existingItems = menu.getItems().map( function ( item ) {
-                               return item.data;
-                       } );
-
-                       // Remove if items' data already exists
-                       filteredItems = items.filter( function ( item ) {
-                               return existingItems.indexOf( item ) === -1;
-                       } );
-
-                       // Map to an array of OO.ui.MenuOptionWidgets
-                       filteredItems = filteredItems.map( function ( item ) {
-                               return new OO.ui.MenuOptionWidget( {
-                                       data: item,
-                                       label: item
-                               } );
-                       } );
-
-                       menu.addItems( filteredItems ).toggle( true );
-               }.bind( this ) );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       CSP.clearInput = function () {
-               CategorySelector.parent.prototype.clearInput.call( this );
-               // Abort all pending requests, we won't need their results
-               this.api.abort();
-       };
-
-       /**
-        * Searches for categories based on the input.
-        *
-        * @private
-        * @method
-        * @param {string} input The input used to prefix search categories
-        * @return {jQuery.Promise} Resolves with an array of categories
-        */
-       CSP.getNewMenuItems = function ( input ) {
-               var i,
-                       promises = [],
-                       deferred = $.Deferred();
-
-               if ( $.trim( input ) === '' ) {
-                       deferred.resolve( [] );
-                       return deferred.promise();
-               }
-
-               // Abort all pending requests, we won't need their results
-               this.api.abort();
-               for ( i = 0; i < this.searchTypes.length; i++ ) {
-                       promises.push( this.searchCategories( input, this.searchTypes[ i ] ) );
-               }
-
-               this.pushPending();
-
-               $.when.apply( $, promises ).done( function () {
-                       var categoryNames,
-                               allData = [],
-                               dataSets = Array.prototype.slice.apply( arguments );
-
-                       // Collect values from all results
-                       allData = allData.concat.apply( allData, dataSets );
-
-                       categoryNames = allData
-                               // Remove duplicates
-                               .filter( function ( value, index, self ) {
-                                       return self.indexOf( value ) === index;
-                               } )
-                               // Get Title objects
-                               .map( function ( name ) {
-                                       return mw.Title.newFromText( name );
-                               } )
-                               // Keep only titles from 'Category' namespace
-                               .filter( function ( title ) {
-                                       return title && title.getNamespaceId() === NS_CATEGORY;
-                               } )
-                               // Convert back to strings, strip 'Category:' prefix
-                               .map( function ( title ) {
-                                       return title.getMainText();
-                               } );
-
-                       deferred.resolve( categoryNames );
-
-               } ).always( this.popPending.bind( this ) );
-
-               return deferred.promise();
-       };
-
-       /**
-        * @inheritdoc
-        */
-       CSP.createItemWidget = function ( data ) {
-               var title = mw.Title.makeTitle( NS_CATEGORY, data );
-               if ( !title ) {
-                       return null;
-               }
-               return new mw.widgets.CategoryCapsuleItemWidget( {
-                       apiUrl: this.api.apiUrl || undefined,
-                       title: title
-               } );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       CSP.getItemFromData = function ( data ) {
-               // This is a bit of a hack... We have to canonicalize the data in the same way that
-               // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
-               var title = mw.Title.makeTitle( NS_CATEGORY, data );
-               if ( !title ) {
-                       return null;
-               }
-               return OO.ui.mixin.GroupElement.prototype.getItemFromData.call( this, title.getMainText() );
-       };
-
-       /**
-        * Validates the values in `this.searchType`.
-        *
-        * @private
-        * @return {boolean}
-        */
-       CSP.validateSearchTypes = function () {
-               var validSearchTypes = false,
-                       searchTypeEnumCount = Object.keys( CategorySelector.SearchType ).length;
-
-               // Check if all values are in the SearchType enum
-               validSearchTypes = this.searchTypes.every( function ( searchType ) {
-                       return searchType > -1 && searchType < searchTypeEnumCount;
-               } );
-
-               if ( validSearchTypes === false ) {
-                       throw new Error( 'Unknown searchType in searchTypes' );
-               }
-
-               // If the searchTypes has CategorySelector.SearchType.SubCategories
-               // it can be the only search type.
-               if ( this.searchTypes.indexOf( CategorySelector.SearchType.SubCategories ) > -1 &&
-                       this.searchTypes.length > 1
-               ) {
-                       throw new Error( 'Can\'t have additional search types with CategorySelector.SearchType.SubCategories' );
-               }
-
-               // If the searchTypes has CategorySelector.SearchType.ParentCategories
-               // it can be the only search type.
-               if ( this.searchTypes.indexOf( CategorySelector.SearchType.ParentCategories ) > -1 &&
-                       this.searchTypes.length > 1
-               ) {
-                       throw new Error( 'Can\'t have additional search types with CategorySelector.SearchType.ParentCategories' );
-               }
-
-               return true;
-       };
-
-       /**
-        * Sets and validates the value of `this.searchType`.
-        *
-        * @param {mw.widgets.CategorySelector.SearchType[]} searchTypes
-        */
-       CSP.setSearchTypes = function ( searchTypes ) {
-               this.searchTypes = searchTypes;
-               this.validateSearchTypes();
-       };
-
-       /**
-        * Searches categories based on input and searchType.
-        *
-        * @private
-        * @method
-        * @param {string} input The input used to prefix search categories
-        * @param {mw.widgets.CategorySelector.SearchType} searchType
-        * @return {jQuery.Promise} Resolves with an array of categories
-        */
-       CSP.searchCategories = function ( input, searchType ) {
-               var deferred = $.Deferred(),
-                       cacheKey = input + searchType.toString();
-
-               // Check cache
-               if ( this.searchCache[ cacheKey ] !== undefined ) {
-                       return this.searchCache[ cacheKey ];
-               }
-
-               switch ( searchType ) {
-                       case CategorySelector.SearchType.OpenSearch:
-                               this.api.get( {
-                                       formatversion: 2,
-                                       action: 'opensearch',
-                                       namespace: NS_CATEGORY,
-                                       limit: this.limit,
-                                       search: input
-                               } ).done( function ( res ) {
-                                       var categories = res[ 1 ];
-                                       deferred.resolve( categories );
-                               } ).fail( deferred.reject.bind( deferred ) );
-                               break;
-
-                       case CategorySelector.SearchType.InternalSearch:
-                               this.api.get( {
-                                       formatversion: 2,
-                                       action: 'query',
-                                       list: 'allpages',
-                                       apnamespace: NS_CATEGORY,
-                                       aplimit: this.limit,
-                                       apfrom: input,
-                                       apprefix: input
-                               } ).done( function ( res ) {
-                                       var categories = res.query.allpages.map( function ( page ) {
-                                               return page.title;
-                                       } );
-                                       deferred.resolve( categories );
-                               } ).fail( deferred.reject.bind( deferred ) );
-                               break;
-
-                       case CategorySelector.SearchType.Exists:
-                               if ( input.indexOf( '|' ) > -1 ) {
-                                       deferred.resolve( [] );
-                                       break;
-                               }
-
-                               this.api.get( {
-                                       formatversion: 2,
-                                       action: 'query',
-                                       prop: 'info',
-                                       titles: 'Category:' + input
-                               } ).done( function ( res ) {
-                                       var categories = [];
-
-                                       $.each( res.query.pages, function ( index, page ) {
-                                               if ( !page.missing ) {
-                                                       categories.push( page.title );
-                                               }
-                                       } );
-
-                                       deferred.resolve( categories );
-                               } ).fail( deferred.reject.bind( deferred ) );
-                               break;
-
-                       case CategorySelector.SearchType.SubCategories:
-                               if ( input.indexOf( '|' ) > -1 ) {
-                                       deferred.resolve( [] );
-                                       break;
-                               }
-
-                               this.api.get( {
-                                       formatversion: 2,
-                                       action: 'query',
-                                       list: 'categorymembers',
-                                       cmtype: 'subcat',
-                                       cmlimit: this.limit,
-                                       cmtitle: 'Category:' + input
-                               } ).done( function ( res ) {
-                                       var categories = res.query.categorymembers.map( function ( category ) {
-                                               return category.title;
-                                       } );
-                                       deferred.resolve( categories );
-                               } ).fail( deferred.reject.bind( deferred ) );
-                               break;
-
-                       case CategorySelector.SearchType.ParentCategories:
-                               if ( input.indexOf( '|' ) > -1 ) {
-                                       deferred.resolve( [] );
-                                       break;
-                               }
-
-                               this.api.get( {
-                                       formatversion: 2,
-                                       action: 'query',
-                                       prop: 'categories',
-                                       cllimit: this.limit,
-                                       titles: 'Category:' + input
-                               } ).done( function ( res ) {
-                                       var categories = [];
-
-                                       $.each( res.query.pages, function ( index, page ) {
-                                               if ( !page.missing && $.isArray( page.categories ) ) {
-                                                       categories.push.apply( categories, page.categories.map( function ( category ) {
-                                                               return category.title;
-                                                       } ) );
-                                               }
-                                       } );
-
-                                       deferred.resolve( categories );
-                               } ).fail( deferred.reject.bind( deferred ) );
-                               break;
-
-                       default:
-                               throw new Error( 'Unknown searchType' );
-               }
-
-               // Cache the result
-               this.searchCache[ cacheKey ] = deferred.promise();
-
-               return deferred.promise();
-       };
-
-       /**
-        * @enum mw.widgets.CategorySelector.SearchType
-        * Types of search available.
-        */
-       CategorySelector.SearchType = {
-               /** Search using action=opensearch */
-               OpenSearch: 0,
-
-               /** Search using action=query */
-               InternalSearch: 1,
-
-               /** Search for existing categories with the exact title */
-               Exists: 2,
-
-               /** Search only subcategories  */
-               SubCategories: 3,
-
-               /** Search only parent categories */
-               ParentCategories: 4
-       };
-
-       mw.widgets.CategorySelector = CategorySelector;
-}( jQuery, mediaWiki ) );
index f67ed3d..b0c9f91 100644 (file)
                }
        };
 
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.ComplexNamespaceInputWidget.prototype.setDisabled = function ( disabled ) {
+               mw.widgets.ComplexNamespaceInputWidget.parent.prototype.setDisabled.call( this, disabled );
+               this.namespace.setDisabled( disabled );
+
+               if ( this.invert ) {
+                       this.invert.setDisabled( disabled );
+               }
+
+               if ( this.associated ) {
+                       this.associated.setDisabled( disabled );
+               }
+       };
+
 }( jQuery, mediaWiki ) );
index 8f48ec3..030fbb0 100644 (file)
                this.title.restorePreInfuseState( state.title );
        };
 
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.ComplexTitleInputWidget.prototype.setDisabled = function ( disabled ) {
+               mw.widgets.ComplexTitleInputWidget.parent.prototype.setDisabled.call( this, disabled );
+               this.namespace.setDisabled( disabled );
+               this.title.setDisabled( disabled );
+       };
+
 }( jQuery, mediaWiki ) );
index f2b6f5f..8c80cb8 100644 (file)
                return mw.ForeignStructuredUpload.BookletLayout.parent.prototype.initialize.call( this ).then(
                        function () {
                                return $.when(
-                                       // Point the CategorySelector to the right wiki
+                                       // Point the CategoryMultiselectWidget to the right wiki
                                        booklet.upload.getApi().then( function ( api ) {
                                                // If this is a ForeignApi, it will have a apiUrl, otherwise we don't need to do anything
                                                if ( api.apiUrl ) {
-                                                       // Can't reuse the same object, CategorySelector calls #abort on its mw.Api instance
+                                                       // Can't reuse the same object, CategoryMultiselectWidget calls #abort on its mw.Api instance
                                                        booklet.categoriesWidget.api = new mw.ForeignApi( api.apiUrl );
                                                }
                                                return $.Deferred().resolve();
                        multiline: true,
                        autosize: true
                } );
-               this.categoriesWidget = new mw.widgets.CategorySelector( {
+               this.categoriesWidget = new mw.widgets.CategoryMultiselectWidget( {
                        // Can't be done here because we don't know the target wiki yet... done in #initialize.
                        // api: new mw.ForeignApi( ... ),
                        $overlay: this.$overlay
index 78634f6..67e2ebb 100644 (file)
                 * This function returns the styleSheet object for convience (due to cross-browsers
                 * difference as to where it is located).
                 *
-                *     var sheet = mw.util.addCSS( '.foobar { display: none; }' );
+                *     var sheet = util.addCSS( '.foobar { display: none; }' );
                 *     $( foo ).click( function () {
                 *         // Toggle the sheet on and off
                 *         sheet.disabled = !sheet.disabled;
                 * (e.g. `document.getElementById( 'foobar' )`) or a jQuery-selector
                 * (e.g. `'#foobar'`) for that item.
                 *
-                *     mw.util.addPortletLink(
+                *     util.addPortletLink(
                 *         'p-tb', 'https://www.mediawiki.org/',
                 *         'mediawiki.org', 't-mworg', 'Go to mediawiki.org', 'm', '#t-print'
                 *     );
                 *
-                *     var node = mw.util.addPortletLink(
+                *     var node = util.addPortletLink(
                 *         'p-tb',
                 *         new mw.Title( 'Special:Example' ).getUrl(),
                 *         'Example'
        }, 'Use mw.notify instead.' );
 
        mw.util = util;
+       module.exports = util;
 
 }( mediaWiki, jQuery ) );
index 8aba831..bafb86a 100644 (file)
@@ -1,42 +1,44 @@
-/* global moment, mw */
+/* global mediaWiki, moment */
 
-// HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
-// wgTranslateNumerals is respected.
-moment.updateLocale( moment.locale(), {
-       preparse: function ( s ) {
-               var i,
-                       table = mw.language.getDigitTransformTable();
-               if ( mw.config.get( 'wgTranslateNumerals' ) ) {
-                       for ( i = 0; i < 10; i++ ) {
-                               if ( table[ i ] !== undefined ) {
-                                       s = s.replace( new RegExp( mw.RegExp.escape( table[ i ] ), 'g' ), i );
+( function ( mw ) {
+       // HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
+       // wgTranslateNumerals is respected.
+       moment.updateLocale( moment.locale(), {
+               preparse: function ( s ) {
+                       var i,
+                               table = mw.language.getDigitTransformTable();
+                       if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+                               for ( i = 0; i < 10; i++ ) {
+                                       if ( table[ i ] !== undefined ) {
+                                               s = s.replace( new RegExp( mw.RegExp.escape( table[ i ] ), 'g' ), i );
+                                       }
                                }
                        }
-               }
-               // HACK: momentjs replaces commas in some languages, which is the only other use of preparse
-               // aside from digit transformation. We can only override preparse, not extend it, so we
-               // have to replicate the comma replacement functionality here.
-               if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
-                       s = s.replace( /،/g, ',' );
-               }
-               return s;
-       },
-       postformat: function ( s ) {
-               var i,
-                       table = mw.language.getDigitTransformTable();
-               if ( mw.config.get( 'wgTranslateNumerals' ) ) {
-                       for ( i = 0; i < 10; i++ ) {
-                               if ( table[ i ] !== undefined ) {
-                                       s = s.replace( new RegExp( i, 'g' ), table[ i ] );
+                       // HACK: momentjs replaces commas in some languages, which is the only other use of preparse
+                       // aside from digit transformation. We can only override preparse, not extend it, so we
+                       // have to replicate the comma replacement functionality here.
+                       if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
+                               s = s.replace( /،/g, ',' );
+                       }
+                       return s;
+               },
+               postformat: function ( s ) {
+                       var i,
+                               table = mw.language.getDigitTransformTable();
+                       if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+                               for ( i = 0; i < 10; i++ ) {
+                                       if ( table[ i ] !== undefined ) {
+                                               s = s.replace( new RegExp( i, 'g' ), table[ i ] );
+                                       }
                                }
                        }
+                       // HACK: momentjs replaces commas in some languages, which is the only other use of postformat
+                       // aside from digit transformation. We can only override postformat, not extend it, so we
+                       // have to replicate the comma replacement functionality here.
+                       if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
+                               s = s.replace( /,/g, '،' );
+                       }
+                       return s;
                }
-               // HACK: momentjs replaces commas in some languages, which is the only other use of postformat
-               // aside from digit transformation. We can only override postformat, not extend it, so we
-               // have to replicate the comma replacement functionality here.
-               if ( [ 'ar', 'ar-sa', 'fa' ].indexOf( mw.config.get( 'wgUserLanguage' ) ) !== -1 ) {
-                       s = s.replace( /,/g, '،' );
-               }
-               return s;
-       }
-} );
+       } );
+}( mediaWiki ) );
index 5ce0b34..784c29c 100644 (file)
@@ -93,7 +93,7 @@ class DbTestPreviewer extends TestRecorder {
                                        $before = 'n';
                                } elseif ( $prevResults[$test] == 1 ) {
                                        $before = 'p';
-                               } else /* if ( $prevResults[$test] == 0 )*/ {
+                               } else /* if ( $prevResults[$test] == 0 ) */ {
                                        $before = 'f';
                                }
 
@@ -101,7 +101,7 @@ class DbTestPreviewer extends TestRecorder {
                                        $after = 'n';
                                } elseif ( $this->results[$test] == 1 ) {
                                        $after = 'p';
-                               } else /*if ( $this->results[$test] == 0 ) */ {
+                               } else /* if ( $this->results[$test] == 0 ) */ {
                                        $after = 'f';
                                }
 
index 04a2a8d..f68f595 100644 (file)
  * @ingroup Testing
  */
 
+use Wikimedia\Rdbms\IMaintainableDatabase;
+
 class DbTestRecorder extends TestRecorder {
        public $version;
+       /** @var Database */
        private $db;
 
-       public function __construct( IDatabase $db ) {
+       public function __construct( IMaintainableDatabase $db ) {
                $this->db = $db;
        }
 
index 35c2480..f100411 100644 (file)
@@ -25,6 +25,7 @@
  * @file
  * @ingroup Testing
  */
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
 
index be6e3a8..935c539 100644 (file)
@@ -8015,10 +8015,10 @@ title=[[Bug462]]
 !! wikitext
 [[Bu&#103;462]] [[Bug462]]
 !! html/php
-<p><strong class="selflink">Bu&#103;462</strong> <strong class="selflink">Bug462</strong>
+<p><a class="mw-selflink selflink">Bu&#103;462</a> <a class="mw-selflink selflink">Bug462</a>
 </p>
 !! html/php+tidy
-<p><strong class="selflink">Bug462</strong> <strong class="selflink">Bug462</strong></p>
+<p><a class="mw-selflink selflink">Bug462</a> <a class="mw-selflink selflink">Bug462</a></p>
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./Bug462" title="Bug462">Bug462</a> <a rel="mw:WikiLink" href="./Bug462" title="Bug462">Bug462</a></p>
 !! end
@@ -8047,7 +8047,7 @@ title=[[0]]
 !! wikitext
 [[0]]
 !! html
-<p><strong class="selflink">0</strong>
+<p><a class="mw-selflink selflink">0</a>
 </p>
 !!end
 
@@ -8503,7 +8503,7 @@ parsoid=wt2html,wt2wt,html2html
 !! wikitext
 [[local:Main Page]]
 !! html/php
-<p><strong class="selflink">local:Main Page</strong>
+<p><a class="mw-selflink selflink">local:Main Page</a>
 </p>
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./Main_Page" title="Main Page">local:Main Page</a></p>
@@ -9962,9 +9962,10 @@ Magic Words LOCAL (UTC)
 Magic Word: {{FULLPAGENAME}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{FULLPAGENAME}}
-!! html
+!! html/*
 <p>User:Ævar Arnfjörð Bjarmason
 </p>
 !! end
@@ -9973,9 +9974,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{FULLPAGENAMEE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{FULLPAGENAMEE}}
-!! html
+!! html/*
 <p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
 </p>
 !! end
@@ -9984,9 +9986,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{TALKSPACE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{TALKSPACE}}
-!! html
+!! html/*
 <p>User talk
 </p>
 !! end
@@ -9995,9 +9998,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{TALKSPACE}}, same namespace
 !! options
 title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{TALKSPACE}}
-!! html
+!! html/*
 <p>User talk
 </p>
 !! end
@@ -10006,9 +10010,10 @@ title=[[User talk:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{TALKSPACE}}, main namespace
 !! options
 title=[[Parser Test]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{TALKSPACE}}
-!! html
+!! html/*
 <p>Talk
 </p>
 !! end
@@ -10017,9 +10022,10 @@ title=[[Parser Test]]
 Magic Word: {{TALKSPACEE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{TALKSPACEE}}
-!! html
+!! html/*
 <p>User_talk
 </p>
 !! end
@@ -10028,9 +10034,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{SUBJECTSPACE}}
 !! options
 title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTSPACE}}
-!! html
+!! html/*
 <p>User
 </p>
 !! end
@@ -10039,9 +10046,10 @@ title=[[User talk:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{SUBJECTSPACE}}, same namespace
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTSPACE}}
-!! html
+!! html/*
 <p>User
 </p>
 !! end
@@ -10050,9 +10058,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{SUBJECTSPACE}}, main namespace
 !! options
 title=[[Parser Test]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTSPACE}}
-!! html
+!! html/*
 
 !! end
 
@@ -10060,9 +10069,10 @@ title=[[Parser Test]]
 Magic Word: {{SUBJECTSPACEE}}
 !! options
 title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTSPACEE}}
-!! html
+!! html/*
 <p>User
 </p>
 !! end
@@ -10071,9 +10081,10 @@ title=[[User talk:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{NAMESPACE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{NAMESPACE}}
-!! html
+!! html/*
 <p>User
 </p>
 !! end
@@ -10082,9 +10093,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{NAMESPACEE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{NAMESPACEE}}
-!! html
+!! html/*
 <p>User
 </p>
 !! end
@@ -10093,9 +10105,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{NAMESPACENUMBER}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{NAMESPACENUMBER}}
-!! html
+!! html/*
 <p>2
 </p>
 !! end
@@ -10104,9 +10117,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{SUBPAGENAME}}
 !! options
 title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBPAGENAME}}
-!! html
+!! html/*
 <p>sub ö
 </p>
 !! end
@@ -10115,9 +10129,10 @@ title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage
 Magic Word: {{SUBPAGENAMEE}}
 !! options
 title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBPAGENAMEE}}
-!! html
+!! html/*
 <p>sub_%C3%B6
 </p>
 !! end
@@ -10126,9 +10141,10 @@ title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage
 Magic Word: {{ROOTPAGENAME}}
 !! options
 title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{ROOTPAGENAME}}
-!! html
+!! html/*
 <p>Ævar Arnfjörð Bjarmason
 </p>
 !! end
@@ -10137,9 +10153,10 @@ title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage
 Magic Word: {{ROOTPAGENAMEE}}
 !! options
 title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{ROOTPAGENAMEE}}
-!! html
+!! html/*
 <p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
 </p>
 !! end
@@ -10148,9 +10165,10 @@ title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage
 Magic Word: {{BASEPAGENAME}}
 !! options
 title=[[Ævar Arnfjörð Bjarmason/sub]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{BASEPAGENAME}}
-!! html
+!! html/*
 <p>Ævar Arnfjörð Bjarmason
 </p>
 !! end
@@ -10159,9 +10177,10 @@ title=[[Ævar Arnfjörð Bjarmason/sub]] subpage
 Magic Word: {{BASEPAGENAMEE}}
 !! options
 title=[[Ævar Arnfjörð Bjarmason/sub]] subpage
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{BASEPAGENAMEE}}
-!! html
+!! html/*
 <p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
 </p>
 !! end
@@ -10170,9 +10189,10 @@ title=[[Ævar Arnfjörð Bjarmason/sub]] subpage
 Magic Word: {{TALKPAGENAME}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{TALKPAGENAME}}
-!! html
+!! html/*
 <p>User talk:Ævar Arnfjörð Bjarmason
 </p>
 !! end
@@ -10181,9 +10201,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{TALKPAGENAMEE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{TALKPAGENAMEE}}
-!! html
+!! html/*
 <p>User_talk:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
 </p>
 !! end
@@ -10192,9 +10213,10 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{SUBJECTPAGENAME}}
 !! options
 title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTPAGENAME}}
-!! html
+!! html/*
 <p>User:Ævar Arnfjörð Bjarmason
 </p>
 !! end
@@ -10203,18 +10225,21 @@ title=[[User talk:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{SUBJECTPAGENAMEE}}
 !! options
 title=[[User talk:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SUBJECTPAGENAMEE}}
-!! html
+!! html/*
 <p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
 </p>
 !! end
 
 !! test
 Magic Word: {{NUMBEROFFILES}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{NUMBEROFFILES}}
-!! html
+!! html/*
 <p>7
 </p>
 !! end
@@ -10223,9 +10248,10 @@ Magic Word: {{NUMBEROFFILES}}
 Magic Word: {{PAGENAME}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{PAGENAME}}
-!! html
+!! html/*
 <p>Ævar Arnfjörð Bjarmason
 </p>
 !! end
@@ -10234,6 +10260,7 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{PAGENAME}} with metacharacters
 !! options
 title=[['foo & bar = baz']]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 ''{{PAGENAME}}''
 !! html/php
@@ -10247,6 +10274,7 @@ title=[['foo & bar = baz']]
 Magic Word: {{PAGENAME}} with metacharacters (T28781)
 !! options
 title=[[*RFC 1234 http://example.com/]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{PAGENAME}}
 !! html/php
@@ -10260,9 +10288,10 @@ title=[[*RFC 1234 http://example.com/]]
 Magic Word: {{PAGENAMEE}}
 !! options
 title=[[User:Ævar Arnfjörð Bjarmason]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{PAGENAMEE}}
-!! html
+!! html/*
 <p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
 </p>
 !! end
@@ -10271,6 +10300,7 @@ title=[[User:Ævar Arnfjörð Bjarmason]]
 Magic Word: {{PAGENAMEE}} with metacharacters (T28781)
 !! options
 title=[[*RFC 1234 http://example.com/]]
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{PAGENAMEE}}
 !! html/php
@@ -10282,53 +10312,65 @@ title=[[*RFC 1234 http://example.com/]]
 
 !! test
 Magic Word: {{REVISIONID}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{REVISIONID}}
-!! html
+!! html/*
 <p>1337
 </p>
 !! end
 
 !! test
 Magic Word: {{SCRIPTPATH}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SCRIPTPATH}}
-!! html
+!! html/*
 
 !! end
 
 !! test
 Magic Word: {{STYLEPATH}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{STYLEPATH}}
-!! html
+!! html/*
 <p>/skins
 </p>
 !! end
 
 !! test
 Magic Word: {{SERVER}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SERVER}}
-!! html
+!! html/*
 <p><a rel="nofollow" class="external free" href="http://example.org">http://example.org</a>
 </p>
 !! end
 
 !! test
 Magic Word: {{SERVERNAME}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SERVERNAME}}
-!! html
+!! html/*
 <p>example.org
 </p>
 !! end
 
 !! test
 Magic Word: {{SITENAME}}
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{SITENAME}}
-!! html
+!! html/*
 <p>MediaWiki
 </p>
 !! end
@@ -10337,18 +10379,21 @@ Magic Word: {{SITENAME}}
 Magic Word: {{PAGELANGUAGE}}
 !! options
 language=fr
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{PAGELANGUAGE}}
-!! html
+!! html/*
 <p>fr
 </p>
 !! end
 
 !! test
 Magic Word: {{PAGELANGUAGE}} on a page with no explicitly set language
+!! options
+parsoid={ "modes": ["wt2html","wt2wt"], "normalizePhp": true }
 !! wikitext
 {{PAGELANGUAGE}}
-!! html
+!! html/*
 <p>en
 </p>
 !! end
@@ -13745,7 +13790,7 @@ Manually-specified thumbnail image
 !! options
 thumbsize=220
 !! wikitext
-[[File:Foobar.jpg|thumb=Thumb.png|Title]]
+[[File:Foobar.jpg|thumbnail=Thumb.png|Title]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
 
@@ -19613,6 +19658,31 @@ File:Test.png
 </gallery>
 !! end
 
+!! test
+Gallery with class attribute
+!! options
+parsoid={
+  "nativeGallery": true
+}
+!! wikitext
+<gallery class="center">
+File:Foobar.jpg
+</gallery>
+!! html/php
+<ul class="gallery mw-gallery-traditional center">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+
+!! html/parsoid
+<ul class="gallery mw-gallery-traditional center" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"class":"center"},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><span style="display: inline-block; height: 100%; vertical-align: middle;"></span><span typeof="mw:Image" style="vertical-align: middle; display: inline-block;"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></span></div><div class="gallerytext"></div></li>
+</ul>
+!! end
+
 !! test
 HTML Hex character encoding (spells the word "JavaScript")
 !! options
@@ -20327,7 +20397,7 @@ title=[[Dunav]] language=sr
 !! wikitext
 Both [[Dunav]] and [[Дунав]] are names for this river.
 !! html
-<p>Both <strong class="selflink">Dunav</strong> and <strong class="selflink">Дунав</strong> are names for this river.
+<p>Both <a class="mw-selflink selflink">Dunav</a> and <a class="mw-selflink selflink">Дунав</a> are names for this river.
 </p>
 !!end
 
@@ -20344,7 +20414,7 @@ title=[[Duna]] language=sr
 !! wikitext
 [[Дуна]] is not a self-link while [[Duna]] and [[Dуна]] are still self-links.
 !! html
-<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <strong class="selflink">Duna</strong> and <strong class="selflink">Dуна</strong> are still self-links.
+<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <a class="mw-selflink selflink">Duna</a> and <a class="mw-selflink selflink">Dуна</a> are still self-links.
 </p>
 !! end
 
@@ -20355,7 +20425,7 @@ title=[[Duna]] language=sr
 !! wikitext
 [[Dуна]] is a self-link while [[Dunа#Foo]] and [[Dуна#Foo]] are not self-links.
 !! html
-<p><strong class="selflink">Dуна</strong> is a self-link while <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dunа#Foo</a> and <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dуна#Foo</a> are not self-links.
+<p><a class="mw-selflink selflink">Dуна</a> is a self-link while <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dunа#Foo</a> and <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dуна#Foo</a> are not self-links.
 </p>
 !! end
 
@@ -21793,7 +21863,7 @@ showindicators
 !! wikitext
 <indicator name=" "></indicator>
 <indicator></indicator>
-!! html
+!! html/php
 <p><span class="error"><strong>Error:</strong> Page status indicators' <code>name</code> attribute must not be empty.</span>
 <span class="error"><strong>Error:</strong> Page status indicators' <code>name</code> attribute must not be empty.</span>
 </p>
@@ -21806,7 +21876,7 @@ showindicators
 !! wikitext
 <indicator name="empty" />
 <indicator name="name"></indicator>
-!! html
+!! html/php
 empty=
 name=
 <p><br />
@@ -21833,7 +21903,7 @@ showindicators
 <indicator name="10">Two
 
 paragraphs</indicator>
-!! html
+!! html/php
 01=hello world
 02=<a href="/wiki/Main_Page" title="Main Page">Main Page</a>
 03=<img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/25px-Foobar.jpg" width="25" height="3" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/38px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg 2x" />
@@ -22746,14 +22816,12 @@ parsoid={
 ## recognized as an extension tag w/o a native handler.
 !! test
 LST Sections: Newfangled approach
-!! options
-parsoid={ "suppressErrors": true }
 !! wikitext
 <section begin="2011-05-16" />
 <section end="2014-04-10 (MW 1.23wmf22)" />
 !! html/parsoid
-<p><span typeof="mw:Extension/section" about="#mwt1" data-parsoid='{"stx":"html","selfClose":true,"src":"&lt;section begin=\"2011-05-16\" />","tagWidths":[30,0]}'>&lt;section begin="2011-05-16" /></span>
-<span typeof="mw:Extension/section" about="#mwt2" data-parsoid='{"stx":"html","selfClose":true,"src":"&lt;section end=\"2014-04-10 (MW 1.23wmf22)\" />","tagWidths":[43,0]}'>&lt;section end="2014-04-10 (MW 1.23wmf22)" /></span></p>
+<p><span typeof="mw:Error mw:Extension/section" about="#mwt1" data-mw='{"name":"section","attrs":{"begin":"2011-05-16"},"body":null,"errors":[{"key":"mw-api-extexpand-error","message":"Could not expand extension source."}]}'>&lt;section begin="2011-05-16" /></span>
+<span typeof="mw:Error mw:Extension/section" about="#mwt2" data-mw='{"name":"section","attrs":{"end":"2014-04-10 (MW 1.23wmf22)"},"body":null,"errors":[{"key":"mw-api-extexpand-error","message":"Could not expand extension source."}]}'>&lt;section end="2014-04-10 (MW 1.23wmf22)" /></span></p>
 !! end
 
 #--------- Test stripping of empty nodes in template content ----------
@@ -23780,7 +23848,8 @@ Links 4. ExtLinks: Escapes needed
 parsoid=html2wt
 !! html/parsoid
 <p><a rel="mw:ExtLink" href="http://google.com">[google]</a>
-<a rel="mw:ExtLink" href="http://google.com">google]</a></p>
+<a rel="mw:ExtLink" href="http://google.com">google]</a>
+<a rel="mw:ExtLink" href="http://google.com">goog] le</a></p>
 <p>[http://google.com]</p>
 <p>[http://google.com google]</p>
 <p>[<a rel="mw:ExtLink" href="http://google.com">http://google.com</a>]</p>
@@ -23788,6 +23857,7 @@ parsoid=html2wt
 !! wikitext
 [http://google.com <nowiki>[google]</nowiki>]
 [http://google.com <nowiki>google]</nowiki>]
+[http://google.com <nowiki>goog] le</nowiki>]
 
 <nowiki>[http://google.com]</nowiki>
 
@@ -23799,6 +23869,7 @@ parsoid=html2wt
 !! html/php
 <p><a rel="nofollow" class="external text" href="http://google.com">[google]</a>
 <a rel="nofollow" class="external text" href="http://google.com">google]</a>
+<a rel="nofollow" class="external text" href="http://google.com">goog] le</a>
 </p><p>[http://google.com]
 </p><p>[http://google.com google]
 </p><p>[<a rel="nofollow" class="external free" href="http://google.com">http://google.com</a>]
@@ -24142,7 +24213,7 @@ parsoid=html2wt
 !! test
 4. No escaping needed
 !! options
-options=html2wt
+parsoid=html2wt
 !! html/parsoid
 <p>'<span><i>bar</i></span>'
 '<span><b>bar</b></span>'
@@ -24279,7 +24350,7 @@ parsoid=html2wt
 !! test
 4. Leading whitespace in indent-pre suppressing contexts should not be escaped
 !! options
-options=html2wt
+parsoid=html2wt
 !! html/parsoid
  <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
 !! wikitext
@@ -26633,6 +26704,20 @@ parsoid= {
 # Tests spec'ing wikitext serialization norms |
 # --------------------------------------------
 
+!! test
+Serialize multi-line indent-pre starting with wikitext syntax
+!! options
+parsoid=html2wt
+!! html/parsoid
+<pre>* 1
+** 2
+* 3</pre>
+!! wikitext
+ * 1
+ ** 2
+ * 3
+!! end
+
 !! test
 1. Categories should always be serialized on their own line
 !! options
index f57db11..f7be801 100644 (file)
@@ -1083,10 +1083,6 @@ class AuthManagerTest extends \MediaWikiTestCase {
        }
 
        public function provideAuthentication() {
-               $user = \User::newFromName( 'UTSysop' );
-               $id = $user->getId();
-               $name = $user->getName();
-
                $rememberReq = new RememberMeAuthenticationRequest;
                $rememberReq->action = AuthManager::ACTION_LOGIN;
 
@@ -1108,6 +1104,8 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $restartResponse2->createRequest->action = AuthManager::ACTION_LOGIN;
                $restartResponse2->neededRequests = [ $rememberReq, $restartResponse2->createRequest ];
 
+               $userName = 'UTSysop';
+
                return [
                        'Failure in pre-auth' => [
                                StatusValue::newFatal( 'fail-from-pre' ),
@@ -1202,7 +1200,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                        'Secondary fail' => [
                                StatusValue::newGood(),
                                [
-                                       AuthenticationResponse::newPass( $name ),
+                                       AuthenticationResponse::newPass( $userName ),
                                ],
                                $tmp = [
                                        AuthenticationResponse::newFail( $this->message( 'fail-in-secondary' ) ),
@@ -1212,7 +1210,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                        'Secondary UI, then abstain' => [
                                StatusValue::newGood(),
                                [
-                                       AuthenticationResponse::newPass( $name ),
+                                       AuthenticationResponse::newPass( $userName ),
                                ],
                                [
                                        $tmp = AuthenticationResponse::newUI( [ $req ], $this->message( '...' ) ),
@@ -1220,19 +1218,19 @@ class AuthManagerTest extends \MediaWikiTestCase {
                                ],
                                [
                                        $tmp,
-                                       AuthenticationResponse::newPass( $name ),
+                                       AuthenticationResponse::newPass( $userName ),
                                ]
                        ],
                        'Secondary pass' => [
                                StatusValue::newGood(),
                                [
-                                       AuthenticationResponse::newPass( $name ),
+                                       AuthenticationResponse::newPass( $userName ),
                                ],
                                [
                                        AuthenticationResponse::newPass()
                                ],
                                [
-                                       AuthenticationResponse::newPass( $name ),
+                                       AuthenticationResponse::newPass( $userName ),
                                ]
                        ],
                ];
index 606a209..45791e2 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * @group Database
  * @group Database
index 036baa8..3693a27 100644 (file)
@@ -66,6 +66,13 @@ class HttpTest extends MediaWikiTestCase {
         * @covers Http::getProxy
         */
        public function testGetProxy() {
+               $this->setMwGlobals( 'wgHTTPProxy', false );
+               $this->assertEquals(
+                       '',
+                       Http::getProxy(),
+                       'default setting'
+               );
+
                $this->setMwGlobals( 'wgHTTPProxy', 'proxy.domain.tld' );
                $this->assertEquals(
                        'proxy.domain.tld',
@@ -140,50 +147,56 @@ class HttpTest extends MediaWikiTestCase {
                ];
        }
 
+       public static function provideRelativeRedirects() {
+               return [
+                       [
+                               'location' => [ 'http://newsite/file.ext', '/newfile.ext' ],
+                               'final' => 'http://newsite/newfile.ext',
+                               'Relative file path Location: interpreted as full URL'
+                       ],
+                       [
+                               'location' => [ 'https://oldsite/file.ext' ],
+                               'final' => 'https://oldsite/file.ext',
+                               'Location to the HTTPS version of the site'
+                       ],
+                       [
+                               'location' => [
+                                       '/anotherfile.ext',
+                                       'http://anotherfile/hoster.ext',
+                                       'https://anotherfile/hoster.ext'
+                               ],
+                               'final' => 'https://anotherfile/hoster.ext',
+                               'Relative file path Location: should keep the latest host and scheme!'
+                       ],
+                       [
+                               'location' => [ '/anotherfile.ext' ],
+                               'final' => 'http://oldsite/anotherfile.ext',
+                               'Relative Location without domain '
+                       ],
+                       [
+                               'location' => null,
+                               'final' => 'http://oldsite/file.ext',
+                               'No Location (no redirect) '
+                       ],
+               ];
+       }
+
        /**
         * Warning:
         *
         * These tests are for code that makes use of an artifact of how CURL
         * handles header reporting on redirect pages, and will need to be
-        * rewritten when T31232 is taken care of (high-level handling of
-        * HTTP redirects).
+        * rewritten when T31232 is taken care of (high-level handling of HTTP redirects).
+        *
+        * @dataProvider provideRelativeRedirects
+        * @covers MWHttpRequest::getFinalUrl
         */
-       public function testRelativeRedirections() {
+       public function testRelativeRedirections( $location, $final, $message = null ) {
                $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext', [], __METHOD__ );
-
-               # Forge a Location header
-               $h->setRespHeaders( 'location', [
-                               'http://newsite/file.ext',
-                               '/newfile.ext',
-                       ]
-               );
-               # Verify we correctly fix the Location
-               $this->assertEquals(
-                       'http://newsite/newfile.ext',
-                       $h->getFinalUrl(),
-                       "Relative file path Location: interpreted as full URL"
-               );
-
-               $h->setRespHeaders( 'location', [
-                               'https://oldsite/file.ext'
-                       ]
-               );
-               $this->assertEquals(
-                       'https://oldsite/file.ext',
-                       $h->getFinalUrl(),
-                       "Location to the HTTPS version of the site"
-               );
-
-               $h->setRespHeaders( 'location', [
-                               '/anotherfile.ext',
-                               'http://anotherfile/hoster.ext',
-                               'https://anotherfile/hoster.ext'
-                       ]
-               );
-               $this->assertEquals(
-                       'https://anotherfile/hoster.ext',
-                       $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
-               );
+               // Forge a Location header
+               $h->setRespHeaders( 'location', $location );
+               // Verify it correctly fixes the Location
+               $this->assertEquals( $final, $h->getFinalUrl(), $message );
        }
 
        /**
@@ -201,8 +214,6 @@ class HttpTest extends MediaWikiTestCase {
         * Extension API: 20140829
         *
         * Commented out constants that were removed in PHP 5.6.0
-        *
-        * @covers CurlHttpRequest::execute
         */
        public function provideCurlConstants() {
                return [
@@ -481,9 +492,8 @@ class HttpTest extends MediaWikiTestCase {
 
        /**
         * Added this test based on an issue experienced with HHVM 3.3.0-dev
-        * where it did not define a cURL constant.
+        * where it did not define a cURL constant. T72570
         *
-        * T72570
         * @dataProvider provideCurlConstants
         */
        public function testCurlConstants( $value ) {
index 4048ffe..5cab8e2 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 class ResourceLoaderWikiModuleTest extends ResourceLoaderTestCase {
 
index 067d159..d711bac 100644 (file)
@@ -40,39 +40,39 @@ class NaiveImportTitleFactoryTest extends MediaWikiTestCase {
                return [
                        [
                                new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
-                               Title::newFromText( 'MainNamespaceArticle' )
+                               'MainNamespaceArticle'
                        ],
                        [
                                new ForeignTitle( null, '', 'MainNamespaceArticle' ),
-                               Title::newFromText( 'MainNamespaceArticle' )
+                               'MainNamespaceArticle'
                        ],
                        [
                                new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
-                               Title::newFromText( 'Talk:Nice_talk' )
+                               'Talk:Nice_talk'
                        ],
                        [
                                new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
-                               Title::newFromText( 'Bogus:Nice_talk' )
+                               'Bogus:Nice_talk'
                        ],
                        [
                                new ForeignTitle( 100, 'Bogus', 'Nice_talk' ),
-                               Title::newFromText( 'Bogus:Nice_talk' ) // not Portal:Nice_talk
+                               'Bogus:Nice_talk' // not Portal:Nice_talk
                        ],
                        [
                                new ForeignTitle( 1, 'Bogus', 'Nice_talk' ),
-                               Title::newFromText( 'Talk:Nice_talk' ) // not Bogus:Nice_talk
+                               'Talk:Nice_talk' // not Bogus:Nice_talk
                        ],
                        [
                                new ForeignTitle( 100, 'Portal', 'Nice_talk' ),
-                               Title::newFromText( 'Portal:Nice_talk' )
+                               'Portal:Nice_talk'
                        ],
                        [
                                new ForeignTitle( 724, 'Portal', 'Nice_talk' ),
-                               Title::newFromText( 'Portal:Nice_talk' )
+                               'Portal:Nice_talk'
                        ],
                        [
                                new ForeignTitle( 2, 'Portal', 'Nice_talk' ),
-                               Title::newFromText( 'User:Nice_talk' )
+                               'User:Nice_talk'
                        ],
                ];
        }
@@ -80,9 +80,10 @@ class NaiveImportTitleFactoryTest extends MediaWikiTestCase {
        /**
         * @dataProvider basicProvider
         */
-       public function testBasic( ForeignTitle $foreignTitle, Title $title ) {
+       public function testBasic( ForeignTitle $foreignTitle, $titleText ) {
                $factory = new NaiveImportTitleFactory();
                $testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+               $title = Title::newFromText( $titleText );
 
                $this->assertTrue( $title->equals( $testTitle ) );
        }
index 01c47fd..9b6ac93 100644 (file)
@@ -40,27 +40,27 @@ class NamespaceImportTitleFactoryTest extends MediaWikiTestCase {
                        [
                                new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
                                0,
-                               Title::newFromText( 'MainNamespaceArticle' )
+                               'MainNamespaceArticle'
                        ],
                        [
                                new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
                                2,
-                               Title::newFromText( 'User:MainNamespaceArticle' )
+                               'User:MainNamespaceArticle'
                        ],
                        [
                                new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
                                0,
-                               Title::newFromText( 'Nice_talk' )
+                               'Nice_talk'
                        ],
                        [
                                new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
                                0,
-                               Title::newFromText( 'Bogus:Nice_talk' )
+                               'Bogus:Nice_talk'
                        ],
                        [
                                new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
                                2,
-                               Title::newFromText( 'User:Bogus:Nice_talk' )
+                               'User:Bogus:Nice_talk'
                        ],
                ];
        }
@@ -68,9 +68,10 @@ class NamespaceImportTitleFactoryTest extends MediaWikiTestCase {
        /**
         * @dataProvider basicProvider
         */
-       public function testBasic( ForeignTitle $foreignTitle, $ns, Title $title ) {
+       public function testBasic( ForeignTitle $foreignTitle, $ns, $titleText ) {
                $factory = new NamespaceImportTitleFactory( $ns );
                $testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+               $title = Title::newFromText( $titleText );
 
                $this->assertTrue( $title->equals( $testTitle ) );
        }
index 01665e5..0e88740 100644 (file)
@@ -1,5 +1,5 @@
 ( function ( mw, $ ) {
-       var
+       var util = require( 'mediawiki.util' ),
                // Based on IPTest.php > testisIPv4
                IPV4_CASES = [
                        [ false, false, 'Boolean false is not an IP' ],
@@ -89,7 +89,7 @@
        } ) );
 
        QUnit.test( 'rawurlencode', function ( assert ) {
-               assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
+               assert.equal( util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
        } );
 
        QUnit.test( 'escapeId', function ( assert ) {
                        'Test:A & B/Here': 'Test:A_.26_B.2FHere',
                        'A&B&amp;C&amp;amp;D&amp;amp;amp;E': 'A.26B.26amp.3BC.26amp.3Bamp.3BD.26amp.3Bamp.3Bamp.3BE'
                }, function ( input, output ) {
-                       assert.equal( mw.util.escapeId( input ), output );
+                       assert.equal( util.escapeId( input ), output );
                } );
        } );
 
        QUnit.test( 'wikiUrlencode', function ( assert ) {
-               assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
+               assert.equal( util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
                // See also wfUrlencodeTest.php#provideURLS
                $.each( {
                        '+': '%2B',
                        '<>': '%3C%3E',
                        '\'': '%27'
                }, function ( input, output ) {
-                       assert.equal( mw.util.wikiUrlencode( input ), output );
+                       assert.equal( util.wikiUrlencode( input ), output );
                } );
        } );
 
                        wgPageName: 'Foobar'
                } );
 
-               href = mw.util.getUrl( 'Sandbox' );
+               href = util.getUrl( 'Sandbox' );
                assert.equal( href, '/wiki/Sandbox', 'simple title' );
 
-               href = mw.util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
+               href = util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
                assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'complex title' );
 
                // T149767
-               href = mw.util.getUrl( 'My$$test$$$$$title' );
+               href = util.getUrl( 'My$$test$$$$$title' );
                assert.equal( href, '/wiki/My$$test$$$$$title', 'title with multiple consecutive dollar signs' );
 
-               href = mw.util.getUrl();
+               href = util.getUrl();
                assert.equal( href, '/wiki/Foobar', 'default title' );
 
-               href = mw.util.getUrl( null, { action: 'edit' } );
+               href = util.getUrl( null, { action: 'edit' } );
                assert.equal( href, '/w/index.php?title=Foobar&action=edit', 'default title with query string' );
 
-               href = mw.util.getUrl( 'Sandbox', { action: 'edit' } );
+               href = util.getUrl( 'Sandbox', { action: 'edit' } );
                assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'simple title with query string' );
 
                // Test fragments
-               href = mw.util.getUrl( 'Foo:Sandbox#Fragment', { action: 'edit' } );
+               href = util.getUrl( 'Foo:Sandbox#Fragment', { action: 'edit' } );
                assert.equal( href, '/w/index.php?title=Foo:Sandbox&action=edit#Fragment', 'namespaced title with query string and fragment' );
 
-               href = mw.util.getUrl( 'Sandbox#', { action: 'edit' } );
+               href = util.getUrl( 'Sandbox#', { action: 'edit' } );
                assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'title with query string and empty fragment' );
 
-               href = mw.util.getUrl( 'Sandbox', {} );
+               href = util.getUrl( 'Sandbox', {} );
                assert.equal( href, '/wiki/Sandbox', 'title with empty query string' );
 
-               href = mw.util.getUrl( '#Fragment' );
+               href = util.getUrl( '#Fragment' );
                assert.equal( href, '/wiki/#Fragment', 'empty title with fragment' );
 
-               href = mw.util.getUrl( '#Fragment', { action: 'edit' } );
+               href = util.getUrl( '#Fragment', { action: 'edit' } );
                assert.equal( href, '/w/index.php?action=edit#Fragment', 'epmty title with query string and fragment' );
 
-               href = mw.util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
+               href = util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
                assert.equal( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_.C3.84', 'title with query string, fragment, and special characters' );
 
-               href = mw.util.getUrl( 'Foo:%23#Fragment', { action: 'edit' } );
+               href = util.getUrl( 'Foo:%23#Fragment', { action: 'edit' } );
                assert.equal( href, '/w/index.php?title=Foo:%2523&action=edit#Fragment', 'title containing %23 (#), fragment, and a query string' );
 
-               href = mw.util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
+               href = util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
                assert.equal( href, '/w/index.php?action=edit#.2B.26.3D:.3B.40.24-_..21.2A.2F.5B.5D.3C.3E.27.C2.A7', 'fragment with various characters' );
        } );
 
                        wgScriptPath: '/w'
                } );
 
-               assert.equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ),
+               assert.equal( util.wikiScript(), mw.config.get( 'wgScript' ),
                        'wikiScript() returns wgScript'
                );
-               assert.equal( mw.util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
+               assert.equal( util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
                        'wikiScript( index ) returns wgScript'
                );
-               assert.equal( mw.util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
+               assert.equal( util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
                        'wikiScript( load ) returns wgLoadScript'
                );
-               assert.equal( mw.util.wikiScript( 'api' ), '/w/api.php', 'API path' );
+               assert.equal( util.wikiScript( 'api' ), '/w/api.php', 'API path' );
        } );
 
        QUnit.test( 'addCSS', function ( assert ) {
                var $el, style;
                $el = $( '<div>' ).attr( 'id', 'mw-addcsstest' ).appendTo( '#qunit-fixture' );
 
-               style = mw.util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
+               style = util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
                assert.equal( typeof style, 'object', 'addCSS returned an object' );
                assert.strictEqual( style.disabled, false, 'property "disabled" is available and set to false' );
 
                var url;
 
                url = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
-               assert.equal( mw.util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
-               assert.strictEqual( mw.util.getParamValue( 'bar', url ), null, 'Return null when not found' );
+               assert.equal( util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
+               assert.strictEqual( util.getParamValue( 'bar', url ), null, 'Return null when not found' );
 
                url = 'http://example.org/#&foo=bad';
-               assert.strictEqual( mw.util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (T29427)' );
+               assert.strictEqual( util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (T29427)' );
 
                url = 'example.org?' + $.param( { TEST: 'a b+c' } );
-               assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c', 'T32441: getParamValue must understand "+" encoding of space' );
+               assert.strictEqual( util.getParamValue( 'TEST', url ), 'a b+c', 'T32441: getParamValue must understand "+" encoding of space' );
 
                url = 'example.org?' + $.param( { TEST: 'a b+c d' } ); // check for sloppy code from r95332 :)
-               assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c d', 'T32441: getParamValue must understand "+" encoding of space (multiple spaces)' );
+               assert.strictEqual( util.getParamValue( 'TEST', url ), 'a b+c d', 'T32441: getParamValue must understand "+" encoding of space (multiple spaces)' );
        } );
 
        QUnit.test( '$content', function ( assert ) {
-               assert.ok( mw.util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
-               assert.strictEqual( mw.util.$content.length, 1, 'mw.util.$content must have length of 1' );
+               assert.ok( util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
+               assert.strictEqual( util.$content.length, 1, 'mw.util.$content must have length of 1' );
        } );
 
        /**
 
                $( '#qunit-fixture' ).append( pTestTb, pCustom, vectorTabs );
 
-               tbRL = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
+               tbRL = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/ResourceLoader',
                        'ResourceLoader', 't-rl', 'More info about ResourceLoader on MediaWiki.org ', 'l'
                );
 
                assert.ok( tbRL && tbRL.nodeType, 'addPortletLink returns a DOM Node' );
 
-               tbMW = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/',
+               tbMW = util.addPortletLink( 'p-test-tb', '//mediawiki.org/',
                        'MediaWiki.org', 't-mworg', 'Go to MediaWiki.org', 'm', tbRL );
                $tbMW = $( tbMW );
 
                assert.equal( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
                assert.strictEqual( $tbMW.next()[ 0 ], tbRL, 'Link is in the correct position (nextnode as Node object)' );
 
-               cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' );
+               cuQuux = util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' );
                $cuQuux = $( cuQuux );
 
                assert.equal( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [test-q]', 'Existing accesskey is stripped and updated' );
                        'addPortletLink did not add the item to all <ul> elements in the portlet (T37082)'
                );
 
-               tbRLDM = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+               tbRLDM = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
                        'Default modules', 't-rldm', 'List of all default modules ', 'd', '#t-rl' );
 
                assert.strictEqual( $( tbRLDM ).next()[ 0 ], tbRL, 'Link is in the correct position (CSS selector as nextnode)' );
 
-               caFoo = mw.util.addPortletLink( 'p-test-views', '#', 'Foo' );
+               caFoo = util.addPortletLink( 'p-test-views', '#', 'Foo' );
 
                assert.strictEqual( $tbMW.find( 'span' ).length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
                assert.strictEqual( $( caFoo ).find( 'span' ).length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
 
-               addedAfter = mw.util.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL ) );
+               addedAfter = util.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL ) );
                assert.strictEqual( $( addedAfter ).next()[ 0 ], tbRL, 'Link is in the correct position (jQuery object as nextnode)' );
 
                // test case - nonexistent id as next node
-               tbRLDMnonexistentid = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+               tbRLDMnonexistentid = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
                        'Default modules', 't-rldm-nonexistent', 'List of all default modules ', 'd', '#t-rl-nonexistent' );
 
                assert.equal( tbRLDMnonexistentid, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode non-matching CSS selector)' );
 
                // test case - empty jquery object as next node
-               tbRLDMemptyjquery = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+               tbRLDMemptyjquery = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
                        'Default modules', 't-rldm-empty-jquery', 'List of all default modules ', 'd', $( '#t-rl-nonexistent' ) );
 
                assert.equal( tbRLDMemptyjquery, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode as empty jQuery object)' );
        } );
 
        QUnit.test( 'validateEmail', function ( assert ) {
-               assert.strictEqual( mw.util.validateEmail( '' ), null, 'Should return null for empty string ' );
-               assert.strictEqual( mw.util.validateEmail( 'user@localhost' ), true, 'Return true for a valid e-mail address' );
+               assert.strictEqual( util.validateEmail( '' ), null, 'Should return null for empty string ' );
+               assert.strictEqual( util.validateEmail( 'user@localhost' ), true, 'Return true for a valid e-mail address' );
 
                // testEmailWithCommasAreInvalids
-               assert.strictEqual( mw.util.validateEmail( 'user,foo@example.org' ), false, 'Emails with commas are invalid' );
-               assert.strictEqual( mw.util.validateEmail( 'userfoo@ex,ample.org' ), false, 'Emails with commas are invalid' );
+               assert.strictEqual( util.validateEmail( 'user,foo@example.org' ), false, 'Emails with commas are invalid' );
+               assert.strictEqual( util.validateEmail( 'userfoo@ex,ample.org' ), false, 'Emails with commas are invalid' );
 
                // testEmailWithHyphens
-               assert.strictEqual( mw.util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
-               assert.strictEqual( mw.util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
+               assert.strictEqual( util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
+               assert.strictEqual( util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
        } );
 
        QUnit.test( 'isIPv6Address', function ( assert ) {
                $.each( IPV6_CASES, function ( i, ipCase ) {
-                       assert.strictEqual( mw.util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+                       assert.strictEqual( util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
                } );
        } );
 
        QUnit.test( 'isIPv4Address', function ( assert ) {
                $.each( IPV4_CASES, function ( i, ipCase ) {
-                       assert.strictEqual( mw.util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+                       assert.strictEqual( util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
                } );
        } );
 
        QUnit.test( 'isIPAddress', function ( assert ) {
                $.each( IPV4_CASES, function ( i, ipCase ) {
-                       assert.strictEqual( mw.util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+                       assert.strictEqual( util.isIPv4Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
                } );
 
                $.each( IPV6_CASES, function ( i, ipCase ) {
-                       assert.strictEqual( mw.util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
+                       assert.strictEqual( util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
                } );
        } );
 }( mediaWiki, jQuery ) );
index 4491c8e..6049eb2 100644 (file)
@@ -1,5 +1,5 @@
-/* eslint no-undef: "error"*/
-/* eslint-env node*/
+/* eslint no-undef: "error" */
+/* eslint-env node */
 'use strict';
 var merge = require( 'deepmerge' ),
        wdioConf = require( './wdio.conf.js' );
index b5dc61a..f132899 100644 (file)
@@ -1,7 +1,7 @@
 /* eslint comma-dangle: 0 */
-/* eslint no-undef: "error"*/
+/* eslint no-undef: "error" */
 /* eslint no-console: 0 */
-/* eslint-env node*/
+/* eslint-env node */
 'use strict';
 
 const path = require( 'path' );