"module": false,
"mw": false,
"$": false,
- "mediaWiki": false,
- "jQuery": false,
"OO": false
},
"rules": {
<ruleset name="MediaWiki">
<rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki">
<exclude name="Generic.ControlStructures.InlineControlStructure" />
- <exclude name="MediaWiki.Commenting.FunctionAnnotations.UnrecognizedAnnotation" />
<exclude name="MediaWiki.Commenting.FunctionComment.MissingDocumentationProtected" />
<exclude name="MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic" />
<exclude name="MediaWiki.Commenting.FunctionComment.MissingParamTag" />
<exclude name="MediaWiki.Commenting.FunctionComment.MissingReturn" />
<exclude name="MediaWiki.Commenting.FunctionComment.ExtraParamComment" />
<exclude name="MediaWiki.Commenting.FunctionComment.WrongStyle" />
- <exclude name="MediaWiki.Commenting.PhpunitAnnotations.NotClassTrait" />
<exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentStart" />
<exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentEnd" />
<exclude name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures" />
'help', 'help-message', 'help-messages' instead.
* (T197179) HTMLFormField::getNotices() is now deprecated.
* The jquery.localize module is now deprecated. Use jquery.i18n instead.
+* The SecondaryDataUpdates hook was deprecated in favor of RevisionDataUpdates,
+ or overriding ContentHandler::getSecondaryDataUpdates (T194038).
+* The WikiPageDeletionUpdates hook was deprecated in favor of
+ PageDeletionDataUpdates, or overriding ContentHandler::getDeletionDataUpdates
+ (T194038).
+* Content::getSecondaryDataUpdates has been deprecated in favor of
+ ContentHandler::getSecondaryDataUpdates() for overriding by extensions
+ (T194038).
+ Application logic should call WikiPage::doSecondaryDataUpdates() (T194037).
+* Content::getDeletionUpdates has been deprecated in favor of
+ ContentHandler::getDeletionUpdates() for overriding by extensions (T194038).
+ Application logic should call WikiPage::doSecondaryDataUpdates() (T194037).
=== Other changes in 1.32 ===
* (T198811) The following tables have had their UNIQUE indexes turned into
'MediaWiki\\ProcOpenError' => __DIR__ . '/includes/exception/ProcOpenError.php',
'MediaWiki\\Revision\\RenderedRevision' => __DIR__ . '/includes/Revision/RenderedRevision.php',
'MediaWiki\\Revision\\RevisionRenderer' => __DIR__ . '/includes/Revision/RevisionRenderer.php',
+ 'MediaWiki\\Revision\\SlotRenderingProvider' => __DIR__ . '/includes/Revision/SlotRenderingProvider.php',
'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
"jakub-onderka/php-parallel-lint": "0.9.2",
"jetbrains/phpstorm-stubs": "dev-master#38ff1a581b297f7901e961b8c923862ea80c3b96",
"justinrainbow/json-schema": "~5.2",
- "mediawiki/mediawiki-codesniffer": "21.0.0",
+ "mediawiki/mediawiki-codesniffer": "22.0.0",
"monolog/monolog": "~1.22.1",
"nikic/php-parser": "3.1.3",
"seld/jsonlint": "1.7.1",
(Used to be called $baseRevId.)
$undidRevId: the rev ID (or 0) this edit undid
+'PageDeletionDataUpdates': Called when constructing a list of DeferrableUpdate to be
+executed when a page is deleted.
+$title The Title of the page being deleted.
+$revision A RevisionRecord representing the page's current revision at the time of deletion.
+&$updates A list of DeferrableUpdate that can be manipulated by the hook handler.
+
'PageHistoryBeforeList': When a history page list is about to be constructed.
&$article: the article that the history is loading for
$context: RequestContext object
added to any module.
&$ResourceLoader: object
+'RevisionDataUpdates': Called when constructing a list of DeferrableUpdate to be
+executed to record secondary data about a revision.
+$title The Title of the page the revision belongs to
+$renderedRevision a RenderedRevision object representing the new revision and providing access
+ to the RevisionRecord as well as ParserOutput of that revision.
+&$updates A list of DeferrableUpdate that can be manipulated by the hook handler.
+
'RevisionRecordInserted': Called after a revision is inserted into the database.
$revisionRecord: the RevisionRecord that has just been inserted.
Note that lists should be in the format name => object and the names in both
lists should be distinct.
-'SecondaryDataUpdates': Allows modification of the list of DataUpdates to
-perform when page content is modified. Currently called by
-AbstractContent::getSecondaryDataUpdates.
+'SecondaryDataUpdates': DEPRECATED! Use RevisionDataUpdates or override
+ContentHandler::getSecondaryDataUpdates instead.
+Allows modification of the list of DataUpdates to perform when page content is modified.
$title: Title of the page that is being edited.
$oldContent: Content object representing the page's content before the edit.
$recursive: bool indicating whether DataUpdates should trigger recursive
&$opts: Options to use for the query
&$join: Join conditions
-'WikiPageDeletionUpdates': manipulate the list of DeferrableUpdates to be
-applied when a page is deleted. Called in WikiPage::getDeletionUpdates(). Note
-that updates specific to a content model should be provided by the respective
-Content's getDeletionUpdates() method.
+'WikiPageDeletionUpdates': DEPRECATED! Use PageDeletionDataUpdates or
+override ContentHandler::getDeletionDataUpdates instead.
+Manipulates the list of DeferrableUpdates to be applied when a page is deleted.
$page: the WikiPage
$content: the Content to generate updates for, or null in case the page revision
could not be loaded. The delete will succeed despite this.
'MediaWiki\\Auth\\' => __DIR__ . '/auth/',
'MediaWiki\\Edit\\' => __DIR__ . '/edit/',
'MediaWiki\\EditPage\\' => __DIR__ . '/editpage/',
- 'MediaWiki\\Linker\\' => __DIR__ .'/linker/',
- 'MediaWiki\\Preferences\\' => __DIR__ .'/preferences/',
- 'MediaWiki\\Services\\' => __DIR__ .'/services/',
- 'MediaWiki\\Session\\' => __DIR__ .'/session/',
- 'MediaWiki\\Shell\\' => __DIR__ .'/shell/',
- 'MediaWiki\\Sparql\\' => __DIR__ .'/sparql/',
- 'MediaWiki\\Storage\\' => __DIR__ .'/Storage/',
- 'MediaWiki\\Tidy\\' => __DIR__ .'/tidy/',
+ 'MediaWiki\\Linker\\' => __DIR__ . '/linker/',
+ 'MediaWiki\\Preferences\\' => __DIR__ . '/preferences/',
+ 'MediaWiki\\Services\\' => __DIR__ . '/services/',
+ 'MediaWiki\\Session\\' => __DIR__ . '/session/',
+ 'MediaWiki\\Shell\\' => __DIR__ . '/shell/',
+ 'MediaWiki\\Sparql\\' => __DIR__ . '/sparql/',
+ 'MediaWiki\\Storage\\' => __DIR__ . '/Storage/',
+ 'MediaWiki\\Tidy\\' => __DIR__ . '/tidy/',
];
}
}
// is if an extension hook aborted from inside ArticleSave.
// Render the status object into $this->hookError
// FIXME this sucks, we should just use the Status object throughout
- $this->hookError = '<div class="error">' ."\n" . $status->getWikiText() .
+ $this->hookError = '<div class="error">' . "\n" . $status->getWikiText() .
'</div>';
return true;
}
*
* @since 1.32
*/
-class RenderedRevision {
+class RenderedRevision implements SlotRenderingProvider {
/**
* @var Title
--- /dev/null
+<?php
+/**
+ * Created by PhpStorm.
+ * User: daki
+ * Date: 05.09.18
+ * Time: 16:08
+ */
+namespace MediaWiki\Revision;
+
+use MediaWiki\Storage\SuppressedDataException;
+use ParserOutput;
+
+/**
+ * A lazy provider of ParserOutput objects for a revision's individual slots.
+ *
+ * @since 1.32
+ */
+interface SlotRenderingProvider {
+
+ /**
+ * @param string $role
+ * @param array $hints Hints given as an associative array. Known keys:
+ * - 'generate-html' => bool: Whether the caller is interested in output HTML (as opposed
+ * to just meta-data). Default is to generate HTML.
+ *
+ * @throws SuppressedDataException if the content is not accessible for the audience
+ * specified in the constructor.
+ * @return ParserOutput
+ */
+ public function getSlotParserOutput( $role, array $hints = [] );
+
+}
use Content;
use ContentHandler;
use DataUpdate;
+use DeferrableUpdate;
use DeferredUpdates;
use Hooks;
use IDBAccessObject;
use InvalidArgumentException;
use JobQueueGroup;
use Language;
+use LinksDeletionUpdate;
use LinksUpdate;
use LogicException;
use MediaWiki\Edit\PreparedEdit;
*
* Contains the following fields:
* - oldRevision (RevisionRecord|null): the revision that was current before the change
- * associated with this update. Might not be set, use getOldRevision() instead of direct
- * access.
+ * associated with this update. Might not be set, use getParentRevision().
* - oldId (int|null): the id of the above revision. 0 if there is no such revision (the change
* was about creating a new page); null if not known (that should not happen).
* - oldIsRedirect (bool|null): whether the page was a redirect before the change. Lazy-loaded,
*/
private $slotsUpdate = null;
+ /**
+ * @var RevisionRecord|null
+ */
+ private $parentRevision = null;
+
/**
* @var RevisionRecord|null
*/
}
/**
- * Returns the revision that was current before the edit. This would be null if the edit
- * created the page, or the revision's parent for a regular edit, or the revision itself
- * for a null-edit.
- * Only defined after calling grabCurrentRevision() or prepareContent() or prepareUpdate()!
+ * Returns the parent revision of the new revision wrapped by this update.
+ * If the update is a null-edit, this will return the parent of the current (and new) revision.
+ * This will return null if the revision wrapped by this update created the page.
+ * Only defined after calling prepareContent() or prepareUpdate()!
*
- * @return RevisionRecord|null the revision that was current before the edit, or null if
- * the edit created the page.
+ * @return RevisionRecord|null the parent revision of the new revision, or null if
+ * the update created the page.
*/
- private function getOldRevision() {
- $this->assertHasPageState( __METHOD__ );
+ private function getParentRevision() {
+ $this->assertPrepared( __METHOD__ );
- // If 'oldRevision' is not set, load it!
- // Useful if $this->oldPageState is initialized by prepareUpdate.
- if ( !array_key_exists( 'oldRevision', $this->pageState ) ) {
- /** @var int $oldId */
- $oldId = $this->pageState['oldId'];
- $flags = $this->useMaster() ? RevisionStore::READ_LATEST : 0;
- $this->pageState['oldRevision'] = $oldId
- ? $this->revisionStore->getRevisionById( $oldId, $flags )
- : null;
+ if ( $this->parentRevision ) {
+ return $this->parentRevision;
}
- return $this->pageState['oldRevision'];
+ if ( !$this->pageState['oldId'] ) {
+ // If there was no current revision, there is no parent revision,
+ // since the page didn't exist.
+ return null;
+ }
+
+ $oldId = $this->revision->getParentId();
+ $flags = $this->useMaster() ? RevisionStore::READ_LATEST : 0;
+ $this->parentRevision = $oldId
+ ? $this->revisionStore->getRevisionById( $oldId, $flags )
+ : null;
+
+ return $this->parentRevision;
}
/**
* @note After prepareUpdate() was called, grabCurrentRevision() will throw an exception
* to avoid confusion, since the page's current revision is then the new revision after
* the edit, which was presumably passed to prepareUpdate() as the $revision parameter.
- * Use getOldRevision() instead to access the revision that used to be current before the
- * edit.
+ * Use getParentRevision() instead to access the revision that is the parent of the
+ * new revision.
*
* @return RevisionRecord|null the page's current revision, or null if the page does not
* yet exist.
// prepareUpdate() is redundant for null-edits
$this->doTransition( 'has-revision' );
+ } else {
+ $this->parentRevision = $parentRevision;
}
}
$this->assertPrepared( __METHOD__ );
if ( !$this->slotsUpdate ) {
- $old = $this->getOldRevision();
+ $old = $this->getParentRevision();
$this->slotsUpdate = RevisionSlotsUpdate::newFromRevisionSlots(
$this->revision->getSlots(),
$old ? $old->getSlots() : null
} else {
throw new LogicException(
'Trying to re-use DerivedPageDataUpdater with revision '
- .$revision->getId()
+ . $revision->getId()
. ', but it\'s already bound to revision '
. $this->revision->getId()
);
if ( !$this->user->equals( $user ) ) {
throw new LogicException(
'The Revision provided has a mismatching actor: expected '
- .$this->user->getName()
+ . $this->user->getName()
. ', got '
. $user->getName()
);
/**
* @param bool $recursive
*
- * @return DataUpdate[]
+ * @return DeferrableUpdate[]
*/
public function getSecondaryDataUpdates( $recursive = false ) {
- // TODO: MCR: getSecondaryDataUpdates() needs a complete overhaul to avoid DataUpdates
- // from different slots overwriting each other in the database. Plan:
- // * replace direct calls to Content::getSecondaryDataUpdates() with calls to this method
- // * Construct LinksUpdate here, on the combined ParserOutput, instead of in AbstractContent
- // for each slot.
- // * Pass $slot into getSecondaryDataUpdates() - probably be introducing a new duplicate
- // version of this function in ContentHandler.
- // * The new method gets the PreparedEdit, but no $recursive flag (that's for LinksUpdate)
- // * Hack: call both the old and the new getSecondaryDataUpdates method here; Pass
- // the per-slot ParserOutput to the old method, for B/C.
- // * Hack: If there is more than one slot, filter LinksUpdate from the DataUpdates
- // returned by getSecondaryDataUpdates, and use a LinksUpdated for the combined output
- // instead.
- // * Call the SecondaryDataUpdates hook here (or kill it - its signature doesn't make sense)
-
- $content = $this->getSlots()->getContent( 'main' );
-
- // NOTE: $output is the combined output, to be shown in the default view.
+ if ( $this->isContentDeleted() ) {
+ // This shouldn't happen, since the current content is always public,
+ // and DataUpates are only needed for current content.
+ return [];
+ }
+
$output = $this->getCanonicalParserOutput();
- $updates = $content->getSecondaryDataUpdates(
- $this->getTitle(), null, $recursive, $output
+ // Construct a LinksUpdate for the combined canonical output.
+ $linksUpdate = new LinksUpdate(
+ $this->getTitle(),
+ $output,
+ $recursive
);
- return $updates;
+ $allUpdates = [ $linksUpdate ];
+
+ // NOTE: Run updates for all slots, not just the modified slots! Otherwise,
+ // info for an inherited slot may end up being removed. This is also needed
+ // to ensure that purges are effective.
+ $renderedRevision = $this->getRenderedRevision();
+ foreach ( $this->getSlots()->getSlotRoles() as $role ) {
+ $slot = $this->getRawSlot( $role );
+ $content = $slot->getContent();
+ $handler = $content->getContentHandler();
+
+ $updates = $handler->getSecondaryDataUpdates(
+ $this->getTitle(),
+ $content,
+ $role,
+ $renderedRevision
+ );
+ $allUpdates = array_merge( $allUpdates, $updates );
+
+ // TODO: remove B/C hack in 1.32!
+ // NOTE: we assume that the combined output contains all relevant meta-data for
+ // all slots!
+ $legacyUpdates = $content->getSecondaryDataUpdates(
+ $this->getTitle(),
+ null,
+ $recursive,
+ $output
+ );
+
+ // HACK: filter out redundant and incomplete LinksUpdates
+ $legacyUpdates = array_filter( $legacyUpdates, function ( $update ) {
+ return !( $update instanceof LinksUpdate );
+ } );
+
+ $allUpdates = array_merge( $allUpdates, $legacyUpdates );
+ }
+
+ // XXX: if a slot was removed by an earlier edit, but deletion updates failed to run at
+ // that time, we don't know for which slots to run deletion updates when purging a page.
+ // We'd have to examine the entire history of the page to determine that. Perhaps there
+ // could be a "try extra hard" mode for that case that would run a DB query to find all
+ // roles/models ever used on the page. On the other hand, removing slots should be quite
+ // rare, so perhaps this isn't worth the trouble.
+
+ // TODO: consolidate with similar logic in WikiPage::getDeletionUpdates()
+ $wikiPage = $this->getWikiPage();
+ $parentRevision = $this->getParentRevision();
+ foreach ( $this->getRemovedSlotRoles() as $role ) {
+ // HACK: we should get the content model of the removed slot from a SlotRoleHandler!
+ // For now, find the slot in the parent revision - if the slot was removed, it should
+ // always exist in the parent revision.
+ $parentSlot = $parentRevision->getSlot( $role, RevisionRecord::RAW );
+ $content = $parentSlot->getContent();
+ $handler = $content->getContentHandler();
+
+ $updates = $handler->getDeletionUpdates(
+ $this->getTitle(),
+ $role
+ );
+ $allUpdates = array_merge( $allUpdates, $updates );
+
+ // TODO: remove B/C hack in 1.32!
+ $legacyUpdates = $content->getDeletionUpdates( $wikiPage );
+
+ // HACK: filter out redundant and incomplete LinksDeletionUpdate
+ $legacyUpdates = array_filter( $legacyUpdates, function ( $update ) {
+ return !( $update instanceof LinksDeletionUpdate );
+ } );
+
+ $allUpdates = array_merge( $allUpdates, $legacyUpdates );
+ }
+
+ // TODO: hard deprecate SecondaryDataUpdates in favor of RevisionDataUpdates in 1.33!
+ Hooks::run(
+ 'RevisionDataUpdates',
+ [ $this->getTitle(), $renderedRevision, &$allUpdates ]
+ );
+
+ return $allUpdates;
}
/**
WikiPage::onArticleEdit( $title, $legacyRevision, $this->getTouchedSlotRoles() );
}
- $oldRevision = $this->getOldRevision();
+ $oldRevision = $this->getParentRevision();
$oldLegacyRevision = $oldRevision ? new Revision( $oldRevision ) : null;
// TODO: In the wiring, register a listener for this on the new PageEventEmitter
}
foreach ( $updates as $update ) {
- $update->setCause( $causeAction, $causeAgent );
+ if ( $update instanceof DataUpdate ) {
+ $update->setCause( $causeAction, $causeAgent );
+ }
if ( $update instanceof LinksUpdate ) {
$update->setRevision( $legacyRevision );
$update->setTriggeringUser( $triggeringUser );
$slot = $rev->getSlot( $role, RevisionRecord::RAW );
Assert::postcondition(
$slot->getContent() !== null,
- $role . ' slot must have content'
+ $role . ' slot must have content'
);
Assert::postcondition(
$slot->hasRevision(),
- $role . ' slot must have a revision associated'
+ $role . ' slot must have a revision associated'
);
}
if ( $nsText === false ) {
// See T165149. Awkward, but better than erroneously linking to the main namespace.
$nsText = MediaWikiServices::getInstance()->getContentLanguage()->
- getNsText( NS_SPECIAL ) . ":Badtitle/NS{$this->mNamespace}";
+ getNsText( NS_SPECIAL ) . ":Badtitle/NS{$this->mNamespace}";
}
$p .= $nsText . ':';
* @return string
*/
public function getFullRequestURL() {
- return wfGetServerUrl( PROTO_CURRENT ) . $this->getRequestURL();
+ return wfGetServerUrl( PROTO_CURRENT ) . $this->getRequestURL();
}
/**
);
$de->showDiff( '', '' );
}
- return;
}
protected function getDescription() {
if ( !is_null( $params[$param] ) ) {
$p = $this->getModulePrefix();
$this->dieWithError(
- [ 'apierror-invalidparammix-cannotusewith', $p.$param, "{$p}user" ],
+ [ 'apierror-invalidparammix-cannotusewith', $p . $param, "{$p}user" ],
'invalidparammix'
);
}
if ( !is_null( $params[$param] ) ) {
$p = $this->getModulePrefix();
$this->dieWithError(
- [ 'apierror-invalidparammix-mustusewith', $p.$param, "{$p}user" ],
+ [ 'apierror-invalidparammix-mustusewith', $p . $param, "{$p}user" ],
'invalidparammix'
);
}
}
if ( $this->params['testactions'] ) {
- $limit = $this->getMain()->canApiHighLimits() ? self::LIMIT_SML1 : self::LIMIT_SML2;
+ $limit = $this->getMain()->canApiHighLimits() ? self::LIMIT_SML2 : self::LIMIT_SML1;
if ( $this->countTestedActions >= $limit ) {
return null; // force a continuation
}
"apihelp-compare-param-fromid": "رقم الصفحة الأول للمقارنة.",
"apihelp-compare-param-fromrev": "أول مراجعة للمقارنة.",
"apihelp-compare-param-frompst": "قم بإجراء تحويل ما قبل الحفظ على <var>fromtext-{slot}</var>.",
+ "apihelp-compare-param-fromslots": "تجاوز محتوى المراجعة المحددة بواسطة <var>fromtitle</var> أو <var>fromid</var> أو <var>fromrev</var>.\n\nيحدد هذا الوسيط الفتحات المراد تعديلها، استخدم <var>fromtext-{slot}</var> و<var>fromcontentmodel-{slot}</var> و<var>fromcontentformat-{slot}</var> لتحديد محتوى لكل فتحة.",
+ "apihelp-compare-param-fromtext-{slot}": "نص الفتحة المحددة، إذا تم حذفها، تتم إزالة الفتحة من المراجعة.",
+ "apihelp-compare-param-fromsection-{slot}": "عندما يكون <var>fromtext-{slot}</var> هو محتوى قسم واحد، فهذا هو رقم القسم، سيتم دمجه في المراجعة المحددة بواسطة <var>fromtitle</var> أو <var>fromid</var> أو <var>fromrev</var> كما لو كانت لتعديل القسم.",
+ "apihelp-compare-param-fromcontentmodel-{slot}": "نموذج محتوى <var>fromtext-{slot}</var>، إذا لم يتم توفيره، فسيتم تخمينه استنادا إلى الوسائط الأخرى.",
+ "apihelp-compare-param-fromcontentformat-{slot}": "تنسيق تسلسل محتوى <var>fromtext-{slot}</var>.",
"apihelp-compare-param-fromtext": "حدد <kbd>fromslots=main</kbd> واستخدم <var>fromtext-main</var> كبديل.",
"apihelp-compare-param-fromcontentmodel": "حدد <kbd>fromslots=main</kbd> واستخدم <var>fromcontentmodel-main</var> كبديل.",
"apihelp-compare-param-fromcontentformat": "حدد <kbd>fromslots=main</kbd> واستخدم <var>fromcontentformat-main</var> كبديل.",
"apihelp-compare-param-torev": "المراجعة الثانية للمقارنة.",
"apihelp-compare-param-torelative": "استخدم مراجعة متعلقة بالمراجعة المحددة من <var>fromtitle</var> أو <var>fromid</var> أو <var>fromrev</var>، سيتم تجاهل جميع خيارات 'إلى' الأخرى.",
"apihelp-compare-param-topst": "قم بإجراء تحويل ما قبل الحفظ على <var>totext</var>.",
+ "apihelp-compare-param-toslots": "تجاوز محتوى المراجعة المحددة بواسطة <var>totitle</var> أو <var>toid</var> أو <var>torev</var>.\n\nيحدد هذا الوسيط الفتحات المراد تعديلها، استخدم <var>totext-{slot}</var> و<var>tocontentmodel-{slot}</var> و<var>tocontentformat-{slot}</var> لتحديد محتوى لكل فتحة.",
+ "apihelp-compare-param-totext-{slot}": "نص الفتحة المحددة، إذا تم حذفه، تتم إزالة الفتحة من المراجعة.",
+ "apihelp-compare-param-tosection-{slot}": "عندما يكون <var>totext-{slot}</var> هو محتوى قسم واحد، فهذا هو رقم القسم، سيتم دمجه في المراجعة المحددة بواسطة <var>totitle</var> أو <var>toid</var> أو <var>torev</var> كما لو كانت لتعديل القسم.",
+ "apihelp-compare-param-tocontentmodel-{slot}": "نموذج محتوى <var>totext-{slot}</var>، إذا لم يتم توفيره، فسيتم تخمينه استنادا إلى الوسائط الأخرى.",
+ "apihelp-compare-param-tocontentformat-{slot}": "تنسيق تسلسل محتوى <var>totext-{slot}</var>.",
"apihelp-compare-param-totext": "حدد <kbd>toslots=main</kbd> واستخدم <var>totext-main</var> كبديل.",
"apihelp-compare-param-tocontentmodel": "حدد <kbd>toslots=main</kbd> واستخدم <var>tocontentmodel-main</var> كبديل.",
"apihelp-compare-param-tocontentformat": "حدد <kbd>toslots=main</kbd> واستخدم <var>tocontentformat-main</var> كبديل.",
"apihelp-compare-paramvalue-prop-comment": "التعليق على المراجعات 'من' و'إلى'.",
"apihelp-compare-paramvalue-prop-parsedcomment": "التعليق المحلل على المراجعات 'من' و'إلى'.",
"apihelp-compare-paramvalue-prop-size": "حجم المراجعات 'من' و'إلى'.",
+ "apihelp-compare-param-slots": "إرجاع فرق فردي لهذه الفتحات، بدلا من فرق واحد مشترك لجميع فتحات.",
"apihelp-compare-example-1": "إنشاء فرق بين المراجعة 1 و2.",
"apihelp-createaccount-summary": "انشاء حساب مستخدم جديد",
"apihelp-createaccount-param-preservestate": "إذا تم عرض <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> بشكل صحيح لـ<samp>hasprimarypreservedstate</samp>، فقد تم تعليم طلبات <samp>primary-required</samp> لكي يجب حذفها، إذا عرضت قيمة غير فارغة لـ<samp>preservedusername</samp> فيجب استخدام اسم المستخدم هذا للوسيط <var>username</var>.",
"apihelp-query+revisions+base-paramvalue-prop-tags": "وسوم للمراجعة.",
"apihelp-query+revisions+base-paramvalue-prop-roles": "أدرج أدوار فتحة المحتوى الموجودة في المراجعة.",
"apihelp-query+revisions+base-paramvalue-prop-parsetree": "استخدم <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> أو <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> بدلا من ذلك، شجرة تحليل XML لمحتوى المراجعة (تتطلب نموذج المحتوى <code>$1</code>).",
+ "apihelp-query+revisions+base-param-slots": "أي الفتحات المراجعة لتعيد البيانات، عندما يتم تضمين الخصائص ذات الصلة بالفتحات في <var>$1props</var>، إذا تم حذفها، فسيتم إرجاع البيانات من فتحة <kbd>main</kbd> بتنسيق متوافق مع الإصدارات السابقة.",
"apihelp-query+revisions+base-param-limit": "الحد من عدد المراجعات التي سيتم إرجاعها.",
"apihelp-query+revisions+base-param-expandtemplates": "استخدم <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> بدلا من ذلك، قم بتوسيع القوالب في محتوى المراجعة (يتطلب $1prop=content).",
"apihelp-query+revisions+base-param-generatexml": "استخدم <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> أو <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> بدلا من ذلك، قم بتوليد شجرة تحليل XML لمحتوى المراجعة (تتطلب $1prop=content).",
"apihelp-json-param-callback": "إذا تم تحديده، فسيقوم بإخراج الإخراج في استدعاء دالة معينة، للسلامة; سيتم تقييد جميع البيانات الخاصة بالمستخدم.",
"apihelp-json-param-utf8": "إذا تم تحديده، يقوم بترميز معظم (وليس كل) الأحرف غير ASCII كـUTF-8 بدلا من استبدالها بتسلسلات الهروب السداسية العشرية، افتراضي عندما لا يكون <var>formatversion</var> <kbd>1</kbd>.",
"apihelp-json-param-ascii": "إذا تم تحديده، يشفر كل غير ASCII باستخدام تسلسلات الهروب السداسية العشرية، افتراضي عندما يكون <var>formatversion</var> <kbd>1</kbd>.",
+ "apihelp-json-param-formatversion": "تنسيق الإخراج: \n;1:تنسيق متوافق مع الإصدارات السابقة (مصفوفات منطقية بتنسيق XML، ومفاتيح <samp>*</samp> لعقد المحتوى، وما إلى ذلك).\n;2:التنسيق الحديث التجريبي، التفاصيل قد تتغير!\n;الأحدث: استخدم أحدث تنسيق (حاليا <kbd>2</kbd>)، قد يتغير دون سابق إنذار.",
"apihelp-jsonfm-summary": "بيانات الإخراج بتنسيق JSON (الطباعة بـHTML).",
"apihelp-none-summary": "عدم إخراج أي شيء.",
"apihelp-php-summary": "بيانات الإخراج بتنسيق PHP المتسلسل.",
+ "apihelp-php-param-formatversion": "تنسيق الإخراج: \n;1:تنسيق متوافق مع الإصدارات السابقة (مصفوفات منطقية بتنسيق XML، ومفاتيح <samp>*</samp> لعقد المحتوى، وما إلى ذلك).\n;2:التنسيق الحديث التجريبي، التفاصيل قد تتغير!\n;الأحدث: استخدم أحدث تنسيق (حاليا <kbd>2</kbd>)، قد يتغير دون سابق إنذار.",
"apihelp-phpfm-summary": "بيانات الإخراج بتنسيق JSON (الطباعة بـHTML).",
"apihelp-rawfm-summary": "بيانات الإخراج، بما في ذلك عناصر تصحيح الأخطاء، بتنسيق JSON (الطباعة بـHTML).",
"apihelp-xml-summary": "بيانات الإخراج بتنسيق XML.",
"apierror-changeauth-norequest": "فشل في إنشاء طلب التغيير.",
"apierror-chunk-too-small": "الحد الأدنى لحجم القطعة هو $1 {{PLURAL:$1|بايت}} للقطع غير النهائية.",
"apierror-cidrtoobroad": "لا يُقبَل مدى $1 CIDR أكبر من /$2.",
+ "apierror-compare-maintextrequired": "الوسيط <var>$1text-main</var> مطلوب عندما يكون <var>$1slots</var> يحتوي على <kbd>main</kbd> (لا يمكن حذف الفتحة الرئيسية).",
"apierror-compare-no-title": "لا يمكن الحفظ المسبق للحفظ بدون عنوان; حاول تحديد <var>fromtitle</var> أو <var>totitle</var>.",
"apierror-compare-nosuchfromsection": "لا يوجد قسم $1 في المحتوى 'من'.",
"apierror-compare-nosuchtosection": "لا يوجد قسم $1 في المحتوى 'إلى'.",
+ "apierror-compare-nofromrevision": "ليس 'من' مراجعة، حدد <var>fromrev</var> أو <var>fromtitle</var> أو <var>fromid</var>.",
+ "apierror-compare-notext": "لا يمكن استخدام الوسيط <var>$1</var> بدون <var>$2</var>.",
+ "apierror-compare-notorevision": "ليس 'إلى' مراجعة، حدد <var>torev</var> أو <var>totitle</var> أو <var>toid</var>.",
"apierror-compare-relative-to-nothing": "لا توجد مراجعة 'من' لـ<var>torelative</var> لتكون نسبة.",
"apierror-contentserializationexception": "فشل تسلسل المحتوى: $1",
"apierror-contenttoobig": "يتجاوز المحتوى الذي أدخلته حد حجم المقالة البالغ $1 {{PLURAL:$1|كيلوبايت}}.",
"apierror-mimesearchdisabled": "تم تعطيل بحث MIME في وضع Miser.",
"apierror-missingcontent-pageid": "محتوى مفقود لمعرف الصفحة $1.",
"apierror-missingcontent-revid": "محتوى مفقود لمعرف المراجعة $1.",
+ "apierror-missingcontent-revid-role": "محتوى مفقود لمعرف المراجعة $1 للدور $2.",
"apierror-missingparam-at-least-one-of": "مطلوب {{PLURAL:$2|الوسيط|واحد على الأقل من الوسائط}} $1.",
"apierror-missingparam-one-of": "مطلوب {{PLURAL:$2|الوسيط|واحد على الأقل من الوسائط}} $1.",
"apierror-missingparam": "يجب تعيين الوسيط <var>$1</var>.",
"apiwarn-deprecation-login-botpw": "تم إيقاف تسجيل الدخول إلى الحساب الرئيسي عبر <kbd>action=login</kbd> وقد يتوقف عن العمل دون سابق إنذار، لمتابعة تسجيل الدخول باستخدام <kbd>action=login</kbd>; راجع [[Special:BotPasswords]]، لمتابعة استخدام تسجيل الدخول إلى الحساب الرئيسي بأمان; راجع <kbd>action=clientlogin</kbd>.",
"apiwarn-deprecation-login-nobotpw": "تم إيقاف تسجيل الدخول إلى الحساب الرئيسي عبر <kbd>action=login</kbd>، وقد يتوقف عن العمل دون سابق إنذار، لتسجيل الدخول بأمان; راجع <kbd>action=clientlogin</kbd>.",
"apiwarn-deprecation-login-token": "تم إيقاف عمل رمز مميز عبر <kbd>action=login</kbd> ;استخدم <kbd>action=query&meta=tokens&type=login</kbd> بدلا من ذلك.",
+ "apiwarn-deprecation-missingparam": "نظرا لعدم تحديد <var>$1</var>; تم استخدام تنسيق قديم للإخراج، تم إيقاف هذا التنسيق، وسيتم دائما استخدام التنسيق الجديد في المستقبل.",
"apiwarn-deprecation-parameter": "تم إيقاف الوسيط <var>$1</var>.",
"apiwarn-deprecation-parse-headitems": "تم إيقاف <kbd>prop=headitems</kbd> منذ ميدياويكي 1.28; استخدم <kbd>prop=headhtml</kbd> عند إنشاء مستندات HTML جديدة، أو <kbd>prop=modules|jsconfigvars</kbd> عند تحديث مستند من جانب العميل.",
"apiwarn-deprecation-purge-get": "تم إيقاف استخدام <kbd>action=purge</kbd> عبر GET; استخدم POST بدلا من ذلك.",
"apiwarn-parse-nocontentmodel": "لم يتم إعطاء <var>title</var> أو <var>contentmodel</var>، على افتراض $1.",
"apiwarn-parse-revidwithouttext": "تم استخدام <var>revid</var> بدون <var>text</var>، وتم طلب خصائص الصفحة المحللة، هل تقصد استخدام <var>oldid</var> بدلا من <var>revid</var>؟",
"apiwarn-parse-titlewithouttext": "تم استخدام <var>title</var> بدون <var>text</var>، وتم طلب خصائص الصفحة المحللة، هل تقصد استخدام <var>page</var> بدلا من <var>title</var>؟",
+ "apiwarn-redirectsandrevids": "لا يمكن استخدام دقة تحويلة مع الوسيط <var>revids</var>، أية تحويلات لنقطة <var>revids</var> لم يتم حلها.",
"apiwarn-tokennotallowed": "الإجراء \"$1\" غير مسموح به للمستخدم الحالي.",
"apiwarn-tokens-origin": "قد لا يتم الحصول على الرموز عند عدم تطبيق السياسة الأصلية.",
"apiwarn-truncatedresult": "تم اقتطاع هذه النتيجة لأنها قد تكون أكبر من حد الـ$1 بايت.",
"apihelp-options-example-complex": "重置所有偏好設定,然後再設定 <kbd>skin</kbd> 與 <kbd>nickname</kbd>。",
"apihelp-paraminfo-summary": "獲得有關 API 模組的資訊。",
"apihelp-paraminfo-param-helpformat": "說明字串的格式。",
+ "apihelp-paraminfo-param-formatmodules": "格式模組名稱清單(<var>format</var> 參數的值)。請改用 <var>$1modules</var> 。",
"apihelp-paraminfo-example-1": "顯示 <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>、<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>、<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>、和 <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> 的資訊。",
"apihelp-paraminfo-example-2": "顯示 <kbd>[[Special:ApiHelp/query|action=query]]</kbd> 所有子模組的資訊。",
"apihelp-parse-summary": "解析內容併回傳解析器輸出。",
"apihelp-query+allimages-param-to": "要停止列舉的圖片標題。僅能與 $1sort=name 一起使用。",
"apihelp-query+allimages-param-start": "要開始列舉的時間戳記。僅能與 $1sort=timestamp 一起使用。",
"apihelp-query+allimages-param-end": "要停止列舉的時間戳記。僅能與 $1sort=timestamp 一起使用。",
+ "apihelp-query+allimages-param-prefix": "搜尋所有以此值為開頭的圖片。僅能與 $1sort=name 一起使用。",
"apihelp-query+allimages-param-minsize": "限制圖片至少要有這樣多的位元組。",
"apihelp-query+allimages-param-maxsize": "限制圖片最多只能這樣多的位元組。",
"apihelp-query+allimages-param-sha1": "圖片的 SHA1 雜湊值。覆蓋 $1sha1base36。",
"apihelp-query+allusers-example-Y": "列出以<kbd>Y</kbd>開頭的使用者。",
"apihelp-query+authmanagerinfo-summary": "取得目前身分核對狀態的資訊。",
"apihelp-query+backlinks-summary": "找出連結至指定頁面的所有頁面。",
+ "apihelp-query+backlinks-param-title": "要搜尋的標題。不能與 <var>$1pageid</var> 一起使用。",
"apihelp-query+backlinks-param-pageid": "要搜尋的頁面 ID。不能與 <var>$1title</var> 一起使用。",
"apihelp-query+backlinks-param-namespace": "要列舉的命名空間。",
"apihelp-query+backlinks-param-dir": "列出時所採用的方向。",
"apihelp-query+blocks-paramvalue-prop-userid": "添加已封鎖使用者的使用者 ID。",
"apihelp-query+blocks-paramvalue-prop-by": "添加進行封鎖中的使用者之使用者名稱。",
"apihelp-query+blocks-paramvalue-prop-byid": "添加進行封鎖中的使用者之使用者 ID。",
+ "apihelp-query+blocks-paramvalue-prop-timestamp": "添加當封鎖生效的時間戳記。",
+ "apihelp-query+blocks-paramvalue-prop-expiry": "添加當封鎖到期的時間戳記。",
"apihelp-query+blocks-paramvalue-prop-reason": "添加封鎖的原因。",
"apihelp-query+blocks-example-simple": "列出封鎖。",
"apihelp-query+blocks-example-users": "列出使用者 <kbd>Alice</kbd> 與 <kbd>Bob</kbd> 的封鎖。",
"apihelp-query+categorymembers-paramvalue-prop-timestamp": "添加在頁面有被包含時的時間戳記。",
"apihelp-query+categorymembers-param-limit": "回傳的頁面數量上限。",
"apihelp-query+categorymembers-param-sort": "作為排序順序的屬性。",
+ "apihelp-query+categorymembers-param-start": "起始列出的時間戳記。僅能與 <kbd>$1sort=timestamp</kbd> 一起使用。",
+ "apihelp-query+categorymembers-param-end": "結束列出的時間戳記。僅能與 <kbd>$1sort=timestamp</kbd> 一起使用。",
"apihelp-query+categorymembers-param-startsortkey": "請改用 $1starthexsortkey。",
"apihelp-query+categorymembers-param-endsortkey": "請改用 $1endhexsortkey。",
"apihelp-query+categorymembers-example-simple": "取得在 <kbd>Category:Physics</kbd> 裡前 10 項的頁面。",
"apihelp-query+logevents-paramvalue-prop-userid": "添加承擔日誌事件的使用者 ID。",
"apihelp-query+logevents-paramvalue-prop-timestamp": "添加日誌事件的時間戳記。",
"apihelp-query+logevents-paramvalue-prop-comment": "添加日誌事件的註釋。",
+ "apihelp-query+logevents-paramvalue-prop-parsedcomment": "添加日誌事件的解析註釋。",
"apihelp-query+logevents-paramvalue-prop-details": "列出日誌事件的額外詳細資訊。",
"apihelp-query+logevents-paramvalue-prop-tags": "列出日誌事件的標籤。",
"apihelp-query+logevents-param-type": "篩選僅為此類型的日誌項目。",
"apihelp-query+logevents-param-tag": "僅列出以此標籤所標記的事件項目。",
"apihelp-query+logevents-param-limit": "要回傳的事件項目總數。",
"apihelp-query+logevents-example-simple": "列出近期日誌事件。",
+ "apihelp-query+pagepropnames-summary": "列出所有在 wiki 使用的頁面屬性名稱。",
"apihelp-query+pagepropnames-param-limit": "回傳的名稱數量上限。",
"apihelp-query+pagepropnames-example-simple": "取得前 10 個屬性名稱。",
"apihelp-query+pageprops-example-simple": "取得頁面 <kbd>Main Page</kbd> 與 <kbd>MediaWiki</kbd> 的屬性。",
"apihelp-query+prefixsearch-param-limit": "回傳的結果數量上限。",
"apihelp-query+prefixsearch-param-offset": "要略過的結果數量。",
"apihelp-query+prefixsearch-example-simple": "搜尋開頭為 <kbd>meaning</kbd> 的頁面標題。",
+ "apihelp-query+prefixsearch-param-profile": "搜尋要使用的配置。",
"apihelp-query+protectedtitles-param-namespace": "僅列出這些命名空間的標題。",
"apihelp-query+protectedtitles-param-level": "僅列出具有這些保護層級的標題。",
"apihelp-query+protectedtitles-param-limit": "要回傳的頁面總數。",
"apihelp-query+protectedtitles-param-prop": "要取得的屬性。",
+ "apihelp-query+protectedtitles-paramvalue-prop-user": "添加做出添加保護操作的使用者。",
+ "apihelp-query+protectedtitles-paramvalue-prop-userid": "添加做出添加保護操作的使用者 ID。",
+ "apihelp-query+protectedtitles-paramvalue-prop-comment": "添加保護的註釋。",
+ "apihelp-query+protectedtitles-paramvalue-prop-parsedcomment": "添加保護的解析註釋。",
"apihelp-query+protectedtitles-paramvalue-prop-level": "添加保護層級。",
"apihelp-query+protectedtitles-example-simple": "列出已保護的標題。",
+ "apihelp-query+querypage-summary": "取得透過特殊頁面 QueryPage-based 所提供的清單。",
"apihelp-query+querypage-param-page": "特殊頁面的名稱。註:區分大小寫。",
"apihelp-query+querypage-param-limit": "回傳的結果數量。",
+ "apihelp-query+querypage-example-ancientpages": "回傳來自 [[Special:Ancientpages]] 的結果。",
"apihelp-query+random-summary": "取得隨機頁面集合",
"apihelp-query+random-param-namespace": "僅回傳在這些命名空間的頁面。",
"apihelp-query+random-param-redirect": "請改用 <kbd>$1filterredir=redirects</kbd>。",
"apihelp-query+recentchanges-param-excludeuser": "不要列出由該使用者作出的更改。",
"apihelp-query+recentchanges-param-tag": "僅列出以此標籤所標記的更改。",
"apihelp-query+recentchanges-param-prop": "包含的額外資訊部份:",
+ "apihelp-query+recentchanges-paramvalue-prop-comment": "添加編輯的註釋。",
+ "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "添加編輯的解析註釋。",
"apihelp-query+recentchanges-paramvalue-prop-flags": "添加編輯的標籤。",
"apihelp-query+recentchanges-paramvalue-prop-timestamp": "添加編輯的時間戳記。",
"apihelp-query+recentchanges-paramvalue-prop-title": "添加編輯的頁面標題。",
"apihelp-query+revisions-example-first5-user": "取得 <kbd>Main Page</kbd> 裡由使用者 <kbd>MediaWiki default</kbd> 所做出的最早前 5 筆修訂。",
"apihelp-query+revisions+base-paramvalue-prop-ids": "修訂 ID。",
"apihelp-query+revisions+base-paramvalue-prop-flags": "修訂標籤(小修改)。",
+ "apihelp-query+revisions+base-paramvalue-prop-timestamp": "修訂的時間戳記。",
"apihelp-query+revisions+base-paramvalue-prop-user": "做出修訂的使用者。",
+ "apihelp-query+revisions+base-paramvalue-prop-userid": "修訂創建者的使用者 ID",
"apihelp-query+revisions+base-paramvalue-prop-size": "修訂的長度(位元組)。",
+ "apihelp-query+revisions+base-paramvalue-prop-sha1": "修訂的 SHA-1(base 16)。",
"apihelp-query+revisions+base-paramvalue-prop-tags": "修訂標籤。",
"apihelp-query+revisions+base-param-limit": "限制所回傳的修訂數量。",
"apihelp-query+search-summary": "執行全文搜尋。",
"apihelp-query+search-param-limit": "要回傳的頁面總數。",
"apihelp-query+search-param-interwiki": "若可用的話,在搜尋裡包含跨 wiki 結果。",
"apihelp-query+search-param-backend": "是否搜尋使用的後端,若否則為預設。",
+ "apihelp-query+search-param-sort": "設定回傳結果的排序。",
"apihelp-query+search-example-simple": "搜尋 <kbd>meaning</kbd>。",
"apihelp-query+search-example-text": "搜尋 <kbd>meaning</kbd> 的文字。",
"apihelp-query+siteinfo-summary": "回傳有關站台的一般資訊。",
"apihelp-query+siteinfo-param-prop": "要取得的資訊:",
"apihelp-query+siteinfo-paramvalue-prop-general": "全面系統資訊。",
"apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "特殊頁面別名清單。",
+ "apihelp-query+siteinfo-param-showalldb": "列出所有資料庫伺服器,不是只有最延遲的那台。",
"apihelp-query+siteinfo-param-numberingroup": "列出在使用者群組裡的使用者數目。",
+ "apihelp-query+siteinfo-param-inlanguagecode": "用於本地化語言的語言代碼(盡可能)與外觀名稱。",
"apihelp-query+siteinfo-example-simple": "索取站台資訊。",
"apihelp-query+siteinfo-example-interwiki": "索取本地端跨 wiki 前綴的清單。",
"apihelp-query+siteinfo-example-replag": "檢查目前的響應延遲。",
"apihelp-query+usercontribs-paramvalue-prop-title": "添加標題與頁面的命名空間 ID。",
"apihelp-query+usercontribs-paramvalue-prop-timestamp": "添加編輯的時間戳記。",
"apihelp-query+usercontribs-paramvalue-prop-comment": "添加編輯的註釋。",
- "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "添加編輯的已解析註解。",
+ "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "添加編輯的解析註釋。",
"apihelp-query+usercontribs-paramvalue-prop-size": "添加編輯的新大小。",
"apihelp-query+usercontribs-paramvalue-prop-flags": "添加編輯的標籤。",
"apihelp-query+usercontribs-paramvalue-prop-patrolled": "標記已巡查編輯。",
"apihelp-query+watchlist-paramvalue-prop-user": "添加有做出編輯的使用者。",
"apihelp-query+watchlist-paramvalue-prop-userid": "添加有做出編輯的使用者 ID。",
"apihelp-query+watchlist-paramvalue-prop-comment": "添加編輯的註釋。",
- "apihelp-query+watchlist-paramvalue-prop-parsedcomment": "添加編輯的已解析註解。",
+ "apihelp-query+watchlist-paramvalue-prop-parsedcomment": "添加編輯的解析註釋。",
"apihelp-query+watchlist-paramvalue-prop-timestamp": "添加編輯的時間戳記。",
"apihelp-query+watchlist-paramvalue-prop-tags": "列出項目的標籤。",
"apihelp-query+watchlist-param-type": "要顯示的更改類型:",
"apihelp-revisiondelete-param-reason": "刪除或取消刪除的原因。",
"apihelp-revisiondelete-param-tags": "在刪除日誌裡套用到項目的標籤。",
"apihelp-rollback-summary": "撤修頁面的最後一次編輯。",
+ "apihelp-rollback-param-tags": "套用到回退的標籤。",
+ "apihelp-rollback-param-summary": "自定義編輯摘要。若為空,則使用預設摘要。",
"apihelp-rollback-param-watchlist": "無條件使用設置將頁面加入或移除目前使用者的監視清單或者是不更改監視清單。",
"apihelp-setnotificationtimestamp-param-entirewatchlist": "在所有已監視頁面運作。",
+ "apihelp-setnotificationtimestamp-example-page": "重新設定用於 <kbd>Main page</kbd> 的通知狀態。",
+ "apihelp-setnotificationtimestamp-example-allpages": "重新設定在 <kbd>{{ns:user}}</kbd> 命名空間裡頁面的通知狀態。",
"apihelp-setpagelanguage-summary": "更改頁面的語言。",
+ "apihelp-setpagelanguage-extended-description-disabled": "您不被允許在此 wiki 上變更頁面的語言。\n\n請啟用 <var>[[mw:Special:MyLanguage/Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> 來進行此操作。",
"apihelp-setpagelanguage-param-reason": "變更的原因。",
"apihelp-setpagelanguage-example-language": "更改 <kbd>Main Page</kbd> 的語言成巴斯克語。",
"apihelp-stashedit-summary": "在分享快取裡預備編輯。",
"apihelp-unblock-param-reason": "解除封鎖的原因。",
"apihelp-unblock-param-tags": "在封鎖日誌裡更改套用到項目的標籤。",
"apihelp-unblock-example-id": "解除封銷 ID #<kbd>105</kbd>。",
+ "apihelp-undelete-summary": "恢復已刪除頁面的修訂。",
"apihelp-undelete-param-title": "要恢復的頁面標題。",
"apihelp-undelete-param-reason": "還原的原因。",
"apihelp-undelete-param-tags": "在刪除日誌裡更改套用到項目的標籤。",
"apihelp-undelete-example-page": "取消刪除頁面 <kbd>Main Page</kbd>。",
"apihelp-undelete-example-revisions": "取消刪除 <kbd>Main Page</kbd> 的兩筆修訂。",
"apihelp-unlinkaccount-summary": "移除目前使用者所連結到的第三方帳號。",
+ "apihelp-upload-summary": "上傳檔案,或取得等待上傳的狀態。",
"apihelp-upload-param-filename": "目標檔案名稱。",
"apihelp-upload-param-comment": "上傳註釋。如果 <var>$1text</var> 未指定的話,也會作為新檔案用的初始頁面文字。",
"apihelp-upload-param-text": "用於新檔案的初始頁面文字。",
"api-format-prettyprint-header-hyperlinked": "這是$1格式的HTML實現。HTML對除錯很有用,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要查看$1格式的非HTML實現,設置[$3 <kbd>format=$2</kbd>]。\n\n參見[[mw:API|完整文件]],或[[Special:ApiHelp/main|API幫助]]以獲取更多信息。",
"api-format-prettyprint-status": "此回應將會傳回HTTP狀態$1 $2。",
"api-login-fail-badsessionprovider": "當使用$1無法登入。",
+ "api-login-fail-sameorigin": "當未套用相同原有方針時無法登入。",
"api-pageset-param-titles": "要使用的標題清單。",
"api-pageset-param-pageids": "要使用的頁面 ID 清單。",
"api-pageset-param-revids": "要使用的修訂 ID 清單。",
"api-help-param-upload": "必須使用 multipart/form-data 以檔案上傳的方式傳送。",
"api-help-param-multi-separate": "將幾個值以 <kbd>|</kbd> 或 [[Special:ApiHelp/main#main/datatypes|alternative]] 分隔。",
"api-help-param-multi-max": "上限值為 {{PLURAL:$1|$1}} (機器人為 {{PLURAL:$2|$2}})。",
+ "api-help-param-multi-max-simple": "值的最大數量為 {{PLURAL:$1|$1}}。",
"api-help-param-multi-all": "要指定所有值,請使用<kbd>$1</kbd>。",
"api-help-param-default": "預設值:$1",
"api-help-param-default-empty": "預設值:<span class=\"apihelp-empty\">(空)</span>",
"api-help-authmanagerhelper-returnurl": "為第三方身份驗證流程傳回URL,必須為絕對值。需要此值或<var>$1continue</var>兩者之一。\n\n在接收<samp>REDIRECT</samp>回應時,一般狀況下您將打開瀏覽器或網站瀏覽功能到特定的<samp>redirecttarget</samp> URL以進行第三方身份驗證流程。當它完成時,第三方會將瀏覽器或網站瀏覽功能送至此URL。您應當提取任何來自URL的查詢或POST參數,並將之作為<var>$1continue</var>請求傳遞至此API模組。",
"api-help-authmanagerhelper-continue": "此請求是在先前的<samp>UI</samp>或<samp>REDIRECT</samp>回應之後的後續動作。必須為此值或<var>$1returnurl</var>。",
"api-help-authmanagerhelper-additional-params": "此模組允許額外參數,取決於可用的身份驗證請求。使用<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>与<kbd>amirequestsfor=$1</kbd>(或之前來自此模組的回應,如果合適)以決定可用請求及其使用的欄位。",
+ "apierror-appendnotsupported": "無法附加到使用內容模組 $1 的頁面。",
"apierror-articleexists": "您所嘗試建立的條目剛剛已被創建。",
"apierror-assertbotfailed": "斷言使用者擁有的 <code>bot</code> 權限失效。",
"apierror-assertnameduserfailed": "斷言使用者「$1」出錯。",
"apierror-contentserializationexception": "內容序列化失敗:$1",
"apierror-copyuploadbadurl": "不允許從此 URL 來上傳。",
"apierror-csp-report": "處理 CSP 報告時錯誤:$1。",
+ "apierror-emptypage": "不允許建立空白的新頁面。",
"apierror-filedoesnotexist": "檔案不存在。",
"apierror-filenopath": "無法取得本地端檔案路徑。",
"apierror-filetypecannotberotated": "無法旋轉的檔案類型。",
"apierror-imageusage-badtitle": "<kbd>$1</kbd>的標題必須是檔案。",
"apierror-import-unknownerror": "未知的匯入錯誤:$1",
"apierror-invalidcategory": "您所輸入的分類名稱無效。",
+ "apierror-invalidlang": "用於參數 <var>$1</var> 的語言代碼無效。",
+ "apierror-invalidoldimage": "<var>oldimage</var> 參數含有無效格式。",
+ "apierror-invalidparammix-cannotusewith": "參數 <kbd>$1</kbd> 不能與 <kbd>$2</kbd> 一起使用。",
+ "apierror-invalidparammix-mustusewith": "<kbd>$1</kbd> 參數僅能與 <kbd>$2</kbd> 一起使用。",
"apierror-invalidparammix": "{{PLURAL:$2|參數}} $1 不能一起使用。",
"apierror-invalidsha1base36hash": "所提供的 SHA1Base36 雜湊無效。",
"apierror-invalidsha1hash": "所提供的 SHA1 雜湊無效。",
"apierror-invalidtitle": "錯誤標題「$1」。",
+ "apierror-invalidurlparam": "<var>$1urlparam</var> 的值無效(<kbd>$2=$3</kbd>)。",
"apierror-invaliduser": "無效的使用者名稱「$1」。",
"apierror-invaliduserid": "使用者 ID <var>$1</var> 無效。",
+ "apierror-maxbytes": "參數 <var>$1</var> 不能大於 $2 {{PLURAL:$2|位元組|位元組}}",
+ "apierror-maxchars": "參數 <var>$1</var> 不能多於 $2 個{{PLURAL:$2|字元|字元}}",
+ "apierror-maxlag-generic": "正等待資料庫伺服器:已延遲 $1 {{PLURAL:$1|秒|秒}}。",
+ "apierror-maxlag": "正等待$2:已延遲 $1 {{PLURAL:$1|秒|秒}}。",
"apierror-mimesearchdisabled": "MIME 搜尋在 Miser 模式裡被停用。",
"apierror-missingcontent-pageid": "遺失頁面 ID 為 $1 的內容。",
"apierror-missingcontent-revid": "遺失修訂 ID 為 $1 的內容。",
+ "apierror-missingparam-one-of": "{{PLURAL:$2|參數|參數其一}} $1 為必要。",
"apierror-missingparam": "<var>$1</var>參數必須被設定。",
"apierror-missingrev-pageid": "沒有頁面 ID 為 $1 的目前修訂。",
"apierror-missingrev-title": "沒有標題為$1的目前修訂。",
"apierror-missingtitle": "您所指定的頁面不存在。",
"apierror-missingtitle-byname": "頁面$1不存在。",
+ "apierror-moduledisabled": "模組 <kbd>$1</kbd> 已停用。",
"apierror-mustbeloggedin-changeauth": "必須登入,才能變更身分核對資取。",
"apierror-mustbeloggedin-generic": "您必須登入。",
"apierror-mustbeloggedin-linkaccounts": "您必須登入到連結帳號。",
* made to replace information about the old content with information about
* the new content.
*
- * This default implementation calls
- * $this->getParserOutput( $content, $title, null, null, false ),
- * and then calls getSecondaryDataUpdates( $title, $recursive ) on the
- * resulting ParserOutput object.
- *
- * Subclasses may implement this to determine the necessary updates more
- * efficiently, or make use of information about the old content.
+ * @deprecated since 1.32, call and override
+ * ContentHandler::getSecondaryDataUpdates instead.
*
* @note Implementations should call the SecondaryDataUpdates hook, like
* AbstractContent does.
* the current state of the database.
*
* @since 1.21
+ * @deprecated since 1.32, call and override
+ * ContentHandler::getDeletionUpdates instead.
*
- * @param WikiPage $page The deleted page
+ * @param WikiPage $page The page the content was deleted from.
* @param ParserOutput|null $parserOutput Optional parser output object
* for efficient access to meta-information about the content object.
* Provide if you have one handy.
use Wikimedia\Assert\Assert;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\SlotRenderingProvider;
use MediaWiki\Search\ParserOutputSearchDataExtractor;
/**
return $parserOutput;
}
+ /**
+ * Returns a list of DeferrableUpdate objects for recording information about the
+ * given Content in some secondary data store.
+ *
+ * Application logic should not call this method directly. Instead, it should call
+ * DerivedPageDataUpdater::getSecondaryDataUpdates().
+ *
+ * @note Implementations must not return a LinksUpdate instance. Instead, a LinksUpdate
+ * is created by the calling code in DerivedPageDataUpdater, on the combined ParserOutput
+ * of all slots, not for each slot individually. This is in contrast to the old
+ * getSecondaryDataUpdates method defined by AbstractContent, which returned a LinksUpdate.
+ *
+ * @note Implementations should not call $content->getParserOutput, they should call
+ * $slotOutput->getSlotRendering( $role, false ) instead if they need to access a ParserOutput
+ * of $content. This allows existing ParserOutput objects to be re-used, while avoiding
+ * creating a ParserOutput when none is needed.
+ *
+ * @param Title $title The title of the page to supply the updates for
+ * @param Content $content The content to generate data updates for.
+ * @param string $role The role (slot) in which the content is being used. Which updates
+ * are performed should generally not depend on the role the content has, but the
+ * DeferrableUpdates themselves may need to know the role, to track to which slot the
+ * data refers, and to avoid overwriting data of the same kind from another slot.
+ * @param SlotRenderingProvider $slotOutput A provider that can be used to gain access to
+ * a ParserOutput of $content by calling $slotOutput->getSlotParserOutput( $role, false ).
+ * @return DeferrableUpdate[] A list of DeferrableUpdate objects for putting information
+ * about this content object somewhere. The default implementation returns an empty
+ * array.
+ * @since 1.32
+ */
+ public function getSecondaryDataUpdates(
+ Title $title,
+ Content $content,
+ $role,
+ SlotRenderingProvider $slotOutput
+ ) {
+ return [];
+ }
+
+ /**
+ * Returns a list of DeferrableUpdate objects for removing information about content
+ * in some secondary data store. This is used when a page is deleted, and also when
+ * a slot is removed from a page.
+ *
+ * Application logic should not call this method directly. Instead, it should call
+ * WikiPage::getSecondaryDataUpdates().
+ *
+ * @note Implementations must not return a LinksDeletionUpdate instance. Instead, a
+ * LinksDeletionUpdate is created by the calling code in WikiPage.
+ * This is in contrast to the old getDeletionUpdates method defined by AbstractContent,
+ * which returned a LinksUpdate.
+ *
+ * @note Implementations should not rely on the page's current content, but rather the current
+ * state of the secondary data store.
+ *
+ * @param Title $title The title of the page to supply the updates for
+ * @param string $role The role (slot) in which the content is being used. Which updates
+ * are performed should generally not depend on the role the content has, but the
+ * DeferrableUpdates themselves may need to know the role, to track to which slot the
+ * data refers, and to avoid overwriting data of the same kind from another slot.
+ *
+ * @return DeferrableUpdate[] A list of DeferrableUpdate objects for putting information
+ * about this content object somewhere. The default implementation returns an empty
+ * array.
+ *
+ * @since 1.32
+ */
+ public function getDeletionUpdates( Title $title, $role ) {
+ return [];
+ }
+
}
* @param int $num
*/
public function setPerRow( $num ) {
- return;
}
}
if ( $flags & self::QOS_ATOMIC ) {
$dbw->endAtomic( $method );
}
-
- return;
}
/**
unset( $req['query']['oldid'] );
}
} elseif ( $reqType === 'transform' ) {
- $req['url'] .= 'transform/'. $parts[3] . '/to/' . $parts[5];
+ $req['url'] .= 'transform/' . $parts[3] . '/to/' . $parts[5];
// the title
if ( isset( $parts[6] ) ) {
$req['url'] .= '/' . $parts[6];
// Make a regex out of the source data to match it to an array of color
// spaces in a case-insensitive way
- $colorSpaceRegex = '/'.preg_quote( $data[0], '/' ).'/i';
+ $colorSpaceRegex = '/' . preg_quote( $data[0], '/' ) . '/i';
if ( empty( preg_grep( $colorSpaceRegex, $colorSpaces ) ) ) {
// We can't establish that this file matches the color space, don't process it
return false;
}
- $profileRegex = '/'.preg_quote( $data[1], '/' ).'/i';
+ $profileRegex = '/' . preg_quote( $data[1], '/' ) . '/i';
if ( empty( preg_grep( $profileRegex, $oldProfileStrings ) ) ) {
// We can't establish that this file has the expected ICC profile, don't process it
return false;
if ( $this->mRevision !== null ) {
// Revision title doesn't match the page title given?
if ( $this->mPage->getId() != $this->mRevision->getPage() ) {
- $function = get_class( $this->mPage ). '::newFromID';
+ $function = get_class( $this->mPage ) . '::newFromID';
$this->mPage = $function( $this->mRevision->getPage() );
}
}
// Note that the ArticleViewHeader hook is allowed to set $outputDone to a
// ParserOutput instance.
$pOutput = ( $outputDone instanceof ParserOutput )
+ // phpcs:ignore MediaWiki.Usage.NestedInlineTernary.UnparenthesizedTernary -- FIXME T203805
? $outputDone // object fetched by hook
: $this->mParserOutput ?: null; // ParserOutput or null, avoid false
* Call to WikiPage function for backwards compatibility.
* @see WikiPage::doDeleteUpdates
*/
- public function doDeleteUpdates( $id, Content $content = null ) {
- return $this->mPage->doDeleteUpdates( $id, $content );
+ public function doDeleteUpdates(
+ $id,
+ Content $content = null,
+ $revision = null,
+ User $user = null
+ ) {
+ $this->mPage->doDeleteUpdates( $id, $content, $revision, $user );
}
/**
} else {
$row .=
'<td dir="' . MediaWikiServices::getInstance()->getContentLanguage()->getDir() .
- '">' . Linker::formatComment( $description, $this->title ) . '</td>';
+ '">' . Linker::formatComment( $description, $this->title ) . '</td>';
}
$rowClass = null;
use MediaWiki\Storage\RevisionRecord;
use MediaWiki\Storage\RevisionSlotsUpdate;
use MediaWiki\Storage\RevisionStore;
+use MediaWiki\Storage\SlotRecord;
use Wikimedia\Assert\Assert;
use Wikimedia\Rdbms\FakeResultWrapper;
use Wikimedia\Rdbms\IDatabase;
* Do some database updates after deletion
*
* @param int $id The page_id value of the page being deleted
- * @param Content|null $content Optional page content to be used when determining
+ * @param Content|null $content Page content to be used when determining
* the required updates. This may be needed because $this->getContent()
* may already return null when the page proper was deleted.
- * @param Revision|null $revision The latest page revision
+ * @param RevisionRecord|Revision|null $revision The current page revision at the time of
+ * deletion, used when determining the required updates. This may be needed because
+ * $this->getRevision() may already return null when the page proper was deleted.
* @param User|null $user The user that caused the deletion
*/
public function doDeleteUpdates(
$id, Content $content = null, Revision $revision = null, User $user = null
) {
+ if ( $id !== $this->getId() ) {
+ throw new InvalidArgumentException( 'Mismatching page ID' );
+ }
+
try {
$countable = $this->isCountable();
} catch ( Exception $ex ) {
) );
// Delete pagelinks, update secondary indexes, etc
- $updates = $this->getDeletionUpdates( $content );
+ $updates = $this->getDeletionUpdates(
+ $revision ? $revision->getRevisionRecord() : $content
+ );
foreach ( $updates as $update ) {
DeferredUpdates::addUpdate( $update );
}
* updates should remove any information about this page from secondary data
* stores such as links tables.
*
- * @param Content|null $content Optional Content object for determining the
- * necessary updates.
+ * @param RevisionRecord|Content|null $rev The revision being deleted. Also accepts a Content
+ * object for backwards compatibility.
* @return DeferrableUpdate[]
*/
- public function getDeletionUpdates( Content $content = null ) {
- if ( !$content ) {
- // load content object, which may be used to determine the necessary updates.
- // XXX: the content may not be needed to determine the updates.
+ public function getDeletionUpdates( $rev = null ) {
+ if ( !$rev ) {
+ wfDeprecated( __METHOD__ . ' without a RevisionRecord', '1.32' );
+
try {
- $content = $this->getContent( Revision::RAW );
+ $rev = $this->getRevisionRecord();
} catch ( Exception $ex ) {
// If we can't load the content, something is wrong. Perhaps that's why
// the user is trying to delete the page, so let's not fail in that case.
// Note that doDeleteArticleReal() will already have logged an issue with
// loading the content.
+ wfDebug( __METHOD__ . ' failed to load current revision of page ' . $this->getId() );
}
}
- if ( !$content ) {
- $updates = [];
+ if ( !$rev ) {
+ $slotContent = [];
+ } elseif ( $rev instanceof Content ) {
+ wfDeprecated( __METHOD__ . ' with a Content object instead of a RevisionRecord', '1.32' );
+
+ $slotContent = [ 'main' => $rev ];
} else {
- $updates = $content->getDeletionUpdates( $this );
+ $slotContent = array_map( function ( SlotRecord $slot ) {
+ return $slot->getContent( Revision::RAW );
+ }, $rev->getSlots()->getSlots() );
}
- Hooks::run( 'WikiPageDeletionUpdates', [ $this, $content, &$updates ] );
- return $updates;
+ $allUpdates = [ new LinksDeletionUpdate( $this ) ];
+
+ // NOTE: once Content::getDeletionUpdates() is removed, we only need to content
+ // model here, not the content object!
+ // TODO: consolidate with similar logic in DerivedPageDataUpdater::getSecondaryDataUpdates()
+ /** @var Content $content */
+ foreach ( $slotContent as $role => $content ) {
+ $handler = $content->getContentHandler();
+
+ $updates = $handler->getDeletionUpdates(
+ $this->getTitle(),
+ $role
+ );
+ $allUpdates = array_merge( $allUpdates, $updates );
+
+ // TODO: remove B/C hack in 1.32!
+ $legacyUpdates = $content->getDeletionUpdates( $this );
+
+ // HACK: filter out redundant and incomplete LinksDeletionUpdate
+ $legacyUpdates = array_filter( $legacyUpdates, function ( $update ) {
+ return !( $update instanceof LinksDeletionUpdate );
+ } );
+
+ $allUpdates = array_merge( $allUpdates, $legacyUpdates );
+ }
+
+ Hooks::run( 'PageDeletionDataUpdates', [ $this->getTitle(), $rev, &$allUpdates ] );
+
+ // TODO: hard deprecate old hook in 1.33
+ Hooks::run( 'WikiPageDeletionUpdates', [ $this, $content, &$allUpdates ] );
+ return $allUpdates;
}
/**
} elseif ( is_array( $contextNode ) ) {
// Node descriptor array
if ( count( $contextNode ) !== 2 ) {
- throw new MWException( __METHOD__.
+ throw new MWException( __METHOD__ .
': found an array where a node descriptor should be' );
}
list( $contextName, $contextChildren ) = $contextNode;
$class = self::class;
}
} else {
- throw new MWException( __METHOD__.': invalid node descriptor' );
+ throw new MWException( __METHOD__ . ': invalid node descriptor' );
}
return new $class( $store, $index );
}
public function __construct( array $store, $index ) {
$descriptor = $store[$index];
if ( $descriptor[PPNode_Hash_Tree::NAME][0] !== '@' ) {
- throw new MWException( __METHOD__.': invalid name in attribute descriptor' );
+ throw new MWException( __METHOD__ . ': invalid name in attribute descriptor' );
}
$this->name = substr( $descriptor[PPNode_Hash_Tree::NAME], 1 );
$this->value = $descriptor[PPNode_Hash_Tree::CHILDREN][0];
if ( self::inDebugMode() ) {
$scripts = new XmlJsCode( "function ( $, jQuery, require, module ) {\n{$scripts->value}\n}" );
} else {
- $scripts = new XmlJsCode( 'function($,jQuery,require,module){'. $scripts->value . '}' );
+ $scripts = new XmlJsCode( 'function($,jQuery,require,module){' . $scripts->value . '}' );
}
} elseif ( !is_string( $scripts ) && !is_array( $scripts ) ) {
throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
}
// Because PHP can't have floats as array keys
- uksort( $logosPerDppx, function ( $a , $b ) {
+ uksort( $logosPerDppx, function ( $a, $b ) {
$a = floatval( $a );
$b = floatval( $b );
// Sort from smallest to largest (e.g. 1x, 1.5x, 2x)
if ( !$signupendMsg->isDisabled() ) {
$usingHTTPS = $this->getRequest()->getProtocol() === 'https';
$signupendText = ( $usingHTTPS && !$signupendHttpsMsg->isBlank() )
- ? $signupendHttpsMsg ->parse() : $signupendMsg->parse();
+ ? $signupendHttpsMsg->parse() : $signupendMsg->parse();
$fieldDefinitions['signupend'] = [
'type' => 'info',
'raw' => true,
/**
* Handle Special:Redirect/user/xxxx (by redirecting to User:YYYY)
*
- * @return string|null Url to redirect to, or null if $mValue is invalid.
+ * @return Status A good status contains the url to redirect to
*/
function dispatchUser() {
if ( !ctype_digit( $this->mValue ) ) {
- return null;
+ // Message: redirect-not-numeric
+ return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
}
$user = User::newFromId( (int)$this->mValue );
$username = $user->getName(); // load User as side-effect
if ( $user->isAnon() ) {
- return null;
+ // Message: redirect-not-exists
+ return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
}
$userpage = Title::makeTitle( NS_USER, $username );
- return $userpage->getFullURL( '', false, PROTO_CURRENT );
+ return Status::newGood( $userpage->getFullURL( '', false, PROTO_CURRENT ) );
}
/**
* Handle Special:Redirect/file/xxxx
*
- * @return string|null Url to redirect to, or null if $mValue is not found.
+ * @return Status A good status contains the url to redirect to
*/
function dispatchFile() {
- $title = Title::makeTitleSafe( NS_FILE, $this->mValue );
-
- if ( !$title instanceof Title ) {
- return null;
+ try {
+ $title = Title::newFromTextThrow( $this->mValue, NS_FILE );
+ if ( $title && !$title->inNamespace( NS_FILE ) ) {
+ // If the given value contains a namespace enforce file namespace
+ $title = Title::newFromTextThrow( Title::makeName( NS_FILE, $this->mValue ) );
+ }
+ } catch ( MalformedTitleException $e ) {
+ return Status::newFatal( $e->getMessageObject() );
}
$file = wfFindFile( $title );
if ( !$file || !$file->exists() ) {
- return null;
+ // Message: redirect-not-exists
+ return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
}
// Default behavior: Use the direct link to the file.
$url = $file->getUrl();
}
}
- return $url;
+ return Status::newGood( $url );
}
/**
* Handle Special:Redirect/revision/xxx
* (by redirecting to index.php?oldid=xxx)
*
- * @return string|null Url to redirect to, or null if $mValue is invalid.
+ * @return Status A good status contains the url to redirect to
*/
function dispatchRevision() {
$oldid = $this->mValue;
if ( !ctype_digit( $oldid ) ) {
- return null;
+ // Message: redirect-not-numeric
+ return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
}
$oldid = (int)$oldid;
if ( $oldid === 0 ) {
- return null;
+ // Message: redirect-not-exists
+ return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
}
- return wfAppendQuery( wfScript( 'index' ), [
+ return Status::newGood( wfAppendQuery( wfScript( 'index' ), [
'oldid' => $oldid
- ] );
+ ] ) );
}
/**
* Handle Special:Redirect/page/xxx (by redirecting to index.php?curid=xxx)
*
- * @return string|null Url to redirect to, or null if $mValue is invalid.
+ * @return Status A good status contains the url to redirect to
*/
function dispatchPage() {
$curid = $this->mValue;
if ( !ctype_digit( $curid ) ) {
- return null;
+ // Message: redirect-not-numeric
+ return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
}
$curid = (int)$curid;
if ( $curid === 0 ) {
- return null;
+ // Message: redirect-not-exists
+ return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
}
- return wfAppendQuery( wfScript( 'index' ), [
+ return Status::newGood( wfAppendQuery( wfScript( 'index' ), [
'curid' => $curid
- ] );
+ ] ) );
}
/**
* (by redirecting to index.php?title=Special:Log&logid=xxx)
*
* @since 1.27
- * @return string|null Url to redirect to, or null if $mValue is invalid.
+ * @return Status A good status contains the url to redirect to
*/
function dispatchLog() {
$logid = $this->mValue;
if ( !ctype_digit( $logid ) ) {
- return null;
+ // Message: redirect-not-numeric
+ return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
}
$logid = (int)$logid;
if ( $logid === 0 ) {
- return null;
+ // Message: redirect-not-exists
+ return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
}
$query = [ 'title' => 'Special:Log', 'logid' => $logid ];
- return wfAppendQuery( wfScript( 'index' ), $query );
+ return Status::newGood( wfAppendQuery( wfScript( 'index' ), $query ) );
}
/**
* or do nothing (if $mValue wasn't set) allowing the form to be
* displayed.
*
- * @return bool True if a redirect was successfully handled.
+ * @return Status|bool True if a redirect was successfully handled.
*/
function dispatch() {
// the various namespaces supported by Special:Redirect
switch ( $this->mType ) {
case 'user':
- $url = $this->dispatchUser();
+ $status = $this->dispatchUser();
break;
case 'file':
- $url = $this->dispatchFile();
+ $status = $this->dispatchFile();
break;
case 'revision':
- $url = $this->dispatchRevision();
+ $status = $this->dispatchRevision();
break;
case 'page':
- $url = $this->dispatchPage();
+ $status = $this->dispatchPage();
break;
case 'logid':
- $url = $this->dispatchLog();
+ $status = $this->dispatchLog();
break;
default:
- $url = null;
+ $status = null;
break;
}
- if ( $url ) {
- $this->getOutput()->redirect( $url );
+ if ( $status && $status->isGood() ) {
+ $this->getOutput()->redirect( $status->getValue() );
return true;
}
if ( !is_null( $this->mValue ) ) {
$this->getOutput()->setStatusCode( 404 );
- // Message: redirect-not-exists
- $msg = $this->getMessagePrefix() . '-not-exists';
- return Status::newFatal( $msg );
+ return $status;
}
return false;
'div',
[
'class' =>
- 'oo-ui-widget oo-ui-widget-enabled oo-ui-optionWidget '.
+ 'oo-ui-widget oo-ui-widget-enabled oo-ui-optionWidget ' .
'oo-ui-tabOptionWidget oo-ui-labelElement' .
( $i === 0 ? ' oo-ui-optionWidget-selected' : '' )
],
[ 'class' => 'oo-ui-layout oo-ui-panelLayout oo-ui-indexLayout-tabPanel' ],
Html::rawElement(
'div',
- [ 'class' => 'oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget '.
+ [ 'class' => 'oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget ' .
'oo-ui-selectWidget-depressed oo-ui-tabSelectWidget' ],
implode( $fakeTabs )
)
// Should these be merged into the title char list?
$unicodeBlacklist = '/[' .
'\x{0080}-\x{009f}' . # iso-8859-1 control chars
- '\x{00a0}' . # non-breaking space
+ '\x{00a0}' . # non-breaking space
'\x{2000}-\x{200f}' . # various whitespace
'\x{2028}-\x{202f}' . # breaks and control chars
- '\x{3000}' . # ideographic space
+ '\x{3000}' . # ideographic space
'\x{e000}-\x{f8ff}' . # private use
']/u';
if ( preg_match( $unicodeBlacklist, $name ) ) {
$text = preg_replace( $pat, $rep, $text );
}
return $text;
- break;
case 'kk-latn':
case 'kk-tr':
foreach ( $this->mCyrl2Latn as $pat => $rep ) {
$text = preg_replace( $pat, $rep, $text );
}
return $text;
- break;
case 'kk-cyrl':
case 'kk-kz':
foreach ( $this->mLatn2Cyrl as $pat => $rep ) {
$text = preg_replace( $pat, $rep, $text );
}
return $text;
- break;
default:
return $text;
}
# load C2L and L2C bidirectional affix mappings
$this->addMappings( $this->prefixMapping,
- $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/'.self::WB, '/u' );
+ $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/' . self::WB, '/u' );
$this->addMappings( $this->suffixMapping,
- $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/', self::WB.'/u' );
+ $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/', self::WB . '/u' );
# tack on one-way mappings to the ends of the prefix and suffix patterns
$this->Cyrl2LatnPatterns += $this->Cyrl2LatnRegexes;
'му([иэИЭ])' => 'mü$1',
# originally L2C, here swapped
- 'роль$1' => 'rol([^ü]|'.self::WB.')',
- 'усть$1' => 'üst([^ü]|'.self::WB.')',
+ 'роль$1' => 'rol([^ü]|' . self::WB . ')',
+ 'усть$1' => 'üst([^ü]|' . self::WB . ')',
# more prefixes
'ком-кок' => 'köm-kök',
// TODO: refactor upper/lower/first capital whole words without
// regexes into simpler list
- '/'.self::WB.'КъЮШ'.self::WB.'/u' => 'QYŞ',
- '/'.self::WB.'ЮШ'.self::WB.'/u' => 'YŞ',
-
- '/'.self::WB.'кок'.self::WB.'/u' => 'kök',
- '/'.self::WB.'Кок'.self::WB.'/u' => 'Kök',
- '/'.self::WB.'КОК'.self::WB.'/u' => 'KÖK',
- '/'.self::WB.'ком-кок'.self::WB.'/u' => 'köm-kök',
- '/'.self::WB.'Ком-кок'.self::WB.'/u' => 'Köm-kök',
- '/'.self::WB.'КОМ-КОК'.self::WB.'/u' => 'KÖM-KÖK',
-
- '/'.self::WB.'коп'.self::WB.'/u' => 'köp',
- '/'.self::WB.'Коп'.self::WB.'/u' => 'Köp',
- '/'.self::WB.'КОП'.self::WB.'/u' => 'KÖP',
-
- '/'.self::WB.'курк'.self::WB.'/u' => 'kürk',
- '/'.self::WB.'Курк'.self::WB.'/u' => 'Kürk',
- '/'.self::WB.'КУРК'.self::WB.'/u' => 'KÜRK',
-
- '/'.self::WB.'ог'.self::WB.'/u' => 'ög',
- '/'.self::WB.'Ог'.self::WB.'/u' => 'Ög',
- '/'.self::WB.'ОГ'.self::WB.'/u' => 'ÖG',
-
- '/'.self::WB.'юрип'.self::WB.'/u' => 'yürip',
- '/'.self::WB.'Юрип'.self::WB.'/u' => 'Yürip',
- '/'.self::WB.'ЮРИП'.self::WB.'/u' => 'YÜRİP',
-
- '/'.self::WB.'юз'.self::WB.'/u' => 'yüz',
- '/'.self::WB.'Юз'.self::WB.'/u' => 'Yüz',
- '/'.self::WB.'ЮЗ'.self::WB.'/u' => 'YÜZ',
-
- '/'.self::WB.'юк'.self::WB.'/u' => 'yük',
- '/'.self::WB.'Юк'.self::WB.'/u' => 'Yük',
- '/'.self::WB.'ЮК'.self::WB.'/u' => 'YÜK',
-
- '/'.self::WB.'буюп'.self::WB.'/u' => 'büyüp',
- '/'.self::WB.'Буюп'.self::WB.'/u' => 'Büyüp',
- '/'.self::WB.'БУЮП'.self::WB.'/u' => 'BÜYÜP',
-
- '/'.self::WB.'буюк'.self::WB.'/u' => 'büyük',
- '/'.self::WB.'Буюк'.self::WB.'/u' => 'Büyük',
- '/'.self::WB.'БУЮК'.self::WB.'/u' => 'BÜYÜK',
-
- '/'.self::WB.'джонк'.self::WB.'/u' => 'cönk',
- '/'.self::WB.'Джонк'.self::WB.'/u' => 'Cönk',
- '/'.self::WB.'ДЖОНК'.self::WB.'/u' => 'CÖNK',
- '/'.self::WB.'джонкю'.self::WB.'/u' => 'cönkü',
- '/'.self::WB.'Джонкю'.self::WB.'/u' => 'Cönkü',
- '/'.self::WB.'ДЖОНКЮ'.self::WB.'/u' => 'CÖNKÜ',
-
- '/'.self::WB.'куркчи/u' => 'kürkçi',
- '/'.self::WB.'Куркчи/u' => 'Kürkçi',
- '/'.self::WB.'КУРКЧИ/u' => 'KÜRKÇI',
-
- '/'.self::WB.'устке'.self::WB.'/u' => 'üstke',
- '/'.self::WB.'Устке'.self::WB.'/u' => 'Üstke',
- '/'.self::WB.'УСТКЕ'.self::WB.'/u' => 'ÜSTKE',
- '/'.self::WB.'устте'.self::WB.'/u' => 'üstte',
- '/'.self::WB.'Устте'.self::WB.'/u' => 'Üstte',
- '/'.self::WB.'УСТТЕ'.self::WB.'/u' => 'ÜSTTE',
- '/'.self::WB.'усттен'.self::WB.'/u' => 'üstten',
- '/'.self::WB.'Усттен'.self::WB.'/u' => 'Üstten',
- '/'.self::WB.'УСТТЕН'.self::WB.'/u' => 'ÜSTTEN',
+ '/' . self::WB . 'КъЮШ' . self::WB . '/u' => 'QYŞ',
+ '/' . self::WB . 'ЮШ' . self::WB . '/u' => 'YŞ',
+
+ '/' . self::WB . 'кок' . self::WB . '/u' => 'kök',
+ '/' . self::WB . 'Кок' . self::WB . '/u' => 'Kök',
+ '/' . self::WB . 'КОК' . self::WB . '/u' => 'KÖK',
+ '/' . self::WB . 'ком-кок' . self::WB . '/u' => 'köm-kök',
+ '/' . self::WB . 'Ком-кок' . self::WB . '/u' => 'Köm-kök',
+ '/' . self::WB . 'КОМ-КОК' . self::WB . '/u' => 'KÖM-KÖK',
+
+ '/' . self::WB . 'коп' . self::WB . '/u' => 'köp',
+ '/' . self::WB . 'Коп' . self::WB . '/u' => 'Köp',
+ '/' . self::WB . 'КОП' . self::WB . '/u' => 'KÖP',
+
+ '/' . self::WB . 'курк' . self::WB . '/u' => 'kürk',
+ '/' . self::WB . 'Курк' . self::WB . '/u' => 'Kürk',
+ '/' . self::WB . 'КУРК' . self::WB . '/u' => 'KÜRK',
+
+ '/' . self::WB . 'ог' . self::WB . '/u' => 'ög',
+ '/' . self::WB . 'Ог' . self::WB . '/u' => 'Ög',
+ '/' . self::WB . 'ОГ' . self::WB . '/u' => 'ÖG',
+
+ '/' . self::WB . 'юрип' . self::WB . '/u' => 'yürip',
+ '/' . self::WB . 'Юрип' . self::WB . '/u' => 'Yürip',
+ '/' . self::WB . 'ЮРИП' . self::WB . '/u' => 'YÜRİP',
+
+ '/' . self::WB . 'юз' . self::WB . '/u' => 'yüz',
+ '/' . self::WB . 'Юз' . self::WB . '/u' => 'Yüz',
+ '/' . self::WB . 'ЮЗ' . self::WB . '/u' => 'YÜZ',
+
+ '/' . self::WB . 'юк' . self::WB . '/u' => 'yük',
+ '/' . self::WB . 'Юк' . self::WB . '/u' => 'Yük',
+ '/' . self::WB . 'ЮК' . self::WB . '/u' => 'YÜK',
+
+ '/' . self::WB . 'буюп' . self::WB . '/u' => 'büyüp',
+ '/' . self::WB . 'Буюп' . self::WB . '/u' => 'Büyüp',
+ '/' . self::WB . 'БУЮП' . self::WB . '/u' => 'BÜYÜP',
+
+ '/' . self::WB . 'буюк' . self::WB . '/u' => 'büyük',
+ '/' . self::WB . 'Буюк' . self::WB . '/u' => 'Büyük',
+ '/' . self::WB . 'БУЮК' . self::WB . '/u' => 'BÜYÜK',
+
+ '/' . self::WB . 'джонк' . self::WB . '/u' => 'cönk',
+ '/' . self::WB . 'Джонк' . self::WB . '/u' => 'Cönk',
+ '/' . self::WB . 'ДЖОНК' . self::WB . '/u' => 'CÖNK',
+ '/' . self::WB . 'джонкю' . self::WB . '/u' => 'cönkü',
+ '/' . self::WB . 'Джонкю' . self::WB . '/u' => 'Cönkü',
+ '/' . self::WB . 'ДЖОНКЮ' . self::WB . '/u' => 'CÖNKÜ',
+
+ '/' . self::WB . 'куркчи/u' => 'kürkçi',
+ '/' . self::WB . 'Куркчи/u' => 'Kürkçi',
+ '/' . self::WB . 'КУРКЧИ/u' => 'KÜRKÇI',
+
+ '/' . self::WB . 'устке' . self::WB . '/u' => 'üstke',
+ '/' . self::WB . 'Устке' . self::WB . '/u' => 'Üstke',
+ '/' . self::WB . 'УСТКЕ' . self::WB . '/u' => 'ÜSTKE',
+ '/' . self::WB . 'устте' . self::WB . '/u' => 'üstte',
+ '/' . self::WB . 'Устте' . self::WB . '/u' => 'Üstte',
+ '/' . self::WB . 'УСТТЕ' . self::WB . '/u' => 'ÜSTTE',
+ '/' . self::WB . 'усттен' . self::WB . '/u' => 'üstten',
+ '/' . self::WB . 'Усттен' . self::WB . '/u' => 'Üstten',
+ '/' . self::WB . 'УСТТЕН' . self::WB . '/u' => 'ÜSTTEN',
# отдельно стоящие Ё и Я
# stand-alone Ё and Я
- '/'.self::WB.'Я'.self::WB.'/u' => 'Ya',
- '/'.self::WB.'Ё'.self::WB.'/u' => 'Yo',
+ '/' . self::WB . 'Я' . self::WB . '/u' => 'Ya',
+ '/' . self::WB . 'Ё' . self::WB . '/u' => 'Yo',
############################
# относятся к началу слова #
# word prefixes #
############################
- '/'.self::WB.'КъЮШн/u' => 'QYŞn',
- '/'.self::WB.'ЮШн/u' => 'YŞn',
+ '/' . self::WB . 'КъЮШн/u' => 'QYŞn',
+ '/' . self::WB . 'ЮШн/u' => 'YŞn',
# need to convert digraphs (гъ, къ, нъ, дж) now to match patterns
'/гъ/u' => 'ğ',
'/Д[жЖ]/u' => 'C',
# о => ö
- '/'.self::WB.'(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u'
- => '$1ö$2$3$4',
- '/'.self::WB.'о(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2$3',
- '/'.self::WB.'(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u'
- => '$1Ö$2$3$4',
- '/'.self::WB.'О(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2$3',
-
- '/'.self::WB.'(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ö$2$3',
- '/'.self::WB.'о(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2',
- '/'.self::WB.'(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ö$2$3',
- '/'.self::WB.'О(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2',
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])о([' . Crh::C_CONS . '])([' . Crh::C_CONS .
+ '])([еиэюьü])/u' => '$1ö$2$3$4',
+ '/' . self::WB . 'о([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ö$1$2$3',
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])О([' . Crh::C_CONS . '])([' . Crh::C_CONS .
+ '])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ö$2$3$4',
+ '/' . self::WB . 'О([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u'
+ => 'Ö$1$2$3',
+
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])о([' . Crh::C_CONS . '])([еиэюьü])/u' => '$1ö$2$3',
+ '/' . self::WB . 'о([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ö$1$2',
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])О([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u'
+ => '$1Ö$2$3',
+ '/' . self::WB . 'О([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2',
# ё => yö
- '/'.self::WB.'ё(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2$3',
- '/'.self::WB.'Ё(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2$3',
- '/'.self::WB.'Ё(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2$3',
- '/'.self::WB.'ё(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2',
- '/'.self::WB.'Ё(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2',
- '/'.self::WB.'Ё(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2',
+ '/' . self::WB . 'ё([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([ьеюü])/u' => 'yö$1$2$3',
+ '/' . self::WB . 'Ё([' . Crh::C_CONS_LC . '])([' . Crh::C_CONS_LC . '])([ьеюü])/u' => 'Yö$1$2$3',
+ '/' . self::WB . 'Ё([' . Crh::C_CONS_UC . '])([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' => 'YÖ$1$2$3',
+ '/' . self::WB . 'ё([' . Crh::C_CONS . '])([ьеюü])/u' => 'yö$1$2',
+ '/' . self::WB . 'Ё([' . Crh::C_CONS_LC . '])([ьеюü])/u' => 'Yö$1$2',
+ '/' . self::WB . 'Ё([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' => 'YÖ$1$2',
# у => ü, ую => üyü
- '/'.self::WB.'(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u'
- => '$1ü$2$3$4',
- '/'.self::WB.'у(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2$3',
- '/'.self::WB.'ую(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2$3',
- '/'.self::WB.'(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u'
- => '$1Ü$2$3$4',
- '/'.self::WB.'У(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2$3',
- '/'.self::WB.'Ую(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2$3',
- '/'.self::WB.'УЮ(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2$3',
-
- '/'.self::WB.'(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ü$2$3',
- '/'.self::WB.'у(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2',
- '/'.self::WB.'ую(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2',
- '/'.self::WB.'(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ü$2$3',
- '/'.self::WB.'У(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2',
- '/'.self::WB.'Ую(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2',
- '/'.self::WB.'УЮ(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2',
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])у([' . Crh::C_CONS . '])([' . Crh::C_CONS .
+ '])([еиэюьü])/u' => '$1ü$2$3$4',
+ '/' . self::WB . 'у([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ü$1$2$3',
+ '/' . self::WB . 'ую([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'üyü$1$2$3',
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])У([' . Crh::C_CONS . '])([' . Crh::C_CONS .
+ '])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ü$2$3$4',
+ '/' . self::WB . 'У([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u'
+ => 'Ü$1$2$3',
+ '/' . self::WB . 'Ую([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'Üyü$1$2$3',
+ '/' . self::WB . 'УЮ([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ÜYÜ$1$2$3',
+
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])у([' . Crh::C_CONS . '])([еиэюьü])/u' => '$1ü$2$3',
+ '/' . self::WB . 'у([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ü$1$2',
+ '/' . self::WB . 'ую([' . Crh::C_CONS . '])([еиэюьü])/u' => 'üyü$1$2',
+ '/' . self::WB . '([' . Crh::C_M_CONS . '])У([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u'
+ => '$1Ü$2$3',
+ '/' . self::WB . 'У([' . Crh::C_CONS . '])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2',
+ '/' . self::WB . 'Ую([' . Crh::C_CONS . '])([еиэюьü])/u' => 'Üyü$1$2',
+ '/' . self::WB . 'УЮ([' . Crh::C_CONS . '])([еиэюьü])/u' => 'ÜYÜ$1$2',
# ю => yü
- '/'.self::WB.'([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u'
+ '/' . self::WB . '([аыоуеиёюАЫОУЕИЁЮ]?)ю([' . Crh::C_CONS . '])([' . Crh::C_CONS . '])([ьеюü])/u'
=> '$1yü$2$3$4',
- '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u'
+ '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_LC . '])([' . Crh::C_CONS_LC . '])([ьеюü])/u'
=> '$1Yü$2$3$4',
- '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u'
+ '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_UC . '])([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u'
=> '$1YÜ$2$3$4',
- '/'.self::WB.'([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])([ьеюü])/u' => '$1yü$2$3',
- '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])([ьеюü])/u' => '$1Yü$2$3',
- '/'.self::WB.'([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => '$1YÜ$2$3',
+ '/' . self::WB . '([аыоуеиёюАЫОУЕИЁЮ]?)ю([' . Crh::C_CONS . '])([ьеюü])/u' => '$1yü$2$3',
+ '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_LC . '])([ьеюü])/u' => '$1Yü$2$3',
+ '/' . self::WB . '([АЫОУЕИЁЮ]?)Ю([' . Crh::C_CONS_UC . '])([ЬЕЮÜ])/u' => '$1YÜ$2$3',
# e => ye, я => ya
- '/'.self::WB.'е/u' => 'ye',
- '/'.self::WB.'Е(['.Crh::C_LC.'cğñqöü])/u' => 'Ye$1',
- '/'.self::WB.'Е(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YE$1',
- '/'.self::WB.'я/u' => 'ya',
- '/'.self::WB.'Я(['.Crh::C_LC.'cğñqöü])/u' => 'Ya$1',
- '/'.self::WB.'Я(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YA$1',
+ '/' . self::WB . 'е/u' => 'ye',
+ '/' . self::WB . 'Е([' . Crh::C_LC . 'cğñqöü])/u' => 'Ye$1',
+ '/' . self::WB . 'Е([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YE$1',
+ '/' . self::WB . 'я/u' => 'ya',
+ '/' . self::WB . 'Я([' . Crh::C_LC . 'cğñqöü])/u' => 'Ya$1',
+ '/' . self::WB . 'Я([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YA$1',
'/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])е/u' => '$1ye',
- '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е(['.Crh::C_LC.'cğñqöü])/u' => '$1Ye$2',
- '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е(['.Crh::C_UC.'CĞÑQÖÜ])/u' => '$1YE$2',
+ '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е([' . Crh::C_LC . 'cğñqöü])/u' => '$1Ye$2',
+ '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => '$1YE$2',
'/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])я/u' => '$1ya',
- '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я(['.Crh::C_LC.'cğñqöü])/u' => '$1Ya$2',
- '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я(['.Crh::C_UC.'CĞÑQÖÜ])/u' => '$1YA$2',
+ '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я([' . Crh::C_LC . 'cğñqöü])/u' => '$1Ya$2',
+ '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => '$1YA$2',
###############################
# не зависят от места в слове #
# Ö, Ü 1-й заход: ё, ю после согласных > ö, ü
# Ö, Ü 1st instance: ё, ю after consonants > ö, ü
- '/(['.Crh::C_CONS.'])ю/u' => '$1ü',
- '/(['.Crh::C_CONS.'])Ю/u' => '$1Ü',
- '/(['.Crh::C_CONS.'])ё/u' => '$1ö',
- '/(['.Crh::C_CONS.'])Ё/u' => '$1Ö',
+ '/([' . Crh::C_CONS . '])ю/u' => '$1ü',
+ '/([' . Crh::C_CONS . '])Ю/u' => '$1Ü',
+ '/([' . Crh::C_CONS . '])ё/u' => '$1ö',
+ '/([' . Crh::C_CONS . '])Ё/u' => '$1Ö',
# остальные вхождения о, у, ё, ю
# other occurences of о, у, ё, ю
- '/Ё(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YO$1',
- '/Ю(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YU$1',
+ '/Ё([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YO$1',
+ '/Ю([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'YU$1',
# Ц & Щ
- '/Ц(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'TS$1',
- '/Щ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'ŞÇ$1',
+ '/Ц([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'TS$1',
+ '/Щ([' . Crh::C_UC . 'CĞÑQÖÜ])/u' => 'ŞÇ$1',
];
$this->Latn2CyrlRegexes = [
// TODO: refactor upper/lower/first capital whole words without
// regexes into simpler list
- '/'.self::WB.'an'.self::WB.'/u' => 'ань',
- '/'.self::WB.'An'.self::WB.'/u' => 'Ань',
- '/'.self::WB.'AN'.self::WB.'/u' => 'АНЬ',
- '/'.self::WB.'ange'.self::WB.'/u' => 'аньге',
- '/'.self::WB.'Ange'.self::WB.'/u' => 'Аньге',
- '/'.self::WB.'ANGE'.self::WB.'/u' => 'АНЬГЕ',
- '/'.self::WB.'ande'.self::WB.'/u' => 'аньде',
- '/'.self::WB.'Ande'.self::WB.'/u' => 'Аньде',
- '/'.self::WB.'ANDE'.self::WB.'/u' => 'АНЬДЕ',
- '/'.self::WB.'anki'.self::WB.'/u' => 'аньки',
- '/'.self::WB.'Anki'.self::WB.'/u' => 'Аньки',
- '/'.self::WB.'ANKİ'.self::WB.'/u' => 'АНЬКИ',
- '/'.self::WB.'deral'.self::WB.'/u' => 'деръал',
- '/'.self::WB.'Deral'.self::WB.'/u' => 'Деръал',
- '/'.self::WB.'DERAL'.self::WB.'/u' => 'ДЕРЪАЛ',
- '/'.self::WB.'kör'.self::WB.'/u' => 'кёр',
- '/'.self::WB.'Kör'.self::WB.'/u' => 'Кёр',
- '/'.self::WB.'KÖR'.self::WB.'/u' => 'КЁР',
- '/'.self::WB.'mer'.self::WB.'/u' => 'мэр',
- '/'.self::WB.'Mer'.self::WB.'/u' => 'Мэр',
- '/'.self::WB.'MER'.self::WB.'/u' => 'МЭР',
-
- '/'.self::WB.'cönk/u' => 'джонк',
- '/'.self::WB.'Cönk/u' => 'Джонк',
- '/'.self::WB.'CÖNK/u' => 'ДЖОНК',
+ '/' . self::WB . 'an' . self::WB . '/u' => 'ань',
+ '/' . self::WB . 'An' . self::WB . '/u' => 'Ань',
+ '/' . self::WB . 'AN' . self::WB . '/u' => 'АНЬ',
+ '/' . self::WB . 'ange' . self::WB . '/u' => 'аньге',
+ '/' . self::WB . 'Ange' . self::WB . '/u' => 'Аньге',
+ '/' . self::WB . 'ANGE' . self::WB . '/u' => 'АНЬГЕ',
+ '/' . self::WB . 'ande' . self::WB . '/u' => 'аньде',
+ '/' . self::WB . 'Ande' . self::WB . '/u' => 'Аньде',
+ '/' . self::WB . 'ANDE' . self::WB . '/u' => 'АНЬДЕ',
+ '/' . self::WB . 'anki' . self::WB . '/u' => 'аньки',
+ '/' . self::WB . 'Anki' . self::WB . '/u' => 'Аньки',
+ '/' . self::WB . 'ANKİ' . self::WB . '/u' => 'АНЬКИ',
+ '/' . self::WB . 'deral' . self::WB . '/u' => 'деръал',
+ '/' . self::WB . 'Deral' . self::WB . '/u' => 'Деръал',
+ '/' . self::WB . 'DERAL' . self::WB . '/u' => 'ДЕРЪАЛ',
+ '/' . self::WB . 'kör' . self::WB . '/u' => 'кёр',
+ '/' . self::WB . 'Kör' . self::WB . '/u' => 'Кёр',
+ '/' . self::WB . 'KÖR' . self::WB . '/u' => 'КЁР',
+ '/' . self::WB . 'mer' . self::WB . '/u' => 'мэр',
+ '/' . self::WB . 'Mer' . self::WB . '/u' => 'Мэр',
+ '/' . self::WB . 'MER' . self::WB . '/u' => 'МЭР',
+
+ '/' . self::WB . 'cönk/u' => 'джонк',
+ '/' . self::WB . 'Cönk/u' => 'Джонк',
+ '/' . self::WB . 'CÖNK/u' => 'ДЖОНК',
# (y)etsin -> етсин/этсин
# note that target starts with CYRILLIC е/Е!
# буква Ё - первый заход
# расставляем Ь после согласных
- '/'.self::WB.'([yY])ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1ö$2ь$3',
- '/'.self::WB.'([yY])Ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1Ö$2Ь$3',
- '/'.self::WB.'AQŞ([^AEI]|'.self::WB.')/u' => 'АКъШ$1',
+ '/' . self::WB . '([yY])ö([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => '$1ö$2ь$3',
+ '/' . self::WB . '([yY])Ö([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => '$1Ö$2Ь$3',
+ '/' . self::WB . 'AQŞ([^AEI]|' . self::WB . ')/u' => 'АКъШ$1',
# буква Ю - первый заход
# расставляем Ь после согласных
- '/'.self::WB.'([yY])ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1ü$2ь$3',
- '/'.self::WB.'([yY])Ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|'.self::WB.')/u' => '$1Ü$2Ь$3',
-
- '/'.self::WB.'([bcgkpşBCGKPŞ])ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
- => '$1ö$2ь$3',
- '/'.self::WB.'([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
- => '$1Ö$2Ь$3',
- '/'.self::WB.'([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
- => '$1Ö$2Ь$3',
- '/'.self::WB.'([bcgkpşBCGKPŞ])ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+ '/' . self::WB . '([yY])ü([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u'
=> '$1ü$2ь$3',
- '/'.self::WB.'([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
- => '$1Ü$2Ь$3',
- '/'.self::WB.'([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u'
+ '/' . self::WB . '([yY])Ü([' . Crh::L_N_CONS . '])([aAuU' . Crh::L_CONS . ']|' . self::WB . ')/u'
=> '$1Ü$2Ь$3',
+ '/' . self::WB . '([bcgkpşBCGKPŞ])ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
+ self::WB . ')/u' => '$1ö$2ь$3',
+ '/' . self::WB . '([bcgkpşBCGKPŞ])Ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
+ self::WB . ')/u' => '$1Ö$2Ь$3',
+ '/' . self::WB . '([bcgkpşBCGKPŞ])Ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
+ self::WB . ')/u' => '$1Ö$2Ь$3',
+ '/' . self::WB . '([bcgkpşBCGKPŞ])ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
+ self::WB . ')/u' => '$1ü$2ь$3',
+ '/' . self::WB . '([bcgkpşBCGKPŞ])Ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
+ self::WB . ')/u' => '$1Ü$2Ь$3',
+ '/' . self::WB . '([bcgkpşBCGKPŞ])Ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
+ self::WB . ')/u' => '$1Ü$2Ь$3',
+
# ö и ü в начале слова
# случаи, когда нужен Ь
- '/'.self::WB.'ö(['.Crh::L_N_CONS.'pP])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'ö$1ь$2',
- '/'.self::WB.'Ö(['.Crh::L_N_CONS_LC.'p])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ö$1ь$2',
- '/'.self::WB.'Ö(['.Crh::L_N_CONS_UC.'P])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ö$1Ь$2',
- '/'.self::WB.'ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'ü$1ь$2',
- '/'.self::WB.'Ü(['.Crh::L_N_CONS_LC.'])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ü$1ь$2',
- '/'.self::WB.'Ü(['.Crh::L_N_CONS_UC.'])(['.Crh::L_CONS.']|'.self::WB.')/u' => 'Ü$1Ь$2',
-
- '/ts'.self::WB.'/u' => 'ц',
- '/şç'.self::WB.'/u' => 'щ',
- '/Ş[çÇ]'.self::WB.'/u' => 'Щ',
- '/T[sS]'.self::WB.'/u' => 'Ц',
+ '/' . self::WB . 'ö([' . Crh::L_N_CONS . 'pP])([' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => 'ö$1ь$2',
+ '/' . self::WB . 'Ö([' . Crh::L_N_CONS_LC . 'p])([' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => 'Ö$1ь$2',
+ '/' . self::WB . 'Ö([' . Crh::L_N_CONS_UC . 'P])([' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => 'Ö$1Ь$2',
+ '/' . self::WB . 'ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => 'ü$1ь$2',
+ '/' . self::WB . 'Ü([' . Crh::L_N_CONS_LC . '])([' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => 'Ü$1ь$2',
+ '/' . self::WB . 'Ü([' . Crh::L_N_CONS_UC . '])([' . Crh::L_CONS . ']|' . self::WB . ')/u'
+ => 'Ü$1Ь$2',
+
+ '/ts' . self::WB . '/u' => 'ц',
+ '/şç' . self::WB . '/u' => 'щ',
+ '/Ş[çÇ]' . self::WB . '/u' => 'Щ',
+ '/T[sS]' . self::WB . '/u' => 'Ц',
# Ь после Л
# add Ь after Л
- '/(['.Crh::L_F.'])l(['.Crh::L_CONS_LC.']|'.self::WB.')/u' => '$1ль$2',
- '/(['.Crh::L_F_UC.'])L(['.Crh::L_CONS.']|'.self::WB.')/u' => '$1ЛЬ$2',
+ '/([' . Crh::L_F . '])l([' . Crh::L_CONS_LC . ']|' . self::WB . ')/u' => '$1ль$2',
+ '/([' . Crh::L_F_UC . '])L([' . Crh::L_CONS . ']|' . self::WB . ')/u' => '$1ЛЬ$2',
# относятся к началу слова
- '/'.self::WB.'ts/u' => 'ц',
- '/'.self::WB.'T[sS]/u' => 'Ц',
+ '/' . self::WB . 'ts/u' => 'ц',
+ '/' . self::WB . 'T[sS]/u' => 'Ц',
- '/'.self::WB.'şç/u' => 'щ',
- '/'.self::WB.'Ş[çÇ]/u' => 'Щ',
+ '/' . self::WB . 'şç/u' => 'щ',
+ '/' . self::WB . 'Ş[çÇ]/u' => 'Щ',
# Э
- '/('.self::WB.'|['.Crh::L_VOW.'аеэяАЕЭЯ])e/u' => '$1э',
- '/('.self::WB.'|['.Crh::L_VOW_UC.'АЕЭЯ])E/u' => '$1Э',
+ '/(' . self::WB . '|[' . Crh::L_VOW . 'аеэяАЕЭЯ])e/u' => '$1э',
+ '/(' . self::WB . '|[' . Crh::L_VOW_UC . 'АЕЭЯ])E/u' => '$1Э',
- '/'.self::WB.'(['.Crh::L_M_CONS.'])ö/u' => '$1о',
- '/'.self::WB.'(['.Crh::L_M_CONS.'])Ö/u' => '$1О',
- '/'.self::WB.'(['.Crh::L_M_CONS.'])ü/u' => '$1у',
- '/'.self::WB.'(['.Crh::L_M_CONS.'])Ü/u' => '$1У',
+ '/' . self::WB . '([' . Crh::L_M_CONS . '])ö/u' => '$1о',
+ '/' . self::WB . '([' . Crh::L_M_CONS . '])Ö/u' => '$1О',
+ '/' . self::WB . '([' . Crh::L_M_CONS . '])ü/u' => '$1у',
+ '/' . self::WB . '([' . Crh::L_M_CONS . '])Ü/u' => '$1У',
- '/'.self::WB.'ö/u' => 'о',
- '/'.self::WB.'Ö/u' => 'О',
- '/'.self::WB.'ü/u' => 'у',
- '/'.self::WB.'Ü/u' => 'У',
+ '/' . self::WB . 'ö/u' => 'о',
+ '/' . self::WB . 'Ö/u' => 'О',
+ '/' . self::WB . 'ü/u' => 'у',
+ '/' . self::WB . 'Ü/u' => 'У',
# некоторые исключения
# some exceptions
'/T[sS][iİ]([^zZñÑ])/u' => 'ЦИ$1',
'/ts([ou])/u' => 'ц$1',
'/T[sS]([oOuU])/u' => 'Ц$1',
- '/ts(['.Crh::L_CONS.'])/u' => 'ц$1',
- '/T[sS](['.Crh::L_CONS.'])/u' => 'Ц$1',
- '/(['.Crh::L_CONS.'])ts/u' => '$1ц',
- '/(['.Crh::L_CONS.'])T[sS]/u' => '$1Ц',
+ '/ts([' . Crh::L_CONS . '])/u' => 'ц$1',
+ '/T[sS]([' . Crh::L_CONS . '])/u' => 'Ц$1',
+ '/([' . Crh::L_CONS . '])ts/u' => '$1ц',
+ '/([' . Crh::L_CONS . '])T[sS]/u' => '$1Ц',
'/tsиал/u' => 'циал',
'/TSИАЛ/u' => 'ЦИАЛ',
'/[ьЬ]([iİ])/u' => '$1',
# ya & ye
- '/(['.Crh::L_CONS.'])ya/u' => '$1ья',
- '/(['.Crh::L_CONS.'])Y[aA]/u' => '$1ЬЯ',
- '/(['.Crh::L_CONS.'])ye/u' => '$1ье',
- '/(['.Crh::L_CONS.'])Y[eE]/u' => '$1ЬЕ',
+ '/([' . Crh::L_CONS . '])ya/u' => '$1ья',
+ '/([' . Crh::L_CONS . '])Y[aA]/u' => '$1ЬЯ',
+ '/([' . Crh::L_CONS . '])ye/u' => '$1ье',
+ '/([' . Crh::L_CONS . '])Y[eE]/u' => '$1ЬЕ',
# расставляем Ь перед Ё
# place Ь in front of Ё
- '/(['.Crh::L_CONS.'])y[oö]/u' => '$1ьё',
- '/(['.Crh::L_CONS.'])Y[oOöÖ]/u' => '$1ЬЁ',
+ '/([' . Crh::L_CONS . '])y[oö]/u' => '$1ьё',
+ '/([' . Crh::L_CONS . '])Y[oOöÖ]/u' => '$1ЬЁ',
# оставшиеся вхождения yo и yö
# remaining occurrences of yo and yö
'/y[oö]/u' => 'ё',
# расставляем Ь перед Ю
# place Ь in front of Ю
- '/(['.Crh::L_CONS.'])y[uü]/u' => '$1ью',
- '/(['.Crh::L_CONS.'])Y[uUüÜ]/u' => '$1ЬЮ',
+ '/([' . Crh::L_CONS . '])y[uü]/u' => '$1ью',
+ '/([' . Crh::L_CONS . '])Y[uUüÜ]/u' => '$1ЬЮ',
# оставшиеся вхождения yu и yü
# remaining occurrences of yu and yü
'/y[uü]/u' => 'ю',
'/[ьЬ]([aA])/u' => '$1',
# дж
- '/C(['.Crh::L_UC.Crh::C_UC.'АЕЁЙОУЭЮЯ])/u' => 'ДЖ$1',
- '/(['.Crh::L_UC.Crh::C_UC.'АЕЁЙОУЭЮЯ])C/u' => '$1ДЖ',
+ '/C([' . Crh::L_UC . Crh::C_UC . 'АЕЁЙОУЭЮЯ])/u' => 'ДЖ$1',
+ '/([' . Crh::L_UC . Crh::C_UC . 'АЕЁЙОУЭЮЯ])C/u' => '$1ДЖ',
# гъ, къ, нъ
- '/Ğ(['.Crh::L_UC.Crh::C_UC.'])/u' => 'ГЪ$1',
- '/(['.Crh::L_UC.Crh::C_UC.'Ъ])Ğ/u' => '$1ГЪ',
+ '/Ğ([' . Crh::L_UC . Crh::C_UC . '])/u' => 'ГЪ$1',
+ '/([' . Crh::L_UC . Crh::C_UC . 'Ъ])Ğ/u' => '$1ГЪ',
- '/Q(['.Crh::L_UC.Crh::C_UC.'])/u' => 'КЪ$1',
- '/(['.Crh::L_UC.Crh::C_UC.'Ъ])Q/u' => '$1КЪ',
+ '/Q([' . Crh::L_UC . Crh::C_UC . '])/u' => 'КЪ$1',
+ '/([' . Crh::L_UC . Crh::C_UC . 'Ъ])Q/u' => '$1КЪ',
- '/Ñ(['.Crh::L_UC.Crh::C_UC.'])/u' => 'НЪ$1',
- '/(['.Crh::L_UC.Crh::C_UC.'Ъ])Ñ/u' => '$1НЪ',
+ '/Ñ([' . Crh::L_UC . Crh::C_UC . '])/u' => 'НЪ$1',
+ '/([' . Crh::L_UC . Crh::C_UC . 'Ъ])Ñ/u' => '$1НЪ',
];
}
"redirect-file": "اسم ملف",
"redirect-logid": "معرف السجل",
"redirect-not-exists": "المطلوب غير موجود",
+ "redirect-not-numeric": "قيمة غير رقمية",
"fileduplicatesearch": "بحث عن ملفات مكررة",
"fileduplicatesearch-summary": "ابحث عن الملفات المكررة بناء على قيم الهاش.",
"fileduplicatesearch-filename": "اسم الملف:",
"customcssprotected": "Nun tienes permisu pa editar esta páxina CSS porque contien preferencies personales d'otru usuariu.",
"customjsonprotected": "Nun tienes permisu pa editar esta páxina JSON porque contien preferencies personales d'otru usuariu.",
"customjsprotected": "Nun tienes permisu pa editar esta páxina de JavaScript porque contien preferencies personales d'otru usuariu.",
- "sitecssprotected": "Nun tienes permisu pa editar esta páxina de CSS porque puede afeutar a tolos visitantes",
- "sitejsonprotected": "Nun tienes permisu pa editar esta páxina en JSON porque puede afeutar a tolos visitantes",
- "sitejsprotected": "Nun tienes permisu para editar esta páxina de JavaScript porque puede afeutar a tolos visitantes",
+ "sitecssprotected": "Nun tienes permisu pa editar esta páxina de CSS porque puede afeutar a tolos visitantes.",
+ "sitejsonprotected": "Nun tienes permisu pa editar esta páxina en JSON porque puede afeutar a tolos visitantes.",
+ "sitejsprotected": "Nun tienes permisu para editar esta páxina de JavaScript porque puede afeutar a tolos visitantes.",
"mycustomcssprotected": "Nun tien permisu pa editar esta páxina CSS.",
"mycustomjsonprotected": "Nun tien permisu pa editar esta páxina JSON.",
"mycustomjsprotected": "Nun tien permisu pa editar esta páxina JavaScript.",
"redirect-file": "Nome del ficheru",
"redirect-logid": "ID del rexistru",
"redirect-not-exists": "Nun s'alcontró'l valor",
+ "redirect-not-numeric": "El valor nun ye un númberu",
"fileduplicatesearch": "Buscar archivos duplicaos",
"fileduplicatesearch-summary": "Busca archivos duplicaos basándose nos sos valores fragmentarios.",
"fileduplicatesearch-filename": "Nome del ficheru:",
"edit-error-long": "Errores:\n\n$1",
"revid": "revisión $1",
"pageid": "ID de páxina $1",
- "interfaceadmin-info": "$1\n\nLos permisos pa editar los ficheros CSS, JS y JSON globales del sitiu fueron apocayá dixebraos del permisu <code>editinterface</code>. Si nun entiendes por qué recibes esti error, por favor llei [[mw:MediaWiki_1.32/interface-admin]].",
+ "interfaceadmin-info": "$1\n\nLos permisos pa editar los ficheros CSS, JS y JSON globales del sitiu dixebráronse apocayá del permisu <code>editinterface</code>. Si nun entiendes por qué recibes esti error, llei [[mw:MediaWiki_1.32/interface-admin]].",
"rawhtml-notallowed": "Les etiquetes <html> nun pueden usase fuera de les páxines normales.",
"gotointerwiki": "Dexando {{SITENAME}}",
"gotointerwiki-invalid": "El títulu especificáu nun ye válidu.",
"currentrev": "最新版本",
"currentrev-asof": "$1 muōi-muōi siŏh-huôi biĕng-cĭk",
"revisionasof": "$1 gì bēng-buōng",
+ "revision-info": "Găk $1 iù {{GENDER:$6|$2}} có̤ gì biĕng-cĭk $7",
"previousrevision": "← Gá-gô gì bēng-buōng",
"nextrevision": "加新其版本→",
"currentrevisionlink": "最新版本",
"yourrealname": "真實姓名:",
"yourlanguage": "語言:",
"yournick": "新其簽名:",
+ "badsig": "Nguòng-sṳ̄ chiĕng-miàng ô dâng.\nGái káng-lâ HTML biēu-chiĕng.",
"email": "電批",
"prefs-help-email": "電子郵件地址是愛寫就寫其,但是如果汝𣍐記密碼咯,密碼重置其時候需要茲。",
"prefs-help-email-others": "汝也會使選擇讓其他其用戶通過汝其用戶頁面或者討論頁面懸頂其鏈接,使電子郵件來聯繫汝。其他其用戶聯繫汝其辰候,汝其電子郵件地址𣍐顯示出來。",
"boteditletter": "^",
"rc-change-size-new": "Siŭ-gāi ī-hâiu biéng có̤ $1 cê-ciék",
"rc-enhanced-hide": "囥起細節",
+ "rc-old-title": "Kī-tàu hô̤ lā̤ „$1“",
"recentchangeslinked": "相關其改變",
"recentchangeslinked-feed": "相關其改變",
"recentchangeslinked-toolbox": "Sŏng-guăng gì gāi-biéng",
"deletecomment": "原因:",
"rollback": "再修改轉去",
"rollbacklink": "duōng",
+ "rollbacklinkcount": "Huòi-tó̤i $1 huòi biĕng-cĭk",
"rollbackfailed": "轉𣍐去",
"cantrollback": "𣍐使恢復修改;最後其貢獻者是茲蜀頁其唯一其作者。",
"alreadyrolled": "𣍐使回滾最後蜀回[[User:$2|$2]] ([[User talk:$2|討論]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])其[[:$1]]編輯;\n有其他儂已經編輯過了或者茲蜀頁已經乞回滾過了。\n\n最後蜀回茲蜀頁其修改是[[User:$3|$3]] ([[User talk:$3|討論]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])改其。",
"tooltip-feed-atom": "Cī-siŏh-hiĕk gì Atom lài-nguòng",
"tooltip-t-contributions": "{{GENDER:$1|茲蜀隻用戶}}其貢獻單單",
"tooltip-t-emailuser": "向{{GENDER:$1|茲蜀隻用戶}}寄電批",
+ "tooltip-t-info": "Cī-siŏh-hiĕk gì gó-sâ̤ séng-sék",
"tooltip-t-upload": "Siông-diòng ùng-giông",
"tooltip-t-specialpages": "Cuòng-buô dĕk-sṳ̀-hiĕk dăng-dăng",
"tooltip-t-print": "Cī-hiĕk â̤ páh-éng gì bēng-buōng",
"watchlisttools-view": "看相關改變",
"watchlisttools-edit": "看共修改監視單",
"watchlisttools-raw": "修改原始監視單",
+ "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|tō̤-lâung]])",
"redirect": "Áng ùng-giông, ê̤ṳng-hô, hiĕk-miêng siŭ-gāi, nĭk-cé ID kó̤ tṳ̀ng-dêng-hióng",
"redirect-submit": "Kó̤",
"redirect-lookup": "Sìng-tō̤:",
"group-autoconfirmed": "Registrerede brugere",
"group-bot": "Robotter",
"group-sysop": "Administratorer",
+ "group-interface-admin": "Grænsesnitadministratorer",
"group-bureaucrat": "Bureaukrater",
"group-suppress": "Undertrykkere",
"group-all": "(alle)",
"recentchanges-page-added-to-category": "[[:$1]] tilføjet til kategori",
"recentchanges-page-added-to-category-bundled": "[[:$1]] tilføjet til kategorien, [[Special:WhatLinksHere/$1|denne side er inkluderet i andre sider]]",
"recentchanges-page-removed-from-category": "[[:$1]] fjernet fra kategori",
+ "autochange-username": "Automatisk MediaWiki-ændring",
"upload": "Læg en fil op",
"uploadbtn": "Læg en fil op",
"reuploaddesc": "Tilbage til formularen til at lægge filer op.",
"uploadstash-bad-path-invalid": "Stien er ugyldig.",
"uploadstash-bad-path-unknown-type": "Ukendt type »$1«.",
"uploadstash-file-not-found-no-object": "Kunne ikke oprette lokalt filobjekt for miniaturebillede.",
+ "uploadstash-file-too-large": "Kan ikke behandle en fil der er større end $1 bytes.",
"uploadstash-not-logged-in": "Ingen bruger er logget ind, filer skal tilhøre brugere.",
"uploadstash-wrong-owner": "Filen ($1) tilhører ikke den nuværende bruger.",
"uploadstash-no-such-key": "Ingen sådan nøgle ($1), kan ikke fjerne.",
"limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
"limitreport-expansiondepth": "Største udvidelsesdybde",
"limitreport-expensivefunctioncount": "Antal dyre parserfunktioner",
+ "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
"expandtemplates": "Udfold skabeloner",
"expand_templates_intro": "Denne specialside tager en tekst og udfolder alle benyttede skabeloner rekursivt.\nDen udfolder også understøttede parserfunktioner så som\n<code><nowiki>{{</nowiki>#language:…}}</code> og variabler så som \n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>\nFaktisk udfolder den stort set alt i dobbelte tuborgklammer.",
"expand_templates_title": "Sammenhængstitel, for {{FULLPAGENAME}} osv.:",
"log-action-filter-move": "Flyttetype:",
"log-action-filter-patrol": "Patruljeringstype:",
"log-action-filter-protect": "Beskyttelsestype:",
+ "log-action-filter-rights": "Type af rettighedændring:",
"log-action-filter-all": "Alle",
"log-action-filter-block-block": "Blokering",
"log-action-filter-block-reblock": "Ændring af blokering",
"authform-notoken": "Mangler nøgle",
"authform-wrongtoken": "Forkert nøgle",
"specialpage-securitylevel-not-allowed-title": "Ikke tilladt",
+ "authpage-cannot-login": "Kunne ikke starte login.",
"cannotauth-not-allowed-title": "Adgang nægtet",
"cannotauth-not-allowed": "Du har ikke tilladelse til at bruge denne side",
"removecredentials": "Fjern akkreditiver",
"redirect-file": "Datei",
"redirect-logid": "Logbucheintrag",
"redirect-not-exists": "Der Wert wurde nicht gefunden",
+ "redirect-not-numeric": "Der Wert ist nicht numerisch",
"fileduplicatesearch": "Dateiduplikatsuche",
"fileduplicatesearch-summary": "Suche nach Dateiduplikaten auf Basis ihres Hashwertes.",
"fileduplicatesearch-filename": "Dateiname:",
"redirect-file": "Filename",
"redirect-logid": "Log ID",
"redirect-not-exists": "Value not found",
+ "redirect-not-numeric": "Value not numeric",
"fileduplicatesearch": "Search for duplicate files",
"fileduplicatesearch-summary": "Search for duplicate files based on hash values.",
"fileduplicatesearch-filename": "Filename:",
"filehist-comment": "Megjegyzés",
"imagelinks": "Fájlhasználat",
"linkstoimage": "Az alábbi {{PLURAL:$1|lap használja|lapok használják}} ezt a fájlt:",
- "linkstoimage-more": "Több mint $1 oldal használja ezt a fájlt.\nA következő lista csak az {{PLURAL:$1|első lapot mutatja, ami használja a képet|első $1 lapot mutatja, amelyek használják a képet}}.\nA teljes lista [[Special:WhatLinksHere/$2|ezen a lapon]] található meg.",
+ "linkstoimage-more": "Több mint $1 oldal használja ezt a fájlt.\nA következő lista csak a fájlt használó {{PLURAL:$1|első|első $1}} lapot mutatja.\nA teljes lista [[Special:WhatLinksHere/$2|ezen a lapon]] található meg.",
"nolinkstoimage": "Ezt a fájlt nem használja egyetlen lap sem.",
"morelinkstoimage": "[[Special:WhatLinksHere/$1|További hivatkozások]] megtekintése",
"linkstoimage-redirect": "$1 (fájlátirányítás) $2",
"confirm-rollback-top": "Visszavonod a változtatásokat?",
"confirm-mcrundo-title": "Egy változtatás visszavonva",
"mcrundofailed": "A visszavonás nem sikerült",
+ "mcrundo-missingparam": "Kötelező paraméterek hiányoznak a kérésből.",
"ellipsis": "…",
"quotation-marks": "„$1”",
"imgmultipageprev": "← előző oldal",
"edit-error-long": "Hibák:\n\n$1",
"revid": "$1 változat",
"pageid": "$1 lapazonosító",
+ "interfaceadmin-info": "$1\n\nA CSS/JS/JSON lapok szerkesztéséhez szükséges jogosultság a közelmúltban elválasztásra került a <code>editinterface</code> jogtól. Amennyiben nem érted, miért látod ezt az üzenetet, [[mw:MediaWiki_1.32/interface-admin|itt tudhatsz meg többet]].",
"rawhtml-notallowed": "<html> címkék nem használhatók normál lapokon kívül.",
"gotointerwiki": "{{SITENAME}} elhagyása",
"gotointerwiki-invalid": "A megadott cím érvénytelen.",
"tooltip-feed-atom": "Այս էջի Ատոմ սնուցումը",
"tooltip-t-contributions": "Դիտել {{GENDER:$1|այս մասնակցի}} ներդրումների ցանկը",
"tooltip-t-emailuser": "Ուղարկել էլ․ նամակ {{GENDER:$1|այս մասնակցին}}",
+ "tooltip-t-info": "Վիճակագրական տվյալներ էջի մասին",
"tooltip-t-upload": "Բեռնել ֆայլեր",
"tooltip-t-specialpages": "Բոլոր սպասարկող էջերի ցանկը",
"tooltip-t-print": "Այս էջի տպելու տարբերակ",
"customcssprotected": "Vu ne es permisita redaktar ita CSS pagino nam ol kontenas personal ajustaji di altra uzero.",
"customjsonprotected": "Vu ne havas permiso por redaktar ica pagino JSON pro ke ol kontenas personal ajustaji di altra uzero.",
"customjsprotected": "Vu ne es permisita redaktar ita JavaScript pagino nam ol kontenas personal ajustaji di altra uzero.",
+ "sitecssprotected": "Vu ne havas permiso pri redaktar ica pagino CSS pro ol povus afektor omna viziteri.",
+ "sitejsonprotected": "Vu ne povas redaktar ica JSON (JavaScript Object Notation), pro ol povas afektar omna viziteri.",
"sitejsprotected": "Vu ne povas redaktar ica JavaScript, pro ol povas afektar omna viziteri.",
"mycustomcssprotected": "Vu ne es permisita redaktar ita CSS pagino.",
"mycustomjsonprotected": "Vu ne es permisita redaktar ita pagino JSON.",
"botpasswords-label-delete": "Efacar",
"botpasswords-label-resetpassword": "Sendez nova pasovorto per e-posto",
"botpasswords-label-grants": "Uzebla grantaji:",
+ "botpasswords-help-grants": "Permisas aceso al yuri quin vua uzero-konto ja havas. Permisar ulo hike furnisos nula altra aceso por altra yuri quin vua konto altramaniere ne havus. Videz la [[Special:ListGrants|tabelo pri permisi]] por plusa informi.",
"botpasswords-label-grants-column": "Permisita",
"botpasswords-bad-appid": "La nomo \"$1\" por la bot-programo esas nevalida.",
"botpasswords-insert-failed": "L'adjunto di nova nomo \"$1\" por la 'bot' faliis. Ka ol ja adjuntesis?",
+ "botpasswords-update-failed": "Ne povis rinomizar la 'bot' nomizita \"$1\". Kad ol efacesis?",
"botpasswords-created-title": "Kreita pasovorto por la 'bot'",
"botpasswords-created-body": "La pasovorto por la 'bot' nomizita \"$1\" del {{GENDER:$2|uzero}} \"$2\" kreesis.",
"botpasswords-updated-title": "La pasovorto dil 'bot' aktualigesis",
"botpasswords-updated-body": "La pasovorto por la 'bot' nomizita \"$1\" del {{GENDER:$2|uzero}} \"$2\" kreesis.",
"botpasswords-deleted-title": "La pasovorto por la 'bot' efacesis",
+ "botpasswords-deleted-body": "La pasovorto por la 'bot' nomizita \"$1\" del {{GENDER:$2|uzero}} \"$2\" kreesis.",
+ "botpasswords-not-exist": "L'uzero \"$1\" ne havas pasovorto nomizita \"$2\" por lua 'bot'.",
+ "botpasswords-needs-reset": "La pasovorto por la 'bot' nomizita \"$1\" dal {{GENDER:$2|uzero}} \"$2\" mustas rikreesar.",
"resetpass_forbidden": "La pasovorti ne povas chanjesar",
"resetpass_forbidden-reason": "Pasovorti ne povas chanjesar: $1",
"resetpass-no-info": "Vu mustas enirar la konto por acesar ita pagino direte.",
"passwordreset": "Sendez nova pasovorto per e-posto",
"passwordreset-text-one": "Garnisez ica formulario por recevar provizora pasovorto per vua e-posto.",
"passwordreset-text-many": "{{PLURAL:$1|Skribez en un ek la texto-buxi por recevar tempala pasovorto per e-posto.}}",
+ "passwordreset-emaildisabled": "La funcioni di e-posto (e-mail) blokusesis en ica Wiki.",
"passwordreset-username": "Uzantonomo:",
"passwordreset-domain": "Interreto-domeno:",
"passwordreset-email": "E-postal adreso:",
"passwordreset-emailtitle": "Detali pri la konto en {{SITENAME}}",
"passwordreset-emailtext-ip": "Ulu (probable vu, de la IP-adresO $1) demandis la remplaso di la pasovorto por {{SITENAME}} ($4). La sequanta {{PLURAL:$3|konto|konti}} esas asociita kun ta adreso di e-posto:\n\n$2\n\nIca tempala {{PLURAL:$3| pasovorto|pasovorti}} perdos la valideso pos {{PLURAL:$5|un dio|$5 dii}}.\nTu mustas facar 'log in' e selektar nova pasovorto nemediate. Se altra persono facis ica demando, o se vu rimemoris l'antea pasovorto e ne pluse bezonas modifikor ol, vu povas ignorar ica mesajo e durar l'uzo dil antea pasovorto.",
+ "passwordreset-emailtext-user": "Ulu (posible vu, de la IP-adreso $1) demandis la remplaso di la pasovorto por {{SITENAME}} ($4). La sequanta {{PLURAL:$3|konto|konti}} esas asociita kun ta adreso di e-posto:\n\n$2\n\nIca tempala {{PLURAL:$3| pasovorto|pasovorti}} perdos la valideso pos {{PLURAL:$5|un dio|$5 dii}}.\nTu mustas facar 'log in' e selektar nova pasovorto nemediate. Se altra persono facis ica demando, o se vu rimemoris l'antea pasovorto e ne pluse bezonas modifikor ol, vu povas ignorar ica mesajo e durar l'uzo dil antea pasovorto.",
"passwordreset-emailelement": "Uzantonomo:\n$1\n\nProvizora pasovorto:\n$2",
"passwordreset-emailsentemail": "Se ica e-posto esas asociita kun vua konto, do la nova pasovorto sendesos a vu per e-posto.",
+ "passwordreset-emailsentusername": "Se ica e-posto esas asociita kun vua konto, do la nova pasovorto sendesos a vu per e-posto.",
"passwordreset-nocaller": "Ula demandero mustas furnisesar",
"passwordreset-nosuchcaller": "La demandero ne existas: $1",
"passwordreset-invalidemail": "Ne-valida e-posto-adreso",
"noarticletext-nopermission": "Til nun ne existas texto en ica pagino.\nVu povas [[Special:Search/{{PAGENAME}}|serchar ica titulo]] en altra pagini, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchar en la relata registri], o [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaktar ica pagino]</span>, tamen vu ne havas permiso por krear ica pagino.",
"userpage-userdoesnotexist": "Uzeronomo \"$1\" ne registragesis.\nVoluntez konfirmar se vu volas krear/redaktar ica pagino.",
"userpage-userdoesnotexist-view": "L'uzeronomo \"$1\" ne enrejistresis.",
+ "blocked-notice-logextract": "Ica uzero nun esas blokusita.\nLa lasta protokolo pri blokuso esas videbla adinfre, por refero:",
"clearyourcache": "<strong>Atencez:</strong> Pos registragar, vu probable mustas renovigar la tempala-magazino di vua navigilo por vidar la chanji.\n* <strong>Firefox / Safari:</strong>Tenez <em>Shift</em> kliktante <em>Reload</em>, o presez sive <em>Ctrl-F5</em> sive <em>Ctrl-R</em> (<em>⌘-R</em> ye Mac);\n* <strong>Google Chrome:</strong> Press <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> en komputeri Mac)\n* <strong>Internet Explorer:</strong> Tenez <em>Ctrl</em> kliktante <em>Refresh</em>, o presez <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Irez a <em>Menu → Settings</em> (<em>Opera → Preferences</em> ye komputeri Mac) e pose a <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
+ "usercssyoucanpreview": "<strong>Sugestajo:</strong> Uzez la butono \"{{int:showpreview}}\" por probar vua nova stilo CSS ante konservar ol.",
+ "userjsonyoucanpreview": "<strong>Sugestajo:</strong> Uzes la butono \"{{int:showpreview}}\" por provar vua nova JSON ante konservar ol.",
+ "userjsyoucanpreview": "<strong>Sugestajo:</strong> Uzes la butono \"{{int:showpreview}}\" por probar vua JavaScript ante konservar ol.",
"usercsspreview": "'''Memorez ke vu nur previdas vua uzero-CSS.'''\n'''Ol ne registragesis ankore!'''",
+ "userjsonpreview": "<strong>Memorez ke vu nur previdas vua JSON (JavaScript Object Notation). Ol ankore ne konservesis!</strong>",
"userjspreview": "'''Memorez ke vu nur previdas vua JavaScript di uzero. Ol ne registragesis ankore!'''",
+ "sitecsspreview": "<strong>Memorez ke vu nur previdas vua uzero-CSS. Ol ankore ne konservesis!</strong>",
"updated": "(Aktualigita)",
"note": "'''Noto:'''",
"previewnote": "<strong>Atencez ke ico esas nur prevido.</strong> Ol ne registragesis ankore!",
"autosumm-blank": "Pagino vakuigesis",
"autosumm-replace": "Kontenajo remplasigesis kun '$1'",
"autoredircomment": "Ridirektas a [[$1]]",
+ "autosumm-changed-redirect-target": "Chanjis la ridirektilo de [[$1]] a [[$2]]",
"autosumm-new": "Pagino kreesis kun '$1'",
"autosumm-newblank": "Kreita vakua pagino",
"watchlistedit-normal-title": "Modifikez surveyo-listo",
"Yusuke1109",
"Afaz",
"Oxbqskeptzwizkgdcxakhnrb",
- "Suyama"
+ "Suyama",
+ "고솜"
]
},
"tog-underline": "リンクの下線:",
"Rul1902"
]
},
+ "underline-always": "ကိုဲၜၠင်",
+ "underline-never": "ၮင်းဖိုင့်အေႋ",
+ "editfont-serif": "ခေါဟ်ထိင်ႋပါ့ဖောင့်",
"sunday": "အ်ုတုက်",
"monday": "အ်ုစန်",
"tuesday": "အ်ုညာႋ",
"oct": "လာထါင့်ခုက်ဖေါဟ်",
"nov": "လာထါင့်ခုက်ဖါဍောဟ်",
"dec": "လာထင်းကၠံင်",
+ "january-date": "ထါင့်ခုက်ဖေါဟ် $1",
+ "february-date": "ထါင့်ခုက်ဖါဍောဟ် $1",
+ "march-date": "လါသိုင့် $1",
+ "april-date": "လါတါ $1",
+ "may-date": "လါယါ့ $1",
+ "june-date": "လါနုဲး $1",
+ "july-date": "လါၰိုဝ် $1",
+ "august-date": "လါခုဂ် $1",
+ "september-date": "ဆီ့မူႋ $1",
+ "october-date": "က္တုဂ်ဝဝ်ႋ $1",
+ "november-date": "လါၮင့် $1",
+ "december-date": "လါလိင် $1",
+ "period-am": "ကေၯဝ်",
+ "period-pm": "ကေၯး",
"pagecategories": "{{PLURAL:$1|အ်ုဆုဂ်တုဂ်|အ်ုဆုဂ်တုဂ်သယ်}}",
"category_header": "အ်ုဆုဂ် \"$1\" ခဝ့် လိက်မေံလ်ုဖး",
"subcategories": "ကဏ္ဍကါင်ဖါသယ်",
"about": "အ်ုကျံင်",
"newwindow": "(ဝင်းဒိုးသင့်လ်ုၮါင်းဝယ် မ်ုပုဂ်ထုင်း)",
"cancel": "မာလှ်ေအေး",
+ "moredotdotdot": "ၰိုဲမေံၜၠာ်...",
+ "morenotlisted": "စ်ုရင့်ယိုဝ် ဍုဂ်ပါင်အေ့ယာႋ။",
+ "mypage": "လက်မေံသး",
"mytalk": "ဆ်ုခၠါန်ကင်ကာ",
+ "anontalk": "ဆ်ုခၠါင်ကင်ကာ",
"navigation": "ပ်ုယုံ့",
"and": " လ်ု",
+ "faq": "ဆ်ုအင်းစာအးသယ်လ်ုဖး",
+ "actions": "ဆ်ုသုဂ်ကၠယ်လ်ုဖး",
"namespaces": "အ်ုမၠိင်ထိုဝ်",
"variants": "အးမိင်အးစိင်လုက်ဆိင့်",
"navigation-heading": "ၮဲဖၠေမီနူး",
+ "errorpagetitle": "ဆ်ုမး",
"returnto": "$1 အိုဝ် မ်ုက္ဍာထါင်။",
"tagline": "{{SITENAME}} ခဝ့်",
"help": "မာၜိုင်မာဆိုင်",
"search": "အင်းၰူ့",
"searchbutton": "အင်းၰူ့",
+ "go": "လေဝ်",
"searcharticle": "လေဝ်",
"history": "ဃွှာန့်မေင်ႋစိင်",
"history_short": "မေင်ႋစိင်",
+ "history_small": "မေင်ႋစိင်",
+ "updatedmarker": "လေဝ်ယောဝ်ႋဝေ့အ်ုလါင်ခါင့်ခါ့ အင်းတင်ထဝေ့",
"printableversion": "လေဝ်",
"permalink": "ဆ်ုသုဂ်ကၠယ်သီ့",
+ "print": "ထုဂ်ထင်းလိက်",
"view": "မ်ုယောဝ်ႋ",
"view-foreign": "မ်ုယောဝ်ႋ $1 ဝယ်",
"edit": "အင်ႋတင်ႋ",
+ "edit-local": "အှ်လင်ကၠယ် ဆ်ုတုဂ်ကၠယ် မ်ုအင်းတင်လင်",
"create": "ပ္တုံထံင်း",
"create-local": "အှ်လင်ကၠယ် ဆ်ုတုဂ်ကၠယ် မ်ုဆူ့ဍုဂ်လင်",
"delete": "ထုဂ်ဆိင့်",
+ "undelete_short": "{{PLURAL:$1|ဆ်ုအင်းတင်လ်ုၮါင်း|ဆ်ုအင်းတင် $1 ၮါင်းၮှ်}}အိုဝ် လ်ုထုက်ဆိင့်လိုင်ၜး",
+ "viewdeleted_short": "{{PLURAL:$1|ထုဂ်ဆိင့်ခၞိက်ဆ်ုအင်းတင်လ်ုၮါင်း|ထုဂ်ဆိင့်ခၞိက် ဆ်ုအင်းတင် $1 ၮါင်း}}ၮှ် မ်ုယောဝ်ႋ",
+ "protect": "ခ်ုဝုင်ႋလာႋ",
+ "protect_change": "မ်ုအင်းလယ်",
+ "unprotect": "ဝီးၜါ်ထ မ်ုအင်းလယ်",
"newpage": "လိက်မေံသင့်",
"talkpagelinktext": "ဆ်ုခၠါင်ကင်ကာ",
+ "specialpage": "လိက်မေံခေါဟ်",
"personaltools": "ဟ်ုဆ်ုမာ ဆ်ုဖၠင့်",
"talk": "လဝ်ထာင်ကင်ကာ",
"views": "ဟ်ုဍးအ်ုလာၯင်သယ်အး",
"toolbox": "ခြီခြာ့သယ်",
+ "tool-link-userrights": "{{GENDER:$1|ၮင့်ဆါႋ}}ကုံလွာဲသယ်လ်ုဖး မ်ုအင်းလယ်",
+ "tool-link-userrights-readonly": "{{GENDER:$1|ၮင့်ဆါႋ}}ကုံလွာဲသယ်လ်ုဖး မ်ုယောဝ်ႋ",
+ "tool-link-emailuser": "ယိုဝ်{{GENDER:$1|ၮင့်ဆါႋ}}ၮှ် မ်ုသုံ့အီမေံႋ",
+ "imagepage": "မ်ုယောဝ်ႋဖိုင့်လိက်မေံ",
+ "mediawikipage": "မ်ုယောဝ်ႋလိက်မေံဖိုဟ်",
+ "templatepage": "တာင်ႋပ်ုလိတ်သယ် မ်ုယောဝ်ႋ",
+ "viewhelppage": "မ်ုယောဝ်ႋဖိုင့်လိက်မေံ",
+ "categorypage": "အ်ုဆုဂ်တုဂ်လိက်မေံသယ် မ်ုယောဝ်ႋ",
+ "viewtalkpage": "မ်ုယောဝ်ႋ လဝ်ခၠါင်ဆ်ုခၠါင်",
"otherlanguages": "လိက်ဆ်ုခၠါင် အ်ုၯာၯံင်သယ်",
"redirectedfrom": "($1 ခဝ့် ပ်ုယုံ့ထာ့)",
"redirectpagesub": "ထါင်ၮဲအ်ုထိုဝ် လိက်မေံၜၠါ်",
"redirectto": "က္ဍာထိုဝ်ၜုဂ် -",
"lastmodifiedat": "လိက်မေံယိုဝ် $1၊ $2 အ်ုခါ့ ဆ်ုအင်ႋတင်ႋထာ့ဝေ့လှ်။",
+ "viewcount": "လိက်မေံယိုဝ် {{PLURAL:$1|လ်ုၜၠင်|$1 ၜၠင်}} အွးလင်ထ။",
+ "protectedpage": "လိက်မေံဆ်ုဝီးၜါ်",
"jumpto": "မ်ုၯယ့်ထါင်ယိုဝ်",
"jumptonavigation": "ပ်ုယုံ့",
"jumptosearch": "အင်းၯူ့",
"disclaimers": "တင်ဆ်ုခၠါင်",
"disclaimerpage": "Project:ကိုဝ်မိင်ကိုဝ်စိင် ၜးတ်ုဒှ်",
"edithelp": "အင်ႋတင်ႋ ဆ်ုမာၜိုင်",
- "mainpage": "á\80\9cá\80á\80\80á\80ºá\80\99á\80±á\80¶á\80\9aá\80¬á\80·",
+ "mainpage": "á\80\9cá\80á\80\80á\80ºá\80\99á\80±á\80¶á\81\9cá\81 á\80«á\80ºá\80\81á\80±á\80«á\80\9fá\80º",
"mainpage-description": "လက်မေံယာ့",
"portal": "အ်ုထိုဝ်အ်ုမေံလင်ႋ",
"portal-url": "Project:အ်ုထိုဝ်အ်ုမေံလင်ႋ",
"protectedtitles-submit": "Rodyti pavadinimus",
"listusers": "Naudotojų sąrašas",
"listusers-editsonly": "Rodyti tik keitimus atlikusius naudotojus",
+ "listusers-temporarygroupsonly": "Rodyti tik laikinųjų vartotojų grupių naudotojus",
"listusers-creationsort": "Rodyti pagal paskyros sukūrimo datą",
"listusers-desc": "Išdėstyti abėcėline tvarka",
"usereditcount": "$1 {{PLURAL:$1|keitimas|keitimai|keitimų}}",
"grouppage-interface-admin": "{{ns:project}}:Администратори на посредникот",
"grouppage-bureaucrat": "{{ns:project}}:Бирократи",
"grouppage-suppress": "{{ns:project}}:Притајување",
- "right-read": "Читање страници",
+ "right-read": "Читање на страници",
"right-edit": "Уредување на страници",
"right-createpage": "Создавање на страници (кои не се разговорни страници)",
"right-createtalk": "Создавање на разговорни страници",
"right-createaccount": "Создавање на нови кориснички сметки",
"right-autocreateaccount": "Автоматска најава со надворешна корисничка сметка",
"right-minoredit": "Означување на уредувањата како ситни",
- "right-move": "Преместување страници",
+ "right-move": "Преместување на страници",
"right-move-subpages": "Преместување на страници со нивните потстраници",
"right-move-rootuserpages": "Преместување на основни кориснички страници",
"right-move-categorypages": "Преместување на категориски страници",
"right-purge": "Бришење од опслужувачки меѓусклад на страницата без барање потврда за тоа",
"right-autoconfirmed": "Без ограничувања на стапки за IP-адреса",
"right-bot": "Третиран како автоматски процес",
- "right-nominornewtalk": "Ситните уредувања да не поттикнуваат потсетник за нова порака",
+ "right-nominornewtalk": "СиÑ\82ниÑ\82е Ñ\83Ñ\80едÑ\83ваÑ\9aа на Ñ\80азговоÑ\80ни Ñ\81Ñ\82Ñ\80аниÑ\86и да не поÑ\82Ñ\82икнÑ\83вааÑ\82 поÑ\82Ñ\81еÑ\82ник за нова поÑ\80ака",
"right-apihighlimits": "Користење на помалку ограничени барања од извршникот",
"right-writeapi": "Можност за запишување во извршникот",
"right-delete": "Бришење страници",
"grant-basic": "Основни права",
"grant-viewdeleted": "Преглед на избришани податотеки и страници",
"grant-viewmywatchlist": "Преглед на вашите набљудувања",
- "grant-viewrestrictedlogs": "Погл. ограничени дневнички ставки",
+ "grant-viewrestrictedlogs": "Преглед на ограничени дневнички ставки",
"newuserlogpage": "Дневник на регистрирања на корисници",
"newuserlogpagetext": "Ова е дневник на регистрирани корисници.",
"rightslog": "Дневник на корисничките права",
"@metadata": {
"authors": [
"Dr Lotus Black",
- "Htawmonzel"
+ "Htawmonzel",
+ "Aue Nai"
]
},
"tog-underline": "လေန် မတာပၞောန်သၟဝ်",
"tog-hideminor": "ပၞုက် အရာမပလေဝ်ဒါန်လဝ် ကိစ္စဟွံဇၞော် နူကဵု ပြဟ်ဟ်ဏအ်",
"tog-hidepatrolled": "ပၞုက် အရာမပလေဝ်ဒါန်လဝ် ကိစ္စဇၞော်ဇၞော် နူကဵု ပြဟ်ဟ်ဏအ်",
"tog-hidecategorization": "ပၞုက် အရာမဖျေဟ်ကဏ္ဍ ကုမုက်လိက်",
+ "tog-showhiddencats": "ထ္ၜးကဆံၚ်မပၞုက်လဝ်",
+ "tog-prefershttps": "လၟိုန်သုၚ်စောဲကေတ် လာၚ်မမၞုံဂီုကၠီု အခိၚ်မလုပ်လံက်အေန်",
+ "underline-always": "လၟိုန်အခါ",
+ "underline-never": "မွဲလှေ်ဟွံမွဲ",
"sunday": "တ္ၚဲအဒိုက်",
"monday": "တ္ၚဲစန်",
"tuesday": "တ္ၚဲအၚာ",
"oct": "အံက်",
"nov": "နဝ်",
"dec": "ဒဳ",
+ "january-date": "ဇန်နဝါရဳ $1",
+ "march-date": "မာတ် $1",
+ "april-date": "ဨပရဳ $1",
+ "may-date": "မေ $1",
+ "june-date": "ဂျေန် $1",
+ "july-date": "ဂျူလာၚ် $1",
+ "august-date": "သြဂုတ် $1",
+ "october-date": "အံက်တိုဘာ $1",
+ "november-date": "နိုဝေန်ဘာ$1",
+ "period-am": "နူဂယး",
+ "period-pm": "သဝ်တ္ၚဲ",
"pagecategories": "{{PLURAL:$1|ကဏ္ဍ|ကဏ္ဍဂမၠိုင်}}",
"category_header": "မုက်လိက်ဂမၠိုင် ပ္ဍဲ ကဏ္ဍ \"$1\"",
"subcategories": "ကဏ္ဍလစှ်ေဂမၠိုင်",
"category-media-header": "မဳဒဳယာ စပ်ကဵု ကဏ္ဍ \"$1\"",
"category-empty": "<em>ကဏ္ဍဏအ် ပြဟ်ဟ်ဏအ် ဟွံမဲ ကု မုက်လိက် ဟွံသေင်မ္ဂး ပရူမွဲမွဲဏီရ</em>",
"hidden-categories": "{{PLURAL:$1|ကဏ္ဍ မပၞုက်|ကဏ္ဍ မပၞုက်ဂမၠိုင်}}",
+ "hidden-category-category": "ကဆံၚ် မပၞုက်လဝ်",
"category-subcat-count": "{{PLURAL:$2|ကဏ္ဍဏအ်ဂှ် ကဏ္ဍလစှ်ေ နွံဆ အတိုင်ဗွဲသၟဝ်ဝွံရ၊၊|ကဏ္ဍဏအ် နွံဆအတိုင် ဗွဲသၟဝ်ဝွံရ၊၊ {{PLURAL:$1|ကဏ္ဍလစှ်ေ|$1 ကဏ္ဍလစှ်ေဂမၠိုင်}}, ပၞောဝ်ကဵု $2 သီုဖအိုတ်}}",
+ "category-subcat-count-limited": "ကဆံၚ်(အဇာ)ဝွံ နွံအတိုၚ်ဗွဲသၟဝ် {{PLURAL:$1|ကဆံၚ်ပါ်|$1ကဆံၚ်ပါ်ဂမၠိုၚ်}}",
"category-article-count": "{{PLURAL:$2|ကဏ္ဍဏအ် နွံဆၜိုတ် အတိုင်ဗွဲသၟဝ်ဏအ်ရ.| ဗွဲသၟဝ်ဏအ်ဂှ် {{PLURAL:$1| ဒှ်လၟိဟ် မုက်လိက်| ဒှ်လၟိဟ် မုက်လိက်ဂမၠိုင် $1 }} စပ် ကုကဏ္ဍဏအ်ရ၊၊ သီုဖအိုတ် နွံ $2}}",
+ "category-article-count-limited": "အတိုၚ်ဗွဲသၟဝ်{{PLURAL:$1|မုက်ဂှ်|$1 မုက်တအ်}} ပ္ဍဲကဆံၚ်မလၟုဟ်.",
"category-file-count": "{{PLURAL:$2|ကဏ္ဍဏအ် နွံဆၜိုတ် ဝှာင်|အတိုင် ဗွဲသၟဝ်ဏအ်ရ {{PLURAL:$1|ဝှာင် ဂှ်|$1 ဝှာင်တအ် ဂှ်}} ပ္ဍဲကဏ္ဍဏအ် သီုဖအိုတ် နွံ $2 ၊၊}}",
"listingcontinuesabbrev": "ဆက်",
"noindex-category": "မုက်လိက် မသက္ကုလိက်",
"subject-preview": "विषयाची झलक:",
"previewerrortext": "आपल्या बदलांची झलक बघण्याचे प्रयत्नादरम्यान त्रुटी उद्भवली.",
"blockedtitle": "हा सदस्य प्रतिबंधित आहे",
- "blockedtext": "'''तुमचे सदस्यनाव अथवा IP पत्ता ब्लॉक केलेला आहे.'''\n\nहा ब्लॉक $1 यांनी केलेला आहे.\nयासाठी ''$2'' हे कारण दिलेले आहे.\n\n* ब्लॉकची सुरूवात: $8\n* ब्लॉकचा शेवट: $6\n* कुणाला ब्लॉक करायचे आहे: $7\n\nतुम्ही ह्या ब्लॉक संदर्भातील चर्चेसाठी $1 अथवा [[{{MediaWiki:Grouppage-sysop}}|प्रबंधकांशी]] संपर्क करू शकता.\nतुम्ही जोवर वैध ई-मेल पत्ता आपल्या [[Special:Preferences|'माझ्या पसंती']] पानावर देत नाही तोवर तुम्ही ’सदस्याला ई-मेल पाठवा’ हा दुवा वापरू शकत नाही. तसेच असे करण्यापासून आपल्याला ब्लॉक केलेले नाही.\nतुमचा सध्याचा IP पत्ता $3 हा आहे, व तुमचा ब्लॉक क्रमांक #$5 हा आहे.\nकृपया या संदर्भातील चर्चेमध्ये वरील सर्व तपशिल उद्घृत करा.",
+ "blockedtext": "<strong>तुमचे सदस्यनाव अथवा IP पत्ता ब्लॉक केलेला आहे.<strong>\n\nहा ब्लॉक $1 यांनी केलेला आहे.\nयासाठी </em>$2</em> हे कारण दिलेले आहे.\n\n* ब्लॉकची सुरूवात: $8\n* ब्लॉकचा शेवट: $6\n* कुणाला ब्लॉक करायचे आहे: $7\n\nतुम्ही ह्या ब्लॉक संदर्भातील चर्चेसाठी $1 अथवा [[{{MediaWiki:Grouppage-sysop}}|प्रबंधकांशी]] संपर्क करू शकता.\nतुम्ही जोवर वैध ई-मेल पत्ता आपल्या [[Special:Preferences|'माझ्या पसंती']] पानावर देत नाही तोवर तुम्ही ’सदस्याला ई-मेल पाठवा’ हा दुवा वापरू शकत नाही. तसेच असे करण्यापासून आपल्याला ब्लॉक केलेले नाही.\nतुमचा सध्याचा IP पत्ता $3 हा आहे, व तुमचा ब्लॉक क्रमांक #$5 हा आहे.\nकृपया या संदर्भातील चर्चेमध्ये वरील सर्व तपशिल उद्घृत करा.",
"autoblockedtext": "तुमचा आंतरजालीय अंकपत्ता आपोआप स्थगित केला आहे कारण तो इतर अशा सदस्याने वापरला, ज्याला $1ने प्रतिबंधित केले.\nआणि दिलेले कारण खालील प्रमाणे आहे\n:''$2''\nब्लॉकची सुरूवात: $8\nब्लॉकचा शेवट: $6\nकुणाला ब्लॉक करायचे आहे: $7\n\nतुम्ही $1शी संपर्क करू शकता किंवा इतर [[{{MediaWiki:Grouppage-sysop}}|प्रबंधकां पैकी]] एकाशी स्थगनाबद्दल चर्चा करू शकता.\n\n[[Special:Preferences|सदस्य पसंतीत]]त शाबीत विपत्र पत्ता नमूद असल्या शिवाय आणि तुम्हाला तो वापरण्या पासून प्रतिबंधित केले असल्यास तुम्ही \"या सदस्यास विपत्र पाठवा\" सुविधा वापरू शकणार नाही.\nतुमचा सध्याचा IP पत्ता $3 हा आहे, व तुमचा ब्लॉक क्रमांक #$5 हा आहे. \nतुमचा स्थगन क्र $5 आहे. कृपया या संदर्भातील चर्चेमध्ये वरील सर्व तपशिल उद्घृत करा.",
"blockednoreason": "कारण दिलेले नाही",
"whitelistedittext": "लेखांचे संपादन करण्यासाठी आधी $1 करा.",
"accmailtext": "[[User talk:$1|$1]] यांसाठी अनियतक्रमाने निर्मित केलेला परवलीचा शब्द $2 यांना पाठवण्यात आला आहे.\n\nया नवीन खात्यासाठीचा परवलीचा शब्द,सनोंद-प्रवेश घेतल्यावर [[Special:ChangePassword|परवलीचा शब्द बदला]] येथे बदलता येईल.",
"newarticle": "(नवीन लेख)",
"newarticletext": "आपण सध्या अस्तित्त्वात नसलेल्या पानाच्या दुव्याचा मागोवा घेत आला आहात.\nहे पान नव्याने तयार करण्यासाठी खालील पेटीत टंकन करणे सुरु करा(अधिक माहितीसाठी [$1 साहाय्य पान] बघा).\n\nजर आपण येथे चुकून आला असाल तर ब्राउझरच्या <strong>परत</strong>(बॅक) कळीवर टिचकी द्या.",
- "anontalkpagetext": "<em>हे चर्चापान अशा अज्ञात सदस्यासाठी आहे, ज्यांनी खाते तयार केलेले नाही किंवा त्याचा वापर करत नाहीत.</em> \nत्यांच्या ओळखीसाठी आम्ही आंतरजाल अंकपत्ता वापरतो आहोत. असा अंकपत्ता बऱ्याच लोकांचा एकच असू शकतो. \nजर आपण अज्ञात सदस्य असाल आणि आपल्याला काही अप्रासंगिक संदेश मिळाला असेल तर कृपया [[Special:CreateAccount| खाते तयार करा]] किंवा [[Special:CreateAccount|सनोंद-प्रवेश करा]] ज्यामुळे, पुढे असे गैरसमज होणार नाहीत.",
+ "anontalkpagetext": "<em>हे चर्चापान अशा अज्ञात सदस्यासाठी आहे, ज्यांनी खाते तयार केलेले नाही किंवा त्याचा वापर करत नाहीत.</em> \nत्यांच्या ओळखीसाठी आम्ही आंतरजाल अंकपत्ता वापरतो आहोत. असा अंकपत्ता बऱ्याच लोकांचा एकच असू शकतो. \nजर आपण अज्ञात सदस्य असाल आणि आपल्याला काही अप्रासंगिक संदेश मिळाला असेल तर कृपया [[Special:CreateAccount| खाते तयार करा]] किंवा [[Special:CreateAccount|सनोंद-प्रवेश करा]] ज्यामुळे, पुढे असे गैरसमज होणार नाहीत.",
"noarticletext": "या लेखात सध्या काहीही मजकूर नाही.\nतुम्ही विकिपीडियावरील इतर लेखांमध्ये या [[Special:Search/{{PAGENAME}}| मथळ्याचा शोध घेऊ शकता]], <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} इतर नोंदी शोधा],\nकिंवा हा लेख [{{fullurl:{{FULLPAGENAME}}|action=edit}}तयार करू शकता]</span>.",
"noarticletext-nopermission": "सध्या या लेखात काहीही मजकूर नाही.\nतुम्ही विकिपीडियावरील इतर लेखांमध्ये [[Special:Search/{{PAGENAME}}| या मथळ्याचा शोध घेऊ शकता]], <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAME}}}}आपण या लेखाच्या इतर नोंदी शोधा]</span>,परंतु, आपणास हा लेख लिहीण्याची परवानगी देण्यात येउ शकत नाही.",
"missing-revision": "\"{{FULLPAGENAME}}\" या लेखाचे #$1 हे संस्करण अस्तित्वात नाही.वगळल्या गेलेल्या लेखपानाच्या जुन्या इतिहास-दुव्याचे अनुसरण केल्यामुळे असे होते.याबाबत विस्तृत माहिती [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} वगळलेल्या नोंदी]येथे बघता येईल.",
"recentchangeslinked-feed": "या पृष्ठासंबंधीचे बदल",
"recentchangeslinked-toolbox": "या पृष्ठासंबंधीचे बदल",
"recentchangeslinked-title": "\"$1\" च्या संदर्भातील बदल",
- "recentchangeslinked-summary": "हे पृष्ठ एखाद्या विशिष्ट पानाशी, (किंवा एखाद्या विशिष्ट वर्गात असणाऱ्या पानांशी), जोडलेल्या पानांवरील बदल दर्शविते.\nआपल्या [[Special:Watchlist|निरीक्षणसूचीत]] ही पाने <strong>ठळक</strong> दिसतील.",
+ "recentchangeslinked-summary": "हे पृष्ठ एखाद्या विशिष्ट पानाशी, (किंवा एखाद्या विशिष्ट वर्गात असणाऱ्या पानांशी), जोडलेल्या पानांवरील बदल दर्शविते.एखाद्या वर्गातील पाने पाहाण्यासाठी तो वर्ग लिहा\nआपल्या [[Special:Watchlist|निरीक्षणसूचीत]] ही पाने <strong>ठळक</strong> दिसतील.",
"recentchangeslinked-page": "पृष्ठ नाव:",
"recentchangeslinked-to": "याऐवजी दिलेल्या पानाला जोडलेल्या पानांवरील बदल दाखवा",
"recentchanges-page-added-to-category": "[[:$1]] हे पान या वर्गास जोडले",
"imagelinks": "संचिका वापर",
"linkstoimage": "खालील {{PLURAL:$1|पान चित्राशी जोडले आहे|$1 पाने चित्रांशी जोडली आहेत}}:",
"linkstoimage-more": "या संचिके ला $1 {{PLURAL:$1|पान जोडले|पाने जोडली}} आहेत.\nखालील यादी या संचिके ला जोडलेल्या {{PLURAL:$1|पहिल्या पानाचा दुवा |पहिल्या $1 पानांचे दुवे }}दर्शविते.\n[[Special:WhatLinksHere/$2|संपुर्ण यादी]] उपलब्ध आहे.",
- "nolinkstoimage": "या चित्राशी जोडलेली पृष्ठे नाही आहेत.",
+ "nolinkstoimage": "या चित्राशी जोडलेली पृष्ठे नाहीत.",
"morelinkstoimage": "या संचिकेचे [[Special:WhatLinksHere/$1|अधिक दुवे]] पहा.",
"linkstoimage-redirect": "$1 (संचिका पुनर्निर्देशन) $2",
"duplicatesoffile": "खालील संचिका या दिलेल्या {{PLURAL:$1|संचिकेची प्रत आहे|$1 संचिकांच्या प्रती आहेत}}. [[Special:FileDuplicateSearch/$2|अधिक माहिती]]",
"booksources": "မှီငြမ်း စာအုပ်များ",
"booksources-search-legend": "စာအုပ်ရင်းမြစ်များကို ရှာရန်",
"booksources-search": "ရှာဖွေရန်",
+ "booksources-text": "အောက်ပါတို့သည် အသုံးပြုပြီးသားနှင့် စာအုပ်သစ်များကို ရောင်းချသော အခြားဆိုဒ်လင့်ခ်များစာရင်းဖြစ်သည်၊ သင်ရှာဖွေနေသော စာအုပ်များနှင့်ပတ်သက်သည့် အခြားသတင်းအချက်အလက်လည်း ရှိနိုင်ပါသည်:",
+ "booksources-invalid-isbn": "ပေးထားသော ISBN မှာ ဆီလျော်သည့်ပုံစံ မရှိပါ၊ မူလရင်းမြစ်မှ ကော်ပီကူးခြင်းအမှားများအတွက် စစ်ဆေးကြည့်ပါ။",
"specialloguserlabel": "ဆောင်ရွက်သူ -",
"speciallogtitlelabel": "ရည်ရွယ်ရာ (ခေါင်းစဉ် သို့ {{ns:user}}:အသုံးပြုသူအတွက် အသုံးပြုအမည်):",
"log": "မှတ်တမ်းများ",
"authmanager-realname-label": "အမည်ရင်း",
"authmanager-realname-help": "အသုံးပြုသူ၏ အမည်ရင်း",
"authmanager-provider-temporarypassword": "ယာယီစကားဝှက်",
+ "authprovider-resetpass-skip-label": "ကျော်ရန်",
"cannotauth-not-allowed-title": "ခွင့်ပြုချက် ငြင်းပယ်လိုက်သည်",
"cannotauth-not-allowed": "သင်သည် ဤစာမျက်နှာကို အသုံးပြုခွင့်မရှိပါ",
"edit-error-short": "အမှား - $1",
"redirect-file": "Bestandsnaam",
"redirect-logid": "Logboekregel-ID",
"redirect-not-exists": "Waarde niet gevonden",
+ "redirect-not-numeric": "Waarde is geen nummer",
"fileduplicatesearch": "Duplicaatbestanden zoeken",
"fileduplicatesearch-summary": "Duplicaatbestanden zoeken op basis van de hashwaarde.",
"fileduplicatesearch-filename": "Bestandsnaam:",
"version-skin-colheader-name": "ସ୍କିନ",
"version-ext-colheader-version": "ସଂସ୍କରଣ",
"version-ext-colheader-license": "ଲାଇସେନ୍ସ",
- "version-ext-colheader-description": "ବର୍ଣନା",
+ "version-ext-colheader-description": "ବରà\8dଣà\8dଣନା",
"version-ext-colheader-credits": "ଲେଖକମାନେ",
"version-license-title": "$1 ପାଇଁ ଲାଇସେନ୍ସ",
"version-license-not-found": "ଏହି ଏକ୍ସଟେନସନରେ କୌଣସି ସବିଶେଷ ସୂଚନା ନାହିଁ ।",
"right-suppressionlog": "Podgląd rejestru ukrywania",
"right-block": "Blokowanie użytkownikom możliwości edycji",
"right-blockemail": "Blokowanie użytkownikom możliwości wysyłania wiadomości",
- "right-hideuser": "Blokowanie użytkownika, niewidoczne publicznie",
+ "right-hideuser": "Blokowanie użytkownika i ukrywanie od publiczności",
"right-ipblock-exempt": "Obejście blokad, automatycznych blokad i blokad zakresów adresów IP",
"right-unblockself": "Odblokowanie samego siebie",
"right-protect": "Zmiana poziomu zabezpieczenia i edycja stron zabezpieczonych kaskadowo",
"redirect-file": "Nome do arquivo",
"redirect-logid": "ID de log",
"redirect-not-exists": "Valor não encontrado",
+ "redirect-not-numeric": "Valor não numérico",
"fileduplicatesearch": "Procurar por arquivos duplicados",
"fileduplicatesearch-summary": "Procure por arquivos duplicados tendo por base seu valor \"hash\".",
"fileduplicatesearch-filename": "Nome do arquivo:",
"redirect-file": "Description of lookup type for [[Special:Redirect]].\n{{Identical|Filename}}",
"redirect-logid": "Description of lookup type for [[Special:Redirect]].\n{{Identical|Log ID}}",
"redirect-not-exists": "Used as error message in [[Special:Redirect]]",
+ "redirect-not-numeric": "Used as error message in [[Special:Redirect]]",
"fileduplicatesearch": "Name of special page [[Special:FileDuplicateSearch]].",
"fileduplicatesearch-summary": "Summary of [[Special:FileDuplicateSearch]]",
"fileduplicatesearch-filename": "Input form of [[Special:FileDuplicateSearch]]:\n\n{{Identical|Filename}}",
"redirect-file": "Название файла",
"redirect-logid": "ID журнала",
"redirect-not-exists": "Значение не найдено",
+ "redirect-not-numeric": "Значение не числовое",
"fileduplicatesearch": "Поиск одинаковых файлов",
"fileduplicatesearch-summary": "Поиск одинаковых файлов по хэш-коду.",
"fileduplicatesearch-filename": "Имя файла:",
"right-move": "Переменованя сторінок",
"right-move-subpages": "Переменованя сторінок і їх підсторінок",
"right-move-rootuserpages": "Переменованя корінёвых сторінок хоснователїв",
+ "right-move-categorypages": "Переменованя сторінок катеґорій",
"right-movefile": "Переменовати файлы",
"right-suppressredirect": "Нестворіня напрямлїня про переменоваю сторінкы",
"right-upload": "Наладовованя файлів",
"right-siteadmin": "Замыкана і одомыканя датабазы",
"right-override-export-depth": "Експорт сторінок включаючі звязаны сторінкы з глубков до 5",
"right-sendemail": "Посыланя пошты іншым хоснователям",
+ "right-applychangetags": "Придаваня [[Special:Tags|значок]] до властных змін",
"newuserlogpage": "Лоґ вытварянь хоснователїв",
"newuserlogpagetext": "Тото є список ново реґістрованых хоснователїв.",
"rightslog": "Лоґ хосновательскых прав",
"action-move": "Переменовати тоту сторінку",
"action-move-subpages": "переменованя той сторінкы зо вшыткыма єй підсторінками",
"action-move-rootuserpages": "переменовати корінёвы сторінкы хостователїв",
+ "action-move-categorypages": "переменованя сторінок катеґорій",
"action-movefile": "переменовати тот файл",
"action-upload": "наладовати тот файл",
"action-reupload": "переписати тот екзістуючій файл",
"redirect-file": "Ime datoteke",
"redirect-logid": "ID dnevnika",
"redirect-not-exists": "Vrednosti ni mogoče najti",
+ "redirect-not-numeric": "Vrednost ni številska",
"fileduplicatesearch": "Iskanje podvojenih datotek",
"fileduplicatesearch-summary": "Iskanje podvojenih datotek, ki temelji na podlagi njenih hashvrednosti.",
"fileduplicatesearch-filename": "Ime datoteke:",
"redirect-file": "Назив датотеке",
"redirect-logid": "ID дневника",
"redirect-not-exists": "Вредност није пронађена",
+ "redirect-not-numeric": "Вредност није нумеричка",
"fileduplicatesearch": "Претрага дупликата датотека",
"fileduplicatesearch-summary": "Претрага дуплираних датотека према хеш вредности.",
"fileduplicatesearch-filename": "Назив датотеке:",
"permissionserrorstext-withaction": "由於下列{{PLURAL:$1|原因}},您沒有權限進行 $2 的動作:",
"contentmodelediterror": "您無法編輯此修訂,因為它的內容模型為<code>$1</code>,與目前使用的頁面內容模型<code>$2</code>不同。",
"recreate-moveddeleted-warn": "<strong>警告:您正重新建立先前已刪除的頁面。</strong>\n\n您應考慮是否繼續編輯此頁。\n在此提供刪除與移動日誌方便作為參考:",
- "moveddeleted-notice": "此頁面已刪除。\n下方提供此頁面的刪除、保護和移動日誌以便參考。",
+ "moveddeleted-notice": "此頁面已遭刪除。\n請參考下方關於此頁面的刪除、保護和移動日誌。",
"moveddeleted-notice-recent": "對不起,此頁面剛剛被刪除(在最近24小時內)。頁面的刪除、保護和移動日誌在下方提供以供參考。",
"log-fulllog": "檢視完整日誌",
"edit-hook-aborted": "編輯已被 Hook 中止。\n且未回應無任何說明。",
"redirect-file": "檔案名稱",
"redirect-logid": "日誌 ID",
"redirect-not-exists": "查無值",
+ "redirect-not-numeric": "值不是數字",
"fileduplicatesearch": "搜尋重複檔案",
"fileduplicatesearch-summary": "依據雜湊值 (Hash) 來搜尋重複的檔案。",
"fileduplicatesearch-filename": "檔案名稱:",
protected $mSelf = "FakeMaintenanceScript";
public function execute() {
- return;
}
}
print "Median: $median ms\n";
print "Mean: $mean ms\n";
print "Maximum: $max ms\n";
- print "Memory usage: " . $contLang->formatSize( memory_get_usage( true ) ) . "\n";
+ print "Memory usage: " . $contLang->formatSize( memory_get_usage( true ) ) . "\n";
print "Peak memory usage: " .
$contLang->formatSize( memory_get_peak_usage( true ) ) . "\n";
}
}
$this->outputStatus( "\n" );
- return;
}
/**
continue;
}
if ( isset( $alreadyWritten[$line] ) ) {
- $this->output( "Password '$line' already written (line " . ( $i + 1 ) .")\n" );
+ $this->output( "Password '$line' already written (line " . ( $i + 1 ) . ")\n" );
$skipped++;
continue;
}
/* Stub function for processing additional options */
public function checkOptions() {
- return;
}
/* Stub function for giving data about what was computed */
public function conclusions() {
- return;
}
/* Core function which does whatever the maintenance script is designed to do */
'user',
'user_name',
[
- 'user_name > ' .$dbw->addQuotes( $lastUsername ),
+ 'user_name > ' . $dbw->addQuotes( $lastUsername ),
],
__METHOD__,
[
/* global extDependencyMap */
-( function ( $ ) {
+( function () {
$( function () {
var $label, labelText;
} );
} );
} );
-}( jQuery ) );
+}() );
*
* @class jQuery.plugin.spinner
*/
-( function ( $ ) {
+( function () {
// Default options for new spinners,
// stored outside the function to share between calls.
* @mixins jQuery.plugin.spinner
*/
-}( jQuery ) );
+}() );
*
* @author Christian Bach/christian.bach@polyester.se
*/
-( function ( $, mw ) {
+( function () {
var ts,
parsers = [];
type: 'numeric'
} );
-}( jQuery, mediaWiki ) );
+}() );
// * This installation of tipsy includes several local modifications to both Javascript and CSS.
// Please be careful when upgrading.
-( function ( mw, $ ) {
+( function () {
function maybeCall(thing, ctx) {
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
}
};
-}( mediaWiki, jQuery ) );
+}() );
*
* @class jQuery.plugin.accessKeyLabel
*/
-( function ( $, mw ) {
+( function () {
// Cached access key modifiers for used browser
var cachedAccessKeyModifiers,
* @mixins jQuery.plugin.accessKeyLabel
*/
-}( jQuery, mediaWiki ) );
+}() );
* @param {string} str
* @return {number}
*/
-mediaWiki.log.deprecate( jQuery, 'byteLength', require( 'mediawiki.String' ).byteLength,
+mw.log.deprecate( $, 'byteLength', require( 'mediawiki.String' ).byteLength,
'Use require( \'mediawiki.String\' ).byteLength instead.', '$.byteLength' );
/**
/**
* @class jQuery.plugin.checkboxShiftClick
*/
-( function ( $ ) {
+( function () {
/**
* Enable checkboxes to be checked or unchecked in a row by clicking one,
* @mixins jQuery.plugin.checkboxShiftClick
*/
-}( jQuery ) );
+}() );
*
* - 2011-01-05: Forked for MediaWiki. See also jQuery.colorUtil plugin
*/
-( function ( $ ) {
+( function () {
function getColor( elem, attr ) {
var color;
};
} );
-}( jQuery ) );
+}() );
* Mostly based on other plugins and functions (linted and optimized a little).
* Sources cited inline.
*/
-( function ( $ ) {
+( function () {
/**
* @class jQuery.colorUtil
* @singleton
};
-}( jQuery ) );
+}() );
*
* @class jQuery.plugin.confirmable
*/
-( function ( $ ) {
+( function () {
var identity = function ( data ) {
return data;
};
noTitle: undefined
}
};
-}( jQuery ) );
+}() );
* This file serves to inject our localised messages into it.
*/
-( function ( mw, $ ) {
+( function () {
$.fn.confirmable.defaultOptions.i18n = {
space: mw.message( 'word-separator' ).text(),
confirm: mw.message( 'confirmable-confirm', mw.user ).text(),
yesTitle: undefined,
noTitle: undefined
};
-}( mediaWiki, jQuery ) );
+}() );
/**
* @class jQuery.plugin.getAttrs
*/
-( function ( $ ) {
+( function () {
function serializeControls( controls ) {
var i,
data = {},
$.fn.serializeObject = function () {
return serializeControls( this.serializeArray() );
};
-}( jQuery ) );
+}() );
*
* @class jQuery.plugin.hidpi
*/
-( function ( $ ) {
+( function () {
/**
* Get reported or approximate device pixel ratio.
* @mixins jQuery.plugin.hidpi
*/
-}( jQuery ) );
+}() );
* TODO: Add a function for restoring the previous text.
* TODO: Accept mappings for converting shortcuts like WP: to Wikipedia:.
*/
-( function ( $, mw ) {
+( function () {
$.highlightText = {
} );
};
-}( jQuery, mediaWiki ) );
+}() );
/**
* @class jQuery.plugin.lengthLimit
*/
-( function ( $, mw ) {
+( function () {
var
eventKeys = [
* @class jQuery
* @mixins jQuery.plugin.lengthLimit
*/
-}( jQuery, mediaWiki ) );
+}() );
/**
* @class jQuery.plugin.localize
*/
-( function ( $, mw ) {
+( function () {
/**
* Gets a localized message, using parameters from options if present.
* @mixins jQuery.plugin.localize
*/
-}( jQuery, mediaWiki ) );
+}() );
*
* @class jQuery.plugin.makeCollapsible
*/
-( function ( $, mw ) {
+( function () {
/**
* Handler for a click on a collapsible toggler.
*
* @mixins jQuery.plugin.makeCollapsible
*/
-}( jQuery, mediaWiki ) );
+}() );
/**
* JavaScript to show jump links to motor-impaired users when they are focused.
*/
-jQuery( function ( $ ) {
+$( function () {
$( '.mw-jump' ).on( 'focus blur', 'a', function ( e ) {
// Confusingly jQuery leaves e.type as focusout for delegated blur events
* input or not.
*/
-( function ( $, mw ) {
+( function () {
var hasOwn = Object.hasOwnProperty;
* @mixins jQuery.plugin.suggestions
*/
-}( jQuery, mediaWiki ) );
+}() );
/**
* @class jQuery.plugin.tabIndex
*/
-( function ( $ ) {
+( function () {
/**
* Find the lowest tabindex in use within a selection.
* @mixins jQuery.plugin.tabIndex
*/
-}( jQuery ) );
+}() );
* $textbox.textSelection( 'encapsulateSelection', { pre: '<b>', post: '</b>' } );
* // Result: Textbox contains 'This is <b>bold</b>!', with cursor before the '!'
*/
-( function ( $ ) {
+( function () {
/**
* Do things to the selection in a `<textarea>`, or a textarea-like editable element.
*
* @inheritdoc jQuery.plugin.textSelection#textSelection
*/
-}( jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* Create an object like mw.Api, but automatically handling everything required to communicate
// Expose
mw.ForeignApi = CoreForeignApi;
-}( mediaWiki, jQuery ) );
+}() );
/* global moment, Uint8Array */
-( function ( $, mw ) {
+( function () {
/**
* mw.ForeignStructuredUpload.BookletLayout encapsulates the process
this.dateWidget.setValue( '' ).setValidityFlag( true );
};
-}( jQuery, mediaWiki ) );
+}() );
-( function ( mw, $, OO ) {
+( function () {
/**
* Used to represent an upload in progress on the frontend.
*
};
mw.ForeignStructuredUpload = ForeignStructuredUpload;
-}( mediaWiki, jQuery, OO ) );
+}() );
-( function ( mw, OO, $ ) {
+( function () {
/**
* Used to represent an upload in progress on the frontend.
*
};
mw.ForeignUpload = ForeignUpload;
-}( mediaWiki, OO, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* @class mw.RegExp
*/
return str.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ); // eslint-disable-line no-useless-escape
}
};
-}( mediaWiki ) );
+}() );
* @since 1.18
*/
-( function ( mw, $ ) {
+( function () {
/**
* Parse titles into an object structure. Note that when using the constructor
* directly, passing invalid titles will result in an exception. Use #newFromText to use the
// Expose
mw.Title = Title;
-}( mediaWiki, jQuery ) );
+}() );
// (It is excluded in jsduck.json.)
// ESLint suggests unquoting some object keys, which would render the file unparseable by Opera 12.
/* eslint-disable quote-props */
-( function ( mw ) {
+( function () {
var toUpperMapping = {
'ß': 'ß',
'ʼn': 'ʼn',
var mapped = toUpperMapping[ chr ];
return mapped || chr.toUpperCase();
};
-}( mediaWiki ) );
+}() );
/* global moment */
-( function ( $, mw, moment ) {
+( function () {
/**
* mw.Upload.BookletLayout encapsulates the process of uploading a file
this.filenameUsageWidget.setValue( null );
};
-}( jQuery, mediaWiki, moment ) );
+}() );
-( function ( $, mw ) {
+( function () {
/**
* mw.Upload.Dialog controls a {@link mw.Upload.BookletLayout BookletLayout}.
this.uploadBooklet.clear();
}, this );
};
-}( jQuery, mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
var UP;
/**
};
mw.Upload = Upload;
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Uri
*/
-( function ( mw, $ ) {
+( function () {
var parser, properties;
/**
return location.href;
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:RevisionDelete
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var colonSeparator = mw.message( 'colon-separator' ).text(),
summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* Scripts for action=delete at domready
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var colonSeparator = mw.message( 'colon-separator' ).text(),
summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
reason.$input.byteLimit( summaryByteLimit, filterFn );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
var collapsibleLists, handleOne;
// Collapsible lists of categories and templates
);
}
} );
-}( mediaWiki ) );
+}() );
/*
* Javascript for module editWarning
*/
-( function ( mw, $ ) {
+( function () {
'use strict';
$( function () {
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* Scripts for action=edit at domready
*/
-( function ( mw, $ ) {
+( function () {
'use strict';
/**
} );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* Live edit preview.
*/
-( function ( mw, $ ) {
+( function () {
/**
* @ignore
$( document.body ).on( 'click', '#wpPreview, #wpDiff', doLivePreview );
} );
-}( mediaWiki, jQuery ) );
+}() );
* Scripts for pre-emptive edit preparing on action=edit
*/
-( function ( mw, $ ) {
+( function () {
if ( !mw.config.get( 'wgAjaxEditStash' ) ) {
return;
}
checkStash();
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for History action
*/
-jQuery( function ( $ ) {
+$( function () {
var $historyCompareForm = $( '#mw-history-compare' ),
$historySubmitter,
$lis = $( '#pagehistory > li' );
/*!
* Enables double-click-to-edit functionality.
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
mw.util.$content.dblclick( function ( e ) {
var $a;
}
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
*
* See also ImagePage.php#makeMetadataTable (creates the HTML)
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var $tables = $( '.mw_metadata' );
if ( !$tables.find( '.mw-metadata-collapsible, .collapsable' ).length ) {
$tables.addClass( 'collapsed' );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
/**
} );
}
-}( mediaWiki, jQuery ) );
+}() );
* This is loaded in the top queue, so avoid unnecessary dependencies
* like mediawiki.Title or mediawiki.Uri.
*/
-( function ( mw, $ ) {
+( function () {
var profile = $.client.profile(),
canonical = mw.config.get( 'wgInternalRedirectTargetUrl' ),
fragment = null,
} );
}
-}( mediaWiki, jQuery ) );
+}() );
* When the user right-clicks in a heading, it will open the
* edit screen.
*/
-( function ( $ ) {
+( function () {
// Trigger this when a contextmenu click on the page targets an h1-h6 element.
// This uses a delegate handler which 1) starts immediately instead of blocking
// response on dom-ready, and 2) selects and binds once instead of N times.
$edit.get( 0 ).click();
}
} );
-}( jQuery ) );
+}() );
/**
* @class mw.Api.plugin.category
*/
-( function ( mw, $ ) {
+( function () {
$.extend( mw.Api.prototype, {
/**
* @mixins mw.Api.plugin.category
*/
-}( mediaWiki, jQuery ) );
+}() );
/**
* @class mw.Api.plugin.edit
*/
-( function ( mw, $ ) {
+( function () {
$.extend( mw.Api.prototype, {
* @mixins mw.Api.plugin.edit
*/
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* @class mw.Api
];
mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings, null, 'mw.Api.warnings' );
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Api.plugin.login
* @since 1.22
*/
-( function ( mw, $ ) {
+( function () {
'use strict';
$.extend( mw.Api.prototype, {
* @mixins mw.Api.plugin.login
*/
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Api.plugin.messages
* @since 1.27
*/
-( function ( mw, $ ) {
+( function () {
'use strict';
$.extend( mw.Api.prototype, {
* @mixins mw.Api.plugin.messages
*/
-}( mediaWiki, jQuery ) );
+}() );
/**
* @class mw.Api.plugin.options
*/
-( function ( mw, $ ) {
+( function () {
$.extend( mw.Api.prototype, {
* @mixins mw.Api.plugin.options
*/
-}( mediaWiki, jQuery ) );
+}() );
/**
* @class mw.Api.plugin.parse
*/
-( function ( mw, $ ) {
+( function () {
$.extend( mw.Api.prototype, {
/**
* @mixins mw.Api.plugin.parse
*/
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Api.plugin.rollback
* @since 1.28
*/
-( function ( mw, $ ) {
+( function () {
$.extend( mw.Api.prototype, {
/**
* @mixins mw.Api.plugin.rollback
*/
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Api.plugin.upload
* @singleton
*/
-( function ( mw, $ ) {
+( function () {
var nonce = 0,
fieldsAllowed = {
stash: true,
* @class mw.Api
* @mixins mw.Api.plugin.upload
*/
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Api.plugin.user
* @since 1.27
*/
-( function ( mw, $ ) {
+( function () {
$.extend( mw.Api.prototype, {
* @mixins mw.Api.plugin.user
*/
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.Api.plugin.watch
* @since 1.19
*/
-( function ( mw, $ ) {
+( function () {
/**
* @private
* @mixins mw.Api.plugin.watch
*/
-}( mediaWiki, jQuery ) );
+}() );
* Jeroen De Dauw <jeroendedauw at gmail dot com>
*/
-( function ( $ ) {
+( function () {
'use strict';
$( function () {
} );
-}( jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* Prevent the closing of a window with a confirm message (the onbeforeunload event seems to
* work in most browsers.)
}
};
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
/**
}
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
var debug,
debug.init();
} );
-}( mediaWiki, jQuery ) );
+}() );
* @private
* @class jQuery.plugin.footHovzer
*/
-( function ( $ ) {
+( function () {
var $hovzer, footHovzer, $spacer;
function getHovzer() {
* @mixins jQuery.plugin.footHovzer
*/
-}( jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
var CONTROL_BUCKET = 'control',
MAX_INT32_UNSIGNED = 4294967295;
}
};
-}( mediaWiki, jQuery ) );
+}() );
* @author Moriel Schottlender, 2015
* @since 1.19
*/
-( function ( mw, $ ) {
+( function () {
/**
* This is a way of getting simple feedback from users. It's useful
* for testing new features -- users can give you feedback without
return this.bugReportLink;
};
-}( mediaWiki, jQuery ) );
+}() );
* @author Mark Holmquist, 2015
* @since 1.25
*/
-( function ( mw, $, oo ) {
+( function () {
var warningConfig = mw.config.get( 'wgFileWarning' ),
warningMessages = warningConfig.messages,
warningLink = warningConfig.link,
.addClass( 'mediawiki-filewarning-info empty' ),
$footer = $( '<p>' )
.addClass( 'mediawiki-filewarning-footer empty' ),
- dialog = new oo.ui.PopupButtonWidget( {
+ dialog = new OO.ui.PopupButtonWidget( {
classes: [ 'mediawiki-filewarning-anchor' ],
label: $mimetype,
flags: [ 'warning' ],
// object at all. Sort of nasty, but it gets the job done.
dialog.getPopup().toggle = $.noop;
}
-}( mediaWiki, jQuery, OO ) );
+}() );
-( function ( mw, $ ) {
+( function () {
// FIXME: mw.htmlform.Element also sets this to empty object
mw.htmlform = {};
return this;
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
// FIXME: mw.htmlform.Checker also sets this to empty object
mw.htmlform = {};
OO.inheritClass( mw.htmlform.ActionFieldLayout, OO.ui.ActionFieldLayout );
OO.mixinClass( mw.htmlform.ActionFieldLayout, mw.htmlform.Element );
-}( mediaWiki ) );
+}() );
* HTMLForm enhancements:
* Set up autocomplete fields.
*/
-( function ( mw, $ ) {
+( function () {
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
var $autocomplete = $root.find( '.mw-htmlform-autocomplete' );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
* HTMLForm enhancements:
* Infuse some OOUI HTMLForm fields (those which benefit from always being infused).
*/
-( function ( mw, $ ) {
+( function () {
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
var $oouiNodes, modules, extraModules;
} );
-}( mediaWiki, jQuery ) );
+}() );
* HTMLForm enhancements:
* Show fancy tooltips for checkmatrix fields.
*/
-( function ( mw ) {
+( function () {
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
var $matrixTooltips = $root.find( '.mw-htmlform-matrix .mw-htmlform-tooltip' );
}
} );
-}( mediaWiki ) );
+}() );
* HTMLForm enhancements:
* Add/remove cloner clones without having to resubmit the form.
*/
-( function ( mw, $ ) {
+( function () {
var cloneCounter = 0;
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
* HTMLForm enhancements:
* Set up 'hide-if' behaviors for form fields that have them.
*/
-( function ( mw, $ ) {
+( function () {
/**
* Helper function for hide-if to find the nearby form field.
}
v = spec[ 2 ];
- if ( !( field instanceof jQuery ) ) {
+ if ( !( field instanceof $ ) ) {
// field is a OO.ui.Widget
if ( field.supports( 'isSelected' ) ) {
getVal = function () {
// It is impossible to submit a form with hidden fields failing validation, e.g. one that
// is required. However, validity is not checked for disabled fields, as these are not
// submitted with the form. So we should also disable fields when hiding them.
- if ( self instanceof jQuery ) {
+ if ( self instanceof $ ) {
// This also finds elements inside any nested fields (in case of HTMLFormFieldCloner),
// which is problematic. But it works because:
// * HTMLFormFieldCloner::createFieldsForKey() copies 'hide-if' rules to nested fields
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
$( function () {
mw.hook( 'htmlform.enhance' ).fire( $( document ) );
$root.find( '.mw-htmlform' ).removeAttr( 'novalidate' );
} );
-}( mediaWiki, jQuery ) );
+}() );
* HTMLForm enhancements:
* Convert multiselect fields from checkboxes to Chosen selector when requested.
*/
-( function ( mw, $ ) {
+( function () {
function addMulti( $oldContainer, $container ) {
var name = $oldContainer.find( 'input:first-child' ).attr( 'name' ),
}
} );
-}( mediaWiki, jQuery ) );
+}() );
* HTMLForm enhancements:
* Add a dynamic max length to the reason field of SelectAndOther.
*/
-( function ( mw, $ ) {
+( function () {
// cache the separator to avoid object creation on each keypress
var colonSeparator = mw.message( 'colon-separator' ).text();
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
* HTMLForm enhancements:
* Animate the SelectOrOther fields, to only show the text field when 'other' is selected.
*/
-( function ( mw, $ ) {
+( function () {
/**
* @class jQuery.plugin.htmlform
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/* eslint-disable no-console */
-( function ( mw, $ ) {
+( function () {
// mw.inspect is a singleton class with static methods
// that itself can also be invoked as a function (mediawiki.base/mw#inspect).
mw.log( 'mw.inspect: reports are not available in debug mode.' );
}
-}( mediaWiki, jQuery ) );
+}() );
* @author neilk@wikimedia.org
* @author mflaschen@wikimedia.org
*/
-( function ( mw, $ ) {
+( function () {
/**
* @class mw.jqueryMsg
* @singleton
if ( typeof children[ i ] !== 'object' ) {
children[ i ] = document.createTextNode( children[ i ] );
}
- if ( children[ i ] instanceof jQuery && children[ i ].hasClass( 'mediaWiki_htmlEmitter' ) ) {
+ if ( children[ i ] instanceof $ && children[ i ].hasClass( 'mediaWiki_htmlEmitter' ) ) {
children[ i ] = children[ i ].contents();
}
}
* @return {string} Textual value of input
*/
function textify( input ) {
- if ( input instanceof jQuery ) {
+ if ( input instanceof $ ) {
input = input.text();
}
return String( input );
var $el,
arg = nodes[ 0 ],
contents = nodes[ 1 ];
- if ( arg instanceof jQuery && !arg.hasClass( 'mediaWiki_htmlEmitter' ) ) {
+ if ( arg instanceof $ && !arg.hasClass( 'mediaWiki_htmlEmitter' ) ) {
$el = arg;
} else {
$el = $( '<a>' );
for ( formIndex = 0; formIndex < forms.length; formIndex++ ) {
form = forms[ formIndex ];
- if ( form instanceof jQuery && form.hasClass( 'mediaWiki_htmlEmitter' ) ) {
+ if ( form instanceof $ && form.hasClass( 'mediaWiki_htmlEmitter' ) ) {
// This is a nested node, may be an explicit plural form like 5=[$2 linktext]
firstChild = form.contents().get( 0 );
if ( firstChild && firstChild.nodeType === Node.TEXT_NODE ) {
};
}() );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
'use strict';
/**
}
};
-}( mediaWiki ) );
+}() );
/*
* Language-fallback-chain-related utilities for mediawiki.language.
*/
-( function ( mw, $ ) {
+( function () {
/**
* @class mw.language
*/
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Base language object with methods related to language support, attempting to mirror some of the
* functionality of the Language class in MediaWiki:
}
};
-}( mediaWiki ) );
+}() );
/*
* Methods for transforming message syntax.
*/
-( function ( mw, $ ) {
+( function () {
/**
* @class mw.language
return forms[ form ][ word ];
}
- transformations = mediaWiki.language.getData( userLanguage, 'grammarTransformations' );
+ transformations = mw.language.getData( userLanguage, 'grammarTransformations' );
if ( !( transformations && transformations[ form ] ) ) {
return word;
}
} );
-}( mediaWiki, jQuery ) );
+}() );
*
* Loading this module also ensures the availability of appropriate messages via mw.msg.
*/
-( function ( mw ) {
+( function () {
var
monthMessages = [
'january', 'february', 'march', 'april',
abbrev: monthAbbrevMessages.map( mwMsgMapper )
};
-}( mediaWiki ) );
+}() );
/*
* Number-related utilities for mediawiki.language.
*/
-( function ( mw, $ ) {
+( function () {
/**
* @class mw.language
*/
} );
-}( mediaWiki, jQuery ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( mw, $ ) {
+( function () {
var ProtectionForm,
reasonCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
reasonByteLimit = mw.config.get( 'wgCommentByteLimit' );
$( ProtectionForm.init.bind( ProtectionForm ) );
-}( mediaWiki, jQuery ) );
+}() );
/**
* MediaWiki legacy wikibits
*/
-( function ( mw, $ ) {
+( function () {
var msg,
loadedScripts = {};
}, 'Use jQuery or mw.loader.load instead.', 'document.' + method );
} );
-}( mediaWiki, jQuery ) );
+}() );
/* global JpegMeta */
-( function ( mw ) {
+( function () {
// Export as module
module.exports = function ( fileReaderResult, fileName ) {
// Back-compat: Also expose via mw.lib
// @deprecated since 1.31
mw.log.deprecate( mw.libs, 'jpegmeta', module.exports );
-}( mediaWiki ) );
+}() );
module.exports = window.pluralRuleParser;
// Back-compat: Also expose via mw.lib
-mediaWiki.libs.pluralRuleParser = window.pluralRuleParser;
+mw.libs.pluralRuleParser = window.pluralRuleParser;
-( function ( mw, $ ) {
+( function () {
/**
* This is an implementation of MessagePoster for wikitext talk pages.
*
mw.messagePoster.factory.register( 'wikitext', WikitextMessagePoster );
mw.messagePoster.WikitextMessagePoster = WikitextMessagePoster;
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* This is the abstract base class for MessagePoster implementations.
*
* something.
*/
mw.messagePoster.MessagePoster.prototype.post = function () {};
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* Factory for MessagePoster objects. This provides a pluggable to way to script the action
* of adding a message to someone's talk page.
mw.messagePoster = {
factory: new MessagePosterFactory()
};
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.plugin.convertmessagebox
* @singleton
*/
-( function ( mw, $ ) {
+( function () {
'use strict';
/**
module.exports = convertmessagebox;
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
var notification,
mw.notification = notification;
-}( mediaWiki, jQuery ) );
+}() );
/**
* @class mw.plugin.notify
*/
-( function ( mw ) {
+( function () {
'use strict';
/**
* @mixins mw.plugin.notify
*/
-}( mediaWiki ) );
+}() );
* - Toggle gallery captions when focused.
* - Dynamically resize images to fill horizontal space.
*/
-( function ( mw, $ ) {
+( function () {
var $galleries,
bound = false,
lastWidth = window.innerWidth,
}
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* mw.GallerySlideshow: Interface controls for the slideshow gallery
*/
-( function ( mw, $, OO ) {
+( function () {
/**
* mw.GallerySlideshow encapsulates the user interface of the slideshow
* galleries. An object is instantiated for each `.mw-gallery-slideshow`
new mw.GallerySlideshow( this );
} );
} );
-}( mediaWiki, jQuery, OO ) );
+}() );
* Implement AJAX navigation for multi-page images so the user may browse without a full page reload.
*/
-( function ( mw, $ ) {
+( function () {
var jqXhr, $multipageimage, $spinner,
cache = {},
cacheOrder = [];
} );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
* @since 1.21
* @author Marius Hoch <hoo@online.de>
*/
-( function ( mw, $ ) {
+( function () {
if ( !mw.user.tokens.exists( 'patrolToken' ) ) {
// Current user has no patrol right, or an old cached version of user.tokens
// that didn't have patrolToken yet.
e.preventDefault();
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
mw.hook( 'wikipage.content' ).add( function ( $content ) {
var $sortable, $collapsible;
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
* @since 1.28
* @author Timo Tijhof
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
$( '.mw-rollback-link' ).on( 'click', 'a[data-mw="interface"]', function ( e ) {
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
// Break out of framesets
if ( mw.config.get( 'wgBreakFrames' ) ) {
// Note: In IE < 9 strict comparison to window is non-standard (the standard didn't exist yet)
}
} );
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.plugin.page.watch.ajax
* @singleton
*/
-( function ( mw, $ ) {
+( function () {
var watch,
// The name of the page to watch or unwatch
title = mw.config.get( 'wgRelevantPageName' );
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* View model for the changes list
*
mw.rcfilters.dm.ChangesListViewModel.prototype.hasUnseenWatchedChanges = function () {
return this.unseenWatchedChanges;
};
-}( mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( mw ) {
+( function () {
/**
* View model for a filter group
*
itemModel.toggleVisible( visibleItems.indexOf( itemModel ) !== -1 );
} );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Filter item model
*
return this.visible;
};
-}( mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( mw, $ ) {
+( function () {
/**
* View model for the filters selection and display
*
this.getItemByName( filterName ).clearHighlightColor();
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* RCFilter base item model
*
mw.rcfilters.dm.ItemModel.prototype.isHighlighted = function () {
return !!this.getHighlightColor();
};
-}( mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( mw, $ ) {
+( function () {
/**
* View model for saved queries
*
mw.rcfilters.dm.SavedQueriesModel.prototype.isConverted = function () {
return this.converted;
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* View model for a single saved query
*
this.emit( 'update' );
}
};
-}( mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( mw, $ ) {
+( function () {
var byteLength = require( 'mediawiki.String' ).byteLength;
this.filtersModel.getViewTrigger( view )
);
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Supported highlight colors.
* Warning: These are also hardcoded in "styles/mw.rcfilters.variables.less"
* @property {string[]}
*/
mw.rcfilters.HighlightColors = [ 'c1', 'c2', 'c3', 'c4', 'c5' ];
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/* eslint no-underscore-dangle: "off" */
/**
* URI Processor for RCFilters
{ urlversion: '2' }
);
};
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:RecentChanges
*/
-( function ( mw, $ ) {
+( function () {
var rcfilters = {
/**
* @member mw.rcfilters
module.exports = rcfilters;
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* @class
* @singleton
}
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget defining the button controlling the popup for the number of results
*
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget defining the popup to choose number of results
*
mw.rcfilters.ui.ChangesLimitPopupWidget.prototype.onGroupByPageModelUpdate = function () {
this.groupByPageCheckbox.setSelected( this.groupByPageItemModel.isSelected() );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* List of changes
*
// Turn off highlights
this.$element.removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlighted' );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A widget representing a single toggle filter
*
mw.rcfilters.ui.CheckboxInputWidget.prototype.onUserChange = function () {
this.emit( 'userChange', this.$input.prop( 'checked' ) );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget defining the popup to choose date for the results
*
*
* A days item was chosen
*/
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* A button to configure highlight for a filter item
*
);
} );
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* Menu header for the RCFilters filters menu
*
mw.rcfilters.ui.FilterMenuHeaderWidget.prototype.onInvertNamespacesButtonClick = function () {
this.controller.toggleInvertedNamespaces();
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A widget representing a single toggle filter
*
} );
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A widget representing a menu section for filter groups
*
return this.model.getName();
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Extend OOUI's FilterTagItemWidget to also display a popup on hover.
*
invalid: this.itemModel.isSelected() && this.itemModel.isConflicted()
} );
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* List displaying all filter groups
*
} );
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* List displaying all filter groups
*
mw.rcfilters.ui.FilterWrapperWidget.prototype.onNewChangesExist = function ( newChangesExist ) {
this.showNewChangesLink.toggle( newChangesExist );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Wrapper for the RC form with hide/show links
* Must be constructed after the model is initialized.
this.$element.detach();
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A group widget to allow for aggregation of events
*
OO.inheritClass( mw.rcfilters.ui.GroupWidget, OO.ui.Widget );
OO.mixinClass( mw.rcfilters.ui.GroupWidget, OO.ui.mixin.GroupWidget );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* A widget representing a filter item highlight color picker
*
}
this.emit( 'chooseColor', color );
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* A popup containing a color picker, for setting highlight colors.
*
this.toggle( false );
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A widget representing a base toggle item
*
return this.itemModel;
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget for toggling live updates
*
this.setState( enable );
};
-}( mediaWiki ) );
+}() );
-( function ( $, mw ) {
+( function () {
/**
* Wrapper for changes list content
*
return new mw.rcfilters.ui.FormWrapperWidget(
this.model, this.changesListModel, this.controller, this.$formContainer );
};
-}( jQuery, mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Button for marking all changes as seen on the Watchlist
*
this.setDisabled( !this.model.hasUnseenWatchedChanges() );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A floating menu widget for the filter list
*
mw.rcfilters.ui.MenuSelectWidget.prototype.setUserSelecting = function ( isSelecting ) {
this.userSelecting = !!isSelecting;
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Top section (between page title and filters) on Special:Recentchanges
*
}
this.$topLinks.toggleClass( 'mw-recentchanges-toplinks-collapsed', state === 'collapsed' );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget to select and display target page on Special:RecentChangesLinked (AKA Related Changes)
*
this.titleSearch.setValue( text );
this.titleSearch.setTitle( text );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget to select to view changes that link TO or FROM the target page
* on Special:RecentChangesLinked (AKA Related Changes)
'rcfilters-filter-showlinkedfrom-label'
) );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Top section (between page title and filters) on Special:RecentChangesLinked (AKA RelatedChanges)
*
/* Initialization */
OO.inheritClass( mw.rcfilters.ui.RclTopSectionWidget, OO.ui.Widget );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Save filters widget. This widget is displayed in the tag area
* and allows the user to save the current state of the system
this.emit( 'saveCurrent' );
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Quick links menu option widget
*
return this.model.getID();
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Quick links widget
*
this.menu.removeItems( [ this.menu.findItemFromData( item.getID() ) ] );
this.placeholderItem.toggle( this.model.isEmpty() );
};
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/**
* Extend OOUI's TagItemWidget to also display a popup on hover.
*
this.itemModel.disconnect( this );
this.closeButton.disconnect( this );
};
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Widget defining the behavior used to choose from a set of values
* in a single_value group
this.selectWidget.selectItemByData( selectedItem.getName() );
}
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* A widget for the footer for the default view, allowing to switch views
*
mw.rcfilters.ui.ViewSwitchWidget.prototype.onButtonClick = function ( buttonWidget ) {
this.controller.switchView( buttonWidget.getData() );
};
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
/**
* Top section (between page title and filters) on Special:Watchlist
*
/* Initialization */
OO.inheritClass( mw.rcfilters.ui.WatchlistTopSectionWidget, OO.ui.Widget );
-}( mediaWiki ) );
+}() );
/*!
* Add search suggestions to the search form.
*/
-( function ( mw, $ ) {
+( function () {
var searchNS = $.map( mw.config.get( 'wgFormattedNamespaces' ), function ( nsName, nsID ) {
if ( nsID >= 0 && mw.user.options.get( 'searchNs' + nsID ) ) {
// Cast string key to number
.find( '.mw-fallbackSearchButton' ).remove();
} );
-}( mediaWiki, jQuery ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( $, mw, OO ) {
+( function () {
'use strict';
var ApiSandbox, Util, WidgetMethods, Validators,
$content, panel, booklet, oldhash, windowManager,
module.exports = ApiSandbox;
-}( jQuery, mediaWiki, OO ) );
+}() );
/*!
* JavaScript for Special:Block
*/
-( function ( mw, $ ) {
+( function () {
// Like OO.ui.infuse(), but if the element doesn't exist, return null instead of throwing an exception.
function infuseOrNull( elem ) {
try {
updateBlockOptions();
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for change credentials form.
*/
-( function ( mw, $, OO ) {
+( function () {
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
var api = new mw.Api();
} );
} );
} );
-}( mediaWiki, jQuery, OO ) );
+}() );
*/
/* Remember the collapse state of the legend on recent changes and watchlist pages. */
-( function ( mw ) {
+( function () {
var
cookieName = 'changeslist-state',
// Expanded by default
};
mw.hook( 'wikipage.content' ).add( doCollapsibleLegend );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
// Return a promise that is resolved when the element is blurred (loses focus).
// If it already is blurred, resolved immediately.
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:EditTags
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:Import
*/
-( function ( $ ) {
+( function () {
var subprojectListAlreadyShown;
function updateImportSubprojectList() {
var $projectField = $( '#mw-import-table-interwiki #interwiki' ),
updateImportSubprojectList();
}
} );
-}( jQuery ) );
+}() );
/*!
* JavaScript for Special:MovePage
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
mw.widgets.visibleByteLimit( wpReason, summaryByteLimit );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript module used on Special:PageLanguage
*/
-( function ( $, OO ) {
+( function () {
$( function () {
// Select the 'Language select' option if user is trying to select language
OO.ui.infuse( 'mw-pl-languageselector' ).on( 'change', function () {
OO.ui.infuse( 'mw-pl-options' ).setValue( '2' );
} );
} );
-}( jQuery, OO ) );
+}() );
/*!
* JavaScript for Special:Preferences: editfont field enhancements.
*/
-( function ( mw ) {
+( function () {
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
var widget, lastValue,
$target = $root.find( '#mw-input-wpeditfont' );
updateLabel( widget.getValue() );
} );
-}( mediaWiki ) );
+}() );
/*!
* JavaScript for Special:Preferences: Tab navigation.
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var $preferences, tabs, wrapper, previousTab, switchingNoHash;
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
* JavaScript for Special:Preferences: Enable save button and prevent the window being accidentally
* closed when any form field is changed.
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var allowCloseWindow, saveButton, restoreButton,
oouiEnabled = $( '#mw-prefs-form' ).hasClass( 'mw-htmlform-ooui' );
$( '#mw-prefs-restoreprefs' ).on( 'click', allowCloseWindow.release );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:Preferences: Check for successbox to replace with notifications.
*/
-( function ( $ ) {
+( function () {
$( function () {
var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' );
convertmessagebox();
} );
-}( jQuery ) );
+}() );
/*!
* JavaScript for Special:Preferences: Email preferences better UX
*/
-( function ( $ ) {
+( function () {
$( function () {
var allowEmail, allowEmailFromNewUsers;
toggleDisabled();
}
} );
-}( jQuery ) );
+}() );
/*!
* JavaScript for Special:Preferences: Tab navigation.
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var $preftoc, $preferences, $fieldsets, labelFunc, previousTab;
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:Preferences: Timezone field enhancements.
*/
-( function ( mw, $ ) {
+( function () {
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
var $tzSelect, $tzTextbox, timezoneWidget, $localtimeHolder, servertime,
$target = $root.find( '#wpTimeCorrection' ),
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:RecentChanges
*/
-( function ( mw, $ ) {
+( function () {
var rc, $checkboxes, $select;
/**
module.exports = rc;
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:RevisionDelete
*/
-( function ( mw, $ ) {
+( function () {
var colonSeparator = mw.message( 'colon-separator' ).text(),
summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
$wpReason.byteLimit( summaryByteLimit, filterFn );
}
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
var api = new mw.Api(),
pageUrl = new mw.Uri(),
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:Search
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var $checkboxes, $headerLinks, updateHeaderLinks, searchWidget;
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:Undelete
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
var summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
mw.widgets.visibleByteLimit( wpComment, summaryByteLimit );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:UnwatchedPages
*/
-( function ( mw, $ ) {
+( function () {
$( function () {
$( 'a.mw-watch-link' ).click( function ( e ) {
var promise,
e.preventDefault();
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/* global Uint8Array */
-( function ( mw, $ ) {
+( function () {
var uploadWarning, uploadTemplatePreview,
ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
$license = $( '#wpLicense' );
$( '.mw-editTools' ).attr( 'tabindex', '0' );
setEditTabindex( '-1' );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for signup form.
*/
-( function ( mw, $ ) {
+( function () {
// When sending password by email, hide the password input fields.
$( function () {
// Always required if checked, otherwise it depends, so we use the original
passwordChecker = new mw.htmlform.Checker( $passwordInput, checkPassword );
passwordChecker.attach( $usernameInput.add( $emailInput ).add( $realNameInput ) );
} );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:UserRights
*/
-( function ( mw, $ ) {
+( function () {
var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' ),
summaryCodePointLimit = mw.config.get( 'wgCommentCodePointLimit' ),
summaryByteLimit = mw.config.get( 'wgCommentByteLimit' ),
$wpReason.byteLimit( summaryByteLimit );
}
-}( mediaWiki, jQuery ) );
+}() );
/*!
* JavaScript for Special:Watchlist
*/
-( function ( $ ) {
+( function () {
$( function () {
$( '.mw-changeslist-line-watched .mw-title a' ).on( 'click', function () {
$( this )
.removeClass( 'mw-changeslist-line-watched' );
} );
} );
-}( jQuery ) );
+}() );
/*!
* JavaScript for Special:Watchlist
*/
-( function ( mw, $, OO ) {
+( function () {
$( function () {
var api = new mw.Api(), $progressBar, $resetForm = $( '#mw-watchlist-resetbutton' );
}
} );
-}( mediaWiki, jQuery, OO )
-);
+}() );
-( function ( mw ) {
+( function () {
'use strict';
// Catch exceptions to avoid fatal in Chrome's "Block data storage" mode
*/
mw.storage.session = new SafeStorage( sessionStorage );
-}( mediaWiki ) );
+}() );
* @class mw.template
* @singleton
*/
-( function ( mw, $ ) {
+( function () {
var compiledTemplates = {},
compilers = {};
}
} );
-}( mediaWiki, jQuery ) );
+}() );
/* global Mustache */
-( function ( mw, $ ) {
+( function () {
// Register mustache compiler
mw.template.registerCompiler( 'mustache', {
compile: function ( src ) {
}
} );
-}( mediaWiki, jQuery ) );
+}() );
-mediaWiki.template.registerCompiler( 'regexp', {
+mw.template.registerCompiler( 'regexp', {
compile: function ( src ) {
return {
render: function () {
-( function ( mw, $ ) {
+( function () {
'use strict';
// Table of contents toggle
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
* @class mw.toolbar
* @singleton
*/
-( function ( mw, $ ) {
+( function () {
var toolbar, isReady, $toolbar, queue, slice, $currentFocused;
/**
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
* @singleton
*/
/* global Uint16Array */
-( function ( mw, $ ) {
+( function () {
var userInfoPromise, pageviewRandomId;
/**
*/
mw.log.deprecate( mw.user, 'stickyRandomId', mw.user.getPageviewToken, 'Please use getPageviewToken instead' );
-}( mediaWiki, jQuery ) );
+}() );
/*!
* Add autocomplete suggestions for names of registered users.
*/
-( function ( mw, $ ) {
+( function () {
var api, config;
config = {
$( function () {
$( '.mw-autocomplete-user' ).suggestions( config );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
var util;
mw.util = util;
module.exports = util;
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
/**
};
mw.viewport = viewport;
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, document ) {
+( function () {
var hidden, visibilityChange,
nextVisibleTimeoutId = 0,
activeTimeouts = {},
+ document = window.document,
init = function ( overrideDoc ) {
if ( overrideDoc !== undefined ) {
document = overrideDoc;
module.exports.setDocument = init;
}
-}( mediaWiki, document ) );
+}() );
-( function ( $, mw ) {
+( function () {
/**
* CalendarWidget displays a calendar that can be used to select a date. It
return this;
};
-}( jQuery, mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( $, mw ) {
+( function () {
/**
* Provides various methods needed for formatting dates and times.
};
};
-}( jQuery, mediaWiki ) );
+}() );
-( function ( $, mw ) {
+( function () {
/**
* DateTimeInputWidgets can be used to input a date, a time, or a date and
this.focus();
};
-}( jQuery, mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( $, mw ) {
+( function () {
/**
* Provides various methods needed for formatting dates and times. This
return ret;
};
-}( jQuery, mediaWiki ) );
+}() );
/* eslint-disable no-restricted-properties */
-( function ( $, mw ) {
+( function () {
/**
* Provides various methods needed for formatting dates and times. This
return ret;
};
-}( jQuery, mediaWiki ) );
+}() );
// Create the namespace object
-mediaWiki.widgets.datetime = {};
+mw.widgets.datetime = {};
-( function ( mw ) {
+( function () {
var byteLength = require( 'mediawiki.String' ).byteLength,
codePointLength = require( 'mediawiki.String' ).codePointLength;
textInputWidget.$input.codePointLimit( limit );
};
-}( mediaWiki ) );
+}() );
*
* @copyright 2011-2016 VisualEditor Team and others; see http://ve.mit-license.org
*/
-( function ( $, mw ) {
+( function () {
/**
* API Results Provider object.
mw.widgets.APIResultsProvider.prototype.setAjaxSettings = function ( settings ) {
this.ajaxSettings = settings;
};
-}( jQuery, mediaWiki ) );
+}() );
*
* @copyright 2011-2016 VisualEditor Team and others; see http://ve.mit-license.org
*/
-( function ( $, mw ) {
+( function () {
/**
* API Results Queue object.
mw.widgets.APIResultsQueue.prototype.getThreshold = function () {
return this.threshold;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* MediaWiki media resource provider.
this.apiurl !== undefined ||
this.scriptDirUrl !== undefined;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* MediaWiki media resource queue.
mw.widgets.MediaResourceQueue.prototype.getMaxHeight = function () {
return this.maxHeight;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Creates an mw.widgets.MediaResultWidget object.
mw.widgets.MediaResultWidget.prototype.hasSrc = function () {
return !!this.src;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* MediaWiki media search provider.
mw.widgets.MediaSearchProvider.prototype.isValid = function () {
return this.getUserParams().gsrsearch && mw.widgets.MediaSearchProvider.super.prototype.isValid.call( this );
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( mw ) {
+( function () {
/**
* MediaWiki media resource queue.
mw.widgets.MediaSearchQueue.prototype.getSearchQuery = function () {
return this.getParams().gsrsearch;
};
-}( mediaWiki ) );
+}() );
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Creates an mw.widgets.MediaSearchWidget object.
mw.widgets.MediaSearchWidget.prototype.getLang = function () {
return this.lang;
};
-}( jQuery, mediaWiki ) );
+}() );
* @license The MIT License (MIT); see LICENSE.txt
*/
/* global moment */
-( function ( $, mw ) {
+( function () {
/**
* Creates an mw.widgets.CalendarWidget object.
return this;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
var hasOwn = Object.prototype.hasOwnProperty,
NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
/** Search only parent categories */
ParentCategories: 4
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
var hasOwn = Object.prototype.hasOwnProperty;
// For backwards compatibility. See T183299.
mw.widgets.CategoryCapsuleItemWidget = mw.widgets.CategoryTagItemWidget;
-}( jQuery, mediaWiki ) );
+}() );
-( function ( $, mw ) {
+( function () {
/**
* A JavaScript version of CheckMatrixWidget.
*
} );
}
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Namespace input widget. Displays a dropdown box with the choice of available namespaces, plus
return this;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Like TitleInputWidget, but the namespace has to be input through a separate dropdown field.
return this;
};
-}( jQuery, mediaWiki ) );
+}() );
* @license The MIT License (MIT); see LICENSE.txt
*/
/* global moment */
-( function ( $, mw ) {
+( function () {
/**
* Creates an mw.widgets.DateInputWidget object.
}
};
-}( jQuery, mediaWiki ) );
+}() );
* @license The MIT License (MIT); see LICENSE.txt
*/
/* global moment */
-( function ( $, mw ) {
+( function () {
/**
* Creates a mw.widgets.ExpiryWidget object.
return this.relativeField.getValue();
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Namespace input widget. Displays a dropdown box with the choice of available namespaces.
return options;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Creates a mw.widgets.SearchInputWidget object.
return items;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2017 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Select with input widget. Displays an OO.ui.TextInputWidget along with
this.emit( 'change', this.getValue() );
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2018 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* RadioSelectInputWidget and a TextInputWidget to set minimum or maximum byte size
this.textinput.restorePreInfuseState( state.textinput );
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2016 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw, OO ) {
+( function () {
/**
* Accepts a stashed file and displays the information for purposes of
return $.Deferred().reject( 'No filekey' );
};
-}( jQuery, mediaWiki, OO ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
var trimByteLength = require( 'mediawiki.String' ).trimByteLength;
} ).newVal;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Creates a mw.widgets.TitleOptionWidget object.
OO.inheritClass( mw.widgets.TitleOptionWidget, OO.ui.MenuOptionWidget );
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( mw ) {
+( function () {
/**
* Creates an mw.widgets.TitleSearchWidget object.
return response.query || {};
};
-}( mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
var hasOwn = Object.prototype.hasOwnProperty;
/**
return !!this.getMWTitle();
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* Creates a mw.widgets.UserInputWidget object.
return items;
};
-}( jQuery, mediaWiki ) );
+}() );
* @copyright 2017 MediaWiki Widgets Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function ( $, mw ) {
+( function () {
/**
* UsersMultiselectWidget can be used to input list of users in a single
this.input.setValue( '' );
};
-}( jQuery, mediaWiki ) );
+}() );
-/* global mediaWiki, moment */
+/* global moment */
-( function ( mw ) {
+( function () {
// HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
// wgTranslateNumerals is respected.
moment.updateLocale( moment.locale(), {
return s;
}
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
var isMobile;
// Connect OOUI to MediaWiki's localisation system
OO.ui.getUserLanguages = mw.language.getFallbackLanguageChain;
}
return isMobile;
};
-}( mediaWiki ) );
+}() );
$this->assertHasCookie( 'foo', 'bar', $request->getCookieJar() );
$this->markTestIncomplete( 'CookieJar does not handle deletion' );
- return;
- $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/delete?foo' );
- $cookieJar = new CookieJar();
- $cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
- $cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'httpbin.org' ] );
- $request->setCookieJar( $cookieJar );
- $status = $request->execute();
- $this->assertTrue( $status->isGood() );
- $this->assertNotHasCookie( 'foo', $request->getCookieJar() );
- $this->assertHasCookie( 'foo2', 'bar2', $request->getCookieJar() );
+ // $request = MWHttpRequest::factory( 'http://httpbin.org/cookies/delete?foo' );
+ // $cookieJar = new CookieJar();
+ // $cookieJar->setCookie( 'foo', 'bar', [ 'domain' => 'httpbin.org' ] );
+ // $cookieJar->setCookie( 'foo2', 'bar2', [ 'domain' => 'httpbin.org' ] );
+ // $request->setCookieJar( $cookieJar );
+ // $status = $request->execute();
+ // $this->assertTrue( $status->isGood() );
+ // $this->assertNotHasCookie( 'foo', $request->getCookieJar() );
+ // $this->assertHasCookie( 'foo2', 'bar2', $request->getCookieJar() );
}
public function testGetResponseHeaders() {
* @return ParserTestResult|false false if skipped
*/
public function runTest( $test ) {
- wfDebug( __METHOD__.": running {$test['desc']}" );
+ wfDebug( __METHOD__ . ": running {$test['desc']}" );
$opts = $this->parseOptions( $test['options'] );
$teardownGuard = $this->perTestSetup( $test );
<?php
-require __DIR__.'/../../maintenance/Maintenance.php';
+require __DIR__ . '/../../maintenance/Maintenance.php';
define( 'MW_PARSER_TEST', true );
*
* @param Title|string|null $title
* @return WikiPage
- * @throws MWException
+ * @throws MWException If this test cases's needsDB() method doesn't return true.
+ * Test cases can use "@group Database" to enable database test support,
+ * or list the tables under testing in $this->tablesUsed, or override the
+ * needsDB() method.
*/
protected function getExistingTestPage( $title = null ) {
+ if ( !$this->needsDB() ) {
+ throw new MWException( 'When testing which pages, the test cases\'s needsDB()' .
+ ' method should return true. Use @group Database or $this->tablesUsed.' );
+ }
+
$title = ( $title === null ) ? 'UTPage' : $title;
$title = is_string( $title ) ? Title::newFromText( $title ) : $title;
$page = WikiPage::factory( $title );
*
* @param Title|string|null $title
* @return WikiPage
- * @throws MWException
+ * @throws MWException If this test cases's needsDB() method doesn't return true.
+ * Test cases can use "@group Database" to enable database test support,
+ * or list the tables under testing in $this->tablesUsed, or override the
+ * needsDB() method.
*/
protected function getNonexistingTestPage( $title = null ) {
+ if ( !$this->needsDB() ) {
+ throw new MWException( 'When testing which pages, the test cases\'s needsDB()' .
+ ' method should return true. Use @group Database or $this->tablesUsed.' );
+ }
+
$title = ( $title === null ) ? 'UTPage-' . rand( 0, 100000 ) : $title;
$title = is_string( $title ) ? Title::newFromText( $title ) : $title;
$page = WikiPage::factory( $title );
* @param int|null $namespace Namespace id (name cannot already contain namespace)
* @param User|null $user If null, static::getTestSysop()->getUser() is used.
* @return array Title object and page id
+ * @throws MWException If this test cases's needsDB() method doesn't return true.
+ * Test cases can use "@group Database" to enable database test support,
+ * or list the tables under testing in $this->tablesUsed, or override the
+ * needsDB() method.
*/
protected function insertPage(
$pageName,
$namespace = null,
User $user = null
) {
+ if ( !$this->needsDB() ) {
+ throw new MWException( 'When testing which pages, the test cases\'s needsDB()' .
+ ' method should return true. Use @group Database or $this->tablesUsed.' );
+ }
+
if ( is_string( $pageName ) ) {
$title = Title::newFromText( $pageName, $namespace );
} else {
* @param string $summary Optional summary string for the revision
* @param int $defaultNs Optional namespace id
* @return array Array as returned by WikiPage::doEditContent()
+ * @throws MWException If this test cases's needsDB() method doesn't return true.
+ * Test cases can use "@group Database" to enable database test support,
+ * or list the tables under testing in $this->tablesUsed, or override the
+ * needsDB() method.
*/
protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) {
+ if ( !$this->needsDB() ) {
+ throw new MWException( 'When testing which pages, the test cases\'s needsDB()' .
+ ' method should return true. Use @group Database or $this->tablesUsed.' );
+ }
+
$title = Title::newFromText( $pageName, $defaultNs );
$page = WikiPage::factory( $title );
use CommentStoreComment;
use Content;
+use ContentHandler;
use LinksUpdate;
use MediaWiki\MediaWikiServices;
use MediaWiki\Storage\DerivedPageDataUpdater;
use MediaWiki\Storage\RevisionSlotsUpdate;
use MediaWiki\Storage\SlotRecord;
use MediaWikiTestCase;
+use MWCallableUpdate;
+use PHPUnit\Framework\MockObject\MockObject;
+use TextContent;
+use TextContentHandler;
use Title;
use User;
use Wikimedia\TestingAccessWrapper;
$dataUpdates = $updater->getSecondaryDataUpdates();
- // TODO: MCR: assert updates from all slots!
$this->assertNotEmpty( $dataUpdates );
$linksUpdates = array_filter( $dataUpdates, function ( $du ) {
$this->assertCount( 1, $linksUpdates );
}
+ /**
+ * @param string $name
+ *
+ * @return ContentHandler
+ */
+ private function defineMockContentModelForUpdateTesting( $name ) {
+ /** @var ContentHandler|MockObject $handler */
+ $handler = $this->getMockBuilder( TextContentHandler::class )
+ ->setConstructorArgs( [ $name ] )
+ ->setMethods(
+ [ 'getSecondaryDataUpdates', 'getDeletionUpdates', 'unserializeContent' ]
+ )
+ ->getMock();
+
+ $dataUpdate = new MWCallableUpdate( 'time' );
+ $dataUpdate->_name = "$name data update";
+
+ $deletionUpdate = new MWCallableUpdate( 'time' );
+ $deletionUpdate->_name = "$name deletion update";
+
+ $handler->method( 'getSecondaryDataUpdates' )->willReturn( [ $dataUpdate ] );
+ $handler->method( 'getDeletionUpdates' )->willReturn( [ $deletionUpdate ] );
+ $handler->method( 'unserializeContent' )->willReturnCallback(
+ function ( $text ) use ( $handler ) {
+ return $this->createMockContent( $handler, $text );
+ }
+ );
+
+ $this->mergeMwGlobalArrayValue(
+ 'wgContentHandlers', [
+ $name => function () use ( $handler ){
+ return $handler;
+ }
+ ]
+ );
+
+ return $handler;
+ }
+
+ /**
+ * @param ContentHandler $handler
+ * @param string $text
+ *
+ * @return Content
+ */
+ private function createMockContent( ContentHandler $handler, $text ) {
+ /** @var Content|MockObject $content */
+ $content = $this->getMockBuilder( TextContent::class )
+ ->setConstructorArgs( [ $text ] )
+ ->setMethods( [ 'getModel', 'getContentHandler' ] )
+ ->getMock();
+
+ $content->method( 'getModel' )->willReturn( $handler->getModelID() );
+ $content->method( 'getContentHandler' )->willReturn( $handler );
+
+ return $content;
+ }
+
+ public function testGetSecondaryDataUpdatesWithSlotRemoval() {
+ global $wgMultiContentRevisionSchemaMigrationStage;
+
+ if ( ! ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) ) {
+ $this->markTestSkipped( 'Slot removal cannot happen with MCR being enabled' );
+ }
+
+ $m1 = $this->defineMockContentModelForUpdateTesting( 'M1' );
+ $a1 = $this->defineMockContentModelForUpdateTesting( 'A1' );
+ $m2 = $this->defineMockContentModelForUpdateTesting( 'M2' );
+
+ $mainContent1 = $this->createMockContent( $m1, 'main 1' );
+ $auxContent1 = $this->createMockContent( $a1, 'aux 1' );
+ $mainContent2 = $this->createMockContent( $m2, 'main 2' );
+
+ $user = $this->getTestUser()->getUser();
+ $page = $this->getPage( __METHOD__ );
+ $this->createRevision(
+ $page,
+ __METHOD__,
+ [ 'main' => $mainContent1, 'aux' => $auxContent1 ]
+ );
+
+ $update = new RevisionSlotsUpdate();
+ $update->modifyContent( 'main', $mainContent2 );
+ $update->removeSlot( 'aux' );
+
+ $page = $this->getPage( __METHOD__ );
+ $updater = $this->getDerivedPageDataUpdater( $page );
+ $updater->prepareContent( $user, $update, false );
+
+ $dataUpdates = $updater->getSecondaryDataUpdates();
+
+ $this->assertNotEmpty( $dataUpdates );
+
+ $updateNames = array_map( function ( $du ) {
+ return isset( $du->_name ) ? $du->_name : get_class( $du );
+ }, $dataUpdates );
+
+ $this->assertContains( LinksUpdate::class, $updateNames );
+ $this->assertContains( 'A1 deletion update', $updateNames );
+ $this->assertContains( 'M2 data update', $updateNames );
+ $this->assertNotContains( 'M1 data update', $updateNames );
+ }
+
/**
* Creates a dummy revision object without touching the database.
*
<?php
+// phpcs:disable MediaWiki.Commenting.PhpunitAnnotations.NotClassTrait
+
namespace MediaWiki\Tests\Storage;
use CommentStoreComment;
/** @var Revision $rev */
$rev = $page->doEditContent(
new WikitextContent( $text ),
- __METHOD__. 'a'
+ __METHOD__ . 'a'
)->value['revision'];
$store = MediaWikiServices::getInstance()->getRevisionStore();
/**
* @group API
* @group medium
+ * @group Database
*
* @covers ApiQueryPrefixSearch
*/
/**
* @group API
* @group medium
+ * @group Database
*
* @covers ApiQuerySiteinfo
*/
<?php
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\SlotRenderingProvider;
/**
* @group ContentHandler
$this->assertArrayHasKey( 'file_text', $data );
$this->assertEquals( 'This is file content', $data['file_text'] );
}
+
+ public function testGetSecondaryDataUpdates() {
+ $title = Title::newFromText( 'Somefile.jpg', NS_FILE );
+ $content = new WikitextContent( '' );
+
+ /** @var SlotRenderingProvider $srp */
+ $srp = $this->getMock( SlotRenderingProvider::class );
+
+ $handler = new WikitextContentHandler();
+ $updates = $handler->getSecondaryDataUpdates( $title, $content, 'main', $srp );
+
+ $this->assertEquals( [], $updates );
+ }
+
+ public function testGetDeletionUpdates() {
+ $title = Title::newFromText( 'Somefile.jpg', NS_FILE );
+ $content = new WikitextContent( '' );
+
+ $srp = $this->getMock( SlotRenderingProvider::class );
+
+ $handler = new WikitextContentHandler();
+ $updates = $handler->getDeletionUpdates( $title, 'main' );
+
+ $this->assertEquals( [], $updates );
+ }
+
}
'email' => 'chad@wikimedia.org',
],
],
- 'description' => 'Constant Database (CDB) wrapper library for PHP. '.
+ 'description' => 'Constant Database (CDB) wrapper library for PHP. ' .
'Provides pure-PHP fallback when dba_* functions are absent.',
],
'cssjanus/cssjanus' => [
// Query added
$this->assertEquals(
- '<a href="/w/index.php?title=Foobar&foo=bar" '. 'title="Foobar">Foobar</a>',
+ '<a href="/w/index.php?title=Foobar&foo=bar" ' . 'title="Foobar">Foobar</a>',
$linkRenderer->makeKnownLink( $target, null, [], [ 'foo' => 'bar' ] )
);
],
[
[ 'Software' => [ 'x-default' => 'paint.net 4.0.12', '_type' => 'lang' ] ],
- [ 'Software' => '<ul class="metadata-langlist">'.
- '<li class="mw-metadata-lang-default">'.
- '<span class="mw-metadata-lang-value">paint.net 4.0.12</span>'.
- "</li>\n".
+ [ 'Software' => '<ul class="metadata-langlist">' .
+ '<li class="mw-metadata-lang-default">' .
+ '<span class="mw-metadata-lang-value">paint.net 4.0.12</span>' .
+ "</li>\n" .
'</ul>'
],
],
use MediaWiki\Edit\PreparedEdit;
use MediaWiki\MediaWikiServices;
use MediaWiki\Storage\RevisionSlotsUpdate;
+use PHPUnit\Framework\MockObject\MockObject;
use Wikimedia\TestingAccessWrapper;
/**
/**
* @param string|Title|WikiPage $page
- * @param string $text
+ * @param string|Content|Content[] $content
* @param int|null $model
*
* @return WikiPage
*/
- protected function createPage( $page, $text, $model = null, $user = null ) {
+ protected function createPage( $page, $content, $model = null, $user = null ) {
if ( is_string( $page ) || $page instanceof Title ) {
$page = $this->newPage( $page, $model );
}
- $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
- $page->doEditContent( $content, "testing", EDIT_NEW, false, $user );
+ if ( !$user ) {
+ $user = $this->getTestUser()->getUser();
+ }
+
+ if ( is_string( $content ) ) {
+ $content = ContentHandler::makeContent( $content, $page->getTitle(), $model );
+ }
+
+ if ( !is_array( $content ) ) {
+ $content = [ 'main' => $content ];
+ }
+
+ $updater = $page->newPageUpdater( $user );
+
+ foreach ( $content as $role => $cnt ) {
+ $updater->setContent( $role, $cnt );
+ }
+
+ $updater->saveRevision( CommentStoreComment::newUnsavedComment( "testing" ) );
return $page;
}
* @covers WikiPage::doDeleteUpdates
*/
public function testDoDeleteUpdates() {
+ $user = $this->getTestUser()->getUser();
$page = $this->createPage(
__METHOD__,
"[[original text]] foo",
CONTENT_MODEL_WIKITEXT
);
$id = $page->getId();
+ $page->loadPageData(); // make sure the current revision is cached.
// Similar to MovePage logic
wfGetDB( DB_MASTER )->delete( 'page', [ 'page_id' => $id ], __METHOD__ );
- $page->doDeleteUpdates( $id );
+ $page->doDeleteUpdates( $page->getId(), $page->getContent(), $page->getRevision(), $user );
// Run the job queue
JobQueueGroup::destroySingletons();
$this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
}
+ /**
+ * @param string $name
+ *
+ * @return ContentHandler
+ */
+ protected function defineMockContentModelForUpdateTesting( $name ) {
+ /** @var ContentHandler|MockObject $handler */
+ $handler = $this->getMockBuilder( TextContentHandler::class )
+ ->setConstructorArgs( [ $name ] )
+ ->setMethods(
+ [ 'getSecondaryDataUpdates', 'getDeletionUpdates', 'unserializeContent' ]
+ )
+ ->getMock();
+
+ $dataUpdate = new MWCallableUpdate( 'time' );
+ $dataUpdate->_name = "$name data update";
+
+ $deletionUpdate = new MWCallableUpdate( 'time' );
+ $deletionUpdate->_name = "$name deletion update";
+
+ $handler->method( 'getSecondaryDataUpdates' )->willReturn( [ $dataUpdate ] );
+ $handler->method( 'getDeletionUpdates' )->willReturn( [ $deletionUpdate ] );
+ $handler->method( 'unserializeContent' )->willReturnCallback(
+ function ( $text ) use ( $handler ) {
+ return $this->createMockContent( $handler, $text );
+ }
+ );
+
+ $this->mergeMwGlobalArrayValue(
+ 'wgContentHandlers', [
+ $name => function () use ( $handler ){
+ return $handler;
+ }
+ ]
+ );
+
+ return $handler;
+ }
+
+ /**
+ * @param ContentHandler $handler
+ * @param string $text
+ *
+ * @return Content
+ */
+ protected function createMockContent( ContentHandler $handler, $text ) {
+ /** @var Content|MockObject $content */
+ $content = $this->getMockBuilder( TextContent::class )
+ ->setConstructorArgs( [ $text ] )
+ ->setMethods( [ 'getModel', 'getContentHandler' ] )
+ ->getMock();
+
+ $content->method( 'getModel' )->willReturn( $handler->getModelID() );
+ $content->method( 'getContentHandler' )->willReturn( $handler );
+
+ return $content;
+ }
+
+ public function testGetDeletionUpdates() {
+ $m1 = $this->defineMockContentModelForUpdateTesting( 'M1' );
+
+ $mainContent1 = $this->createMockContent( $m1, 'main 1' );
+
+ $page = new WikiPage( Title::newFromText( __METHOD__ ) );
+ $page = $this->createPage(
+ $page,
+ [ 'main' => $mainContent1 ]
+ );
+
+ $dataUpdates = $page->getDeletionUpdates( $page->getRevisionRecord() );
+ $this->assertNotEmpty( $dataUpdates );
+
+ $updateNames = array_map( function ( $du ) {
+ return isset( $du->_name ) ? $du->_name : get_class( $du );
+ }, $dataUpdates );
+
+ $this->assertContains( LinksDeletionUpdate::class, $updateNames );
+ $this->assertContains( 'M1 deletion update', $updateNames );
+ }
+
/**
* @covers WikiPage::getRevision
*/
return true;
}
+ public function testGetDeletionUpdates() {
+ $m1 = $this->defineMockContentModelForUpdateTesting( 'M1' );
+ $a1 = $this->defineMockContentModelForUpdateTesting( 'A1' );
+
+ $mainContent1 = $this->createMockContent( $m1, 'main 1' );
+ $auxContent1 = $this->createMockContent( $a1, 'aux 1' );
+
+ $page = new WikiPage( Title::newFromText( __METHOD__ ) );
+ $page = $this->createPage(
+ $page,
+ [ 'main' => $mainContent1, 'aux' => $auxContent1 ]
+ );
+
+ $dataUpdates = $page->getDeletionUpdates( $page->getRevisionRecord() );
+ $this->assertNotEmpty( $dataUpdates );
+
+ $updateNames = array_map( function ( $du ) {
+ return isset( $du->_name ) ? $du->_name : get_class( $du );
+ }, $dataUpdates );
+
+ $this->assertContains( LinksDeletionUpdate::class, $updateNames );
+ $this->assertContains( 'M1 deletion update', $updateNames );
+ $this->assertContains( 'A1 deletion update', $updateNames );
+ }
+
}
return false;
}
+ public function testGetDeletionUpdates() {
+ $mainContent1 = new WikitextContent( '' );
+
+ $title = Title::makeTitle( $this->getDefaultWikitextNS(), __METHOD__ );
+ $page = new WikiPage( $title );
+ $page = $this->createPage(
+ $page,
+ [ 'main' => $mainContent1 ]
+ );
+
+ $dataUpdates = $page->getDeletionUpdates( $page->getRevisionRecord() );
+ $this->assertNotEmpty( $dataUpdates );
+
+ $updateNames = array_map( function ( $du ) {
+ return isset( $du->_name ) ? $du->_name : get_class( $du );
+ }, $dataUpdates );
+
+ $this->assertContains( LinksDeletionUpdate::class, $updateNames );
+ }
+
}
/**
* @covers PoolWorkArticleView
+ * @group Database
*/
class PoolWorkArticleViewTest extends MediaWikiTestCase {
// Set up objects
$module = $this->getMockBuilder( TestResourceLoaderWikiModule::class )
- ->setMethods( [ 'getPages' ] ) ->getMock();
+ ->setMethods( [ 'getPages' ] )->getMock();
$module->method( 'getPages' )->willReturn( $pages );
$module::$returnFetchTitleInfo = $titleInfo;
$rl = new EmptyResourceLoader();
public function testGetContent( $expected, $title ) {
$context = $this->getResourceLoaderContext( [], new EmptyResourceLoader );
$module = $this->getMockBuilder( ResourceLoaderWikiModule::class )
- ->setMethods( [ 'getContentObj' ] ) ->getMock();
+ ->setMethods( [ 'getContentObj' ] )->getMock();
$module->expects( $this->any() )
->method( 'getContentObj' )->willReturn( null );
],
[
'method' => 'GET',
- 'userAgent' => Http::userAgent() ." SparqlClient",
+ 'userAgent' => Http::userAgent() . " SparqlClient",
'timeout' => 30
]
],
--- /dev/null
+<?php
+
+/**
+ * Test class for SpecialRedirect class
+ *
+ * @since 1.32
+ *
+ * @license GPL-2.0-or-later
+ * @group Database
+ */
+class SpecialRedirectTest extends MediaWikiTestCase {
+
+ protected $tablesUsed = [ 'user' ];
+
+ const CREATE_USER = 'create_user';
+
+ /**
+ * @dataProvider provideDispatch
+ * @covers SpecialRedirect::dispatchUser()
+ * @covers SpecialRedirect::dispatchFile()
+ * @covers SpecialRedirect::dispatchRevision()
+ * @covers SpecialRedirect::dispatchPage()
+ * @covers SpecialRedirect::dispatchLog()
+ */
+ public function testDispatch( $method, $type, $value, $expectedStatus ) {
+ $page = new SpecialRedirect();
+
+ // setup the user object
+ if ( $value === self::CREATE_USER ) {
+ $user = User::newFromName( __CLASS__ );
+ $user->addToDatabase();
+ $value = $user->getId();
+ }
+
+ $page->setParameter( $type . '/' . $value );
+
+ $status = $page->$method();
+ $this->assertSame(
+ $status->isGood(), $expectedStatus === 'good',
+ $method . ' does not return expected status "' . $expectedStatus . '"'
+ );
+ }
+
+ public static function provideDispatch() {
+ foreach ( [
+ [ 'nonumeric', 'fatal' ],
+ [ '3', 'fatal' ],
+ [ self::CREATE_USER, 'good' ],
+ ] as $dispatchUser ) {
+ yield [ 'dispatchUser', 'user', $dispatchUser[0], $dispatchUser[1] ];
+ }
+ foreach ( [
+ [ 'bad<name', 'fatal' ],
+ [ 'File:Non-exists.jpg', 'fatal' ],
+ // TODO Cannot test the good path here, because a file must exists
+ ] as $dispatchFile ) {
+ yield [ 'dispatchFile', 'file', $dispatchFile[0], $dispatchFile[1] ];
+ }
+ foreach ( [
+ [ 'nonumeric', 'fatal' ],
+ [ '0', 'fatal' ],
+ [ '1', 'good' ],
+ ] as $dispatch ) {
+ yield [ 'dispatchRevision', 'revision', $dispatch[0], $dispatch[1] ];
+ yield [ 'dispatchPage', 'revision', $dispatch[0], $dispatch[1] ];
+ yield [ 'dispatchLog', 'log', $dispatch[0], $dispatch[1] ];
+ }
+ }
+
+}
"(wl_notificationtimestamp >= 'TS111TS') OR (wl_notificationtimestamp IS NULL)" .
'))))' .
') OR ((wl_namespace = 1) AND (' .
- "(((wl_title = 'AnotherDbKey') AND (".
+ "(((wl_title = 'AnotherDbKey') AND (" .
"(wl_notificationtimestamp >= 'TS123TS') OR (wl_notificationtimestamp IS NULL)" .
')))))';
$mockDb->expects( $this->once() )
"(wl_notificationtimestamp >= 'TS111TS') OR (wl_notificationtimestamp IS NULL)" .
'))))' .
') OR ((wl_namespace = 1) AND (' .
- "(((wl_title = 'AnotherDbKey') AND (".
+ "(((wl_title = 'AnotherDbKey') AND (" .
"(wl_notificationtimestamp >= 'TS123TS') OR (wl_notificationtimestamp IS NULL)" .
'))))' .
') OR ' .
-mediaWiki.loader.testCallback();
+mw.loader.testCallback();
/* global sinon */
-( function ( $, mw, QUnit ) {
+( function () {
'use strict';
var addons, nested;
} );
} );
-}( jQuery, mediaWiki, QUnit ) );
+}() );
-( function ( $ ) {
+( function () {
var getAccessKeyPrefixTestData, updateTooltipAccessKeysTestData;
QUnit.module( 'jquery.accessKeyLabel', QUnit.newMwEnvironment( {
$.fn.updateTooltipAccessKeys.setTestMode( false );
} );
-}( jQuery ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'jquery.color', QUnit.newMwEnvironment() );
QUnit.test( 'animate', function ( assert ) {
} )
.always( done );
} );
-}( jQuery ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'jquery.colorUtil', QUnit.newMwEnvironment() );
QUnit.test( 'getRGB', function ( assert ) {
b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 );
assert.strictEqual( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
} );
-}( jQuery ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() );
QUnit.test( 'getAttrs()', function ( assert ) {
assert.propEqual( $el.getAttrs(), attrs, 'keys and values match' );
} );
-}( jQuery ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() );
QUnit.test( 'devicePixelRatio', function ( assert ) {
assert.strictEqual( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
assert.strictEqual( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
} );
-}( jQuery ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'jquery.highlightText', QUnit.newMwEnvironment() );
QUnit.test( 'Check', function ( assert ) {
);
} );
} );
-}( jQuery ) );
+}() );
-( function ( $, mw ) {
+( function () {
var simpleSample, U_20AC, poop, mbSample;
QUnit.module( 'jquery.lengthLimit', QUnit.newMwEnvironment() );
expected: '\uD800'
} );
-}( jQuery, mediaWiki ) );
+}() );
-( function ( $, mw ) {
+( function () {
QUnit.module( 'jquery.localize', QUnit.newMwEnvironment() );
QUnit.test( 'Handle basic replacements', function ( assert ) {
assert.strictEqual( $lc.length, 1, 'link is created' );
assert.strictEqual( $lc.text(), 'link', 'the link text got added' );
} );
-}( jQuery, mediaWiki ) );
+}() );
-( function ( $ ) {
+( function () {
var loremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';
QUnit.module( 'jquery.makeCollapsible', QUnit.newMwEnvironment() );
assert.assertFalse( $collapsible2.find( '> .mw-collapsible-toggle' ).hasClass( 'mw-collapsible-toggle-collapsed' ) );
} ).find( '> .mw-collapsible-toggle a' ).trigger( 'click' );
} );
-}( jQuery ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'jquery.tabIndex', QUnit.newMwEnvironment() );
QUnit.test( 'firstTabIndex', function ( assert ) {
$testB = $( '<div>' );
assert.strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' );
} );
-}( jQuery ) );
+}() );
-( function ( $, mw ) {
+( function () {
/**
* This module tests the input/output capabilities of the parsers of tablesorter.
* It does not test actual sorting.
// TODO add numbers sorting tests for T10115 with a different language
-}( jQuery, mediaWiki ) );
+}() );
-( function ( $, mw ) {
+( function () {
var header = [ 'Planet', 'Radius (km)' ],
// Data set "planets"
);
} );
-}( jQuery, mediaWiki ) );
+}() );
-( function ( $ ) {
+( function () {
var caretSample,
sig = {
pre: '--~~~~'
end: 11,
mode: 'set'
} );
-}( jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.ForeignApi', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
return api.post( {} );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.api.category', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
} );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
QUnit.module( 'mediawiki.api.edit', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.api.messages', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
);
} );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.api.options', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
} )
);
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.api.parse', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
assert.strictEqual( html, '<p><b>Earth</b> is a planet.</p>', 'Parse page by Title object' );
} );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
QUnit.module( 'mediawiki.api', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
var self = this,
requests = this.requests = [];
this.api = new mw.Api();
- this.sandbox.stub( jQuery, 'ajax', function () {
+ this.sandbox.stub( $, 'ajax', function () {
var request = $.extend( {
abort: self.sandbox.spy()
}, $.Deferred() );
assert.ok( request.abort.calledOnce, 'abort request number ' + i );
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
QUnit.module( 'mediawiki.api.upload', QUnit.newMwEnvironment( {} ) );
QUnit.test( 'Basic functionality', function ( assert ) {
assert.strictEqual( $input.val(), 'Testing API upload.jpg', 'input value' );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.api.watch', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
} );
} );
-}( mediaWiki ) );
+}() );
/* eslint-disable camelcase */
/* eslint no-underscore-dangle: "off" */
-( function ( mw, $ ) {
+( function () {
var mockFilterStructure = [ {
name: 'group1',
title: 'Group 1',
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
/* eslint-disable camelcase */
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.rcfilters - FilterItem' );
QUnit.test( 'Initializing filter item', function ( assert ) {
assert.strictEqual( item.getValue(), '1', 'Value is kept as-is' );
} );
-}( mediaWiki ) );
+}() );
/* eslint-disable camelcase */
-( function ( mw, $ ) {
+( function () {
var filterDefinition = [ {
name: 'group1',
type: 'send_unselected_if_any',
} );
assert.strictEqual( model.areVisibleFiltersEmpty(), false );
} );
-}( mediaWiki, jQuery ) );
+}() );
/* eslint-disable camelcase */
-( function ( mw ) {
+( function () {
var filterDefinition = [ {
name: 'group1',
type: 'send_unselected_if_any',
'Invert parameter saved if there are namespaces.'
);
} );
-}( mediaWiki ) );
+}() );
/* eslint-disable camelcase */
-( function ( mw ) {
+( function () {
var itemData = {
params: {
param1: '1',
'Default state represented when item initialized with default:true.'
);
} );
-}( mediaWiki ) );
+}() );
-( function ( $ ) {
+( function () {
QUnit.module( 'mediawiki.special.recentchanges', QUnit.newMwEnvironment() );
// TODO: verify checkboxes == [ 'nsassociated', 'nsinvert' ]
// DOM cleanup
$env.remove();
} );
-}( jQuery ) );
+}() );
QUnit.module( 'mediawiki.widgets.APIResultsQueue' );
-( function ( $, mw ) {
+( function () {
var itemCounter, FullResourceProvider, EmptyResourceProvider, SingleResultResourceProvider;
itemCounter = 0;
// Finish the async test
.then( done );
} );
-}( jQuery, mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.RegExp' );
QUnit.test( 'escape', function ( assert ) {
assert.strictEqual( mw.RegExp.escape( normal ), normal, 'Alphanumerals are left alone' );
} );
-}( mediaWiki ) );
+}() );
-( function ( $, mw ) {
+( function () {
var simpleSample, U_20AC, poop, mbSample,
trimByteLength = require( 'mediawiki.String' ).trimByteLength;
expected: '\uD800'
} );
-}( jQuery, mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/* eslint-disable camelcase */
var repeat = function ( input, multiplier ) {
return new Array( multiplier + 1 ).join( input );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment( {
setup: function () {
this.mwUriOrg = mw.Uri;
href = uri.toString();
assert.strictEqual( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.base' );
QUnit.test( 'mw.hook - basic', function ( assert ) {
} ] );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
var pluralTestcases = {
/*
* Sample:
pluralTest( langCode, tests );
}
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
var NOW = 9012, // miliseconds
DEFAULT_DURATION = 5678, // seconds
assert.strictEqual( key, 'barfoo' );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.errorLogger', QUnit.newMwEnvironment() );
QUnit.test( 'installGlobalHandler', function ( assert ) {
assert.strictEqual( w.onerror( errorMessage, errorUrl, errorLine ), true,
'Global handler preserves true return from previous handler' );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
var getBucket = mw.experiments.getBucket;
);
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.html' );
QUnit.test( 'escape', function ( assert ) {
);
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.inspect' );
);
} );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
/* eslint-disable camelcase */
var formatText, formatParse, formatnumTests, specialCharactersPageName, expectedListUsers,
expectedListUsersSitename, expectedLinkPagenamee, expectedEntrypoints,
'setParserDefaults is deep if requested'
);
} );
-}( mediaWiki, jQuery ) );
+}() );
* Some misc JavaScript compatibility tests,
* just to make sure the environments we run in are consistent.
*/
-( function ( $ ) {
+( function () {
QUnit.module( 'mediawiki.jscompat', QUnit.newMwEnvironment() );
QUnit.test( 'Variable with Unicode letter in name', function ( assert ) {
assert.strictEqual( $textarea.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
}
} );
-}( jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
'use strict';
var grammarTests, bcp47Tests;
assert.strictEqual( mw.language.bcp47( input ), expected );
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
QUnit.module( 'mediawiki.loader', QUnit.newMwEnvironment( {
setup: function ( assert ) {
// Expose for load.mock.php
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
var TEST_MODEL = 'test-content-model';
QUnit.module( 'mediawiki.messagePoster', QUnit.newMwEnvironment( {
'Throws exception is same model is registered a second time'
);
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.requestIdleCallback', QUnit.newMwEnvironment( {
setup: function () {
var clock = this.clock = this.sandbox.useFakeTimers();
} );
}
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.storage' );
QUnit.test( 'set/get with storage support', function ( assert ) {
mw.storage.store = old;
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.template.mustache', {
beforeEach: function () {
assert.strictEqual( htmlPartial, 'Hello goodbye', 'Render with partial' );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.template', {
beforeEach: function () {
);
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
var specialCharactersPageName,
// Can't mock SITENAME since jqueryMsg caches it at load
siteName = mw.config.get( 'wgSiteName' );
assert.strictEqual( mw.msg( 'int-msg' ), 'Some Other Message', 'int is resolved' );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
QUnit.module( 'mediawiki.toc', QUnit.newMwEnvironment( {
setup: function () {
// Prevent live cookies from interferring with the test
return $tocList.promise();
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.track' );
QUnit.test( 'track', function ( assert ) {
[ 'unsub', { key: 2 } ]
], 'Stop when unsubscribing' );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment( {
setup: function () {
this.server = this.sandbox.useFakeServer();
assert.strictEqual( result.trim(), result, 'no leading or trailing whitespace' );
assert.strictEqual( result2, result, 'retained' );
} );
-}( mediaWiki ) );
+}() );
-( function ( mw, $ ) {
+( function () {
var util = require( 'mediawiki.util' ),
// Based on IPTest.php > testisIPv4
IPV4_CASES = [
} );
QUnit.test( '$content', function ( assert ) {
- assert.ok( util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
+ assert.ok( util.$content instanceof $, 'mw.util.$content instance of jQuery' );
assert.strictEqual( util.$content.length, 1, 'mw.util.$content must have length of 1' );
} );
assert.strictEqual( util.isIPv6Address( ipCase[ 1 ] ), ipCase[ 0 ], ipCase[ 2 ] );
} );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw, $ ) {
+( function () {
// Simulate square element with 20px long edges placed at (20, 20) on the page
var
'It should default to a threshold of 50px and the window\'s viewport' );
} );
-}( mediaWiki, jQuery ) );
+}() );
-( function ( mw ) {
+( function () {
QUnit.module( 'mediawiki.visibleTimeout', QUnit.newMwEnvironment( {
setup: function () {
this.sandbox.clock.tick( 50 );
assert.strictEqual( called, 1 );
} );
-}( mediaWiki ) );
+}() );