meaning that JavaScript is no longer executed in these browser versions.
* Browser support for Opera 11 lowered from Grade A to Grade C.
* Removed IEFixes module which existed purely to provide support for MSIE versions
+ below 7 (conditionally loaded only for those browsers).
* Deprecated SpecialPageFactory::getList() in favor of
SpecialPageFactory::getNames()
- below 7 (conditionally loaded only for those browsers).
* Action::checkCanExecute() no longer has a return value.
* Removed cleanupForIRC(), loadFromCurRow(), newFromCurRow(), notifyRC2UDP()
and sendToUDP() from RecentChange.php. (deprecated since 1.22)
* Added jquery.throttle-debounce ResourceLoader module to limit the number of
callbacks for frequently occurring events.
* Special:ProtectedPages shows now a table. The timestamp, the reason and
- the protecting user is also shown.
+ the protecting user are also shown.
* Added experimental support for using Microsoft SQL Server as the database
backend.
** Added new Microsoft SQL Server-specific configuration variable
* (bug 52810) Preference "Justify paragraphs" was removed.
* OutputPage::showErrorPage raises a notice if arguments are incoherent.
* Thumbnails that keep failing to render in thumb.php will be rate-limited
- againt further render attempts for 1 hour. $wgAttemptFailureEpoch can be
+ against further render attempts for 1 hour. $wgAttemptFailureEpoch can be
altered to reset all rate-limited thumbnails at once.
* (bug 56572) Builds of the OOjs and OOjs UI libraries are now available.
* mw.loader.go and mw.loader.version have been removed.
HTML output is now exclusively HTML5.
* $wgDBOracleDRCP added. True enables persistent connection with DRCP on Oracle.
* $wgLogAutopatrol added to allow disabling logging of autopatrol edits in the logging table.
- default for $wgLogAutopatrol is true.
+ Default for $wgLogAutopatrol is true.
* The 'edit' right no longer allows for editing a user's own CSS and JS.
* New rights 'editmyusercss', 'editmyuserjs', 'viewmywatchlist',
'editmywatchlist', 'viewmyprivateinfo', 'editmyprivateinfo', and
* $wgCascadingRestrictionLevels was added, allowing one to specify restriction levels
which can be cascading (previously 'sysop' was hard-coded as the only one).
* XHTML5 support has been improved. If you set $wgMimeType = 'application/xhtml+xml'
- MediaWiki will try outputting markup acording to XHTML5 rules.
+ MediaWiki will try outputting markup according to XHTML5 rules.
* Altered hook 'ProtectionForm::save', adding the reason page protection is
changed as third parameter.
* New hook 'TitleSquidURLs' for manipulating the list of URLs to be purged from
* Make thumb.php give HTTP redirects for file redirects
* (bug 30607) Special:ListFiles can now show old versions of files. Additionally
Special:AllMyUploads was introduced so the user can get a list of all things
- they have ever uploaded, even if it was subsequently overriden.
+ they have ever uploaded, even if it was subsequently overridden.
* Introduced Special:MyFiles and Special:AllMyFiles as an alias for Special:MyUploads
and Special:AllMyUploads respectively.
* IPv6 addresses in X-Forwarded-For headers are now normalised before checking
The skins/common/wikiprintable.css file no longer exists. Return value of
Skin#commonPrintStylesheet is ignored. Please use the 'mediawiki.legacy.commonPrint'
module instead or base your skin on SkinTemplate.
-* (bug 49629) The hook ExtractThumbParamaters has been deprecated in favour
+* (bug 49629) The hook ExtractThumbParameters has been deprecated in favour
of media handler overriding MediaHandler::parseParamString.
* (bug 46512) The collapsibleNav feature from the Vector extension has been moved
to the Vector skin in core.
* Added $wgCopyUploadProxy global to define which proxy to use for copy
uploads.
* (bug 40448) mediawiki.legacy.mwsuggest has been replaced with a new module,
- mediawiki.searchSuggest, based on SimpleSeach from Extension:Vector.
+ mediawiki.searchSuggest, based on SimpleSearch from Extension:Vector.
=== Known issues in 1.20.0 ===
These are issues that we're targeting to be fixed in a later release
* (bug 34735) Updated compressOld.php documentation to mention the different
usages of -s and -n parameters depending on compression type.
* (bug 13896) Rendering of devanagari numbers in automatic '#' number lists.
-* (bug 33689) Upgrade to 1.19 on Postgres fails due to incomplete query when.
+* (bug 33689) Upgrade to 1.19 on Postgres fails due to incomplete query when
trying to defer foreign key for externallinks.
* (bug 32748) Printer friendly version of article decode Unicode chars as a
pretty IRI in footer.
* (bug 30410) Removed deprecated $wgFilterCallback and the 'filtered' API error.
* (bug 32604) Some messages needs escaping of wikitext inside username.
* (bug 36537) Rename wfArrayToCGI to wfArrayToCgi for consistency with wfCgiToArray.
-* (bug 25946) The message on the top of Special:RecentChanges is now displayed.
+* (bug 25946) The message on the top of Special:RecentChanges is now displayed
in user language instead of content language.
* (bug 35264) Wrong type used for <ns> in export.xsd
* (bug 24985) Use $wgTmpDirectory as the default temp directory so that people
until the second was introduced in 1.17.
* BREAKING CHANGE: Style rules for wikitable are now more specific and prevent
inheritance to nested tables which caused various issues (bug 30485 and bug
- 33434). If your wiki has overriden rules for ".wikitable", please revise them and
- adjust where neccecary. For comparison, use the "table.wikitable" section in
+ 33434). If your wiki has overridden rules for ".wikitable", please revise them and
+ adjust where necessary. For comparison, use the "table.wikitable" section in
skins/common/shared.css as base.
* $wgUploadNavigationUrl is now used for file redlinks if
$wgUploadMissingFileUrl is not set. The former was used for this until the
"create account" when the user cannot create an account.
* (bug 31818) 'usercreated' message now supports GENDER.
* (bug 32022) Our phpunit.php script can now be executed from another directory.
-* (bug 26020) Setting $wgEmailConfirmToEdit to true no longer removes diffs.
+* (bug 26020) Setting $wgEmailConfirmToEdit to true no longer removes diffs
from recent changes feeds.
* (bug 30232) add current time to message wlnote on Special:Watchlist.
* (bug 29110) $wgFeedDiffCutoff did not affect new pages.
* (bug 32168) Add wfAssembleUrl for use in wfExpandUrl.
* (bug 32168) fixed - wfExpandUrl expands dot segments now.
* (bug 31535) Upload comments now truncated properly, and don't have brackets.
-* (bug 32086) Special:PermanentLink now show an error message when no subpage
+* (bug 32086) Special:PermanentLink now shows an error message when no subpage
was specified.
* (bug 30368) Special:Newpages now shows the new page name for moved pages.
* (bug 1697) The way to search blocked usernames in block log should be clearer.
* (bug 28936, bug 5280) Broken or invalid titles can't be removed from watchlist.
* (bug 34600) Older skins using useHeadElement=false were broken in 1.18.
* (bug 34604) [mw.config] wgActionPaths should be an object instead of a numeral
- array.* (bug 12262) Indents and lists are now aligned
+ array.
+* (bug 12262) Indents and lists are now aligned
* (bug 29753) mw.util.tooltipAccessKeyPrefix should be alt-shift for Chrome
on Windows
* (bug 25095) Special:Categories should also include the first relevant item
address blocks for list=blocks.
* (bug 30591) Add support to only return keys in ApiAllMessages.
* The API now respects $wgShowHostnames and won't share the hostname in
- severedby if it's set to false.
+ servedby if it's set to false.
* wlexcludeuser parameter added to ApiFeedWatchlist.
* (bug 7304) Links on redirect pages no longer cause the redirect page to show
up as a redirect to the linked page on Special:Whatlinkshere.
This is a maintenance and security release of the MediaWiki 1.18 branch.
=== Changes since 1.18.1 ===
-* (bug 33686) could not get a list of contributor for an article when using
- a SQLite database.
+* (bug 33686) could not get a list of contributors for an article when using
+ a SQLite database.
* (Bug 33865) Exception thrown in action=parse when attempting to use the title
parameter without setting the text parameter.
* UserMailer could potentially throw a fatal error when a MailAddress object had
=== New features in 1.18 ===
* BREAKING CHANGE: action=watch / action=unwatch now requires a token.
-* BREAKING CHANGE: Article class hierarchy split into WikiPage (backend).
+* BREAKING CHANGE: Article class hierarchy split into WikiPage (backend)
and Article (frontend) hierarchies. Several hooks now pass a WikiPage object instead
- of an Article object. These hooks all use an $article paramater as documented in hooks.txt.
+ of an Article object. These hooks all use an $article parameter as documented in hooks.txt.
Extensions should be updated to account for this, though most won't require any changes.
* (bug 27860) Minor edit after clicking 'new section' tab
Now the "This is a minor edit" checkbox is not available when you
unicode code point is (aka pre-1.17 behavior).
* (bug 30940) Add a hook in User:getDefaultOptions.
To give extensions a better and more flexible way of providing default
- values for preferences a hook has been introdiced in User:getDefaultOptions().
+ values for preferences a hook has been introduced in User:getDefaultOptions().
Setting preferences in $wgDefaultUserOptions still work fine, but when reading
them (i.e. with array_keys) to get a list of all preferences, then
$wgDefaultUserOptions should no longer be used as it will contain those set via
file description page for multi-paged documents.
* (bug 28883) Message names for different compression types commonly
used in Tiff files.
-* When translcuding a special page, do not let it interpret url parameters.
+* When transcluding a special page, do not let it interpret url parameters.
* (bug 28887) Special page classes are no longer re-used during 1 request.
* (bug 28888) Searching for something starting with a # sign no longer tells
the user a page named [[:]] already exists.
RefreshLinks::deleteLinksFromNonexistent.
* (bug 29797) Error: "Tried to load block with invalid type" when subpages
are disabled for user pages.
-* (bug 12205) Bidirectional names in action=credits are split and displayed.
+* (bug 12205) Bidirectional names in action=credits are split and displayed
incorrectly when wrapped to the next line.
* (bug 20781) Move 'mainpagetext' messages to installer's .i18n file.
* (bug 29737) "MediaWiki:Qbsettings-directionality" should refer to script,
to the FCKEditor extension.
* (bug 28762) Resizing to specified height broken for very thin images.
* (bug 29959) Installer fatal when cURL and allow_url_fopen is disabled and user
- tries to subsribe to mediawiki-announce.
+ tries to subscribe to mediawiki-announce.
* (bug 27427) mw.util.getParamValue shouldn't return value from hash even if
param is only present in hash.
* Installer checked for magic_quotes_runtime instead of register_globals.
* (bug 30335) Fix for HTMLForms using GET breaking when non-friendly URLs
are used.
* (bug 30264) Changed installer-generated LocalSettings.php to use require_once()
- instead require() for included extensions.
+ instead of require() for included extensions.
* Tracking categories are no longer shown in footer for special pages.
* (bug 30684) Fix bad escaping in mw.message for inexistent messages (i.e. <key>).
* $wgOverrideSiteFeed no longer double escapes urls.
* (bug 27897) list=allusers and list=users list hidden users.
* (bug 27717) API's exturlusage module does not respect $wgMiserMode.
* (bug 27588) list=filearchive&faprop=sha1 returns empty attribute.
-* (bug 28010) Passing a non existant user to list=users gives internal error.
+* (bug 28010) Passing a non existent user to list=users gives internal error.
* (bug 27549) action=query&list=users&usprop=groups doesn't show implicit
groups if a user doesn't have explicit groups.
* (bug 27670) Ordering by timestamp (and usage of start and end) isn't as clear
* $wgSVGMaxSize is now applied to the smaller of width or height, making very
wide pano/timeline/diagram SVGs renderable at saner sizes.
* (bug 29959) Installer fatal when cURL and allow_url_fopen is disabled and user
- tries to subsribe to mediawiki-announce.
+ tries to subscribe to mediawiki-announce.
* Installer checked for magic_quotes_runtime instead of register_globals
* (bug 30131) XCache with variable caching disabled no longer used for variable
caching (CACHE_ACCEL)
* Fixed recentchanges FK violation on page delete and cache purge error in updater
for Oracle DB.
* (bug 32276) Skins were generating output using the internal page title which
- would allow anonymous users to determine wheter a page exists, potentially
+ would allow anonymous users to determine whether a page exists, potentially
leaking private data. In fact, the curid and oldid request parameters would
allow page titles to be enumerated even when they are not guessable.
* (bug 32616) action=ajax requests were dispatched to the relevant internal
with $wgPasswordSender configurable.
* (bug 22463) $wgFooterIcons added to allow configuration of the icons shown in
the footers of skins.
-* $wgFileCacheDepth can be used to set the depth of the subdirectory hierarchy.
+* $wgFileCacheDepth can be used to set the depth of the subdirectory hierarchy
used for the file cache. Default value is 2, which matches former behavior.
=== Bug fixes in 1.17 ===
language.
* (bug 22852) "Served in" comment is now the time used to cache a single page
when using rebuildFileCache.php
-* (bug 22496) Viewing diff of a redirect page without specifying "oldid".
+* (bug 22496) Viewing diff of a redirect page without specifying "oldid"
parameter no longer makes the page displayed as being the redirect target.
* (bug 22918) Feed cache keys now use $wgRenderHashAppend.
* (bug 21916) Last-Modified header is now correct when outputting cached feed.
* (bug 20049) Fixed PHP notice in search highlighter that occurs in some cases.
* (bug 23017) Special:Disambiguations now list pages in content namespaces
rather than only main namespace.
-* (bug 23063) $wgMaxAnimatedGifArea is checked against the total size of all.
+* (bug 23063) $wgMaxAnimatedGifArea is checked against the total size of all
frames, and $wgMaxImageArea against the size of the first frame, rather than
the other way around. Both now default to 12.5 megapixels. Also, images
exceeding $wgMaxImageArea can still be embedded at original size.
correct link.
* (bug 23284) Times are now rounded correctly.
* (bug 23375) Added ogv, oga, spx as extensions for ogg files.
-* (bug 18408) All required permissions for uploading (upload, edit, create).
+* (bug 18408) All required permissions for uploading (upload, edit, create)
are now checked when loading Special:Upload. Toolbar link for Special:Upload
is no longer shown if the user does not have the required permissions.
* (bug 23397) texvc in html mode renders \sim as ˜ not ∼
* (bug 19910) Headings of the form ===+\s+ are now displayed as valid headings.
* (bug 24022) Only check file extensions on the uploadpage when needed.
* (bug 24076) Recognize Office 2003 files with OpenXML trailers.
-* (bug 24244) Updated comments in DefaultSettings.php to reflect.
+* (bug 24244) Updated comments in DefaultSettings.php to reflect
Image: --> File: namespace rename.
* Make wfTimestamp recognize negative unix timestamp values.
* (bug 24401) SimpleSearch: No button/text indicating 'Search' if image is
* (bug 20744) Wiki forgets about an uploaded file.
* (bug 17913) Don't show "older edit" when no older edit available.
* (bug 6204) TOC not properly rendered when using $wgMaxTocLevel.
-* (bug 24977) The accesskey in history page now lead directly to the diff.
+* (bug 24977) The accesskey in history page now lead directly to the diff
instead of alternating focus between the two buttons.
* (bug 24987) Special:ListUsers does not take external groups into account.
* (bug 20633) update.php has mixed language output.
* (bug 25175) HTML file cache now honor $wgCacheDirectory if
$wgFileCacheDirectory is not set.
* (bug 13353) Diff3 version checks were too strict, did not detect working diff3.
-* (bug 25843) Links to special pages using link= attribute on images are now.
+* (bug 25843) Links to special pages using link= attribute on images are now
normalised like normal links to special pages.
* (bug 21364) External links using link= attribute on images now respect
$wgExternalLinkTarget.
* (bug 27508) SVGMetadataExtractor takes too much resources on huge svgs.
* (bug 27465) SVG thumbnail generation.
* (bug 27467) preload can leave UNIQ.
-* (bug 27539) Allow attributes beginning with a digit in wiktext tag parameters.
+* (bug 27539) Allow attributes beginning with a digit in wikitext tag parameters.
* (bug 27328) using relative paths in CSS imports in MediaWiki:Common.css broken
in 1.17.
* (bug 27333) Fix repetitive last-seen time queries on page history.
* (bug 22764) uselang parameter for action=parse.
* (bug 22944) API: watchlist options are inconsistent.
* (bug 22868) don't list infinite block expiry date as "now" in API logevents.
-* (bug 22290) prop=revisions now outputs "comment" field even when comment.
+* (bug 22290) prop=revisions now outputs "comment" field even when comment
is empty, for consistency with list=recentchanges.
* (bug 19721) API action=help should have a way to just list for a specific
module.
* (bug 23524) Api Modules as followup to bug 14473 (Add iwlinks table to
track inline interwiki link usage).
* Add pltitles and tltemplates to prop=links and prop=templates respectively,
- similar to prop=categories's clcategorie.
+ similar to prop=categories's clcategories.
* (bug 23834) Invalid "thumbwidth" and "thumbheight" in "imageinfo" query when
thumbnailing larger than original image.
* (bug 23835) Need "thumbmime" result in "imageinfo" query.
current revision id, try the parser cache, and save it to it if necessary.
* (bug 25463) Export header should not be shown if no pages were requested, to
reduce confusion.
-* (bug 25648) API discovery information has been added as RSD link in page.
+* (bug 25648) API discovery information has been added as RSD link in page
<head> and by providing an API module action=rsd. Added hook
ApiRsdServiceApis for extensions to add their own service to the services
list.
* Moroccan Spoken Arabic (ary)
* Banjar (bjn)
-* Kabardian (kdb)
+* Kabardian (kbd)
* Kabardian (Cyrillic) (kbd-cyrl)
* Latgalian (ltg)
* Minangkabau (min)
similarly to the category namespace.
* $wgEnableSorbs renamed to $wgDnsBlacklistUrls ($wgEnableSorbs kept for
backward compatibility)
-* $wgUploadNavigationUrl now also affects images inline images that do not
+* $wgUploadNavigationUrl now also affects inline images that do not
exist. In that case the URL will get (?|&)wpDestFile=<filename> appended to
it as appropriate.
* If $wgLocaltimezone is null, use the server's timezone as the default for
* Added a feature to allow per-article process pool size control for the parsing
task, to limit resource usage when the cache for a heavily-viewed article is
invalidated. Requires an external daemon.
-* (bug 19576) Moved the id attribues from the anchors accompanying section
+* (bug 19576) Moved the id attributes from the anchors accompanying section
headers to the <span class="mw-headline"> elements within the section headers,
removing the redundant anchor elements.
* Parser::setFunctionTagHook now can be used to add a new tag which is parsed at
* (bug 18943) Handle invalid titles gracefully at Special:Mostlinked
* (bug 8873) Enable variant conversion in text on 'alt' and 'title' attributes
* (bug 10837) Introducing the StubUserVariant class to determine the variant
- variable instead of using this to overrules the user language preference.
+ variable instead of using this to overrule the user language preference.
* (bug 19014) If user had deletedhistory right, but not undeleted right, then
show "view" instead of "view/restore" on logs.
* (bug 19017) TOC level calculation error in an odd case
are no longer recorded in the pagelinks table
* (bug 19784) date option "ISO 8601" produced illegal id
* (bug 19761) Removed autogenerated <meta keywords> tag with link data.
- Keyword set was not useful, and is ignored by modern search engines anway.
+ Keyword set was not useful, and is ignored by modern search engines anyway.
* (bug 19827) Special:SpecialPages title is "Upload file
* (bug 19355) Added .xhtml, .xht to upload file extension blacklist
* (bug 19287) Workaround for lag on history page in Firefox 3.5
* The display of the language list on the preferences is more comply with the
BCP 47 standards.
* (bug 19849) Custom X-Vary-Options header now disabled unless $wgUseXVO is set
-* (bug 19301) Duplicates entries in $wgAddGroups, $wgRemoveGroups,
+* (bug 19301) Duplicate entries in $wgAddGroups, $wgRemoveGroups,
$wgGroupsAddToSelf and $wgGroupsRemoveFromSelf are no more displayed on
Special:ListGroupRights
* (bug 18799) Special:Userlogin now handles correctly the returnto parameter
* (bug 15680) Split the edit tip message of user CSS/JS subpage into
"usercssyoucanpreview" and "userjsyoucanpreview" respectively.
* (bug 12110) Split the rights for editing users' CSS/JS subpage from
- "editusercssjs" into "editusercss" and edituserjs" respectively.
+ "editusercssjs" into "editusercss" and "edituserjs" respectively.
* (bug 19394) RecentChanges feed URLs for log items with no revisions
(eg Newuser, Userrights) are no longer broken
* (bug 17395) Remote file descriptions use user language ($wgLang), not wiki
"unknown error"
* (bug 18762) both redirects and links get fixed one after another if
redirects-only switch is not present
-* (bug 20159) thumbnails rerendered if older that $wgThumbnailEpoch
+* (bug 20159) thumbnails rerendered if older than $wgThumbnailEpoch
* Fixed a bug which in some situations causes the job queue to grow forever,
due to an infinite loop of job requeues.
* (bug 21523) File that can have multiple pages (djvu, pdf, ...) no longer have
* (bug 21776) Interwiki urls like http://en.wikibooks.org/wiki/cs: should give
a redirect instead of a baderror.
* (bug 21803) Special:MyContributions now keeps the query string parameters
-* Redirecting special pages now keep query string paramters set to "0" (e.g.
+* Redirecting special pages now keep query string parameters set to "0" (e.g.
for namespace)
* (bug 20765) Special:ListGroupRights no longer misses addables and removables
groups if there are duplicate entries
* refreshLinks.php now purges orphaned redirect table rows
* (bug 2971) Swap links of hist & diff location on Special:Contributions for
consistency with RC/WL
-* (bug 21986) Special page names were are now capitalized by content language
-* If two log type have the same description, they're now both displayed in the
+* (bug 21986) Special page names are now capitalized by content language
+* If two log types have the same description, they're now both displayed in the
type selector on Special:Log
* (bug 20115) Special:Userlogin title says "Log in / create account" even if the
user can't create an account
* Added $wgNoFollowDomainExceptions to allow exempting particular domain names
from rel="nofollow" on external links
* (bug 12970) Brought back $wgUseImageResize.
-* Added $wgRedirectOnLogin to allow specifying a specifc page to redirect users
+* Added $wgRedirectOnLogin to allow specifying a specific page to redirect users
to upon logging in (ex: "Main Page")
* Add $wgExportFromNamespaces for enabling/disabling the "export all from
namespace" option (disabled by default)
$wgRedirectOnLogin
* Added a link to Special:UserRights on Special:Contributions for privileged users
* (bug 10336) Added new magic word {{REVISIONUSER}}, which displays the editor
- of the displayed revision's author user name
+ of the displayed revision
* LinkerMakeExternalLink now has an $attribs parameter for link attributes and
a $linkType parameter for the type of external link being made
* (bug 17785) Dynamic dates surrounded with a <span> tag, fixing sortable tables with
* (bug 17778) MediaWiki:Catseparator can now have HTML entities
* (bug 17676) Error on Special:ListFiles when using Postgres
* Special:Export doesn't use raw SQL queries anymore
-* (bug 14771) Thumbnail links to individual DjVu pages have two no longer have
+* (bug 14771) Thumbnail links to individual DjVu pages no longer have
two "page" parameters
* (bug 17972) Special:FileDuplicateSearch form now works correctly on wikis that
don't use PathInfo or short urls
* Dropped old Paser_OldPP class. Only new parser with preprocessor is used.
* Moved password reset form from Special:Preferences to Special:ResetPass
* Added Special:ChangePassword as a special page alias for Special:ResetPass
-* Added complimentary function for addHandler() called removeHandler() for removing events
+* Added complementary function for addHandler() called removeHandler() for removing events
* Improved security of file uploads for IE clients, using a reverse-engineered
algorithm very similar to IE's content detection algorithm.
* Cascading protection no longer requires that both edit and move are restricted
* (bug 13705) Don't show rollback link in page history on incorrect revisions
* (bug 13708) Don't set "Search results" title when loading Special:Search
without query
-* (bug 13736) Don't show MediaWiki:Anontalkpagetext on non-existant IP addresses
+* (bug 13736) Don't show MediaWiki:Anontalkpagetext on non-existent IP addresses
* (bug 13728) Don't trim initial whitespace during section edits
* (bug 13727) Don't delete log entries from recentchanges on page deletion
* (bug 13752) Redirects to sections now work again
* (bug 14764) Fix regression in from Article::lastModified(), failed to work
on non-mySQL schemas.
* (bug 14763) Child classes of Database (DatabasePostgres and DatabaseOracle)
- had stict standards issues with setFakeSlaveLag() and setFakeMaster().
+ had strict standards issues with setFakeSlaveLag() and setFakeMaster().
* (bug 451) Improve the phrase mappings of the Chinese converter arrays.
* (bug 12487) Rights log is not fully internationalized
* (bug 10837) Language variants no longer override other languages than base
* (bug 13128) Added patrolled flag to list=recentchanges
* Implemented {bl,ei,iu}redirect (lists links through redirects as well)
* (bug 13154) Introduced subpages flag to meta=siteinfo&siprop=namespaces
-* (bug 13157) Added ucuserprefix parameter to list=usercontibs
+* (bug 13157) Added ucuserprefix parameter to list=usercontribs
* (bug 12394) Added rctitles parameter to list=recentchanges, making rcid
retrieval easier
* (bug 13218) Fix inclusion of " character in hyperlinks
* (bug 3953) Work around poor display of parenthesis in the in other
languages section of MonoBook skin
* (bug 8539) Enable PLURAL option for another message of recentchanges.
-* (bug 8728) MediaWiki:Badfiletype splitted into 3 messages
+* (bug 8728) MediaWiki:Badfiletype split into 3 messages
* (bug 9131) Allow SpecialContributions to work with Postgres
* (bug 9155) Allow footer info to wrap in Monobook
* (bug 8847) Strip spurious #fragments from request URI to fix redirect
* (bug 6304) Show timestamp for current revision in diff pages
* Vertically align current version with old version header in diff display
* (bug 6174) Remove redundant "emailforlost" message
-* (bug 6189) Show an error to an unprivilleged user trying to create account
+* (bug 6189) Show an error to an unprivileged user trying to create account
* (bug 6365) Show user information in the "old revision" navigation links
* Introduce 'FetchChangesList' hook; see docs/hooks.txt for more information
* (bug 6345) Update to Indonesian localisation (id) #22
* (bug 1956) Hide bot uploads from Special:Newimages
* (bug 3220) Fix escaping of block URLs in Recentchanges
* (bug 3284) Ipblocklist paging, substring search
-* Allow filtering of robot edits in Special:Watchlist by stting
+* Allow filtering of robot edits in Special:Watchlist by setting
$wgFilterRobotsWL = true.
* Fix interlanguage links on special pages when extra namespaces configured
* (bug 3475) anon contrib links on Special:Newpages
* Supplying a reason for a block is no longer mandatory
* Language conversion support for category pages
* $wgStyleSheetDirectory is no longer an alias for $wgStyleDirectory;
-* Special:Movepage can now take paramaters like Special:Movepage/Page_to_move
- (used to just be able to take paramaters via a GET request like index.php?title=Special:Movepage&target=Page_to_move)
+* Special:Movepage can now take parameters like Special:Movepage/Page_to_move
+ (used to just be able to take parameters via a GET request like index.php?title=Special:Movepage&target=Page_to_move)
* (bug 2151) The delete summary now includes editor name, if only one has edited the article.
* (bug 2105) Fixed from argument to the PHP mail() function. A missing space could prevent sending mail with some versions of sendmail.
* (bug 2228) Updated the Slovak translation
* Skip sidebar entries where link text is '-'
* Convert non-UTF-8 URL parameters even if referer is local
* (bug 2460) <img> width & height properly filled when resizing image
-* (bug 2273) deletion log comment used user interface langage
+* (bug 2273) deletion log comment used user interface language
* Try reading revision _text_ from master if no result on slave
* Use content-language message cache for raw view of message pages
* (bug 2530) Not displaying talk pages on Special:Watchlist/edit
== MediaWiki ==
-MediaWiki is a popular and free, open-source wiki software package written in
-PHP. It serves as the platform for Wikipedia and the other projects of the Wikimedia
-Foundation, which deliver content in over 280 languages to more than half a billion
-people each month. MediaWiki's reliability and robust feature set have earned it a
-large and vibrant community of third-party users and developers.
+MediaWiki is a free and open-source wiki software package written in PHP. It
+serves as the platform for Wikipedia and the other projects of the Wikimedia
+Foundation, which deliver content in over 280 languages to more than half a
+billion people each month. MediaWiki's reliability and robust feature set have
+earned it a large and vibrant community of third-party users and developers.
MediaWiki is:
-* feature-rich and extensible, both on-wiki and with over 2,000 extensions;
+* feature-rich and extensible, both on-wiki and with hundreds of extensions;
* scalable and suitable for both small and large sites;
-* available in your language; and
-* simple to install, working on most hardware/software combinations.
+* simple to install, working on most hardware/software combinations; and
+* available in your language.
For system requirements, installation, and upgrade details, see the files
RELEASE-NOTES, INSTALL, and UPGRADE.
* Seeking help from a person?
** https://www.mediawiki.org/wiki/Communication
* Looking to file a bug report or a feature request?
-** https://bugzilla.wikimedia.org/
+** https://bugs.mediawiki.org/
* Interested in helping out?
** https://www.mediawiki.org/wiki/How_to_contribute
* $wgOpenSearchTemplate is deprecated in favor of $wgOpenSearchTemplates.
* Edits are now prepared via AJAX as users type edit summaries. This behavior
can be disabled via $wgAjaxEditStash.
-* (bug 44740) The temporary option $wgIncludejQueryMigrate was removed, along
+* (T46740) The temporary option $wgIncludejQueryMigrate was removed, along
with the jQuery Migrate library, as indicated when this option was provided in
MediaWiki 1.24.
* Page moving was refactored into a MovePage class. As part of that:
** The AbortMove hook was removed.
** MovePageIsValidMove is for extensions to specify whether a page
- cannot be moved for technical reasons, and should not be overriden.
+ cannot be moved for technical reasons, and should not be overridden.
** MovePageCheckPermissions is for checking whether the given user is
allowed to make the move.
** Title::moveNoAuth() was deprecated. Use the MovePage class instead.
** In source text of the form '{$A}'{$B}' or `{$A}`{$B}`, where variable A
does not exist yet variable B does, the latter may not be replaced.
However, this difference is unlikely to arise in practice.
+* (T67278) RFC, PMID, and ISBN "magic links" must be surrounded by non-word
+ characters on both sides.
== Compatibility ==
// Last chance hook before executing the API
wfRunHooks( 'ApiBeforeMain', array( &$processor ) );
if ( !$processor instanceof ApiMain ) {
- throw new MWException( 'ApiBeforMain hook set $processor to a non-ApiMain class' );
+ throw new MWException( 'ApiBeforeMain hook set $processor to a non-ApiMain class' );
}
} catch ( Exception $e ) {
// Crap. Try to report the exception in API format to be friendly to clients.
'ResourceLoaderFileModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderFileModule.php',
'ResourceLoaderFilePageModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderFilePageModule.php',
'ResourceLoaderFilePath' => __DIR__ . '/includes/resourceloader/ResourceLoaderFilePath.php',
+ 'ResourceLoaderImage' => __DIR__ . '/includes/resourceloader/ResourceLoaderImage.php',
+ 'ResourceLoaderImageModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderImageModule.php',
'ResourceLoaderLanguageDataModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderLanguageDataModule.php',
'ResourceLoaderLanguageNamesModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderLanguageNamesModule.php',
'ResourceLoaderModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderModule.php',
'ResourceLoaderSkinModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderSkinModule.php',
'ResourceLoaderStartUpModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderStartUpModule.php',
'ResourceLoaderUserCSSPrefsModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
+ 'ResourceLoaderUserDefaultsModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserDefaultsModule.php',
'ResourceLoaderUserGroupsModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserGroupsModule.php',
'ResourceLoaderUserModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserModule.php',
'ResourceLoaderUserOptionsModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserOptionsModule.php',
],
"license": "GPL-2.0",
"support": {
- "issues": "https://bugzilla.wikimedia.org/",
+ "issues": "https://bugs.mediawiki.org/",
"irc": "irc://irc.freenode.net/mediawiki",
"wiki": "https://www.mediawiki.org/"
},
"php": ">=5.3.3",
"psr/log": "1.0.0",
"cssjanus/cssjanus": "1.1.1",
- "cdb/cdb": "1.0.0"
+ "wikimedia/cdb": "1.0.1",
+ "oojs/oojs-ui": "0.5.0"
},
"require-dev": {
"phpunit/phpunit": "*"
<!-- if a page is deleted and recreated. -->
<id>1</id>
- <!-- Tag wether this article is a redirect and its target -->
+ <!-- Tag whether this article is a redirect and its target -->
<!-- This corresponds to the page_is_redirect in the page table -->
<redirect title="Target" />
# code to actually show the article goes here
if ($wgNotifyArticle) {
- wfNotifyArticleShow($article));
+ wfNotifyArticleShow($article);
}
}
'BeforeParserFetchFileAndTitle': Before an image is rendered by Parser.
$parser: Parser object
$nt: the image title
-&$options: array of options to RepoGroup::findFile
+&$options: array of options to RepoGroup::findFile. If it contains 'broken'
+ as a key then the file will appear as a broken thumbnail.
&$descQuery: query string to add to thumbnail URL
-FIXME: Where does the below sentence fit in?
-If 'broken' is a key in $options then the file will appear as a broken thumbnail.
-
'BeforeParserFetchTemplateAndtitle': Before a template is fetched by Parser.
$parser: Parser object
$title: title of the template
Use the $status object to indicate whether the edit should be allowed, and to provide
a reason for disallowing it. Return false to abort the edit, and true to continue.
Returning true if $status->isOK() returns false means "don't save but continue user
-interaction", e.g. show the edit form.
+interaction", e.g. show the edit form. $status->apiHookResult can be set to an array
+to be returned by api.php action=edit. This is used to deliver captchas.
$context: object implementing the IContextSource interface.
$content: content of the edit box, as a Content object.
$status: Status object to represent errors, etc.
'SkinTemplateOutputPageBeforeExec': Before SkinTemplate::outputPage() starts
page output.
&$sktemplate: SkinTemplate object
-&$tpl: Template engine object
+&$tpl: QuickTemplate engine object
'SkinTemplatePreventOtherActiveTabs': Use this to prevent showing active tabs.
$sktemplate: SkinTemplate object
-MediaWiki has optional support for memcached, a "high-performance,
-distributed memory object caching system". For general information
+MediaWiki has optional support for memcached, a "high-performance,
+distributed memory object caching system". For general information
on it, see: http://www.danga.com/memcached/
Memcached is likely more trouble than a small site will need, but
== Installation ==
Packages are available for Fedora, Debian, Ubuntu and probably other
-Linux distributions. If you there's no package available for your
+Linux distributions. If there's no package available for your
distribution, you can compile it from source.
== Compilation ==
* memcached: http://www.danga.com/memcached/download.bml
(as of this writing, 1.1.9 is current)
-
+
Memcached and libevent are under BSD-style licenses.
The server should run on Linux and other Unix-like systems... you
the internet can put data into and read data from your cache.
An attacker familiar with MediaWiki internals could use this to steal
-passwords and email addresses, or to make themselves a sysop and
-install malicious javascript on the site. There may be other types
-of vulnerability, no audit has been done -- so be safe and keep it
+passwords and email addresses, or to make themselves a sysop and
+install malicious javascript on the site. There may be other types
+of vulnerability, no audit has been done -- so be safe and keep it
behind a firewall.
********************* W A R N I N G ! ! ! ! ! ***********************
stores: instance of class User
set in: User::saveToCache()
cleared by: User::saveSettings(), User::clearSharedCache()
-
+
... more to come ...
RewriteEngine On
RewriteCond %{QUERY_STRING} \.[^\\/:*?\x22<>|%]+(#|\?|$) [nocase]
RewriteRule . - [forbidden]
+ # Fix for bug T64289
+ Options +FollowSymLinks
</IfModule>
}
}
- wfRunHooks( 'GetAutoPromoteGroups', array( $user, &$promote ) );
+ Hooks::run( 'GetAutoPromoteGroups', array( $user, &$promote ) );
return $promote;
}
return in_array( 'bot', User::getGroupPermissions( $user->getGroups() ) );
default:
$result = null;
- wfRunHooks( 'AutopromoteCondition', array( $cond[0],
+ Hooks::run( 'AutopromoteCondition', array( $cond[0],
array_slice( $cond, 1 ), $user, &$result ) );
if ( $result === null ) {
throw new MWException( "Unrecognized condition {$cond[0]} for autopromotion!" );
$this->forcedTargetID = $user; // needed for foreign users
}
if ( $by ) { // local user
- $this->setBlocker( User::newFromID( $by ) );
+ $this->setBlocker( User::newFromId( $by ) );
} else { // foreign user
$this->setBlocker( $byText );
}
protected function initFromRow( $row ) {
$this->setTarget( $row->ipb_address );
if ( $row->ipb_by ) { // local user
- $this->setBlocker( User::newFromID( $row->ipb_by ) );
+ $this->setBlocker( User::newFromId( $row->ipb_by ) );
} else { // foreign user
$this->setBlocker( $row->ipb_by_text );
}
if ( $this->isAutoblocking() && $this->getType() == self::TYPE_USER ) {
wfDebug( "Doing retroactive autoblocks for " . $this->getTarget() . "\n" );
- $continue = wfRunHooks(
+ $continue = Hooks::run(
'PerformRetroactiveAutoblock', array( $this, &$blockIds ) );
if ( $continue ) {
}
# Allow hooks to cancel the autoblock.
- if ( !wfRunHooks( 'AbortAutoblock', array( $autoblockIP, &$this ) ) ) {
+ if ( !Hooks::run( 'AbortAutoblock', array( $autoblockIP, &$this ) ) ) {
wfDebug( "Autoblock aborted by hook.\n" );
return false;
}
/**
* @deprecated since 1.25
*/
-abstract class CdbReader extends \Cdb\Reader {}
+abstract class CdbReader extends \Cdb\Reader {
+}
/**
* @deprecated since 1.25
*/
-abstract class CdbWriter extends \Cdb\Writer {}
+abstract class CdbWriter extends \Cdb\Writer {
+}
/**
* @deprecated since 1.25
*/
-class CdbException extends \Cdb\Exception {}
+class CdbException extends \Cdb\Exception {
+}
$emptyTags[] = $row->vt_tag;
}
- wfRunHooks( 'ListDefinedTags', array( &$emptyTags ) );
+ Hooks::run( 'ListDefinedTags', array( &$emptyTags ) );
$emptyTags = array_filter( array_unique( $emptyTags ) );
# Provide a mechanism for extensions to hook in.
$collationObject = null;
- wfRunHooks( 'Collation::factory', array( $collationName, &$collationObject ) );
+ Hooks::run( 'Collation::factory', array( $collationName, &$collationObject ) );
if ( $collationObject instanceof Collation ) {
return $collationObject;
/**
* A few constants that might be needed during LocalSettings.php.
*
- * Note: these constants must all be resolvable at compile time by HipHop,
- * since this file will not be executed during request startup for a compiled
- * MediaWiki.
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
define( 'MW_SUPPORTS_PARSERFIRSTCALLINIT', 1 );
define( 'MW_SUPPORTS_LOCALISATIONCACHE', 1 );
define( 'MW_SUPPORTS_CONTENTHANDLER', 1 );
+define( 'MW_EDITFILTERMERGED_SUPPORTS_API', 1 );
/**@}*/
/** Support for $wgResourceModules */
*/
const AS_NO_CHANGE_CONTENT_MODEL = 235;
+ /**
+ * Status: user tried to create self-redirect (redirect to the same article) and
+ * wpIgnoreSelfRedirect == false
+ */
+ const AS_SELF_REDIRECT = 236;
+
/**
* Status: can't parse content
*/
/** @var bool */
protected $allowBlankArticle = false;
+ /** @var bool */
+ protected $selfRedirect = false;
+
+ /** @var bool */
+ protected $allowSelfRedirect = false;
+
/** @var string */
public $autoSumm = '';
function edit() {
global $wgOut, $wgRequest, $wgUser;
// Allow extensions to modify/prevent this form or submission
- if ( !wfRunHooks( 'AlternateEdit', array( $this ) ) ) {
+ if ( !Hooks::run( 'AlternateEdit', array( $this ) ) ) {
return;
}
}
if ( !$this->mTitle->getArticleID() ) {
- wfRunHooks( 'EditFormPreloadText', array( &$this->textbox1, &$this->mTitle ) );
+ Hooks::run( 'EditFormPreloadText', array( &$this->textbox1, &$this->mTitle ) );
} else {
- wfRunHooks( 'EditFormInitialText', array( $this ) );
+ Hooks::run( 'EditFormInitialText', array( $this ) );
}
}
throw new PermissionsError( $action, $permErrors );
}
- wfRunHooks( 'EditPage::showReadOnlyForm:initial', array( $this, &$wgOut ) );
+ Hooks::run( 'EditPage::showReadOnlyForm:initial', array( $this, &$wgOut ) );
$wgOut->setRobotPolicy( 'noindex,nofollow' );
$wgOut->setPageTitle( wfMessage(
$this->autoSumm = $request->getText( 'wpAutoSummary' );
$this->allowBlankArticle = $request->getBool( 'wpIgnoreBlankArticle' );
+ $this->allowSelfRedirect = $request->getBool( 'wpIgnoreSelfRedirect' );
} else {
# Not a posted form? Start with nothing.
wfDebug( __METHOD__ . ": Not a posted form.\n" );
$this->section === 'new' ? 'MediaWiki:addsection-editintro' : '' );
// Allow extensions to modify form data
- wfRunHooks( 'EditPage::importFormData', array( $this, $request ) );
+ Hooks::run( 'EditPage::importFormData', array( $this, $request ) );
wfProfileOut( __METHOD__ );
}
case self::AS_MAX_ARTICLE_SIZE_EXCEEDED:
case self::AS_END:
case self::AS_BLANK_ARTICLE:
+ case self::AS_SELF_REDIRECT:
return true;
case self::AS_HOOK_ERROR:
$sectionanchor = $resultDetails['sectionanchor'];
// Give extensions a chance to modify URL query on update
- wfRunHooks(
+ Hooks::run(
'ArticleUpdateBeforeRedirect',
array( $this->mArticle, &$sectionanchor, &$extraQuery )
);
protected function runPostMergeFilters( Content $content, Status $status, User $user ) {
// Run old style post-section-merge edit filter
if ( !ContentHandler::runLegacyHooks( 'EditFilterMerged',
- array( $this, $content, &$this->hookError, $this->summary ) ) ) {
-
+ array( $this, $content, &$this->hookError, $this->summary ) )
+ ) {
# Error messages etc. could be handled within the hook...
$status->fatal( 'hookaborted' );
$status->value = self::AS_HOOK_ERROR;
}
// Run new style post-section-merge edit filter
- if ( !wfRunHooks( 'EditFilterMergedContent',
- array( $this->mArticle->getContext(), $content, $status, $this->summary,
- $user, $this->minoredit ) ) ) {
-
+ if ( !Hooks::run( 'EditFilterMergedContent',
+ array( $this->mArticle->getContext(), $content, $status, $this->summary,
+ $user, $this->minoredit ) )
+ ) {
# Error messages etc. could be handled within the hook...
- // XXX: $status->value may already be something informative...
- $this->hookError = $status->getWikiText();
- $status->fatal( 'hookaborted' );
- $status->value = self::AS_HOOK_ERROR;
+ if ( $status->isGood() ) {
+ $status->fatal( 'hookaborted' );
+ // Not setting $this->hookError here is a hack to allow the hook
+ // to cause a return to the edit page without $this->hookError
+ // being set. This is used by ConfirmEdit to display a captcha
+ // without any error message cruft.
+ } else {
+ $this->hookError = $status->getWikiText();
+ }
+ // Use the existing $status->value if the hook set it
+ if ( !$status->value ) {
+ $status->value = self::AS_HOOK_ERROR;
+ }
return false;
} elseif ( !$status->isOK() ) {
# ...or the hook could be expecting us to produce an error
wfProfileIn( __METHOD__ );
wfProfileIn( __METHOD__ . '-checks' );
- if ( !wfRunHooks( 'EditPage::attemptSave', array( $this ) ) ) {
+ if ( !Hooks::run( 'EditPage::attemptSave', array( $this ) ) ) {
wfDebug( "Hook 'EditPage::attemptSave' aborted article saving\n" );
$status->fatal( 'hookaborted' );
$status->value = self::AS_HOOK_ERROR;
wfProfileOut( __METHOD__ );
return $status;
}
- if ( !wfRunHooks(
+ if ( !Hooks::run(
'EditFilter',
array( $this, $this->textbox1, $this->section, &$this->hookError, $this->summary ) )
) {
$status->value = self::AS_SUCCESS_UPDATE;
}
+ if ( !$this->allowSelfRedirect
+ && $content->isRedirect()
+ && $content->getRedirectTarget()->equals( $this->getTitle() )
+ ) {
+ $this->selfRedirect = true;
+ $status->fatal( 'selfredirect' );
+ $status->value = self::AS_SELF_REDIRECT;
+ wfProfileOut( __METHOD__ );
+ return $status;
+ }
+
// Check for length errors again now that the section is merged in
$this->kblength = (int)( strlen( $this->toEditText( $content ) ) / 1024 );
if ( $this->kblength > $wgMaxArticleSize ) {
* Send the edit form and related headers to $wgOut
* @param callable|null $formCallback That takes an OutputPage parameter; will be called
* during form output near the top, for captchas and the like.
+ *
+ * The $formCallback parameter is deprecated since MediaWiki 1.25. Please
+ * use the EditPage::showEditForm:fields hook instead.
*/
function showEditForm( $formCallback = null ) {
global $wgOut, $wgUser;
$previewOutput = $this->getPreviewText();
}
- wfRunHooks( 'EditPage::showEditForm:initial', array( &$this, &$wgOut ) );
+ Hooks::run( 'EditPage::showEditForm:initial', array( &$this, &$wgOut ) );
$this->setHeaders();
) );
if ( is_callable( $formCallback ) ) {
+ wfWarn( 'The $formCallback parameter to ' . __METHOD__ . 'is deprecated' );
call_user_func_array( $formCallback, array( &$wgOut ) );
}
. Xml::closeElement( 'div' )
);
- wfRunHooks( 'EditPage::showEditForm:fields', array( &$this, &$wgOut ) );
+ Hooks::run( 'EditPage::showEditForm:fields', array( &$this, &$wgOut ) );
// Put these up at the top to ensure they aren't lost on early form submission
$this->showFormBeforeText();
$wgOut->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
}
+ if ( $this->selfRedirect ) {
+ $wgOut->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
+ }
+
if ( $this->hasPresetSummary ) {
// If a summary has been preset using &summary= we don't want to prompt for
// a different summary. Only prompt for a summary if the summary is blanked.
$wgOut->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
}
+ if ( $this->selfRedirect ) {
+ $wgOut->wrapWikiMsg( "<div id='mw-selfredirect'>\n$1\n</div>", 'selfredirect' );
+ }
+
if ( $this->hookError !== '' ) {
$wgOut->addWikiText( $this->hookError );
}
}
# This hook seems slightly odd here, but makes things more
# consistent for extensions.
- wfRunHooks( 'OutputPageBeforeHTML', array( &$wgOut, &$text ) );
+ Hooks::run( 'OutputPageBeforeHTML', array( &$wgOut, &$text ) );
$wgOut->addHTML( $text );
if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
$this->mArticle->closeShowCategory();
if ( $newContent ) {
ContentHandler::runLegacyHooks( 'EditPageGetDiffText', array( $this, &$newContent ) );
- wfRunHooks( 'EditPageGetDiffContent', array( $this, &$newContent ) );
+ Hooks::run( 'EditPageGetDiffContent', array( $this, &$newContent ) );
$popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
$newContent = $newContent->preSaveTransform( $this->mTitle, $wgUser, $popts );
*/
protected function showTosSummary() {
$msg = 'editpage-tos-summary';
- wfRunHooks( 'EditPageTosSummary', array( $this->mTitle, &$msg ) );
+ Hooks::run( 'EditPageTosSummary', array( $this->mTitle, &$msg ) );
if ( !wfMessage( $msg )->isDisabled() ) {
global $wgOut;
$wgOut->addHTML( '<div class="mw-tos-summary">' );
'[[' . wfMessage( 'copyrightpage' )->inContentLanguage()->text() . ']]' );
}
// Allow for site and per-namespace customization of contribution/copyright notice.
- wfRunHooks( 'EditPageCopyrightWarning', array( $title, &$copywarnMsg ) );
+ Hooks::run( 'EditPageCopyrightWarning', array( $title, &$copywarnMsg ) );
return "<div id=\"editpage-copywarn\">\n" .
call_user_func_array( 'wfMessage', $copywarnMsg )->$format() . "\n</div>";
Html::openElement( 'tbody' );
foreach ( $output->getLimitReportData() as $key => $value ) {
- if ( wfRunHooks( 'ParserLimitReportFormat',
+ if ( Hooks::run( 'ParserLimitReportFormat',
array( $key, &$value, &$limitReport, true, true )
) ) {
$keyMsg = wfMessage( $key );
$wgOut->addHTML( " <span class='editHelp'>{$edithelp}</span>\n" );
$wgOut->addHTML( "</div><!-- editButtons -->\n" );
- wfRunHooks( 'EditPage::showStandardInputs:options', array( $this, $wgOut, &$tabindex ) );
+ Hooks::run( 'EditPage::showStandardInputs:options', array( $this, $wgOut, &$tabindex ) );
$wgOut->addHTML( "</div><!-- editOptions -->\n" );
}
protected function showConflict() {
global $wgOut;
- if ( wfRunHooks( 'EditPageBeforeConflictDiff', array( &$this, &$wgOut ) ) ) {
+ if ( Hooks::run( 'EditPageBeforeConflictDiff', array( &$this, &$wgOut ) ) ) {
$wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
$content1 = $this->toEditContent( $this->textbox1 );
$content = $this->toEditContent( $this->textbox1 );
$previewHTML = '';
- if ( !wfRunHooks(
+ if ( !Hooks::run(
'AlternateEditPreview',
array( $this, &$content, &$previewHTML, &$this->mParserOutput ) )
) {
}
$parserOptions = $this->mArticle->makeParserOptions( $this->mArticle->getContext() );
- $parserOptions->setEditSection( false );
$parserOptions->setIsPreview( true );
$parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' );
$hook_args = array( $this, &$content );
ContentHandler::runLegacyHooks( 'EditPageGetPreviewText', $hook_args );
- wfRunHooks( 'EditPageGetPreviewContent', $hook_args );
+ Hooks::run( 'EditPageGetPreviewContent', $hook_args );
$parserOptions->enableLimitReport();
# For CSS/JS pages, we should have called the ShowRawCssJs hook here.
# But it's now deprecated, so never mind
- $content = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions );
- $parserOutput = $content->getParserOutput(
- $this->getArticle()->getTitle(),
- null,
- $parserOptions
+ $pstContent = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions );
+ $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions );
+
+ # Try to stash the edit for the final submission step
+ # @todo: different date format preferences cause cache misses
+ ApiStashEdit::stashEditFromPreview(
+ $this->getArticle(), $content, $pstContent,
+ $parserOutput, $parserOptions, $parserOptions, wfTimestampNow()
);
+ $parserOutput->setEditSectionTokens( false ); // no section edit links
$previewHTML = $parserOutput->getText();
$this->mParserOutput = $parserOutput;
$wgOut->addParserOutputMetadata( $parserOutput );
$toolbar = '<div id="toolbar"></div>';
- wfRunHooks( 'EditPageBeforeEditToolbar', array( &$toolbar ) );
+ Hooks::run( 'EditPageBeforeEditToolbar', array( &$toolbar ) );
return $toolbar;
}
$checkboxes['watch'] = $watchThisHtml;
}
}
- wfRunHooks( 'EditPageBeforeEditChecks', array( &$this, &$checkboxes, &$tabindex ) );
+ Hooks::run( 'EditPageBeforeEditChecks', array( &$this, &$checkboxes, &$tabindex ) );
return $checkboxes;
}
$buttons['diff'] = Html::submitButton( wfMessage( 'showdiff' )->text(),
$attribs );
- wfRunHooks( 'EditPageBeforeEditButtons', array( &$this, &$buttons, &$tabindex ) );
+ Hooks::run( 'EditPageBeforeEditButtons', array( &$this, &$buttons, &$tabindex ) );
return $buttons;
}
$wgOut->prepareErrorPage( wfMessage( 'nosuchsectiontitle' ) );
$res = wfMessage( 'nosuchsectiontext', $this->section )->parseAsBlock();
- wfRunHooks( 'EditPageNoSuchSection', array( &$this, &$res ) );
+ Hooks::run( 'EditPageNoSuchSection', array( &$this, &$res ) );
$wgOut->addHTML( $res );
$wgOut->returnToMain( false, $this->mTitle );
# Default JOIN, to be overridden...
$join['revision'] = array( 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' );
# One, and only one hook should set this, and return false
- if ( wfRunHooks( 'WikiExporter::dumpStableQuery', array( &$tables, &$opts, &$join ) ) ) {
+ if ( Hooks::run( 'WikiExporter::dumpStableQuery', array( &$tables, &$opts, &$join ) ) ) {
wfProfileOut( __METHOD__ );
throw new MWException( __METHOD__ . " given invalid history dump type." );
}
$result = null; // Assuring $result is not undefined, if exception occurs early
try {
- wfRunHooks( 'ModifyExportQuery',
+ Hooks::run( 'ModifyExportQuery',
array( $this->db, &$tables, &$cond, &$opts, &$join ) );
# Do the query!
strval( $row->page_restrictions ) ) . "\n";
}
- wfRunHooks( 'XmlDumpWriterOpenPage', array( $this, &$out, $row, $title ) );
+ Hooks::run( 'XmlDumpWriterOpenPage', array( $this, &$out, $row, $title ) );
return $out;
}
$out .= " <sha1/>\n";
}
- wfRunHooks( 'XmlDumpWriterWriteRevision', array( &$this, &$out, $row, $text ) );
+ Hooks::run( 'XmlDumpWriterWriteRevision', array( &$this, &$out, $row, $text ) );
$out .= " </revision>\n";
}
if ( $status->isOK() ) {
- wfRunHooks( 'FileDeleteComplete', array( &$file, &$oldimage, &$page, &$user, &$reason ) );
+ Hooks::run( 'FileDeleteComplete', array( &$file, &$oldimage, &$page, &$user, &$reason ) );
}
return $status;
if ( self::$viewers === false ) {
self::$viewers = $wgGitRepositoryViewers;
- wfRunHooks( 'GitViewers', array( &self::$viewers ) );
+ Hooks::run( 'GitViewers', array( &self::$viewers ) );
}
return self::$viewers;
* @param string|bool $dest Destination of the message:
* - 'all': both to the log and HTML (debug toolbar or HTML comments)
* - 'log': only to the log and not in HTML
- * - 'private': only to the specifc log if set in $wgDebugLogGroups and
+ * - 'private': only to the specific log if set in $wgDebugLogGroups and
* discarded otherwise
* For backward compatibility, it can also take a boolean:
* - true: same as 'all'
function wfMsgGetKey( $key, $useDB = true, $langCode = false, $transform = true ) {
wfDeprecated( __METHOD__, '1.21' );
- wfRunHooks( 'NormalizeMessageKey', array( &$key, &$useDB, &$langCode, &$transform ) );
+ Hooks::run( 'NormalizeMessageKey', array( &$key, &$useDB, &$langCode, &$transform ) );
$cache = MessageCache::singleton();
$message = $cache->get( $key, $useDB, $langCode );
$frames = array_map( function ( $frame ) use ( $frameFormat ) {
$file = !empty( $frame['file'] ) ? basename( $frame['file'] ) : '-';
- $line = $frame['line'] ?: '-';
+ $line = isset( $frame['line'] ) ? $frame['line'] : '-';
$call = $frame['function'];
if ( !empty( $frame['class'] ) ) {
$call = $frame['class'] . $frame['type'] . $call;
global $wgPhpCli;
// Give site config file a chance to run the script in a wrapper.
// The caller may likely want to call wfBasename() on $script.
- wfRunHooks( 'wfShellWikiCmd', array( &$script, &$parameters, &$options ) );
+ Hooks::run( 'wfShellWikiCmd', array( &$script, &$parameters, &$options ) );
$cmd = isset( $options['php'] ) ? array( $options['php'] ) : array( $wgPhpCli );
if ( isset( $options['wrapper'] ) ) {
$cmd[] = $options['wrapper'];
$_SESSION = $tmp;
}
$newSessionId = session_id();
- wfRunHooks( 'ResetSessionID', array( $oldSessionId, $newSessionId ) );
+ Hooks::run( 'ResetSessionID', array( $oldSessionId, $newSessionId ) );
}
/**
*
* @return DatabaseBase
*/
-function &wfGetDB( $db, $groups = array(), $wiki = false ) {
+function wfGetDB( $db, $groups = array(), $wiki = false ) {
return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
}
*
* @return LBFactory
*/
-function &wfGetLBFactory() {
+function wfGetLBFactory() {
return LBFactory::singleton();
}
* @param string|null $deprecatedVersion Optionally mark hook as deprecated with version number
*
* @return bool True if no handler aborted the hook
+ * @deprecated 1.25
*/
function wfRunHooks( $event, array $args = array(), $deprecatedVersion = null ) {
return Hooks::run( $event, $args, $deprecatedVersion );
# Run the extension hook
$bad = false;
- if ( !wfRunHooks( 'BadImage', array( $name, &$bad ) ) ) {
+ if ( !Hooks::run( 'BadImage', array( $name, &$bad ) ) ) {
wfProfileOut( __METHOD__ );
return $bad;
}
*/
function wfCanIPUseHTTPS( $ip ) {
$canDo = true;
- wfRunHooks( 'CanIPUseHTTPS', array( $ip, &$canDo ) );
+ Hooks::run( 'CanIPUseHTTPS', array( $ip, &$canDo ) );
return !!$canDo;
}
*/
public function finishImportPage( $title, $origTitle, $revCount, $sRevCount, $pageInfo ) {
$args = func_get_args();
- return wfRunHooks( 'AfterImportPage', $args );
+ return Hooks::run( 'AfterImportPage', $args );
}
/**
$tag = $this->reader->name;
$type = $this->reader->nodeType;
- if ( !wfRunHooks( 'ImportHandleToplevelXMLTag', array( $this ) ) ) {
+ if ( !Hooks::run( 'ImportHandleToplevelXMLTag', array( $this ) ) ) {
// Do nothing
} elseif ( $tag == 'mediawiki' && $type == XmlReader::END_ELEMENT ) {
break;
$tag = $this->reader->name;
- if ( !wfRunHooks( 'ImportHandleLogItemXMLTag', array(
+ if ( !Hooks::run( 'ImportHandleLogItemXMLTag', array(
$this, $logInfo
) ) ) {
// Do nothing
if ( $badTitle ) {
// The title is invalid, bail out of this page
$skip = true;
- } elseif ( !wfRunHooks( 'ImportHandlePageXMLTag', array( $this,
+ } elseif ( !Hooks::run( 'ImportHandlePageXMLTag', array( $this,
&$pageInfo ) ) ) {
// Do nothing
} elseif ( in_array( $tag, $normalFields ) ) {
$tag = $this->reader->name;
- if ( !wfRunHooks( 'ImportHandleRevisionXMLTag', array(
+ if ( !Hooks::run( 'ImportHandleRevisionXMLTag', array(
$this, $pageInfo, $revisionInfo
) ) ) {
// Do nothing
$tag = $this->reader->name;
- if ( !wfRunHooks( 'ImportHandleUploadXMLTag', array(
+ if ( !Hooks::run( 'ImportHandleUploadXMLTag', array(
$this, $pageInfo
) ) ) {
// Do nothing
$dummy = new DummyLinker; // dummy linker instance for bc on the hooks
$ret = null;
- if ( !wfRunHooks( 'LinkBegin',
+ if ( !Hooks::run( 'LinkBegin',
array( $dummy, $target, &$html, &$customAttribs, &$query, &$options, &$ret ) )
) {
wfProfileOut( __METHOD__ );
}
$ret = null;
- if ( wfRunHooks( 'LinkEnd', array( $dummy, $target, $options, &$html, &$attribs, &$ret ) ) ) {
+ if ( Hooks::run( 'LinkEnd', array( $dummy, $target, $options, &$html, &$attribs, &$ret ) ) ) {
$ret = Html::rawElement( 'a', $attribs, $html );
}
*/
public static function makeSelfLinkObj( $nt, $html = '', $query = '', $trail = '', $prefix = '' ) {
$ret = "<strong class=\"selflink\">{$prefix}{$html}</strong>{$trail}";
- if ( !wfRunHooks( 'SelfLinkBegin', array( $nt, &$html, &$trail, &$prefix, &$ret ) ) ) {
+ if ( !Hooks::run( 'SelfLinkBegin', array( $nt, &$html, &$trail, &$prefix, &$ret ) ) ) {
return $ret;
}
$alt = self::fnamePart( $url );
}
$img = '';
- $success = wfRunHooks( 'LinkerMakeExternalImage', array( &$url, &$alt, &$img ) );
+ $success = Hooks::run( 'LinkerMakeExternalImage', array( &$url, &$alt, &$img ) );
if ( !$success ) {
wfDebug( "Hook LinkerMakeExternalImage changed the output of external image "
. "with url {$url} and alt text {$alt} to {$img}\n", true );
) {
$res = null;
$dummy = new DummyLinker;
- if ( !wfRunHooks( 'ImageBeforeProduceHTML', array( &$dummy, &$title,
+ if ( !Hooks::run( 'ImageBeforeProduceHTML', array( &$dummy, &$title,
&$file, &$frameParams, &$handlerParams, &$time, &$res ) ) ) {
return $res;
}
'title' => $alt
);
- if ( !wfRunHooks( 'LinkerMakeMediaLinkFile',
+ if ( !Hooks::run( 'LinkerMakeMediaLinkFile',
array( $title, $file, &$html, &$attribs, &$ret ) ) ) {
wfDebug( "Hook LinkerMakeMediaLinkFile changed the output of link "
. "with url {$url} and text {$html} to {$ret}\n", true );
}
$attribs['rel'] = Parser::getExternalLinkRel( $url, $title );
$link = '';
- $success = wfRunHooks( 'LinkerMakeExternalLink',
+ $success = Hooks::run( 'LinkerMakeExternalLink',
array( &$url, &$text, &$link, &$attribs, $linktype ) );
if ( !$success ) {
wfDebug( "Hook LinkerMakeExternalLink changed the output of link "
$items[] = self::emailLink( $userId, $userText );
}
- wfRunHooks( 'UserToolLinksEdit', array( $userId, $userText, &$items ) );
+ Hooks::run( 'UserToolLinksEdit', array( $userId, $userText, &$items ) );
if ( $items ) {
return wfMessage( 'word-separator' )->plain()
$auto = $match[2];
$post = $match[3];
$comment = null;
- wfRunHooks( 'FormatAutocomments', array( &$comment, $pre, $auto, $post, $title, $local ) );
+ Hooks::run( 'FormatAutocomments', array( &$comment, $pre, $auto, $post, $title, $local ) );
if ( $comment === null ) {
$link = '';
if ( $title ) {
) {
global $wgShowRollbackEditCount, $wgMiserMode;
- // To config which pages are effected by miser mode
+ // To config which pages are affected by miser mode
$disableRollbackEditCountSpecialPage = array( 'Recentchanges', 'Watchlist' );
if ( $context === null ) {
/**
* @since 1.20
*/
- wfRunHooks( 'NamespaceIsMovable', array( $index, &$result ) );
+ Hooks::run( 'NamespaceIsMovable', array( $index, &$result ) );
return $result;
}
if ( is_array( $wgExtraNamespaces ) ) {
$namespaces += $wgExtraNamespaces;
}
- wfRunHooks( 'CanonicalNamespaces', array( &$namespaces ) );
+ Hooks::run( 'CanonicalNamespaces', array( &$namespaces ) );
}
return $namespaces;
}
$offsetRel = $relativeTo->offsetForUser( $user );
$ts = '';
- if ( wfRunHooks( 'GetHumanTimestamp', array( &$ts, $this, $relativeTo, $user, $lang ) ) ) {
+ if ( Hooks::run( 'GetHumanTimestamp', array( &$ts, $this, $relativeTo, $user, $lang ) ) ) {
$ts = $lang->getHumanTimestamp( $this, $relativeTo, $user );
}
$ts = '';
$diff = $this->diff( $relativeTo );
- if ( wfRunHooks(
+ if ( Hooks::run(
'GetRelativeTimestamp',
array( &$ts, &$diff, $this, $relativeTo, $user, $lang )
) ) {
static function getVariableIDs() {
if ( !self::$mVariableIDsInitialised ) {
# Get variable IDs
- wfRunHooks( 'MagicWordwgVariableIDs', array( &self::$mVariableIDs ) );
+ Hooks::run( 'MagicWordwgVariableIDs', array( &self::$mVariableIDs ) );
self::$mVariableIDsInitialised = true;
}
return self::$mVariableIDs;
*/
static function getDoubleUnderscoreArray() {
if ( is_null( self::$mDoubleUnderscoreArray ) ) {
- wfRunHooks( 'GetDoubleUnderscoreIDs', array( &self::$mDoubleUnderscoreIDs ) );
+ Hooks::run( 'GetDoubleUnderscoreIDs', array( &self::$mDoubleUnderscoreIDs ) );
self::$mDoubleUnderscoreArray = new MagicWordArray( self::$mDoubleUnderscoreIDs );
}
return self::$mDoubleUnderscoreArray;
}
$unused = null; // To pass it by reference
- wfRunHooks( 'BeforeInitialize', array( &$title, &$unused, &$output, &$user, $request, $this ) );
+ Hooks::run( 'BeforeInitialize', array( &$title, &$unused, &$output, &$user, $request, $this ) );
// Invalid titles. Bug 21776: The interwikis must redirect even if the page name is empty.
if ( is_null( $title ) || ( $title->getDBkey() == '' && !$title->isExternal() )
&& ( $request->getVal( 'title' ) === null
|| $title->getPrefixedDBkey() != $request->getVal( 'title' ) )
&& !count( $request->getValueNames( array( 'action', 'title' ) ) )
- && wfRunHooks( 'TestCanonicalRedirect', array( $request, $title, $output ) )
+ && Hooks::run( 'TestCanonicalRedirect', array( $request, $title, $output ) )
) {
if ( $title->isSpecialPage() ) {
list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
// Give extensions a change to ignore/handle redirects as needed
$ignoreRedirect = $target = false;
- wfRunHooks( 'InitializeArticleMaybeRedirect',
+ Hooks::run( 'InitializeArticleMaybeRedirect',
array( &$title, &$request, &$ignoreRedirect, &$target, &$article ) );
// Follow redirects only for... redirects.
$title = $this->context->getTitle();
$user = $this->context->getUser();
- if ( !wfRunHooks( 'MediaWikiPerformAction',
+ if ( !Hooks::run( 'MediaWikiPerformAction',
array( $output, $page, $title, $user, $request, $this ) )
) {
wfProfileOut( __METHOD__ );
return;
}
- if ( wfRunHooks( 'UnknownAction', array( $request->getVal( 'action', 'view' ), $page ) ) ) {
+ if ( Hooks::run( 'UnknownAction', array( $request->getVal( 'action', 'view' ), $page ) ) ) {
$output->setStatusCode( 404 );
$output->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
}
$redirUrl = preg_replace( '#^http://#', 'https://', $oldUrl );
// ATTENTION: This hook is likely to be removed soon due to overall design of the system.
- if ( wfRunHooks( 'BeforeHttpsRedirect', array( $this->context, &$redirUrl ) ) ) {
+ if ( Hooks::run( 'BeforeHttpsRedirect', array( $this->context, &$redirUrl ) ) ) {
if ( $request->wasPosted() ) {
// This is weird and we'd hope it almost never happens. This
global $IP;
# Allow media handling extensions adding MIME-types and MIME-info
- wfRunHooks( 'MimeMagicInit', array( $this ) );
+ Hooks::run( 'MimeMagicInit', array( $this ) );
$types = MM_WELL_KNOWN_MIME_TYPES;
wfDebug( __METHOD__ . ": can't load mime types from $mimeTypeFile\n" );
}
} else {
- wfDebug( __METHOD__ . ": no mime types file defined, using build-ins only.\n" );
+ wfDebug( __METHOD__ . ": no mime types file defined, using built-ins only.\n" );
}
$types .= "\n" . $this->mExtraTypes;
wfDebug( __METHOD__ . ": can't load mime info from $mimeInfoFile\n" );
}
} else {
- wfDebug( __METHOD__ . ": no mime info file defined, using build-ins only.\n" );
+ wfDebug( __METHOD__ . ": no mime info file defined, using built-ins only.\n" );
}
$info .= "\n" . $this->mExtraInfo;
}
# Media handling extensions can improve the MIME detected
- wfRunHooks( 'MimeMagicImproveFromExtension', array( $this, $ext, &$mime ) );
+ Hooks::run( 'MimeMagicImproveFromExtension', array( $this, $ext, &$mime ) );
if ( isset( $this->mMimeTypeAliases[$mime] ) ) {
$mime = $this->mMimeTypeAliases[$mime];
# people will hopefully nag and submit patches :)
$mime = false;
# Some strings by reference for performance - assuming well-behaved hooks
- wfRunHooks(
+ Hooks::run(
'MimeMagicGuessFromContent',
array( $this, &$head, &$tail, $file, &$mime )
);
}
}
- wfRunHooks( 'MovePageCheckPermissions',
+ Hooks::run( 'MovePageCheckPermissions',
array( $this->oldTitle, $this->newTitle, $user, $reason, $status )
);
}
// Hook for extensions to say a title can't be moved for technical reasons
- wfRunHooks( 'MovePageIsValidMove', array( $this->oldTitle, $this->newTitle, $status ) );
+ Hooks::run( 'MovePageIsValidMove', array( $this->oldTitle, $this->newTitle, $status ) );
return $status;
}
public function move( User $user, $reason, $createRedirect ) {
global $wgCategoryCollation;
- wfRunHooks( 'TitleMove', array( $this->oldTitle, $this->newTitle, $user ) );
+ Hooks::run( 'TitleMove', array( $this->oldTitle, $this->newTitle, $user ) );
// If it is a file, move it first.
// It is done before all other moving stuff is done because it's hard to revert.
$dbw->commit( __METHOD__ );
- wfRunHooks( 'TitleMoveComplete', array( &$this->oldTitle, &$this->newTitle, &$user, $pageid, $redirid, $reason ) );
+ Hooks::run( 'TitleMoveComplete', array( &$this->oldTitle, &$this->newTitle, &$user, $pageid, $redirid, $reason ) );
return Status::newGood();
}
$newpage->updateRevisionOn( $dbw, $nullRevision );
- wfRunHooks( 'NewRevisionFromEditComplete',
+ Hooks::run( 'NewRevisionFromEditComplete',
array( $newpage, $nullRevision, $nullRevision->getParentId(), $user ) );
$newpage->doEditUpdates( $nullRevision, $user,
$redirectRevision->insertOn( $dbw );
$redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
- wfRunHooks( 'NewRevisionFromEditComplete',
+ Hooks::run( 'NewRevisionFromEditComplete',
array( $redirectArticle, $redirectRevision, false, $user ) );
$redirectArticle->doEditUpdates( $redirectRevision, $user, array( 'created' => true ) );
$headers = headers_list();
$foundVary = false;
foreach ( $headers as $header ) {
- if ( substr( $header, 0, 5 ) == 'Vary:' ) {
+ $headerName = strtolower( substr( $header, 0, 5 ) );
+ if ( $headerName == 'vary:' ) {
$foundVary = true;
break;
}
// bug 44570: the core page itself may not change, but resources might
$modifiedTimes['sepoch'] = wfTimestamp( TS_MW, time() - $config->get( 'SquidMaxage' ) );
}
- wfRunHooks( 'OutputPageCheckLastModified', array( &$modifiedTimes ) );
+ Hooks::run( 'OutputPageCheckLastModified', array( &$modifiedTimes ) );
$maxModified = max( $modifiedTimes );
$this->mLastModified = wfTimestamp( TS_RFC2822, $maxModified );
}
/**
- * Add a subtitle containing a backlink to a page
+ * Build message object for a subtitle containing a backlink to a page
*
* @param Title $title Title to link to
* @param array $query Array of additional parameters to include in the link
+ * @return Message
+ * @since 1.25
*/
- public function addBacklinkSubtitle( Title $title, $query = array() ) {
+ public static function buildBacklinkSubtitle( Title $title, $query = array() ) {
if ( $title->isRedirect() ) {
$query['redirect'] = 'no';
}
- $this->addSubtitle( $this->msg( 'backlinksubtitle' )
- ->rawParams( Linker::link( $title, null, array(), $query ) ) );
+ return wfMessage( 'backlinksubtitle' )
+ ->rawParams( Linker::link( $title, null, array(), $query ) );
+ }
+
+ /**
+ * Add a subtitle containing a backlink to a page
+ *
+ * @param Title $title Title to link to
+ * @param array $query Array of additional parameters to include in the link
+ */
+ public function addBacklinkSubtitle( Title $title, $query = array() ) {
+ $this->addSubtitle( self::buildBacklinkSubtitle( $title, $query ) );
}
/**
}
# Add the remaining categories to the skin
- if ( wfRunHooks(
+ if ( Hooks::run(
'OutputPageMakeCategoryLinks',
array( &$this, $categories, &$this->mCategoryLinks ) )
) {
// Link flags are ignored for now, but may in the future be
// used to mark individual language links.
$linkFlags = array();
- wfRunHooks( 'LanguageLinks', array( $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ) );
- wfRunHooks( 'OutputPageParserOutput', array( &$this, $parserOutput ) );
+ Hooks::run( 'LanguageLinks', array( $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ) );
+ Hooks::run( 'OutputPageParserOutput', array( &$this, $parserOutput ) );
}
/**
*/
public function addParserOutputText( $parserOutput ) {
$text = $parserOutput->getText();
- wfRunHooks( 'OutputPageBeforeHTML', array( &$this, &$text ) );
+ Hooks::run( 'OutputPageBeforeHTML', array( &$this, &$text ) );
$this->addHTML( $text );
}
),
$config->get( 'CacheVaryCookies' )
);
- wfRunHooks( 'GetCacheVaryCookies', array( $this, &$cookies ) );
+ Hooks::run( 'GetCacheVaryCookies', array( $this, &$cookies ) );
}
return $cookies;
}
$redirect = $this->mRedirect;
$code = $this->mRedirectCode;
- if ( wfRunHooks( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) {
+ if ( Hooks::run( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) {
if ( $code == '301' || $code == '303' ) {
if ( !$config->get( 'DebugRedirects' ) ) {
$message = HttpStatus::getMessage( $code );
// Hook that allows last minute changes to the output page, e.g.
// adding of CSS or Javascript by extensions.
- wfRunHooks( 'BeforePageDisplay', array( &$this, &$sk ) );
+ Hooks::run( 'BeforePageDisplay', array( &$this, &$sk ) );
wfProfileIn( 'Output-skin' );
$sk->outputPage();
}
// This hook allows last minute changes to final overall output by modifying output buffer
- wfRunHooks( 'AfterFinalPageOutput', array( $this ) );
+ Hooks::run( 'AfterFinalPageOutput', array( $this ) );
$this->sendCacheControl();
// Allow skins and extensions to add body attributes they need
$sk->addToBodyAttributes( $this, $bodyAttrs );
- wfRunHooks( 'OutputPageBodyAttributes', array( $this, $sk, &$bodyAttrs ) );
+ Hooks::run( 'OutputPageBodyAttributes', array( $this, $sk, &$bodyAttrs ) );
$ret .= Html::openElement( 'body', $bodyAttrs ) . "\n";
// Use the 'ResourceLoaderGetConfigVars' hook if the variable is not
// page-dependant but site-wide (without state).
// Alternatively, you may want to use OutputPage->addJsConfigVars() instead.
- wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars, $this ) );
+ Hooks::run( 'MakeGlobalVariablesScript', array( &$vars, $this ) );
// Merge in variables from addJsConfigVars last
return array_merge( $vars, $this->getJsConfigVars() );
self::searchPreferences( $user, $context, $defaultPreferences );
self::miscPreferences( $user, $context, $defaultPreferences );
- wfRunHooks( 'GetPreferences', array( $user, &$defaultPreferences ) );
+ Hooks::run( 'GetPreferences', array( $user, &$defaultPreferences ) );
self::loadPreferenceValues( $user, $context, $defaultPreferences );
self::$defaultPreferences = $defaultPreferences;
$user->setOption( $key, $value );
}
- wfRunHooks( 'PreferencesFormPreSave', array( $formData, $form, $user, &$result ) );
+ Hooks::run( 'PreferencesFormPreSave', array( $formData, $form, $user, &$result ) );
$user->saveSettings();
}
*/
function getLegend( $key ) {
$legend = parent::getLegend( $key );
- wfRunHooks( 'PreferencesGetLegend', array( $this, $key, &$legend ) );
+ Hooks::run( 'PreferencesGetLegend', array( $this, $key, &$legend ) );
return $legend;
}
}
$search = $title->getText();
if ( $ns[0] == NS_MAIN ) {
$ns = $namespaces; // no explicit prefix, use default namespaces
- wfRunHooks( 'PrefixSearchExtractNamespace', array( &$ns, &$search ) );
+ Hooks::run( 'PrefixSearchExtractNamespace', array( &$ns, &$search ) );
}
return $this->searchBackend( $ns, $search, $limit, $offset );
}
$namespaces = array( $title->getNamespace() );
$search = '';
} else {
- wfRunHooks( 'PrefixSearchExtractNamespace', array( &$namespaces, &$search ) );
+ Hooks::run( 'PrefixSearchExtractNamespace', array( &$namespaces, &$search ) );
}
return $this->searchBackend( $namespaces, $search, $limit, $offset );
}
}
$srchres = array();
- if ( wfRunHooks( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres, $offset ) ) ) {
+ if ( Hooks::run( 'PrefixSearchBackend', array( $namespaces, $search, $limit, &$srchres, $offset ) ) ) {
return $this->titles( $this->defaultSearchBackend( $namespaces, $search, $limit, $offset ) );
}
return $this->strings( $this->handleResultFromHook( $srchres, $namespaces, $search, $limit ) );
return $this->pullFront( $key, $srchres );
}
$redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
- if ( isset( $redirectTargetsToRedirect[ $target ] ) ) {
+ if ( isset( $redirectTargetsToRedirect[$target] ) ) {
// The exact match and something in the results list are both redirects
// to the same thing! In this case we'll pull the returned match to the
// top following the same logic above. Again, it might not be a perfect
// choice but it'll do.
- return $this->pullFront( $redirectTargetsToRedirect[ $target ], $srchres );
+ return $this->pullFront( $redirectTargetsToRedirect[$target], $srchres );
}
} else {
$redirectTargetsToRedirect = $this->redirectTargetsToRedirect( $srchres );
- if ( isset( $redirectTargetsToRedirect[ $string ] ) ) {
+ if ( isset( $redirectTargetsToRedirect[$string] ) ) {
// The exact match is the target of a redirect already in the results list so remove
// the redirect from the results list and push the exact match to the front
- array_splice( $srchres, $redirectTargetsToRedirect[ $string ], 1 );
+ array_splice( $srchres, $redirectTargetsToRedirect[$string], 1 );
array_unshift( $srchres, $string );
return $srchres;
}
if ( !$target ) {
continue;
}
- $result[ $target ] = $key;
+ $result[$target] = $key;
}
return $result;
}
* you can also return an array of message name and its parameters
*/
$errorMsg = '';
- if ( !wfRunHooks( 'ProtectionForm::save', array( $this->mArticle, &$errorMsg, $reasonstr ) ) ) {
+ if ( !Hooks::run( 'ProtectionForm::save', array( $this->mArticle, &$errorMsg, $reasonstr ) ) ) {
if ( $errorMsg == '' ) {
$errorMsg = array( 'hookaborted' );
}
"</td></tr>";
}
# Give extensions a chance to add items to the form
- wfRunHooks( 'ProtectionForm::buildForm', array( $this->mArticle, &$out ) );
+ Hooks::run( 'ProtectionForm::buildForm', array( $this->mArticle, &$out ) );
$out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
$out->addHTML( Xml::element( 'h2', null, $protectLogPage->getName()->text() ) );
LogEventsList::showLogExtract( $out, 'protect', $this->mTitle );
# Let extensions add other relevant log extracts
- wfRunHooks( 'ProtectionForm::showLogExtract', array( $this->mArticle, $out ) );
+ Hooks::run( 'ProtectionForm::showLogExtract', array( $this->mArticle, $out ) );
}
}
$this->mId = $rev_id !== null ? $rev_id : $dbw->insertId();
- wfRunHooks( 'RevisionInsertComplete', array( &$this, $data, $flags ) );
+ Hooks::run( 'RevisionInsertComplete', array( &$this, $data, $flags ) );
wfProfileOut( __METHOD__ );
return $this->mId;
*/
public static function validateEmail( $addr ) {
$result = null;
- if ( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) {
+ if ( !Hooks::run( 'isValidEmailAddr', array( $addr, &$result ) ) ) {
return $result;
}
wfProfileOut( $fname . '-memcached' );
// Most of the config is out, some might want to run hooks here.
-wfRunHooks( 'SetupAfterCache' );
+Hooks::run( 'SetupAfterCache' );
wfProfileIn( $fname . '-session' );
if ( !is_object( $wgAuth ) ) {
$wgAuth = new AuthPlugin;
- wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
+ Hooks::run( 'AuthPluginSetup', array( &$wgAuth ) );
}
/**
public function __toString() {
$status = $this->isOK() ? "OK" : "Error";
if ( count( $this->errors ) ) {
- $errorcount = "collected " . ( count($this->errors) ) . " error(s) on the way";
+ $errorcount = "collected " . ( count( $this->errors ) ) . " error(s) on the way";
} else {
$errorcount = "no errors detected";
}
$errorcount,
$valstr
);
- if ( count ($this->errors ) > 0 ) {
+ if ( count( $this->errors ) > 0 ) {
$hdr = sprintf( "+-%'-4s-+-%'-25s-+-%'-40s-+\n", "", "", "" );
$i = 1;
$out .= "\n";
$out .= $hdr;
- foreach( $this->getStatusArray() as $stat ) {
+ foreach ( $this->getStatusArray() as $stat ) {
$out .= sprintf( "| %4d | %-25.25s | %-40.40s |\n",
$i,
$stat[0],
- implode(" ", array_slice( $stat, 1 ) )
+ implode( " ", array_slice( $stat, 1 ) )
);
$i += 1;
}
* @param string $title The DB key form the title
* @param string $fragment The link fragment (after the "#")
* @param string $interwiki The interwiki prefix
- * @param boolean $canoncialNamespace If true, use the canonical name for
+ * @param bool $canoncialNamespace If true, use the canonical name for
* $ns instead of the localized version.
* @return string The prefixed form of the title
*/
* Is this in a namespace that allows actual pages?
*
* @return bool
- * @internal note -- uses hardcoded namespace index instead of constants
*/
public function canExist() {
return $this->mNamespace >= NS_MAIN;
}
$result = true;
- wfRunHooks( 'TitleIsMovable', array( $this, &$result ) );
+ Hooks::run( 'TitleIsMovable', array( $this, &$result ) );
return $result;
}
# It's called here again to make sure hook functions can force this
# method to return true even outside the MediaWiki namespace.
- wfRunHooks( 'TitleIsCssOrJsPage', array( $this, &$isCssOrJsPage ), '1.25' );
+ Hooks::run( 'TitleIsCssOrJsPage', array( $this, &$isCssOrJsPage ), '1.25' );
return $isCssOrJsPage;
}
# Finally, add the fragment.
$url .= $this->getFragmentForURL();
- wfRunHooks( 'GetFullURL', array( &$this, &$url, $query ) );
+ Hooks::run( 'GetFullURL', array( &$this, &$url, $query ) );
return $url;
}
$dbkey = wfUrlencode( $this->getPrefixedDBkey() );
if ( $query == '' ) {
$url = str_replace( '$1', $dbkey, $wgArticlePath );
- wfRunHooks( 'GetLocalURL::Article', array( &$this, &$url ) );
+ Hooks::run( 'GetLocalURL::Article', array( &$this, &$url ) );
} else {
global $wgVariantArticlePath, $wgActionPaths, $wgContLang;
$url = false;
}
}
- wfRunHooks( 'GetLocalURL::Internal', array( &$this, &$url, $query ) );
+ Hooks::run( 'GetLocalURL::Internal', array( &$this, &$url, $query ) );
// @todo FIXME: This causes breakage in various places when we
// actually expected a local URL and end up with dupe prefixes.
$url = $wgServer . $url;
}
}
- wfRunHooks( 'GetLocalURL', array( &$this, &$url, $query ) );
+ Hooks::run( 'GetLocalURL', array( &$this, &$url, $query ) );
return $url;
}
$query = self::fixUrlQueryArgs( $query, $query2 );
$server = $wgInternalServer !== false ? $wgInternalServer : $wgServer;
$url = wfExpandUrl( $server . $this->getLocalURL( $query ), PROTO_HTTP );
- wfRunHooks( 'GetInternalURL', array( &$this, &$url, $query ) );
+ Hooks::run( 'GetInternalURL', array( &$this, &$url, $query ) );
return $url;
}
public function getCanonicalURL( $query = '', $query2 = false ) {
$query = self::fixUrlQueryArgs( $query, $query2 );
$url = wfExpandUrl( $this->getLocalURL( $query ) . $this->getFragmentForURL(), PROTO_CANONICAL );
- wfRunHooks( 'GetCanonicalURL', array( &$this, &$url, $query ) );
+ Hooks::run( 'GetCanonicalURL', array( &$this, &$url, $query ) );
return $url;
}
private function checkQuickPermissions( $action, $user, $errors,
$doExpensiveQueries, $short
) {
- if ( !wfRunHooks( 'TitleQuickPermissions',
+ if ( !Hooks::run( 'TitleQuickPermissions',
array( $this, $user, $action, &$errors, $doExpensiveQueries, $short ) )
) {
return $errors;
private function checkPermissionHooks( $action, $user, $errors, $doExpensiveQueries, $short ) {
// Use getUserPermissionsErrors instead
$result = '';
- if ( !wfRunHooks( 'userCan', array( &$this, &$user, $action, &$result ) ) ) {
+ if ( !Hooks::run( 'userCan', array( &$this, &$user, $action, &$result ) ) ) {
return $result ? array() : array( array( 'badaccess-group0' ) );
}
// Check getUserPermissionsErrors hook
- if ( !wfRunHooks( 'getUserPermissionsErrors', array( &$this, &$user, $action, &$result ) ) ) {
+ if ( !Hooks::run( 'getUserPermissionsErrors', array( &$this, &$user, $action, &$result ) ) ) {
$errors = $this->resultToError( $errors, $result );
}
// Check getUserPermissionsErrorsExpensive hook
if (
$doExpensiveQueries
&& !( $short && count( $errors ) > 0 )
- && !wfRunHooks( 'getUserPermissionsErrorsExpensive', array( &$this, &$user, $action, &$result ) )
+ && !Hooks::run( 'getUserPermissionsErrorsExpensive', array( &$this, &$user, $action, &$result ) )
) {
$errors = $this->resultToError( $errors, $result );
}
if ( !$whitelisted ) {
# If the title is not whitelisted, give extensions a chance to do so...
- wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
+ Hooks::run( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
if ( !$whitelisted ) {
$errors[] = $this->missingPermissionError( $action, $short );
}
$types = array_diff( $types, array( 'upload' ) );
}
- wfRunHooks( 'TitleGetRestrictionTypes', array( $this, &$types ) );
+ Hooks::run( 'TitleGetRestrictionTypes', array( $this, &$types ) );
wfDebug( __METHOD__ . ': applicable restrictions to [[' .
$this->getPrefixedText() . ']] are {' . implode( ',', $types ) . "}\n" );
$urls[] = $this->getInternalUrl( 'action=raw&ctype=text/css' );
}
- wfRunHooks( 'TitleSquidURLs', array( $this, &$urls ) );
+ Hooks::run( 'TitleSquidURLs', array( $this, &$urls ) );
return $urls;
}
*/
public function exists() {
$exists = $this->getArticleID() != 0;
- wfRunHooks( 'TitleExists', array( $this, &$exists ) );
+ Hooks::run( 'TitleExists', array( $this, &$exists ) );
return $exists;
}
* @param Title $title
* @param bool|null $isKnown
*/
- wfRunHooks( 'TitleIsAlwaysKnown', array( $this, &$isKnown ) );
+ Hooks::run( 'TitleIsAlwaysKnown', array( $this, &$isKnown ) );
if ( !is_null( $isKnown ) ) {
return $isKnown;
// on the Title object passed in, and should probably
// tell the users to run updateCollations.php --force
// in order to re-sort existing category relations.
- wfRunHooks( 'GetDefaultSortkey', array( $this, &$unprefixed ) );
+ Hooks::run( 'GetDefaultSortkey', array( $this, &$unprefixed ) );
if ( $prefix !== '' ) {
# Separate with a line feed, so the unprefixed part is only used as
# a tiebreaker when two pages have the exact same prefix.
}
}
- wfRunHooks( 'TitleGetEditNotices', array( $this, $oldid, &$notices ) );
+ Hooks::run( 'TitleGetEditNotices', array( $this, $oldid, &$notices ) );
return $notices;
}
}
*/
static function newFromResult( $res ) {
$array = null;
- if ( !wfRunHooks( 'TitleArrayFromResult', array( &$array, $res ) ) ) {
+ if ( !Hooks::run( 'TitleArrayFromResult', array( &$array, $res ) ) ) {
return null;
}
if ( $array === null ) {
*/
const MAX_WATCHED_ITEMS_CACHE = 100;
+ /**
+ * Exclude user options that are set to their default value.
+ * @since 1.25
+ */
+ const GETOPTIONS_EXCLUDE_DEFAULTS = 1;
+
/**
* @var PasswordFactory Lazily loaded factory object for passwords
*/
// Loading from session failed. Load defaults.
$this->loadDefaults();
}
- wfRunHooks( 'UserLoadAfterLoadFromSession', array( $this ) );
+ Hooks::run( 'UserLoadAfterLoadFromSession', array( $this ) );
break;
default:
wfProfileOut( __METHOD__ );
static $reservedUsernames = false;
if ( !$reservedUsernames ) {
$reservedUsernames = $wgReservedUsernames;
- wfRunHooks( 'UserGetReservedNames', array( &$reservedUsernames ) );
+ Hooks::run( 'UserGetReservedNames', array( &$reservedUsernames ) );
}
// Certain names may be reserved for batch processes.
$result = false; //init $result to false for the internal checks
- if ( !wfRunHooks( 'isValidPassword', array( $password, &$result, $this ) ) ) {
+ if ( !Hooks::run( 'isValidPassword', array( $password, &$result, $this ) ) ) {
$status->error( $result );
return $status;
}
);
}
// Give extensions a chance to force an expiration
- wfRunHooks( 'ResetPasswordExpiration', array( $this, &$newExpire ) );
+ Hooks::run( 'ResetPasswordExpiration', array( $this, &$newExpire ) );
$this->mPasswordExpires = $newExpire;
}
$this->mRegistration = wfTimestamp( TS_MW );
$this->mGroups = array();
- wfRunHooks( 'UserLoadDefaults', array( $this, $name ) );
+ Hooks::run( 'UserLoadDefaults', array( $this, $name ) );
wfProfileOut( __METHOD__ );
}
*/
private function loadFromSession() {
$result = null;
- wfRunHooks( 'UserLoadFromSession', array( $this, &$result ) );
+ Hooks::run( 'UserLoadFromSession', array( $this, &$result ) );
if ( $result !== null ) {
return $result;
}
: array()
);
- wfRunHooks( 'UserLoadFromDatabase', array( $this, &$s ) );
+ Hooks::run( 'UserLoadFromDatabase', array( $this, &$s ) );
if ( $s !== false ) {
// Initialise user table data
}
$defOpt['skin'] = Skin::normalizeKey( $wgDefaultSkin );
- wfRunHooks( 'UserGetDefaultOptions', array( &$defOpt ) );
+ Hooks::run( 'UserGetDefaultOptions', array( &$defOpt ) );
return $defOpt;
}
}
// Extensions
- wfRunHooks( 'GetBlockedStatus', array( &$this ) );
+ Hooks::run( 'GetBlockedStatus', array( &$this ) );
wfProfileOut( __METHOD__ );
}
public function pingLimiter( $action = 'edit', $incrBy = 1 ) {
// Call the 'PingLimiter' hook
$result = false;
- if ( !wfRunHooks( 'PingLimiter', array( &$this, $action, &$result, $incrBy ) ) ) {
+ if ( !Hooks::run( 'PingLimiter', array( &$this, $action, &$result, $incrBy ) ) ) {
return $result;
}
wfDebug( __METHOD__ . ": self-talk page, ignoring any blocks\n" );
}
- wfRunHooks( 'UserIsBlockedFrom', array( $this, $title, &$blocked, &$allowUsertalk ) );
+ Hooks::run( 'UserIsBlockedFrom', array( $this, $title, &$blocked, &$allowUsertalk ) );
wfProfileOut( __METHOD__ );
return $blocked;
$ip = $this->getRequest()->getIP();
}
$blocked = false;
- wfRunHooks( 'UserIsBlockedGlobally', array( &$this, $ip, &$blocked ) );
+ Hooks::run( 'UserIsBlockedGlobally', array( &$this, $ip, &$blocked ) );
$this->mBlockedGlobally = (bool)$blocked;
return $this->mBlockedGlobally;
}
*/
public function getNewMessageLinks() {
$talks = array();
- if ( !wfRunHooks( 'UserRetrieveNewTalks', array( &$this, &$talks ) ) ) {
+ if ( !Hooks::run( 'UserRetrieveNewTalks', array( &$this, &$talks ) ) ) {
return $talks;
} elseif ( !$this->getNewtalk() ) {
return array();
*/
public function getEmail() {
$this->load();
- wfRunHooks( 'UserGetEmail', array( $this, &$this->mEmail ) );
+ Hooks::run( 'UserGetEmail', array( $this, &$this->mEmail ) );
return $this->mEmail;
}
*/
public function getEmailAuthenticationTimestamp() {
$this->load();
- wfRunHooks( 'UserGetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
+ Hooks::run( 'UserGetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
return $this->mEmailAuthenticated;
}
}
$this->invalidateEmail();
$this->mEmail = $str;
- wfRunHooks( 'UserSetEmail', array( $this, &$this->mEmail ) );
+ Hooks::run( 'UserSetEmail', array( $this, &$this->mEmail ) );
}
/**
/**
* Get all user's options
*
+ * @param int $flags Bitwise combination of:
+ * User::GETOPTIONS_EXCLUDE_DEFAULTS Exclude user options that are set
+ * to the default value. (Since 1.25)
* @return array
*/
- public function getOptions() {
+ public function getOptions( $flags = 0 ) {
global $wgHiddenPrefs;
$this->loadOptions();
$options = $this->mOptions;
}
}
+ if ( $flags & self::GETOPTIONS_EXCLUDE_DEFAULTS ) {
+ $options = array_diff_assoc( $options, self::getDefaultOptions() );
+ }
+
return $options;
}
}
}
- wfRunHooks( 'UserResetAllOptions', array( $this, &$newOptions, $this->mOptions, $resetKinds ) );
+ Hooks::run( 'UserResetAllOptions', array( $this, &$newOptions, $this->mOptions, $resetKinds ) );
$this->mOptions = $newOptions;
$this->mOptionsLoaded = true;
return false;
} else {
$https = $this->getBoolOption( 'prefershttps' );
- wfRunHooks( 'UserRequiresHTTPS', array( $this, &$https ) );
+ Hooks::run( 'UserRequiresHTTPS', array( $this, &$https ) );
if ( $https ) {
$https = wfCanIPUseHTTPS( $this->getRequest()->getIP() );
}
public function getRights() {
if ( is_null( $this->mRights ) ) {
$this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() );
- wfRunHooks( 'UserGetRights', array( $this, &$this->mRights ) );
+ Hooks::run( 'UserGetRights', array( $this, &$this->mRights ) );
// Force reindexation of rights when a hook has unset one of them
$this->mRights = array_values( array_unique( $this->mRights ) );
}
$this->getAutomaticGroups( $recache ) // implicit groups
) );
// Hook for additional groups
- wfRunHooks( 'UserEffectiveGroups', array( &$this, &$this->mEffectiveGroups ) );
+ Hooks::run( 'UserEffectiveGroups', array( &$this, &$this->mEffectiveGroups ) );
// Force reindexation of groups when a hook has unset one of them
$this->mEffectiveGroups = array_values( array_unique( $this->mEffectiveGroups ) );
wfProfileOut( __METHOD__ );
* @param string $group Name of the group to add
*/
public function addGroup( $group ) {
- if ( wfRunHooks( 'UserAddGroup', array( $this, &$group ) ) ) {
+ if ( Hooks::run( 'UserAddGroup', array( $this, &$group ) ) ) {
$dbw = wfGetDB( DB_MASTER );
if ( $this->getId() ) {
$dbw->insert( 'user_groups',
*/
public function removeGroup( $group ) {
$this->load();
- if ( wfRunHooks( 'UserRemoveGroup', array( $this, &$group ) ) ) {
+ if ( Hooks::run( 'UserRemoveGroup', array( $this, &$group ) ) ) {
$dbw = wfGetDB( DB_MASTER );
$dbw->delete( 'user_groups',
array(
// If we're working on user's talk page, we should update the talk page message indicator
if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
- if ( !wfRunHooks( 'UserClearNewTalkNotification', array( &$this, $oldid ) ) ) {
+ if ( !Hooks::run( 'UserClearNewTalkNotification', array( &$this, $oldid ) ) ) {
return;
}
$cookies['Token'] = false;
}
- wfRunHooks( 'UserSetCookies', array( $this, &$session, &$cookies ) );
+ Hooks::run( 'UserSetCookies', array( $this, &$session, &$cookies ) );
foreach ( $session as $name => $value ) {
$request->setSessionData( $name, $value );
* Log this user out.
*/
public function logout() {
- if ( wfRunHooks( 'UserLogout', array( &$this ) ) ) {
+ if ( Hooks::run( 'UserLogout', array( &$this ) ) ) {
$this->doLogout();
}
}
$this->saveOptions();
- wfRunHooks( 'UserSaveSettings', array( $this ) );
+ Hooks::run( 'UserSaveSettings', array( $this ) );
$this->clearSharedCache();
$this->getUserPage()->invalidateCache();
}
// and fire the ConfirmEmailComplete hook on redundant confirmations.
if ( !$this->isEmailConfirmed() ) {
$this->setEmailAuthenticationTimestamp( wfTimestampNow() );
- wfRunHooks( 'ConfirmEmailComplete', array( $this ) );
+ Hooks::run( 'ConfirmEmailComplete', array( $this ) );
}
return true;
}
$this->mEmailTokenExpires = null;
$this->setEmailAuthenticationTimestamp( null );
$this->mEmail = '';
- wfRunHooks( 'InvalidateEmailComplete', array( $this ) );
+ Hooks::run( 'InvalidateEmailComplete', array( $this ) );
return true;
}
public function setEmailAuthenticationTimestamp( $timestamp ) {
$this->load();
$this->mEmailAuthenticated = $timestamp;
- wfRunHooks( 'UserSetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
+ Hooks::run( 'UserSetEmailAuthenticationTimestamp', array( $this, &$this->mEmailAuthenticated ) );
}
/**
return false;
}
$canSend = $this->isEmailConfirmed();
- wfRunHooks( 'UserCanSendEmail', array( &$this, &$canSend ) );
+ Hooks::run( 'UserCanSendEmail', array( &$this, &$canSend ) );
return $canSend;
}
global $wgEmailAuthentication;
$this->load();
$confirmed = true;
- if ( wfRunHooks( 'EmailConfirmed', array( &$this, &$confirmed ) ) ) {
+ if ( Hooks::run( 'EmailConfirmed', array( &$this, &$confirmed ) ) ) {
if ( $this->isAnon() ) {
return false;
}
}
// Allow extensions (e.g. OAuth) to say false
- if ( !wfRunHooks( 'UserIsEveryoneAllowed', array( $right ) ) ) {
+ if ( !Hooks::run( 'UserIsEveryoneAllowed', array( $right ) ) ) {
$cache[$right] = false;
return false;
}
} else {
self::$mAllRights = self::$mCoreRights;
}
- wfRunHooks( 'UserGetAllRights', array( &self::$mAllRights ) );
+ Hooks::run( 'UserGetAllRights', array( &self::$mAllRights ) );
}
return self::$mAllRights;
}
$groups = $wgImplicitGroups;
# Deprecated, use $wgImplicitGroups instead
- wfRunHooks( 'UserGetImplicitGroups', array( &$groups ), '1.25' );
+ Hooks::run( 'UserGetImplicitGroups', array( &$groups ), '1.25' );
return $groups;
}
$this->mOptionsLoaded = true;
- wfRunHooks( 'UserLoadOptions', array( $this, &$this->mOptions ) );
+ Hooks::run( 'UserLoadOptions', array( $this, &$this->mOptions ) );
}
/**
// Allow hooks to abort, for instance to save to a global profile.
// Reset options to default state before saving.
- if ( !wfRunHooks( 'UserSaveOptions', array( $this, &$saveOptions ) ) ) {
+ if ( !Hooks::run( 'UserSaveOptions', array( $this, &$saveOptions ) ) ) {
return;
}
*/
static function newFromResult( $res ) {
$userArray = null;
- if ( !wfRunHooks( 'UserArrayFromResult', array( &$userArray, $res ) ) ) {
+ if ( !Hooks::run( 'UserArrayFromResult', array( &$userArray, $res ) ) ) {
return null;
}
if ( $userArray === null ) {
);
}
- wfRunHooks( 'WebRequestPathInfoRouter', array( $router ) );
+ Hooks::run( 'WebRequestPathInfoRouter', array( $router ) );
$matches = $router->parse( $path );
}
}
# Allow extensions to improve our guess
- wfRunHooks( 'GetIP', array( &$ip ) );
+ Hooks::run( 'GetIP', array( &$ip ) );
if ( !$ip ) {
throw new MWException( "Unable to determine IP." );
$func = $options['raw'] ? 'setrawcookie' : 'setcookie';
- if ( wfRunHooks( 'WebResponseSetCookie', array( &$name, &$value, &$expire, $options ) ) ) {
+ if ( Hooks::run( 'WebResponseSetCookie', array( &$name, &$value, &$expire, $options ) ) ) {
wfDebugLog( 'cookie',
$func . ': "' . implode( '", "',
array(
public static function label( $label, $id, $attribs = array() ) {
$a = array( 'for' => $id );
- # FIXME avoid copy pasting below:
- if ( isset( $attribs['class'] ) ) {
- $a['class'] = $attribs['class'];
- }
- if ( isset( $attribs['title'] ) ) {
- $a['title'] = $attribs['title'];
+ foreach ( array( 'class', 'title' ) as $attr ) {
+ if ( isset( $attribs[$attr] ) ) {
+ $a[$attr] = $attribs[$attr];
+ }
}
return self::element( 'label', $a, $label );
$page = $this->page;
$user = $this->getUser();
- if ( wfRunHooks( 'CustomEditor', array( $page, $user ) ) ) {
+ if ( Hooks::run( 'CustomEditor', array( $page, $user ) ) ) {
$editor = new EditPage( $page );
$editor->edit();
}
$this->fields = $this->getFormFields();
// Give hooks a chance to alter the form, adding extra fields or text etc
- wfRunHooks( 'ActionModifyFormFields', array( $this->getName(), &$this->fields, $this->page ) );
+ Hooks::run( 'ActionModifyFormFields', array( $this->getName(), &$this->fields, $this->page ) );
$form = new HTMLForm( $this->fields, $this->getContext(), $this->getName() );
$form->setSubmitCallback( array( $this, 'onSubmit' ) );
$this->alterForm( $form );
// Give hooks a chance to alter the form, adding extra fields or text etc
- wfRunHooks( 'ActionBeforeFormDisplay', array( $this->getName(), &$form, $this->page ) );
+ Hooks::run( 'ActionBeforeFormDisplay', array( $this->getName(), &$form, $this->page ) );
return $form;
}
'</fieldset></form>'
);
- wfRunHooks( 'PageHistoryBeforeList', array( &$this->page, $this->getContext() ) );
+ Hooks::run( 'PageHistoryBeforeList', array( &$this->page, $this->getContext() ) );
// Create and output the list.
$pager = new HistoryPager( $this, $year, $month, $tagFilter, $conds );
$queryInfo['options'],
$this->tagFilter
);
- wfRunHooks( 'PageHistoryPager::getQueryInfo', array( &$this, &$queryInfo ) );
+ Hooks::run( 'PageHistoryPager::getQueryInfo', array( &$this, &$queryInfo ) );
return $queryInfo;
}
}
}
// Allow extension to add their own links here
- wfRunHooks( 'HistoryRevisionTools', array( $rev, &$tools ) );
+ Hooks::run( 'HistoryRevisionTools', array( $rev, &$tools ) );
if ( $tools ) {
$s2 .= ' ' . $this->msg( 'parentheses' )->rawParams( $lang->pipeList( $tools ) )->escaped();
$s .= ' <span class="mw-changeslist-separator">. .</span> ' . $s2;
}
- wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row, &$s, &$classes ) );
+ Hooks::run( 'PageHistoryLineEnding', array( $this, &$row, &$s, &$classes ) );
$attribs = array();
if ( $classes ) {
$pageInfo = $this->pageInfo();
// Allow extensions to add additional information
- wfRunHooks( 'InfoAction', array( $this->getContext(), &$pageInfo ) );
+ Hooks::run( 'InfoAction', array( $this->getContext(), &$pageInfo ) );
// Render page information
foreach ( $pageInfo as $header => $infoTable ) {
// Page protection
$pageInfo['header-restrictions'] = array();
- // Is this page effected by the cascading protection of something which includes it?
+ // Is this page affected by the cascading protection of something which includes it?
if ( $title->isCascadeProtected() ) {
$cascadingFrom = '';
$sources = $title->getCascadeProtectionSources(); // Array deferencing is in PHP 5.4 :(
$response->header( 'HTTP/1.x 404 Not Found' );
}
- if ( !wfRunHooks( 'RawPageViewBeforeOutput', array( &$this, &$text ) ) ) {
+ if ( !Hooks::run( 'RawPageViewBeforeOutput', array( &$this, &$text ) ) ) {
wfDebug( __METHOD__ . ": RawPageViewBeforeOutput hook broke raw page output.\n" );
}
}
protected function getDescription() {
- $this->getOutput()->addBacklinkSubtitle( $this->getTitle() );
-
- return '';
+ return OutputPage::buildBacklinkSubtitle( $this->getTitle() );
}
}
$page = WikiPage::factory( $title );
$status = Status::newFatal( 'hookaborted' );
- if ( wfRunHooks( 'WatchArticle', array( &$user, &$page, &$status ) ) ) {
+ if ( Hooks::run( 'WatchArticle', array( &$user, &$page, &$status ) ) ) {
$status = Status::newGood();
$user->addWatch( $title, $checkRights );
- wfRunHooks( 'WatchArticleComplete', array( &$user, &$page ) );
+ Hooks::run( 'WatchArticleComplete', array( &$user, &$page ) );
}
return $status;
$page = WikiPage::factory( $title );
$status = Status::newFatal( 'hookaborted' );
- if ( wfRunHooks( 'UnwatchArticle', array( &$user, &$page, &$status ) ) ) {
+ if ( Hooks::run( 'UnwatchArticle', array( &$user, &$page, &$status ) ) ) {
$status = Status::newGood();
$user->removeWatch( $title );
- wfRunHooks( 'UnwatchArticleComplete', array( &$user, &$page ) );
+ Hooks::run( 'UnwatchArticleComplete', array( &$user, &$page ) );
}
return $status;
}
/**
- * Indicates whether this module is "internal" or unstable
+ * Indicates whether this module is "internal"
+ * Internal API modules are not (yet) intended for 3rd party use and may be unstable.
* @since 1.25
* @return bool
*/
*/
public function getFinalDescription() {
$desc = $this->getDescription();
- wfRunHooks( 'APIGetDescription', array( &$this, &$desc ) );
+ Hooks::run( 'APIGetDescription', array( &$this, &$desc ) );
$desc = self::escapeWikiText( $desc );
if ( is_array( $desc ) ) {
$desc = join( "\n", $desc );
}
$msgs = array( $msg );
- wfRunHooks( 'APIGetDescriptionMessages', array( $this, &$msgs ) );
+ Hooks::run( 'APIGetDescriptionMessages', array( $this, &$msgs ) );
return $msgs;
}
) + ( isset( $params['token'] ) ? $params['token'] : array() );
}
- wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params, $flags ) );
+ Hooks::run( 'APIGetAllowedParams', array( &$this, &$params, $flags ) );
return $params;
}
*/
public function getFinalParamDescription() {
$desc = $this->getParamDescription();
- wfRunHooks( 'APIGetParamDescription', array( &$this, &$desc ) );
+ Hooks::run( 'APIGetParamDescription', array( &$this, &$desc ) );
if ( !$desc ) {
$desc = array();
}
}
- wfRunHooks( 'APIGetParamDescriptionMessages', array( $this, &$msgs ) );
+ Hooks::run( 'APIGetParamDescriptionMessages', array( $this, &$msgs ) );
return $msgs;
}
$loginForm = new LoginForm();
$loginForm->setContext( $context );
- wfRunHooks( 'AddNewAccountApiForm', array( $this, $loginForm ) );
+ Hooks::run( 'AddNewAccountApiForm', array( $this, $loginForm ) );
$loginForm->load();
$status = $loginForm->addNewaccountInternal();
// Save settings (including confirmation token)
$user->saveSettings();
- wfRunHooks( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
+ Hooks::run( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
if ( $params['mailpassword'] ) {
$logAction = 'byemail';
}
// Give extensions a chance to modify the API result data
- wfRunHooks( 'AddNewAccountApiResult', array( $this, $loginForm, &$result ) );
+ Hooks::run( 'AddNewAccountApiResult', array( $this, $loginForm, &$result ) );
$apiResult->addValue( null, 'createaccount', $result );
}
list( $params['undo'], $params['undoafter'] ) =
array( $params['undoafter'], $params['undo'] );
}
- $undoafterRev = Revision::newFromID( $params['undoafter'] );
+ $undoafterRev = Revision::newFromId( $params['undoafter'] );
}
- $undoRev = Revision::newFromID( $params['undo'] );
+ $undoRev = Revision::newFromId( $params['undo'] );
if ( is_null( $undoRev ) || $undoRev->isDeleted( Revision::DELETED_TEXT ) ) {
$this->dieUsageMsg( array( 'nosuchrevid', $params['undo'] ) );
}
'model' => $contentHandler->getModelID(),
'wpEditToken' => $params['token'],
'wpIgnoreBlankSummary' => '',
- 'wpIgnoreBlankArticle' => true
+ 'wpIgnoreBlankArticle' => true,
+ 'wpIgnoreSelfRedirect' => true,
);
if ( !is_null( $params['summary'] ) ) {
// Run hooks
// Handle APIEditBeforeSave parameters
$r = array();
- if ( !wfRunHooks( 'APIEditBeforeSave', array( $ep, $content, &$r ) ) ) {
+ if ( !Hooks::run( 'APIEditBeforeSave', array( $ep, $content, &$r ) ) ) {
if ( count( $r ) ) {
$r['result'] = 'Failure';
$apiResult->addValue( null, $this->getModuleName(), $r );
switch ( $status->value ) {
case EditPage::AS_HOOK_ERROR:
case EditPage::AS_HOOK_ERROR_EXPECTED:
- $this->dieUsageMsg( 'hookaborted' );
+ if ( isset( $status->apiHookResult ) ) {
+ $r = $status->apiHookResult;
+ $r['result'] = 'Failure';
+ $apiResult->addValue( null, $this->getModuleName(), $r );
+ return;
+ } else {
+ $this->dieUsageMsg( 'hookaborted' );
+ }
case EditPage::AS_PARSE_ERROR:
$this->dieUsage( $status->getMessage(), 'parseerror' );
)
);
- if ( wfRunHooks( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) {
+ if ( Hooks::run( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) {
$out->addHTML(
Html::element( 'pre', array( 'class' => 'api-pretty-content' ), $result )
);
$module->modifyHelp( $help, $options );
- wfRunHooks( 'APIHelpModifyOutput', array( $module, &$help, $options ) );
+ Hooks::run( 'APIHelpModifyOutput', array( $module, &$help, $options ) );
$out .= join( "\n", $help );
}
// @todo FIXME: Split back and frontend from this hook.
// @todo FIXME: This hook should be placed in the backend
$injected_html = '';
- wfRunHooks( 'UserLoginComplete', array( &$user, &$injected_html ) );
+ Hooks::run( 'UserLoginComplete', array( &$user, &$injected_html ) );
$result['result'] = 'Success';
$result['lguserid'] = intval( $user->getId() );
// Give extensions to do something after user logout
$injected_html = '';
- wfRunHooks( 'UserLogoutComplete', array( &$user, &$injected_html, $oldName ) );
+ Hooks::run( 'UserLogoutComplete', array( &$user, &$injected_html, $oldName ) );
}
public function isReadMode() {
if ( $uselang === 'user' ) {
$uselang = $this->getUser()->getOption( 'language' );
$uselang = RequestContext::sanitizeLangCode( $uselang );
- wfRunHooks( 'UserGetLanguageObject', array( $this->getUser(), &$uselang, $this ) );
+ Hooks::run( 'UserGetLanguageObject', array( $this->getUser(), &$uselang, $this ) );
} elseif ( $uselang === 'content' ) {
global $wgContLang;
$uselang = $wgContLang->getCode();
}
// Allow extra cleanup and logging
- wfRunHooks( 'ApiMain::onException', array( $this, $e ) );
+ Hooks::run( 'ApiMain::onException', array( $this, $e ) );
// Log it
if ( !( $e instanceof UsageException ) ) {
// Allow extensions to stop execution for arbitrary reasons.
$message = false;
- if ( !wfRunHooks( 'ApiCheckCanExecute', array( $module, $user, &$message ) ) ) {
+ if ( !Hooks::run( 'ApiCheckCanExecute', array( $module, $user, &$message ) ) ) {
$this->dieUsageMsg( $message );
}
}
// Execute
$module->profileIn();
$module->execute();
- wfRunHooks( 'APIAfterExecute', array( &$module ) );
+ Hooks::run( 'APIAfterExecute', array( &$module ) );
$module->profileOut();
$this->reportUnusedParams();
}
public function getCustomPrinter() {
- switch( $this->getFormat() ) {
+ switch ( $this->getFormat() ) {
case 'json':
return $this->getMain()->createPrinterByName( 'json' . $this->fm );
$this->search( $search, $limit, $namespaces, $resolveRedir, $results );
// Allow hooks to populate extracts and images
- wfRunHooks( 'ApiOpenSearchSuggest', array( &$results ) );
+ Hooks::run( 'ApiOpenSearchSuggest', array( &$results ) );
// Trim extracts, if necessary
$length = $this->getConfig()->get( 'OpenSearchDescriptionLength' );
// Find matching titles as Title objects
$searcher = new TitlePrefixSearch;
$titles = $searcher->searchWithVariants( $search, $limit, $namespaces );
+ if ( !$titles ) {
+ return;
+ }
if ( $resolveRedir ) {
// Query for redirects
if ( !$isDryRun ) {
$generator->executeGenerator( $this );
- wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
+ Hooks::run( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
} else {
// Prevent warnings from being reported on these parameters
$main = $this->getMain();
*
* @param ApiResult|array &$result
* @param array $path
- * @return boolean Whether the data fit
+ * @return bool Whether the data fit
*/
public function populateGeneratorData( &$result, array $path = array() ) {
if ( $result instanceof ApiResult ) {
if ( !$this->mAllowGenerator ) {
unset( $result['generator'] );
} elseif ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
- $result['generator'][ApiBase::PARAM_TYPE] = $this->getGenerators();
- foreach ( $result['generator'][ApiBase::PARAM_TYPE] as $g ) {
+ foreach ( $this->getGenerators() as $g ) {
$result['generator'][ApiBase::PARAM_TYPE][] = $g;
$result['generator'][ApiBase::PARAM_VALUE_LINKS][$g] = "Special:ApiHelp/query+$g";
}
if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) {
if ( !is_null( $oldid ) ) {
// Don't use the parser cache
- $rev = Revision::newFromID( $oldid );
+ $rev = Revision::newFromId( $oldid );
if ( !$rev ) {
$this->dieUsage( "There is no revision ID $oldid", 'missingrev' );
}
// Link flags are ignored for now, but may in the future be
// included in the result.
$linkFlags = array();
- wfRunHooks( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
+ Hooks::run( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
}
} else {
$langlinks = false;
$this->requireOnlyOneParameter( $params, 'rcid', 'revid' );
if ( isset( $params['rcid'] ) ) {
- $rc = RecentChange::newFromID( $params['rcid'] );
+ $rc = RecentChange::newFromId( $params['rcid'] );
if ( !$rc ) {
$this->dieUsageMsg( array( 'nosuchrcid', $params['rcid'] ) );
}
$cacheMode, $module->getCacheMode( $params ) );
$module->profileIn();
$module->execute();
- wfRunHooks( 'APIQueryAfterExecute', array( &$module ) );
+ Hooks::run( 'APIQueryAfterExecute', array( &$module ) );
$module->profileOut();
}
'import' => array( 'ApiQueryInfo', 'getImportToken' ),
'watch' => array( 'ApiQueryInfo', 'getWatchToken' ),
);
- wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
$pageInfo['preload'] = '';
} else {
$text = null;
- wfRunHooks( 'EditFormPreloadText', array( &$text, &$title ) );
+ Hooks::run( 'EditFormPreloadText', array( &$text, &$title ) );
$pageInfo['preload'] = $text;
}
$this->tokenFunctions = array(
'patrol' => array( 'ApiQueryRecentChanges', 'getPatrolToken' )
);
- wfRunHooks( 'APIQueryRecentChangesTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryRecentChangesTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
$this->tokenFunctions = array(
'rollback' => array( 'ApiQueryRevisions', 'getRollbackToken' )
);
- wfRunHooks( 'APIQueryRevisionsTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryRevisionsTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
// DifferenceEngine returns a rather ambiguous empty
// string if that's not the case
if ( $params['diffto'] != 0 ) {
- $difftoRev = Revision::newFromID( $params['diffto'] );
+ $difftoRev = Revision::newFromId( $params['diffto'] );
if ( !$difftoRev ) {
$this->dieUsageMsg( array( 'nosuchrevid', $params['diffto'] ) );
}
$hasInterwikiResults = false;
$totalhits = null;
if ( $interwiki && $resultPageSet === null && $matches->hasInterwikiResults() ) {
- foreach( $matches->getInterwikiResults() as $matches ) {
+ foreach ( $matches->getInterwikiResults() as $matches ) {
$matches = $matches->getInterwikiResults();
$hasInterwikiResults = true;
$data['favicon'] = wfExpandUrl( $favicon, PROTO_RELATIVE );
}
- wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
+ Hooks::run( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
return $this->getResult()->addValue( 'query', $property, $data );
}
$data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
$data['jobs'] = intval( SiteStats::jobs() );
- wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
+ Hooks::run( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
return $this->getResult()->addValue( 'query', $property, $data );
}
'rollback' => 'rollback',
'userrights' => 'userrights',
);
- wfRunHooks( 'ApiQueryTokensRegisterTypes', array( &$salts ) );
+ Hooks::run( 'ApiQueryTokensRegisterTypes', array( &$salts ) );
ksort( $salts );
wfProfileOut( __METHOD__ );
}
$this->tokenFunctions = array(
'userrights' => array( 'ApiQueryUsers', 'getUserrightsToken' ),
);
- wfRunHooks( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
)
),
);
- wfRunHooks( 'ApiRsdServiceApis', array( &$apis ) );
+ Hooks::run( 'ApiRsdServiceApis', array( &$apis ) );
return $apis;
}
$this->dieUsage( "Unsupported content model/format", 'badmodelformat' );
}
- $text = trim( $params['text'] ); // needed so the key SHA1's match
+ // Trim and fix newlines so the key SHA1's match (see RequestContext::getText())
+ $text = rtrim( str_replace( "\r\n", "\n", $params['text'] ) );
$textContent = ContentHandler::makeContent(
$text, $title, $params['contentmodel'], $params['contentformat'] );
$editInfo = false;
$status = 'ratelimited';
} elseif ( $wgMemc->lock( $key, 0, 30 ) ) {
- $contentFormat = $content->getDefaultFormat();
- $editInfo = $page->prepareContentForEdit( $content, null, $user, $contentFormat );
- $wgMemc->unlock( $key );
+ $format = $content->getDefaultFormat();
+ $editInfo = $page->prepareContentForEdit( $content, null, $user, $format, false );
$status = 'error'; // default
+ $unlocker = new ScopedCallback( function() use ( $key ) {
+ global $wgMemc;
+ $wgMemc->unlock( $key );
+ } );
} else {
$editInfo = false;
$status = 'busy';
}
if ( $editInfo && $editInfo->output ) {
- $parserOutput = $editInfo->output;
- // If an item is renewed, mind the cache TTL determined by config and parser functions
- $since = time() - wfTimestamp( TS_UNIX, $parserOutput->getTimestamp() );
- $ttl = min( $parserOutput->getCacheExpiry() - $since, 5 * 60 );
- if ( $ttl > 0 && !$parserOutput->getFlag( 'vary-revision' ) ) {
- // Only store what is actually needed
- $stashInfo = (object)array(
- 'pstContent' => $editInfo->pstContent,
- 'output' => $editInfo->output,
- 'timestamp' => $editInfo->timestamp
- );
+ list( $stashInfo, $ttl ) = self::buildStashValue(
+ $editInfo->pstContent, $editInfo->output, $editInfo->timestamp
+ );
+ if ( $stashInfo ) {
$ok = $wgMemc->set( $key, $stashInfo, $ttl );
if ( $ok ) {
$status = 'stashed';
}
/**
- * Get the temporary prepared edit stash key for a user
+ * Attempt to cache PST content and corresponding parser output in passing
*
- * @param Title $title
- * @param Content $content
- * @param User $user User to get parser options from
- * @return string
+ * This method can be called when the output was already generated for other
+ * reasons. Parsing should not be done just to call this method, however.
+ * $pstOpts must be that of the user doing the edit preview. If $pOpts does
+ * not match the options of WikiPage::makeParserOptions( 'canonical' ), this
+ * will do nothing. Provided the values are cacheable, they will be stored
+ * in memcached so that final edit submission might make use of them.
+ *
+ * @param Article|WikiPage $page Page title
+ * @param Content $content Proposed page content
+ * @param Content $pstContent The result of preSaveTransform() on $content
+ * @param ParserOutput $pOut The result of getParserOutput() on $pstContent
+ * @param ParserOptions $pstOpts Options for $pstContent (MUST be for prospective author)
+ * @param ParserOptions $pOpts Options for $pOut
+ * @param string $timestamp TS_MW timestamp of parser output generation
+ * @return bool Success
*/
- protected static function getStashKey(
- Title $title, Content $content, User $user
+ public static function stashEditFromPreview(
+ Page $page, Content $content, Content $pstContent, ParserOutput $pOut,
+ ParserOptions $pstOpts, ParserOptions $pOpts, $timestamp
) {
- return wfMemcKey( 'prepared-edit',
- md5( $title->getPrefixedDBkey() ), // handle rename races
- $content->getModel(),
- $content->getDefaultFormat(),
- sha1( $content->serialize( $content->getDefaultFormat() ) ),
- $user->getId() ?: md5( $user->getName() ), // account for user parser options
- $user->getId() ? $user->getTouched() : '-' // handle preference change races
- );
+ global $wgMemc;
+
+ // getIsPreview() controls parser function behavior that references things
+ // like user/revision that don't exists yet. The user/text should already
+ // be set correctly by callers, just double check the preview flag.
+ if ( !$pOpts->getIsPreview() ) {
+ return false; // sanity
+ } elseif ( $pOpts->getIsSectionPreview() ) {
+ return false; // short-circuit (need the full content)
+ }
+
+ // PST parser options are for the user (handles signatures, etc...)
+ $user = $pstOpts->getUser();
+ // Get a key based on the source text, format, and user preferences
+ $key = self::getStashKey( $page->getTitle(), $content, $user );
+
+ // Parser output options must match cannonical options.
+ // Treat some options as matching that are different but don't matter.
+ $canonicalPOpts = $page->makeParserOptions( 'canonical' );
+ $canonicalPOpts->setIsPreview( true ); // force match
+ $canonicalPOpts->setTimestamp( $pOpts->getTimestamp() ); // force match
+ if ( !$pOpts->matches( $canonicalPOpts ) ) {
+ wfDebugLog( 'StashEdit', "Uncacheable preview output for key '$key' (options)." );
+ return false;
+ }
+
+ // Build a value to cache with a proper TTL
+ list( $stashInfo, $ttl ) = self::buildStashValue( $pstContent, $pOut, $timestamp );
+ if ( !$stashInfo ) {
+ wfDebugLog( 'StashEdit', "Uncacheable parser output for key '$key' (rev/TTL)." );
+ return false;
+ }
+
+ $ok = $wgMemc->set( $key, $stashInfo, $ttl );
+ if ( !$ok ) {
+ wfDebugLog( 'StashEdit', "Failed to cache preview parser output for key '$key'." );
+ } else {
+ wfDebugLog( 'StashEdit', "Cached preview output for key '$key'." );
+ }
+
+ return $ok;
}
/**
if ( $wgMemc->lock( $key, 30, 30 ) ) {
$editInfo = $wgMemc->get( $key );
$wgMemc->unlock( $key );
- $sec = microtime( true ) - $start;
- wfDebugLog( 'StashEdit', "Waited $sec seconds on '$key'." );
}
+ $sec = microtime( true ) - $start;
+ wfDebugLog( 'StashEdit', "Waited $sec seconds on '$key'." );
}
if ( !is_object( $editInfo ) || !$editInfo->output ) {
+ wfDebugLog( 'StashEdit', "No cache value for key '$key'." );
return false;
}
return $editInfo;
}
+ /**
+ * Get the temporary prepared edit stash key for a user
+ *
+ * This key can be used for caching prepared edits provided:
+ * - a) The $user was used for PST options
+ * - b) The parser output was made from the PST using cannonical matching options
+ *
+ * @param Title $title
+ * @param Content $content
+ * @param User $user User to get parser options from
+ * @return string
+ */
+ protected static function getStashKey( Title $title, Content $content, User $user ) {
+ $hash = sha1( implode( ':', array(
+ $content->getModel(),
+ $content->getDefaultFormat(),
+ sha1( $content->serialize( $content->getDefaultFormat() ) ),
+ $user->getId() ?: md5( $user->getName() ), // account for user parser options
+ $user->getId() ? $user->getTouched() : '-' // handle preference change races
+ ) ) );
+
+ return wfMemcKey( 'prepared-edit', md5( $title->getPrefixedDBkey() ), $hash );
+ }
+
+ /**
+ * Build a value to store in memcached based on the PST content and parser output
+ *
+ * This makes a simple version of WikiPage::prepareContentForEdit() as stash info
+ *
+ * @param Content $pstContent
+ * @param ParserOutput $parserOutput
+ * @param string $timestamp TS_MW
+ * @return array (stash info array, TTL in seconds) or (null, 0)
+ */
+ protected static function buildStashValue(
+ Content $pstContent, ParserOutput $parserOutput, $timestamp
+ ) {
+ // If an item is renewed, mind the cache TTL determined by config and parser functions
+ $since = time() - wfTimestamp( TS_UNIX, $parserOutput->getTimestamp() );
+ $ttl = min( $parserOutput->getCacheExpiry() - $since, 5 * 60 );
+ if ( $ttl > 0 && !$parserOutput->getFlag( 'vary-revision' ) ) {
+ // Only store what is actually needed
+ $stashInfo = (object)array(
+ 'pstContent' => $pstContent,
+ 'output' => $parserOutput,
+ 'timestamp' => $timestamp
+ );
+ return array( $stashInfo, $ttl );
+ }
+
+ return array( null, 0 );
+ }
+
public function getAllowedParams() {
return array(
'title' => array(
foreach ( $names as $name ) {
$types[$name] = array( 'ApiQueryInfo', 'get' . ucfirst( $name ) . 'Token' );
}
- wfRunHooks( 'ApiTokensGetTokenTypes', array( &$types ) );
+ Hooks::run( 'ApiTokensGetTokenTypes', array( &$types ) );
ksort( $types );
wfProfileOut( __METHOD__ );
}
if ( $retval[1] ) {
- wfRunHooks( 'FileUndeleteComplete',
+ Hooks::run( 'FileUndeleteComplete',
array( $titleObj, $params['fileids'], $this->getUser(), $params['reason'] ) );
}
{
"@metadata": {
"authors": [
- "Meno25"
+ "Meno25",
+ "أحمد المحمودي"
]
},
"apihelp-main-param-format": "صيغة الخرج.",
"apihelp-createaccount-param-name": "اسم المستخدم.",
"apihelp-delete-description": "حذف صفحة.",
"apihelp-delete-param-unwatch": "أزل الصفحة من قائمة مراقبتك.",
- "apihelp-edit-description": "إنشاء وتعديل الصفحات."
+ "apihelp-edit-description": "إنشاء وتعديل الصفحات.",
+ "apihelp-query+prefixsearch-param-offset": "عدد النتائج المراد تخطيها."
}
"apihelp-block-param-user": "Імя ўдзельніка, IP-адрас або IP-дыяпазон, якія вы хочаце заблякаваць.",
"apihelp-block-param-expiry": "Час заканчэньня. Можа быць адносным (напрыклад, «5 months» або «2 weeks») ці аблсалютным (напрыклад, «2014-09-18T12:34:56Z»). Калі выстаўлены на «infinite», «indefinite» ці «never», блякаваньне будзе бестэрміновым.",
"apihelp-block-param-reason": "Прычына блякаваньня.",
- "apihelp-block-param-anononly": "Заблякаваць толькі ананімных удзельнікаў (напрыклад, забараніць ананімныя праўкі з гэтага IP-адрасу)."
+ "apihelp-block-param-anononly": "Заблякаваць толькі ананімных удзельнікаў (напрыклад, забараніць ананімныя праўкі з гэтага IP-адрасу).",
+ "apihelp-block-param-nocreate": "Забарона стварэньня рахункаў.",
+ "apihelp-block-param-autoblock": "Аўтаматычна блякаваць апошні ўжыты IP-адрас, а таксама ўсе наступныя IP-адрасы, зь якіх будуць спробы ўваходу.",
+ "apihelp-block-param-noemail": "Забараняе ўдзельніку дасылаць лісты электроннай пошты празь вікі (трэба мець права «blockemail»).",
+ "apihelp-block-param-hidename": "Схаваць імя ўдзельніка з журналу блякаваньняў (патрабуе права «hideuser»).",
+ "apihelp-block-param-allowusertalk": "Дазволіць удзельніку рэдагаваць уласную старонку гутарак (залежыць ад $wgBlockAllowsUTEdit).",
+ "apihelp-block-param-reblock": "Калі ўдзельнік ужо заблякаваны, перапісаць дзейнае блякаваньне."
}
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Palapa"
+ ]
+ },
+ "apihelp-block-description": "Blokiraj korisnika",
+ "apihelp-block-param-reason": "Razlog za blokadu",
+ "apihelp-delete-description": "Obriši stranicu.",
+ "apihelp-edit-param-minor": "Mala izmjena."
+}
"apihelp-query+usercontribs-param-userprefix": "Retrieve contributions for all users whose names begin with this value. Overrides $1user.",
"apihelp-query+usercontribs-param-namespace": "Only list contributions in these namespaces.",
"apihelp-query+usercontribs-param-prop": "Include additional pieces of information:\n;ids:Adds the page ID and revision ID.\n;title:Adds the title and namespace ID of the page.\n;timestamp:Adds the timestamp of the edit.\n;comment:Adds the comment of the edit.\n;parsedcomment:Adds the parsed comment of the edit.\n;size:Adds the new size of the edit.\n;sizediff:Adds the size delta of the edit against its parent.\n;flags:Adds flags of the edit.\n;patrolled:Tags patrolled edits.\n;tags:Lists tags for the edit.",
- "apihelp-query+usercontribs-param-show": "Show only items that meet thse criteria, e.g. non minor edits only: $2show=!minor.\n\nIf $2show=patrolled or $2show=!patrolled is set, revisions older than [https://www.mediawiki.org/wiki/Manual:$wgRCMaxAge $wgRCMaxAge] ($1 {{PLURAL:$1|second|seconds}}) won't be shown.",
+ "apihelp-query+usercontribs-param-show": "Show only items that meet these criteria, e.g. non minor edits only: $2show=!minor.\n\nIf $2show=patrolled or $2show=!patrolled is set, revisions older than [https://www.mediawiki.org/wiki/Manual:$wgRCMaxAge $wgRCMaxAge] ($1 {{PLURAL:$1|second|seconds}}) won't be shown.",
"apihelp-query+usercontribs-param-tag": "Only list revisions tagged with this tag.",
"apihelp-query+usercontribs-param-toponly": "Only list changes which are the latest revision.",
"apihelp-query+usercontribs-example-user": "Show contributions of [[User:Example]]",
"apihelp-main-param-format": "El formato de la salida.",
"apihelp-main-param-curtimestamp": "Incluir la marca de tiempo actual en el resultado.",
"apihelp-block-description": "Bloquear usuario",
+ "apihelp-block-param-user": "El nombre de usuario, dirección IP o intervalo de IP que quieres bloquear.",
"apihelp-block-param-reason": "Razón para el bloqueo.",
+ "apihelp-block-param-anononly": "Bloquear solo usuarios anónimos (es decir, desactivar ediciones anónimas de esta IP).",
"apihelp-block-param-nocreate": "Prevenir la creación de cuentas.",
"apihelp-compare-param-fromtitle": "Primer título para comparar",
"apihelp-createaccount-description": "Crear una nueva cuenta de usuario.",
"apihelp-edit-param-minor": "Edición menor.",
"apihelp-edit-param-notminor": "Edición no menor.",
"apihelp-edit-param-bot": "Marcar esta edición como de bot.",
+ "apihelp-edit-param-createonly": "No editar la página si ya existe.",
+ "apihelp-edit-param-watch": "Añadir la página a tu lista de seguimiento.",
+ "apihelp-edit-param-unwatch": "Quitar la página de tu lista de seguimiento.",
"apihelp-edit-example-edit": "Editar una página",
+ "apihelp-emailuser-description": "Enviar un mensaje de correo electrónico a un usuario.",
"apihelp-expandtemplates-param-title": "Título de la página.",
"apihelp-expandtemplates-param-text": "Sintaxis wiki que se convertirá.",
"apihelp-feedcontributions-description": "Devuelve el canal de contribuciones de un usuario.",
"apihelp-feedcontributions-param-feedformat": "El formato del canal.",
+ "apihelp-feedcontributions-param-year": "A partir del año (y anteriores).",
+ "apihelp-feedcontributions-param-month": "A partir del mes (y anteriores).",
+ "apihelp-feedcontributions-param-deletedonly": "Mostrar solo las contribuciones borradas.",
"apihelp-feedrecentchanges-param-hideminor": "Ocultar cambios menores.",
+ "apihelp-import-param-summary": "Resumen de importación.",
"apihelp-login-param-name": "Nombre de usuario.",
"apihelp-login-param-password": "Contraseña.",
"apihelp-login-param-domain": "Dominio (opcional).",
"apihelp-move-description": "Mover una página.",
"apihelp-opensearch-param-search": "Buscar cadena.",
+ "apihelp-options-example-reset": "Restablecer todas las preferencias",
"apihelp-patrol-example-rcid": "Patrullar un cambio reciente",
"apihelp-patrol-example-revid": "Patrullar una revisión",
"apihelp-protect-example-protect": "Proteger una página",
"apihelp-opensearch-param-format": "فرمت خروجی.",
"apihelp-opensearch-example-te": "یافتن صفحههایی که با «ته» آغاز میشوند",
"apihelp-options-example-reset": "بازنشانی همه تنظیمات.",
+ "apihelp-paraminfo-param-helpformat": "ساختار راهنمای رشتهها",
"apihelp-parse-example-page": "تجزیه یک صفحه.",
"apihelp-parse-example-text": "تجزیه متن ویکی.",
"apihelp-parse-example-summary": "تجزیه خلاصه.",
"apihelp-query+allpages-param-filterredir": "صفحههایی که باید فهرست شوند.",
"apihelp-query+allpages-param-minsize": "محدودکردن به صفحههایی که همراه دست کم این تعداد بایت است.",
"apihelp-query+allredirects-param-limit": "تعداد آیتمها برای بازگرداندن.",
+ "apihelp-query+blocks-example-simple": "فهرست بستهشدهها",
"apihelp-query+categorymembers-description": "فهرستکردن همهٔ صفحهها در یک ردهٔ مشخصشده.",
+ "apihelp-query+categorymembers-param-sort": "خصوصیت برای مرتبسازی",
+ "apihelp-query+categorymembers-param-dir": "جهت مرتب شدن",
"apihelp-query+categorymembers-param-startsortkey": "جایش از $1starthexsortkey استفاده کنید.",
"apihelp-query+imageinfo-param-urlheight": "مشابه $1urlwidth.",
"apihelp-query+info-description": "دریافت اطلاعات سادهٔ صفحه.",
"apihelp-query+iwbacklinks-param-limit": "تعداد صفحهها برای بازگرداندن.",
"apihelp-query+linkshere-param-limit": "تعداد برای بازگرداندن.",
"apihelp-query+logevents-description": "دریافت رویدادها از سیاههها.",
+ "apihelp-query+prefixsearch-param-search": "جستجوی رشته",
+ "apihelp-query+prefixsearch-param-namespace": "فضاهای نامی برای جستجو",
+ "apihelp-query+prefixsearch-param-limit": "حداکثر تعداد نتایج برای بازگرداندن.",
+ "apihelp-query+prefixsearch-param-offset": "تعداد نتایج برای رها کردن.",
"apihelp-query+protectedtitles-param-namespace": "فقط عنوانها در این فضاهای نام را فهرست کنید.",
"apihelp-query+protectedtitles-param-level": "فقط عنوانها در این سطحهای حفاظت را فهرست کنید.",
"apihelp-query+protectedtitles-param-limit": "تعداد صفحهها برای بازگرداندن.",
"apihelp-rollback-example-summary": "Annuler les dernières modifications sur [[Main Page]] par l’utilisateur à l’adresse IP 192.0.2.5 avec le résumé « Annulation de vandalisme », et marquer ces modifications et l’annulation comme « robot »",
"apihelp-rsd-description": "Exporter un schéma RSD (Découverte Très Simple).",
"apihelp-rsd-example-simple": "Exporter le schéma RSD",
+ "apihelp-setnotificationtimestamp-description": "Mettre à jour l’horodatage de notification pour les pages suivies.\n\nCela affecte la mise en évidence des pages modifiées dans la liste de suivi et l’historique, et l’envoi de courriel quand la préférence « M’envoyer un courriel quand une page de ma liste de suivi est modifiée » est activée.",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "Travailler sur toutes les pages suivies.",
+ "apihelp-setnotificationtimestamp-param-timestamp": "Horodatage auquel dater la notification.",
+ "apihelp-setnotificationtimestamp-param-torevid": "Révision pour laquelle fixer l’horodatage de notification (une page uniquement).",
+ "apihelp-setnotificationtimestamp-param-newerthanrevid": "Révision pour fixer l’horodatage de notification plus récent (une page uniquement).",
+ "apihelp-setnotificationtimestamp-example-all": "Réinitialiser l’état de notification pour toute la liste de suivi",
+ "apihelp-setnotificationtimestamp-example-page": "Réinitialiser l’état de notification pour la « Page principale »",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "Fixer l’horodatage de notification pour « Page principale » afin que toutes les modifications depuis le 1 janvier 2012 soient non vues",
+ "apihelp-setnotificationtimestamp-example-allpages": "Réinitialiser l’état de notification sur les pages dans l’espace de noms Utilisateur",
+ "apihelp-tokens-description": "Obtenir les jetons pour les actions modifiant les données.\n\nCe module est obsolète, remplacé par [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "apihelp-tokens-param-type": "Types de jeton à demander.",
+ "apihelp-tokens-example-edit": "Récupérer un jeton de modification (par défaut).",
+ "apihelp-tokens-example-emailmove": "Récupérer un jeton de courriel et un jeton de déplacement.",
+ "apihelp-unblock-description": "Débloquer un utilisateur.",
+ "apihelp-unblock-param-id": "ID du blocage à lever (obtenu via list=blocks). Impossible à utiliser avec $1user.",
+ "apihelp-unblock-param-user": "Nom d’utilisateur, adresse IP ou plage d’adresse IP à débloquer. Impossible à utiliser avec $1id.",
+ "apihelp-unblock-param-reason": "Motif de déblocage.",
+ "apihelp-unblock-example-id": "Lever le blocage d’ID #105",
+ "apihelp-unblock-example-user": "Débloquer l’utilisateur Bob avec le motif « Désolé Bob »",
+ "apihelp-undelete-description": "Restaurer les révisions d’une page supprimée.\n\nUne liste des révisions supprimées (avec les horodatages) peut être récupérée via [[Special:ApiHelp/query+deletedrevs|list=deletedrevs]], et une liste d’IDs de fichier supprimé peut être récupérée via [[Special:ApiHelp/query+filearchive|list=filearchive]].",
+ "apihelp-undelete-param-title": "Titre de la page à restaurer.",
+ "apihelp-undelete-param-reason": "Motif de restauration.",
+ "apihelp-undelete-param-timestamps": "Horodatages des révisions à restaurer. Si $1timestamps et $1fileids sont vides, toutes seront restaurées.",
+ "apihelp-undelete-param-fileids": "IDs des révisions de fichier à restaurer. Si $1timestamps et $1fileids sont vides, toutes seront restaurées.",
+ "apihelp-undelete-param-watchlist": "Ajouter ou supprimer la page de votre liste de suivi sans condition, utiliser les préférences ou ne pas modifier le suivi.",
+ "apihelp-undelete-example-page": "Annuler la suppression de [[Main Page]]",
+ "apihelp-undelete-example-revisions": "Annuler la suppression de deux révisions de [[Main Page]]",
+ "apihelp-upload-description": "Télécharger un fichier, ou obtenir l’état des téléchargements en cours.\n\nPlusieurs méthodes sont disponibles :\n* Télécharger directement le contenu du fichier, en utilisant le paramètre « $1file ».\n* Télécharger le fichier par morceaux, en utilsiant les paramètres « $1filesize », « $1chunk » et « $1offset ».* Pour que le serveur MédiaWiki cherche un fichier depuis une URL, utiliser le paramètre « $1url ».\n* Terminer un téléchargement précédent qui a échoué à cause d’avertissements, en utilisant le paramètre « $1filekey ».\nNoter que le POST HTTP doit être fait comme un téléchargement de fichier (par ex. en utilisant multipart/form-data) en envoyant le « $1file ».",
+ "apihelp-upload-param-filename": "Nom de fichier cible.",
+ "apihelp-upload-param-comment": "Télécharger le commentaire. Utilisé aussi comme texte de la page initiale pour les nouveaux fichiers si « $1text » n’est pas spécifié.",
+ "apihelp-upload-param-text": "Texte de page initiale pour les nouveaux fichiers.",
+ "apihelp-upload-param-watch": "Suivre la page.",
+ "apihelp-upload-param-watchlist": "Ajouter ou supprimer sans condition la page de votre liste de suivi, utiliser les préférences ou ne pas changer le suivi.",
+ "apihelp-upload-param-ignorewarnings": "Ignorer tous les avertissements.",
+ "apihelp-upload-param-file": "Contenu du fichier.",
+ "apihelp-upload-param-url": "URL où chercher le fichier.",
+ "apihelp-upload-param-filekey": "Clé identifiant un téléchargement précédent temporairement mis en attente.",
+ "apihelp-upload-param-sessionkey": "Comme $1filekey, conservé pour des raisons de compatibilité descendante.",
+ "apihelp-upload-param-stash": "Si positionné, le serveur conservera temporairement le fichier au lieu de l’ajouter au dépôt.",
+ "apihelp-upload-param-filesize": "Taille du fichier de tout le téléchargement.",
+ "apihelp-upload-param-offset": "Décalage du bloc en octets.",
+ "apihelp-upload-param-chunk": "Partie du contenu.",
+ "apihelp-upload-param-async": "Faire de façon asynchrone les grosses opérations sur les fichiers quand c’est possible.",
+ "apihelp-upload-param-asyncdownload": "Faire de façon asynchrone la recherche d’une URL.",
+ "apihelp-upload-param-leavemessage": "Si asyncdownload est utilisé, laisser un message sur la page de discussion de l’utilisateur quand c’est terminé.",
+ "apihelp-upload-param-statuskey": "Récupérer l’état de téléchargement pour cette clé de fichier (téléchargé par URL).",
+ "apihelp-upload-param-checkstatus": "Récupérer uniquement l’état de téléchargement pour la clé de fichier donnée.",
+ "apihelp-upload-example-url": "Télécharger depuis une URL",
+ "apihelp-upload-example-filekey": "Terminer un téléchargement qui a échoué à cause d’avertissements",
+ "apihelp-userrights-description": "Modifier l’appartenance d’un utilisateur à un groupe.",
+ "apihelp-userrights-param-user": "Nom d’utilisateur.",
+ "apihelp-userrights-param-userid": "ID de l’utilisateur.",
+ "apihelp-userrights-param-add": "Ajouter l’utilisateur à ces groupes.",
+ "apihelp-userrights-param-remove": "Supprimer l’utilisateur de ces groupes.",
+ "apihelp-userrights-param-reason": "Motif pour la modification.",
+ "apihelp-userrights-example-user": "Ajouter l’utilisateur FooBot au groupe « robot », et le supprimer des groupes « sysop » et « bureaucrate »",
+ "apihelp-userrights-example-userid": "Ajouter l’utilisateur d’ID 123 au groupe « robot », et le supprimer des groupes « sysop » et « bureaucrate »",
+ "apihelp-watch-description": "Ajouter ou supprimer des pages de la liste de suivi de l’utilisateur actuel.",
+ "apihelp-watch-param-title": "La page à (ne plus) suivre. Utiliser plutôt $1titles.",
+ "apihelp-watch-param-unwatch": "Si défini, la page ne sera plus suivie plutôt que suivie.",
+ "apihelp-watch-example-watch": "Suivre la page « Page principale »",
+ "apihelp-watch-example-unwatch": "Ne plus suivre la page « Page principale »",
+ "apihelp-watch-example-generator": "Suivre les quelques premières pages de l’espace de nom principal",
"apihelp-format-example-generic": "Mettre en forme le résultat de la requête dans le format $1",
"apihelp-dbg-description": "Extraire les données au format de var_export() de PHP.",
"apihelp-dbgfm-description": "Extraire les données au format de var_export() de PHP (affiché proprement en HTML).",
"apihelp-yamlfm-description": "Extraire les données YAML (affiché proprement en HTML).",
"api-format-title": "Résultat de l’API de MédiaWiki",
"api-format-prettyprint-header": "Vous regardez la représentation HTML du format $1. HTML est utile pour le débogage, mais inapproprié pour être utilisé dans une application.\n\nSpécifiez le paramètre format pour modifier le format de sortie. Pour voir la représentation non HTML du format $1, mettez format=$2.\n\nVoyez la [https://www.mediawiki.org/wiki/API documentation complète], ou l’ [[Special:ApiHelp/main|aide de l’API]] pour plus d’information.",
+ "api-orm-param-props": "Champs à rechercher.",
+ "api-orm-param-limit": "Nombre maximal de lignes à renvoyer.",
+ "api-pageset-param-titles": "Une liste des titres sur lesquels travailler.",
+ "api-pageset-param-pageids": "Une liste des IDs de page sur lesquelles travailler.",
+ "api-pageset-param-revids": "Une liste des IDs de révision sur lesquelles travailler.",
+ "api-pageset-param-generator": "Obtenir la liste des pages sur lesquelles travailler en exécutant le module de recherche spécifié.\n\n'''NOTE :''' les noms de paramètre du générateur doivent être préfixés avec un « g », voir les exemples.",
+ "api-pageset-param-redirects-generator": "Résoudre automatiquement les redirections dans $1titles, $1pageids et $1revids, et dans les pages renvoyées par $1generator.",
+ "api-pageset-param-redirects-nogenerator": "Résoudre automatiquement les redirections dans $1titles, $1pageids et $1revids.",
+ "api-pageset-param-converttitles": "Convertir les titres dans d’autres variantes si nécessaire. Fonctionne uniquement si la langue de contenu du wiki supporte la conversion en variantes. Les langues qui supportent la conversion en variante incluent $1.",
"api-help-title": "Aide de l’API de MediaWiki",
"api-help-lead": "Ceci est une page d’aide de l’API de MédiaWiki générée automatiquement.\n\nDocumentation et exemples : https://www.mediawiki.org/wiki/API",
"api-help-main-header": "Module principal",
"api-help-param-default": "Par défaut : $1",
"api-help-param-default-empty": "Par défaut : <span class=\"apihelp-empty\">(vide)</span>",
"api-help-param-token": "Un jeton « $1 » récupéré par [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-token-webui": "Pour rester compatible, le jeton utilisé dans l’IHM web est aussi accepté.",
+ "api-help-param-disabled-in-miser-mode": "Désactivé à cause du [https://www.mediawiki.org/wiki/Manual:$wgMiserMode mode minimal].",
+ "api-help-param-limited-in-miser-mode": "'''NOTE :''' Du fait du [https://www.mediawiki.org/wiki/Manual:$wgMiserMode mode minimal], utiliser cela peut aboutir à moins de résultats que « $1limit » renvoyés avant de continuer ; dans les cas extrêmes, zéro résultats peuvent être renvoyés.",
+ "api-help-param-direction": "Dans quelle direction énumérer :\n;newer:Lister les plus anciens en premier. Note : $1start doit être avant $1end.\n;older:Lister les nouveaux en premier (par défaut). Note : $1start doit être postérieur à $1end.",
+ "api-help-param-continue": "Quand plus de résultats sont disponibles, utiliser cela pour continuer.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(aucune description)</span>",
"api-help-examples": "{{PLURAL:$1|Exemple|Exemples}} :",
"api-help-permissions": "{{PLURAL:$1|Droit|Droits}} :",
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Elisardojm"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Documentación]\n* [https://www.mediawiki.org/wiki/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discusión]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios da API]\n* [https://bugzilla.wikimedia.org/buglist.cgi?component=API&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts Erros e solicitudes]\n</div>\n<strong>Estado:</strong> Tódalas funcionalidades mostradas nesta páxina deberían estar funcionanado, pero a API aínda está desenrolo, e pode ser modificada en calquera momento. Apúntese na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discusión mediawiki-api-announce] para estar informado acerca das actualizacións.\n\n<strong>Solicitudes incorrectas:</strong> Cando se envían solicitudes incorrectas á API, envíase unha cabeceira HTTP coa chave \"MediaWiki-API-Error\" e, a seguir, tanto o valor da cabeceira como o código de erro retornado serán definidos co mesmo valor. Para máis información, consulte https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
+ "apihelp-main-param-action": "Que acción se realizará.",
+ "apihelp-main-param-format": "O formato de saída.",
+ "apihelp-main-param-curtimestamp": "Incluir a marca de tempo actual no resultado.",
+ "apihelp-block-description": "Bloquear un usuario.",
+ "apihelp-block-param-reason": "Motivo para o bloqueo.",
+ "apihelp-block-param-anononly": "Bloquear só usuarios anónimos (é dicir, desactivar edicións anónimas desta IP).",
+ "apihelp-block-param-nocreate": "Previr a creación de contas.",
+ "apihelp-block-param-autoblock": "Bloquear automaticamente o último enderezo IP utilizado, e calquera outro enderezo desde o que intente conectarse.",
+ "apihelp-block-param-watchuser": "Vixiar a páxina de usuario ou IP e a de conversa deste usuario",
+ "apihelp-compare-param-fromtitle": "Primeiro título para comparar.",
+ "apihelp-compare-param-totitle": "Segundo título para comparar.",
+ "apihelp-createaccount-description": "Crear unha nova conta de usuario.",
+ "apihelp-createaccount-param-name": "Nome de usuario.",
+ "apihelp-createaccount-param-email": "Enderezo de correo eletrónico do usuario (opcional).",
+ "apihelp-createaccount-param-realname": "Nome real do usuario (opcional).",
+ "apihelp-delete-description": "Borrar a páxina.",
+ "apihelp-delete-param-watch": "Engadir esta páxina á lista de vixilancia.",
+ "apihelp-delete-param-unwatch": "Eliminar esta páxina da lista de vixilancia.",
+ "apihelp-delete-example-simple": "Borrar a Páxina Principal",
+ "apihelp-disabled-description": "Este módulo foi desactivado.",
+ "apihelp-edit-description": "Crear e editar páxinas.",
+ "apihelp-edit-param-text": "Contido da páxina.",
+ "apihelp-edit-param-minor": "Edición pequena.",
+ "apihelp-edit-param-notminor": "Edición non pequena.",
+ "apihelp-edit-param-bot": "Marcar esta edición como de bot.",
+ "apihelp-edit-param-createonly": "Non editar a páxina se xa existe.",
+ "apihelp-edit-param-watch": "Engadir esta páxina á lista de vixilancia.",
+ "apihelp-edit-param-unwatch": "Eliminar esta páxina da lista de vixilancia.",
+ "apihelp-edit-example-edit": "Editar a páxina",
+ "apihelp-emailuser-description": "Enviar un correo electrónico a un usuario.",
+ "apihelp-expandtemplates-param-title": "Título da páxina.",
+ "apihelp-expandtemplates-param-text": "Sintaxis wiki a converter."
+}
"apihelp-block-param-nocreate": "Et Neu-Aanmelde verbeede",
"apihelp-block-param-autoblock": "Dun automattesch de läzde <i lang=\"en\" xml:lang=\"en\">IP</i>-Adräß schpärre, di dä Metmaacher jehatt hät, un och all di <i lang=\"en\" xml:lang=\"en\">IP</i>-Adräße, vun wo dä versöhk, jet ze ändere.",
"apihelp-block-param-watchuser": "Donn de Metmaachersigg un de Klaafsigg dohzoh op mig Oppaßleß säze.",
+ "apihelp-compare-description": "Donn de Ongerscheide zwesche zwai Sigge beschtemme.\n\nDo moß derför jeweils en Väsjohn, ene Tettel, odder ener Sigg iehr Kännong aanjävve, för de beide Sigge.",
+ "apihelp-compare-param-fromtitle": "Der Tettel vun dä eezte Sigg zom verjlihsche.",
+ "apihelp-compare-param-fromid": "De Kännong vun dä eezte Sigg zom verjlihsche.",
+ "apihelp-compare-param-fromrev": "De Väsjohn vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-param-totitle": "Der Tettel vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-param-toid": "De Kännong vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-param-torev": "De Väsjohn vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-example-1": "Fengk de Ongerscheide zwesche dä Väsjohne 1 un 2",
"apihelp-createaccount-description": "Ene neue Zohjang för ene Metmaacher aanlähje.",
"apihelp-createaccount-param-name": "Der Nahme för dä Metmaacher.",
"apihelp-createaccount-param-password": "Et Paßwoot (Weed ävver it jebruc un övverjange, wann <code lang=\"en\" xml:lang=\"en\">$1mailpassword</code> jesaz es)",
+ "apihelp-createaccount-param-realname": "Dämm Medmaacher singe reschtejje Nahme - kann fott blihve.",
"apihelp-delete-description": "Schmieß en Sigg fott.",
"apihelp-delete-param-watch": "Donn die Sigg en Ding Oppassliss opnemme.",
"apihelp-delete-param-unwatch": "Schmiiß di Sigg us Dinge Oppassless erus.",
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Jagwar"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Torohevitra be kokoa]\n* [https://www.mediawiki.org/wiki/API:FAQ Fanontaniana miverina matetika]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lisitry ny mailaka manaraka]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Filazana API]\n* [https://bugzilla.wikimedia.org/buglist.cgi?component=API&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts Baogy & hataka]\n</div>\n<strong>Status:</strong> \nTokony mandeha avokoa ny fitaovana aseho eto amin'ity pehy ity, na dia izany aza mbola am-panamboarana ny API ary mety hiova na oviana na oviana. Araho amin'ny alalan'ny fisoratana ny mailakao ao amin'ny [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce lisitra fampielezana] ny fiovana.\n\n<strong>Hataka diso:</strong> \nRehefa alefa ao amin'i API ny hata, ho alefa miaraka amin'ny lakile \"MediaWiki-API-Error\" ny header HTTP ary samy homen-tsanda mitovy ny header ary ny kaodin-kadisoana. Ho an'ny torohay fanampiny dia jereo https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
+ "apihelp-main-param-action": "Inona ny zavatra ho atao.",
+ "apihelp-main-param-format": "Format mivoaka",
+ "apihelp-createaccount-param-name": "Anaram-pikambana."
+}
"Bjankuloski06"
]
},
- "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Ð\94окÑ\83менÑ\82аÑ\86иÑ\98а]\n* [https://www.mediawiki.org/wiki/API:FAQ ЧÐ\9fÐ\9f]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Ð\9fоÑ\88Ñ\82енÑ\81ки Ñ\81пиÑ\81ок]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce СоопÑ\88Ñ\82ениÑ\98а за Ð\9fÑ\80илогоÑ\82]\n* [https://bugzilla.wikimedia.org/buglist.cgi?component=API&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts Ð\93Ñ\80еÑ\88ки и баÑ\80аÑ\9aа]\n</div>\n<strong>СÑ\82аÑ\82Ñ\83Ñ\81:</strong> СиÑ\82е Ñ\81Ñ\82авки на Ñ\81Ñ\82Ñ\80аниÑ\86ава би Ñ\82Ñ\80ебало да Ñ\80абоÑ\82аÑ\82, но Ð\9fÑ\80илогоÑ\82 Ñ\81епак е во акÑ\82ивна Ñ\80азÑ\80абоÑ\82ка, Ñ\88Ñ\82о знаÑ\87и дека може да Ñ\81е Ñ\81мени во Ñ\81екое вÑ\80еме. Ð\9eбÑ\98авиÑ\82е за измени можеÑ\82е да ги дознаваÑ\82е ако Ñ\81е пÑ\80иÑ\98авиÑ\82е на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ поÑ\88Ñ\82енÑ\81киоÑ\82 Ñ\81пиÑ\81ок â\80\9ethe mediawiki-api-announceâ\80\9c].\n\n<strong>Ð\9fогÑ\80еÑ\88ни баÑ\80аÑ\9aа:</strong> Ð\9aога Ð\9fÑ\80илогот ќе добие погрешни барања, ќе се испрати HTTP-заглавие со клучот „MediaWiki-API-Error“ и потоа на вредностите на заглавието и шифрата на грешката што ќе се појават ќе им биде зададена истата вредност. ПОвеќе информации ќе најдете на https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Ð\94окÑ\83менÑ\82аÑ\86иÑ\98а]\n* [https://www.mediawiki.org/wiki/API:FAQ ЧÐ\9fÐ\9f]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Ð\9fоÑ\88Ñ\82енÑ\81ки Ñ\81пиÑ\81ок]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce СоопÑ\88Ñ\82ениÑ\98а за Ð\98звÑ\80Ñ\88никоÑ\82]\n* [https://bugzilla.wikimedia.org/buglist.cgi?component=API&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts Ð\93Ñ\80еÑ\88ки и баÑ\80аÑ\9aа]\n</div>\n<strong>СÑ\82аÑ\82Ñ\83Ñ\81:</strong> СиÑ\82е Ñ\81Ñ\82авки на Ñ\81Ñ\82Ñ\80аниÑ\86ава би Ñ\82Ñ\80ебало да Ñ\80абоÑ\82аÑ\82, но Ð\98звÑ\80Ñ\88никоÑ\82 Ñ\81епак е во акÑ\82ивна Ñ\80азÑ\80абоÑ\82ка, Ñ\88Ñ\82о знаÑ\87и дека може да Ñ\81е Ñ\81мени во Ñ\81екое вÑ\80еме. Ð\9eбÑ\98авиÑ\82е за измени можеÑ\82е да ги дознаваÑ\82е ако Ñ\81е пÑ\80иÑ\98авиÑ\82е на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ поÑ\88Ñ\82енÑ\81киоÑ\82 Ñ\81пиÑ\81ок â\80\9ethe mediawiki-api-announceâ\80\9c].\n\n<strong>Ð\9fогÑ\80еÑ\88ни баÑ\80аÑ\9aа:</strong> Ð\9aога Ð\98звÑ\80Ñ\88никот ќе добие погрешни барања, ќе се испрати HTTP-заглавие со клучот „MediaWiki-API-Error“ и потоа на вредностите на заглавието и шифрата на грешката што ќе се појават ќе им биде зададена истата вредност. ПОвеќе информации ќе најдете на https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
"apihelp-main-param-action": "Кое дејство да се изврши.",
"apihelp-main-param-format": "Формат на изводот.",
"apihelp-main-param-maxlag": "Максималниот заостаток може да се користи кога МедијаВики е воспоставен на грозд умножен од базата. За да спречите дополнителни заостатоци од дејства, овој параметар му наложува на клиентот да почека додека заостатокот не се намали под укажаната вредност. Во случај на преголем заостаток, системт ја дава грешката со код „maxlag“ со порака од обликот „Го чекам $host: има заостаток од $lag секунди“.<br />Погл. https://www.mediawiki.org/wiki/Manual:Maxlag_parameter за повеќе информации.",
"apihelp-options-example-reset": "Врати ги сите поставки по основно",
"apihelp-options-example-change": "Смени ги поставките „skinЗ“ и „hideminor“",
"apihelp-options-example-complex": "Врати ги сите нагодувања по основно, а потоа задај ги „skin“ и „nickname“",
- "apihelp-paraminfo-description": "Ð\9dабави инÑ\84оÑ\80маÑ\86ии за пÑ\80илоÑ\88ки (API) модули.",
+ "apihelp-paraminfo-description": "Ð\9dабави инÑ\84оÑ\80маÑ\86ии за извÑ\80Ñ\88ниÑ\87ки (API) модули.",
"apihelp-paraminfo-param-modules": "Список на називи на модули (вредности на параметрите action= и format=, или пак „main“). Може да се укажат подмодули со „+“.",
"apihelp-paraminfo-param-helpformat": "Формат на помошните низи.",
"apihelp-paraminfo-param-querymodules": "Список на називи на модули за барања (вредност на параметарот prop=, meta= или list=). Користете го „$1modules=query+foo“ наместо „$1querymodules=foo“.",
"apihelp-protect-param-reason": "Причиина за (од)заштитување",
"apihelp-protect-example-protect": "Заштити страница",
"apihelp-purge-param-forcelinkupdate": "Поднови ги табелите со врски.",
- "apihelp-purge-example-simple": "Ð\9fÑ\80евÑ\87иÑ\82аÑ\98 ги â\80\9eÐ\93лавна Ñ\81Ñ\82Ñ\80аниÑ\86аâ\80\9c и â\80\9eÐ\9fÑ\80илог“",
+ "apihelp-purge-example-simple": "Ð\9fÑ\80евÑ\87иÑ\82аÑ\98 ги â\80\9eÐ\93лавна Ñ\81Ñ\82Ñ\80аниÑ\86аâ\80\9c и â\80\9eÐ\98звÑ\80Ñ\88ник“",
"apihelp-query-param-list": "Кои списоци да се набават.",
"apihelp-query-param-meta": "Кои метаподатоци да се набават.",
"apihelp-query+allcategories-description": "Наброј ги сите категории.",
"apihelp-xmlfm-description": "Давај го изводот во XML-формат (подобрен испис во HTML).",
"apihelp-yaml-description": "Давај го изводот во YAML-формат.",
"apihelp-yamlfm-description": "Давај го изводот во YAML-формат (подобрен испис во HTML).",
- "api-format-title": "РезÑ\83лÑ\82аÑ\82 од Ð\9fÑ\80илогот на МедијаВики",
- "api-format-prettyprint-header": "Ја гледате HTML-претставата на форматот $1. HTML е добар за отстранување на грешки, но не е погоден за употреб во прилог.\n\nУкажете го параметарот за формат за да го смените изводниот формат. За да ги видите претставите на форматот $1 вон HTML, задајте format=$2.\n\nПовеќе информации ќе најдете на [https://www.mediawiki.org/wiki/API целосната документација], или пак [[Special:ApiHelp/main|помош со прилогот]].",
+ "api-format-title": "РезÑ\83лÑ\82аÑ\82 од Ð\98звÑ\80Ñ\88никот на МедијаВики",
+ "api-format-prettyprint-header": "Ја гледате HTML-претставата на форматот $1. HTML е добар за отстранување на грешки, но не е погоден за употреба во извршник.\n\nУкажете го параметарот за формат за да го смените изводниот формат. За да ги видите претставите на форматот $1 вон HTML, задајте format=$2.\n\nПовеќе информации ќе најдете на [https://www.mediawiki.org/wiki/API целосната документација], или пак [[Special:ApiHelp/main|помош со извршникот]].",
"api-orm-param-props": "Полиња за пребарување.",
"api-orm-param-limit": "Макс. број на редови во изводот.",
"api-pageset-param-titles": "Список на наслови на кои ќе се работи",
"api-pageset-param-pageids": "Список на назнаки за страници на кои ќе се работи",
"api-pageset-param-revids": "Список на назнаки на преработки на кои ќе се работи",
"api-pageset-param-generator": "Дај го списокот на страници на кои ќе се работи исполнувајќи го укажаниот модул за барање.\n\n'''НАПОМЕНА:''' називите на создавачките параметри мора да ја имаат претставката „g“. Погледајте ги примерите.",
- "api-help-title": "Ð\9fомоÑ\88 Ñ\81о Ð\9fÑ\80илогот на МедијаВики",
- "api-help-lead": "Ð\9eва е Ñ\81амоÑ\81оздадена докÑ\83менÑ\82аÑ\86иÑ\81ка Ñ\81Ñ\82Ñ\80аниÑ\86а за Ð\9fÑ\80илогоÑ\82 на Ð\9cедиÑ\98аÐ\92ики.\n\nDocumentation and examples: https://www.mediawiki.org/wiki/API",
+ "api-help-title": "Ð\9fомоÑ\88 Ñ\81о Ð\98звÑ\80Ñ\88никот на МедијаВики",
+ "api-help-lead": "Ð\9eва е Ñ\81амоÑ\81оздадена докÑ\83менÑ\82аÑ\86иÑ\81ка Ñ\81Ñ\82Ñ\80аниÑ\86а за извÑ\80Ñ\88никоÑ\82 на Ð\9cедиÑ\98аÐ\92ики.\n\nÐ\94окÑ\83менÑ\82аÑ\86иÑ\98а и пÑ\80имеÑ\80и: https://www.mediawiki.org/wiki/API",
"api-help-main-header": "Главен модул",
"api-help-flag-deprecated": "Овој модул е застарен.",
"api-help-flag-internal": "<strong>Овој модул е внатрешен или нестабилен.</strong> Работењето може да му се промени без предупредување.",
"api-help-permissions-granted-to": "{{PLURAL:$1|Доделена на}: $2",
"api-help-right-apihighlimits": "Уоптреба на повисоки ограничувања за приложни барања (бавни барања: $1; брзи барања: $2). Ограничувањата за бавни барања важат и за повеќевредносни параметри.",
"api-credits-header": "Признанија",
- "api-credits": "РазÑ\80абоÑ\82Ñ\83ваÑ\87и на Ð\9fÑ\80илогот:\n* Роан Катау (главен резработувач од септември 2007 до 2009 г.)\n* Виктор Василев\n* Брајан Тонг Мињ\n* Сем Рид\n* Јуриј Астрахан (создавач, главен разработувач од септември 2006 до септември 2007 г.)\n* Brad Jorsch (главен разработувач од 2013 г. до денес)\n\nВашите коментари, предлози и прашања испраќајте ги на mediawiki-api@lists.wikimedia.org\nа грешките пријавувајте ги на https://bugzilla.wikimedia.org/."
+ "api-credits": "РазÑ\80абоÑ\82Ñ\83ваÑ\87и на Ð\98звÑ\80Ñ\88никот:\n* Роан Катау (главен резработувач од септември 2007 до 2009 г.)\n* Виктор Василев\n* Брајан Тонг Мињ\n* Сем Рид\n* Јуриј Астрахан (создавач, главен разработувач од септември 2006 до септември 2007 г.)\n* Brad Jorsch (главен разработувач од 2013 г. до денес)\n\nВашите коментари, предлози и прашања испраќајте ги на mediawiki-api@lists.wikimedia.org\nа грешките пријавувајте ги на https://bugzilla.wikimedia.org/."
}
"apihelp-help-example-main": "Bantuan untuk modul utama",
"apihelp-help-example-recursive": "Segala bantuan dalam satu halaman",
"apihelp-help-example-help": "Bantuan untuk modul bantuan",
+ "apihelp-query+prefixsearch-param-offset": "Bilangan hasil untuk dilangkau.",
"apihelp-userrights-param-userid": "ID pengguna.",
"apihelp-dbgfm-description": "Data output dalam format var_export() PHP (''pretty-print'' dalam HTML).",
"apihelp-dump-description": "Output data dalam format var_dump() PHP.",
"Siebrand",
"Sjoerddebruin",
"Robin0van0der0vliet",
- "Mar(c)"
+ "Mar(c)",
+ "Valhallasw"
]
},
"apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Documentatie]\n* [https://www.mediawiki.org/wiki/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-maillijst]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aankondigingen]\n* [https://bugzilla.wikimedia.org/buglist.cgi?component=API&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts Bugs & verzoeken]\n</div>\n<strong>Status:</strong> Alle functies die op deze pagina worden weergegeven horen te werken. Aan de API wordt actief gewerkt, en deze kan gewijzigd worden. Abonneer u op de [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-maillijst mediawiki-api-announce] voor meldingen over aanpassingen.\n\n<strong>Foutieve verzoeken:</strong> als de API foutieve verzoeken ontvangt, wordt er geantwoord met een HTTP-header met de sleutel \"MediaWiki-API-Error\" en daarna worden de waarde van de header en de foutcode op dezelfde waarde ingesteld. Zie https://www.mediawiki.org/wiki/API:Errors_and_warnings voor meer informatie.",
"apihelp-main-param-maxlag": "De maximale vertraging kan gebruikt worden als MediaWiki is geïnstalleerd op een databasecluster die gebruik maakt van replicatie. Om te voorkomen dat handelingen nog meer databasereplicatievertraging veroorzaken, kan deze parameter er voor zorgen dat de client wacht totdat de replicatievertraging lager is dan de aangegeven waarde. In het geval van buitensporige vertraging, wordt de foutcode \"maxlag\" teruggegeven met een bericht als \"Waiting for $host: $lag seconds lagged\".<br />Zie https://www.mediawiki.org/wiki/Manual:Maxlag_parameter voor mee informatie.",
"apihelp-main-param-smaxage": "Stelt de header \"s-maxage\" in op het aangegeven aantal seconden. Foutmeldingen komen nooit in de cache.",
"apihelp-main-param-maxage": "Stelt de header \"max-age\" in op het aangegeven aantal seconden. Foutmeldingen komen nooit in de cache.",
+ "apihelp-main-param-assert": "Controleer of de gebruiker ingelogd is als \"user\" is meegegeven, en of de gebruiker het bot-gebruikersrecht heeft als \"bot\" is meegegeven.",
+ "apihelp-main-param-requestid": "Elke waarde die hier gegeven wordt wordt aan het antwoord toegevoegd. Dit kan gebruikt worden om verzoeken te onderscheiden.",
+ "apihelp-main-param-servedby": "Voeg de hostnaam van de server die de aanvraag heeft afgehandeld toe aan het antwoord.",
+ "apihelp-main-param-curtimestamp": "Voeg de huidige tijd toe aan het antwoord.",
"apihelp-block-description": "Gebruiker blokkeren.",
"apihelp-block-param-reason": "Reden voor blokkade.",
"apihelp-edit-example-edit": "Pagina bewerken",
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Veeven"
+ ]
+ },
+ "apihelp-feedrecentchanges-example-simple": "ఇటీవలి మార్పులను చూడండి"
+}
"apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page/zh 文档]\n* [https://www.mediawiki.org/wiki/API:FAQ/zh 常见问题]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://bugzilla.wikimedia.org/buglist.cgi?component=API&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong> 本页所展示的所有特性都应正常工作,但是API仍在开发当中,将会随时变化。请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong> 当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅 https://www.mediawiki.org/wiki/API:Errors_and_warnings 。",
"apihelp-main-param-action": "要执行的操作。",
"apihelp-main-param-format": "输出的格式。",
+ "apihelp-main-param-assert": "如果设置为“user”就验证用户是否登录,或如果设置为“bot”就验证是否有机器人用户权限。",
"apihelp-main-param-servedby": "包含保存结果请求的主机名。",
"apihelp-main-param-curtimestamp": "在结果中包括当前时间戳。",
"apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。这必须匹配Origin中的一个起点:从头到底,因此它已经设置为像http://zh.wikipedia.org或https://meta.wikimedia.org的东西。如果此参数不匹配Origin: header,就返回403错误响应。如果此参数匹配Origin: header并且起点被白名单,将设置一个Access-Control-Allow-Origin开头。",
"apihelp-compare-param-fromid": "要比较的第一个页面 ID。",
"apihelp-compare-param-fromrev": "要比较的第一个修订版本。",
"apihelp-compare-param-totitle": "要比较的第二个标题。",
- "apihelp-compare-param-toid": "è¦\81æ¯\94è¾\83ç\9a\84第ä¸\80个页面 ID。",
+ "apihelp-compare-param-toid": "è¦\81æ¯\94è¾\83ç\9a\84第äº\8c个页面 ID。",
"apihelp-compare-param-torev": "要比较的第二个修订版本。",
"apihelp-compare-example-1": "在版本1和2中创建差异",
"apihelp-createaccount-description": "创建一个新用户账户。",
"apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "不能与$3user一起使用。",
"apihelp-query+alldeletedrevisions-param-from": "从此标题开始列出。",
"apihelp-query+alldeletedrevisions-param-to": "列出至此标题为止。",
+ "apihelp-query+alldeletedrevisions-param-user": "只列出此用户做出的修订。",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
"apihelp-query+alldeletedrevisions-param-namespace": "只列出此名字空间的页面。",
"apihelp-query+alldeletedrevisions-param-miser-user-namespace": "'''注意:'''由于[https://www.mediawiki.org/wiki/Manual:$wgMiserMode miser模式],同时使用$1user和$1namespace将导致继续前返回少于“$1limit”个结果,在极端条件下可能不返回任何结果。",
"apihelp-query+alldeletedrevisions-example-user": "列出由User:Example作出的最近50次已删除贡献",
"apihelp-query+alldeletedrevisions-example-ns-main": "列出最近50次已删除的主名字空间修订",
+ "apihelp-query+allfileusages-param-prefix": "搜索此值开头的所有文件标题。",
+ "apihelp-query+allfileusages-param-limit": "要返回的总计项目。",
"apihelp-query+allfileusages-param-dir": "罗列所采用的方向。",
"apihelp-query+allfileusages-example-unique": "列出唯一性的文件标题",
"apihelp-query+allfileusages-example-unique-generator": "获取所有文件标题,并标记出缺失者",
"apihelp-query+categoryinfo-example-simple": "获取有关[[:Category:Foo]]和[[:Category:Bar]]的信息",
"apihelp-query+categorymembers-description": "在指定的分类中列出所有页面。",
"apihelp-query+categorymembers-param-sort": "要作为排序方式的属性。",
+ "apihelp-query+categorymembers-param-dir": "排序的方向。",
+ "apihelp-query+categorymembers-param-start": "开始列举的时间戳。不能与$1sort=timestamp一起使用。",
+ "apihelp-query+categorymembers-param-end": "列举的结尾时间戳。不能与$1sort=timestamp一起使用。",
"apihelp-query+categorymembers-param-startsortkey": "请改用$1starthexsortkey。",
"apihelp-query+categorymembers-param-endsortkey": "请改用$1endhexsortkey。",
"apihelp-query+categorymembers-example-simple": "获取[[:Category:Physics]]中的前10个页面。",
"apihelp-query+categorymembers-example-generator": "获取关于[[:Category:Physics]]中的前10个页面的页面信息。",
+ "apihelp-query+contributors-description": "获取对一个页面的登录贡献者列表和匿名贡献数。",
+ "apihelp-query+contributors-param-limit": "返回的贡献数。",
"apihelp-query+contributors-example-simple": "显示[[首页]]的贡献",
"apihelp-query+deletedrevisions-example-titles": "列出[[首页]]和[[Talk:首页]]的已删除修订,包含内容",
"apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|模式}}:$2",
"apihelp-query+deletedrevs-param-from": "从此标题开始列出。",
"apihelp-query+deletedrevs-param-to": "列出至此标题为止。",
+ "apihelp-query+deletedrevs-param-user": "只列出此用户做出的修订。",
+ "apihelp-query+deletedrevs-param-excludeuser": "不要列出此用户做出的修订。",
"apihelp-query+deletedrevs-param-namespace": "只列出此名字空间的页面。",
"apihelp-query+deletedrevs-example-mode1": "列出最近已删除的对首页和Talk:首页的贡献,带内容(模式1)",
"apihelp-query+deletedrevs-example-mode2": "列出由Bob作出的最近50次已删除贡献(模式2)",
"apihelp-query+links-example-simple": "从[[首页]]获取链接",
"apihelp-query+links-example-generator": "获取有关[[首页]]链接页面的信息",
"apihelp-query+links-example-namespaces": "获取用户和模板名字空间中来自[[首页]]的链接",
+ "apihelp-query+linkshere-param-namespace": "只包括这些名字空间的页面。",
"apihelp-query+linkshere-param-limit": "返回多少。",
+ "apihelp-query+linkshere-param-show": "只显示符合以下标准的项:\n;redirect:只显示重定向。\n;!redirects:只显示非重定向。",
"apihelp-query+linkshere-example-simple": "获取链接至[[首页]]的页面列表",
"apihelp-query+linkshere-example-generator": "获取有关链接至[[首页]]的页面的信息",
"apihelp-query+logevents-description": "从日志获取事件。",
"apihelp-yaml-description": "输出数据为YAML格式。",
"apihelp-yamlfm-description": "输出数据为YAML格式(HTML优质打印效果)。",
"api-format-title": "MediaWiki API 结果",
+ "api-format-prettyprint-header": "您正在查看$1格式的HTML表示。HTML对调试很有用,但不适合应用程序使用。\n\n指定格式参数以更改输出格式。要查看$1格式的非HTML表示,设置format=$2。\n\n参见[https://www.mediawiki.org/wiki/Special:MyLanguage/API 完整文档],或[[Special:ApiHelp/main|API帮助]]以获取更多信息。",
"api-orm-param-props": "要查询的字段。",
"api-help-title": "MediaWiki API 帮助",
"api-help-lead": "这是自动生成的MediaWiki API文档页面。\n\n文档和例子:https://www.mediawiki.org/wiki/API:Main_page/zh",
"apihelp-emailuser-param-text": "郵件內容。",
"apihelp-emailuser-param-ccme": "寄送一份此郵件的複本給我。",
"apihelp-emailuser-example-email": "寄送電子郵件給使用者 \"WikiSysop\" 使用內容 \"Content\"",
- "apihelp-expandtemplates-description": "展開所有於 wikitext 中的樣板。",
+ "apihelp-expandtemplates-description": "展開所有於 wikitext 中模板。",
"apihelp-expandtemplates-param-title": "頁面標題。",
"apihelp-expandtemplates-param-text": "要轉換的 Wikitext。",
"apihelp-login-param-name": "使用者名稱。",
return $prefixes[$table];
} else {
$prefix = null;
- wfRunHooks( 'BacklinkCacheGetPrefix', array( $table, &$prefix ) );
+ Hooks::run( 'BacklinkCacheGetPrefix', array( $table, &$prefix ) );
if ( $prefix ) {
return $prefix;
} else {
break;
default:
$conds = null;
- wfRunHooks( 'BacklinkCacheGetConditions', array( $table, $this->title, &$conds ) );
+ Hooks::run( 'BacklinkCacheGetConditions', array( $table, $this->title, &$conds ) );
if ( !$conds ) {
throw new MWException( "Invalid table \"$table\" in " . __CLASS__ );
}
return false;
}
// Allow extensions to disable caching
- return wfRunHooks( 'HTMLFileCache::useFileCache', array( $context ) );
+ return Hooks::run( 'HTMLFileCache::useFileCache', array( $context ) );
}
/**
use Cdb\Exception as CdbException;
use Cdb\Reader as CdbReader;
use Cdb\Writer as CdbWriter;
+
/**
* Class for caching the contents of localisation files, Messages*.php
* and *.i18n.php.
# Allow extensions an opportunity to adjust the data for this
# fallback
- wfRunHooks( 'LocalisationCacheRecacheFallback', array( $this, $csCode, &$csData ) );
+ Hooks::run( 'LocalisationCacheRecacheFallback', array( $this, $csCode, &$csData ) );
# Merge the data for this fallback into the final array
if ( $csCode === $code ) {
}
# Run hooks
$purgeBlobs = true;
- wfRunHooks( 'LocalisationCacheRecache', array( $this, $code, &$allData, &$purgeBlobs ) );
+ Hooks::run( 'LocalisationCacheRecache', array( $this, $code, &$allData, &$purgeBlobs ) );
if ( is_null( $allData['namespaceNames'] ) ) {
wfProfileOut( __METHOD__ );
global $wgContLang;
MessageBlobStore::getInstance()->updateMessage( $wgContLang->lcfirst( $msg ) );
- wfRunHooks( 'MessageCacheReplace', array( $title, $text ) );
+ Hooks::run( 'MessageCacheReplace', array( $title, $text ) );
wfProfileOut( __METHOD__ );
}
$lckey = $wgContLang->lcfirst( $lckey );
}
- wfRunHooks( 'MessageCache::get', array( &$lckey ) );
+ Hooks::run( 'MessageCache::get', array( &$lckey ) );
if ( ord( $lckey ) < 128 ) {
$uckey = ucfirst( $lckey );
} else {
// XXX: This is not cached in process cache, should it?
$message = false;
- wfRunHooks( 'MessagesPreLoad', array( $title, &$message ) );
+ Hooks::run( 'MessagesPreLoad', array( $title, &$message ) );
if ( $message !== false ) {
return $message;
}
public static function newFromContext( ResourceLoaderContext $context ) {
$cache = new self();
- if ( $context->getOnly() === 'styles' ) {
+ if ( $context->getImage() ) {
+ $cache->mType = 'image';
+ } elseif ( $context->getOnly() === 'styles' ) {
$cache->mType = 'css';
} else {
$cache->mType = 'js';
// Get all query values
$queryVals = $context->getRequest()->getValues();
foreach ( $queryVals as $query => $val ) {
- if ( $query === 'modules' || $query === 'version' || $query === '*' ) {
+ if ( in_array( $query, array( 'modules', 'image', 'variant', 'version', '*' ) ) ) {
+ // Use file cache regardless of the value of this parameter
continue; // note: &* added as IE fix
} elseif ( $query === 'skin' && $val === $wgDefaultSkin ) {
continue;
continue;
} elseif ( $query === 'debug' && $val === 'false' ) {
continue;
+ } elseif ( $query === 'format' && $val === 'rasterized' ) {
+ continue;
}
return false;
$user = $context->getUser();
$sk = $context->getSkin();
$list = null;
- if ( wfRunHooks( 'FetchChangesList', array( $user, &$sk, &$list ) ) ) {
+ if ( Hooks::run( 'FetchChangesList', array( $user, &$sk, &$list ) ) ) {
$new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) );
return $new ? new EnhancedChangesList( $context ) : new OldChangesList( $context );
* @param ResultWrapper|array $rows
*/
public function initChangesListRows( $rows ) {
- wfRunHooks( 'ChangesListInitRows', array( $this, $rows ) );
+ Hooks::run( 'ChangesListInitRows', array( $this, $rows ) );
}
/**
# RTL/LTR marker
$articlelink .= $this->getLanguage()->getDirMark();
- wfRunHooks( 'ChangesListInsertArticleLink',
+ Hooks::run( 'ChangesListInsertArticleLink',
array( &$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched ) );
$s .= " $articlelink";
$rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
}
- if ( !wfRunHooks( 'OldChangesListRecentChangesLine', array( &$this, &$html, $rc, &$classes ) ) ) {
+ if ( !Hooks::run( 'OldChangesListRecentChangesLine', array( &$this, &$html, $rc, &$classes ) ) ) {
wfProfileOut( __METHOD__ );
return false;
/**
* @param RecentChange $rc
* @param string[] &$classes
- * @param boolean $watched
+ * @param bool $watched
*
* @return string
*/
public function getPerformer() {
if ( $this->mPerformer === false ) {
if ( $this->mAttribs['rc_user'] ) {
- $this->mPerformer = User::newFromID( $this->mAttribs['rc_user'] );
+ $this->mPerformer = User::newFromId( $this->mAttribs['rc_user'] );
} else {
$this->mPerformer = User::newFromName( $this->mAttribs['rc_user_text'], false );
}
$this->mAttribs['rc_id'] = $dbw->insertId();
# Notify extensions
- wfRunHooks( 'RecentChange_save', array( &$this ) );
+ Hooks::run( 'RecentChange_save', array( &$this ) );
# Notify external application via UDP
if ( !$noudp ) {
$editor = $this->getPerformer();
$title = $this->getTitle();
- if ( wfRunHooks( 'AbortEmailNotification', array( $editor, $title, $this ) ) ) {
+ if ( Hooks::run( 'AbortEmailNotification', array( $editor, $title, $this ) ) ) {
# @todo FIXME: This would be better as an extension hook
$enotif = new EmailNotification();
$enotif->notifyOnPageChange( $editor, $title,
// Automatic patrol needs "autopatrol", ordinary patrol needs "patrol"
$right = $auto ? 'autopatrol' : 'patrol';
$errors = array_merge( $errors, $this->getTitle()->getUserPermissionsErrors( $right, $user ) );
- if ( !wfRunHooks( 'MarkPatrolled', array( $this->getAttribute( 'rc_id' ), &$user, false ) ) ) {
+ if ( !Hooks::run( 'MarkPatrolled', array( $this->getAttribute( 'rc_id' ), &$user, false ) ) ) {
$errors[] = array( 'hookaborted' );
}
// Users without the 'autopatrol' right can't patrol their
$this->reallyMarkPatrolled();
// Log this patrol event
PatrolLog::record( $this, $auto, $user );
- wfRunHooks( 'MarkPatrolledComplete', array( $this->getAttribute( 'rc_id' ), &$user, false ) );
+ Hooks::run( 'MarkPatrolledComplete', array( $this->getAttribute( 'rc_id' ), &$user, false ) );
return array();
}
$lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
$result = false;
- wfRunHooks( 'ConvertContent', array( $this, $toModel, $lossy, &$result ) );
+ Hooks::run( 'ConvertContent', array( $this, $toModel, $lossy, &$result ) );
return $result;
}
$po = new ParserOutput();
- if ( wfRunHooks( 'ContentGetParserOutput',
+ if ( Hooks::run( 'ContentGetParserOutput',
array( $this, $title, $revId, $options, $generateHtml, &$po ) ) ) {
// Save and restore the old value, just in case something is reusing
$options->setRedirectTarget( $oldRedir );
}
- wfRunHooks( 'ContentAlterParserOutput', array( $this, $title, $po ) );
+ Hooks::run( 'ContentAlterParserOutput', array( $this, $title, $po ) );
return $po;
}
$model = MWNamespace::getNamespaceContentModel( $ns );
// Hook can determine default model
- if ( !wfRunHooks( 'ContentHandlerDefaultModelFor', array( $title, &$model ) ) ) {
+ if ( !Hooks::run( 'ContentHandlerDefaultModelFor', array( $title, &$model ) ) ) {
if ( !is_null( $model ) ) {
return $model;
}
}
// Hook can force JS/CSS
- wfRunHooks( 'TitleIsCssOrJsPage', array( $title, &$isCssOrJsPage ), '1.25' );
+ Hooks::run( 'TitleIsCssOrJsPage', array( $title, &$isCssOrJsPage ), '1.25' );
// Is this a .css subpage of a user page?
$isJsCssSubpage = NS_USER == $ns
$isWikitext = $isWikitext && !$isCssOrJsPage && !$isJsCssSubpage;
// Hook can override $isWikitext
- wfRunHooks( 'TitleIsWikitextPage', array( $title, &$isWikitext ), '1.25' );
+ Hooks::run( 'TitleIsWikitextPage', array( $title, &$isWikitext ), '1.25' );
if ( !$isWikitext ) {
switch ( $ext ) {
if ( empty( $wgContentHandlers[$modelId] ) ) {
$handler = null;
- wfRunHooks( 'ContentHandlerForModelID', array( $modelId, &$handler ) );
+ Hooks::run( 'ContentHandlerForModelID', array( $modelId, &$handler ) );
if ( $handler === null ) {
throw new MWException( "No handler for model '$modelId' registered in \$wgContentHandlers" );
$pageLang = wfGetLangObj( $lang );
}
- wfRunHooks( 'PageContentLanguage', array( $title, &$pageLang, $wgLang ) );
+ Hooks::run( 'PageContentLanguage', array( $title, &$pageLang, $wgLang ) );
return wfGetLangObj( $pageLang );
}
public function canBeUsedOn( Title $title ) {
$ok = true;
- wfRunHooks( 'ContentModelCanBeUsedOn', array( $this->getModelID(), $title, &$ok ) );
+ Hooks::run( 'ContentModelCanBeUsedOn', array( $this->getModelID(), $title, &$ok ) );
return $ok;
}
}
// call the hook functions
- $ok = wfRunHooks( $event, $args );
+ $ok = Hooks::run( $event, $args );
// see if the hook changed the text
foreach ( $contentTexts as $k => $orig ) {
# Inserting a new section
$subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
- if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
+ if ( Hooks::run( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
$text = strlen( trim( $oldtext ) ) > 0
? "{$oldtext}\n\n{$subject}{$text}"
: "{$subject}{$text}";
if ( $this->title === null ) {
global $wgTitle; # fallback to $wg till we can improve this
$this->title = $wgTitle;
- wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetAllCallers() . ' with no title set.' );
+ wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetAllCallers( 5 ) . ' with no title set.' );
}
return $this->title;
* @param WikiPage $p
*/
public function setWikiPage( WikiPage $p ) {
- $contextTitle = $this->getTitle();
$pageTitle = $p->getTitle();
- if ( !$contextTitle || !$pageTitle->equals( $contextTitle ) ) {
+ if ( !$this->hasTitle() || !$pageTitle->equals( $this->getTitle() ) ) {
$this->setTitle( $pageTitle );
}
// Defer this to the end since setTitle sets it to null.
$code = $request->getVal( 'uselang', $user->getOption( 'language' ) );
$code = self::sanitizeLangCode( $code );
- wfRunHooks( 'UserGetLanguageObject', array( $user, &$code, $this ) );
+ Hooks::run( 'UserGetLanguageObject', array( $user, &$code, $this ) );
if ( $code === $this->getConfig()->get( 'LanguageCode' ) ) {
$this->lang = $wgContLang;
wfProfileIn( __METHOD__ . '-createskin' );
$skin = null;
- wfRunHooks( 'RequestContextCreateSkin', array( $this, &$skin ) );
+ Hooks::run( 'RequestContextCreateSkin', array( $this, &$skin ) );
$factory = SkinFactory::getDefaultInstance();
// If the hook worked try to set a skin from it
/** Maximum time to wait before retry */
const DEADLOCK_DELAY_MAX = 1500000;
-# ------------------------------------------------------------------------------
-# Variables
-# ------------------------------------------------------------------------------
+ /** How many row changes in a write query trigger a log entry */
+ const LOG_WRITE_THRESHOLD = 300;
protected $mLastQuery = '';
protected $mDoneWrites = false;
*/
protected $allViews = null;
-# ------------------------------------------------------------------------------
-# Accessors
-# ------------------------------------------------------------------------------
- # These optionally set a variable and return the previous state
-
/**
* A string describing the current software version, and possibly
* other details in a user-friendly way. Will be listed on Special:Version, etc.
return $this->getSqlFilePath( 'update-keys.sql' );
}
-# ------------------------------------------------------------------------------
-# Other functions
-# ------------------------------------------------------------------------------
+ /**
+ * Get the type of the DBMS, as it appears in $wgDBtype.
+ *
+ * @return string
+ */
+ abstract function getType();
+
+ /**
+ * Open a connection to the database. Usually aborts on failure
+ *
+ * @param string $server Database server host
+ * @param string $user Database user name
+ * @param string $password Database user password
+ * @param string $dbName Database name
+ * @return bool
+ * @throws DBConnectionError
+ */
+ abstract function open( $server, $user, $password, $dbName );
+
+ /**
+ * Fetch the next row from the given result object, in object form.
+ * Fields can be retrieved with $row->fieldname, with fields acting like
+ * member variables.
+ * If no more rows are available, false is returned.
+ *
+ * @param ResultWrapper|stdClass $res Object as returned from DatabaseBase::query(), etc.
+ * @return stdClass|bool
+ * @throws DBUnexpectedError Thrown if the database returns an error
+ */
+ abstract function fetchObject( $res );
+
+ /**
+ * Fetch the next row from the given result object, in associative array
+ * form. Fields are retrieved with $row['fieldname'].
+ * If no more rows are available, false is returned.
+ *
+ * @param ResultWrapper $res Result object as returned from DatabaseBase::query(), etc.
+ * @return array|bool
+ * @throws DBUnexpectedError Thrown if the database returns an error
+ */
+ abstract function fetchRow( $res );
+
+ /**
+ * Get the number of rows in a result object
+ *
+ * @param mixed $res A SQL result
+ * @return int
+ */
+ abstract function numRows( $res );
+
+ /**
+ * Get the number of fields in a result object
+ * @see http://www.php.net/mysql_num_fields
+ *
+ * @param mixed $res A SQL result
+ * @return int
+ */
+ abstract function numFields( $res );
+
+ /**
+ * Get a field name in a result object
+ * @see http://www.php.net/mysql_field_name
+ *
+ * @param mixed $res A SQL result
+ * @param int $n
+ * @return string
+ */
+ abstract function fieldName( $res, $n );
+
+ /**
+ * Get the inserted value of an auto-increment row
+ *
+ * The value inserted should be fetched from nextSequenceValue()
+ *
+ * Example:
+ * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
+ * $dbw->insert( 'page', array( 'page_id' => $id ) );
+ * $id = $dbw->insertId();
+ *
+ * @return int
+ */
+ abstract function insertId();
+
+ /**
+ * Change the position of the cursor in a result object
+ * @see http://www.php.net/mysql_data_seek
+ *
+ * @param mixed $res A SQL result
+ * @param int $row
+ */
+ abstract function dataSeek( $res, $row );
+
+ /**
+ * Get the last error number
+ * @see http://www.php.net/mysql_errno
+ *
+ * @return int
+ */
+ abstract function lastErrno();
+
+ /**
+ * Get a description of the last error
+ * @see http://www.php.net/mysql_error
+ *
+ * @return string
+ */
+ abstract function lastError();
+
+ /**
+ * mysql_fetch_field() wrapper
+ * Returns false if the field doesn't exist
+ *
+ * @param string $table Table name
+ * @param string $field Field name
+ *
+ * @return Field
+ */
+ abstract function fieldInfo( $table, $field );
+
+ /**
+ * Get information about an index into an object
+ * @param string $table Table name
+ * @param string $index Index name
+ * @param string $fname Calling function name
+ * @return mixed Database-specific index description class or false if the index does not exist
+ */
+ abstract function indexInfo( $table, $index, $fname = __METHOD__ );
+
+ /**
+ * Get the number of rows affected by the last write query
+ * @see http://www.php.net/mysql_affected_rows
+ *
+ * @return int
+ */
+ abstract function affectedRows();
+
+ /**
+ * Wrapper for addslashes()
+ *
+ * @param string $s String to be slashed.
+ * @return string Slashed string.
+ */
+ abstract function strencode( $s );
+
+ /**
+ * Returns a wikitext link to the DB's website, e.g.,
+ * return "[http://www.mysql.com/ MySQL]";
+ * Should at least contain plain text, if for some reason
+ * your database has no website.
+ *
+ * @return string Wikitext of a link to the server software's web site
+ */
+ abstract function getSoftwareLink();
+
+ /**
+ * A string describing the current software version, like from
+ * mysql_get_server_info().
+ *
+ * @return string Version information from the database server.
+ */
+ abstract function getServerVersion();
/**
* Constructor.
global $wgUser, $wgDebugDBTransactions, $wgDebugDumpSqlLength;
$this->mLastQuery = $sql;
- if ( $this->isWriteQuery( $sql ) ) {
+
+ $isWriteQuery = $this->isWriteQuery( $sql );
+ if ( $isWriteQuery ) {
# Set a flag indicating that writes have been done
wfDebug( __METHOD__ . ': Writes done: ' . DatabaseBase::generalizeSQL( $sql ) . "\n" );
$this->mDoneWrites = microtime( true );
}
# Keep track of whether the transaction has write queries pending
- if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $this->isWriteQuery( $sql ) ) {
+ if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $isWriteQuery ) {
$this->mTrxDoneWrites = true;
Profiler::instance()->getTransactionProfiler()->transactionWritingIn(
$this->mServer, $this->mDBname, $this->mTrxShortId );
if ( $queryProf != '' ) {
$queryStartTime = microtime( true );
$queryProfile = new ScopedCallback(
- function() use ( $queryStartTime, $queryProf, $isMaster ) {
+ function () use ( $queryStartTime, $queryProf, $isMaster ) {
$trxProfiler = Profiler::instance()->getTransactionProfiler();
$trxProfiler->recordQueryCompletion( $queryProf, $queryStartTime, $isMaster );
}
if ( false === $ret ) {
$this->reportQueryError( $this->lastError(), $this->lastErrno(), $sql, $fname, $tempIgnore );
+ } else {
+ $n = $this->affectedRows();
+ if ( $isWriteQuery && $n > self::LOG_WRITE_THRESHOLD && PHP_SAPI !== 'cli' ) {
+ wfDebugLog( 'DBPerformance',
+ "Query affected $n rows:\n$sql\n" . wfBacktrace( true ) );
+ }
}
- return $this->resultObject( $ret );
+ $res = $this->resultObject( $ret );
+
+ // Destroy profile sections in the opposite order to their creation
+ $queryProfSection = false;
+ $totalProfSection = false;
+
+ return $res;
}
/**
class MySQLMasterPos implements DBMasterPos {
/** @var string */
public $file;
-
- /** @var int Timestamp */
+ /** @var int Position */
public $pos;
+ /** @var float UNIX timestamp */
+ public $asOfTime = 0.0;
function __construct( $file, $pos ) {
$this->file = $file;
$this->pos = $pos;
+ $this->asOfTime = microtime( true );
}
function __toString() {
return ( $thisPos && $thatPos && $thisPos >= $thatPos );
}
+
+ function asOfTime() {
+ return $this->asOfTime;
+ }
}
}
$p['tablePrefix'] = strtoupper( $p['tablePrefix'] );
parent::__construct( $p );
- wfRunHooks( 'DatabaseOraclePostInit', array( $this ) );
+ Hooks::run( 'DatabaseOraclePostInit', array( $this ) );
}
function __destruct() {
* The implementation details of this opaque type are up to the database subclass.
*/
interface DBMasterPos {
+ /**
+ * @return float UNIX timestamp
+ */
+ public function asOfTime();
}
*
* @return LBFactory
*/
- public static function &singleton() {
+ public static function singleton() {
global $wgLBFactoryConf;
if ( is_null( self::$instance ) ) {
* Construct a factory based on a configuration array (typically from $wgLBFactoryConf)
* @param array $conf
*/
- public abstract function __construct( array $conf );
+ abstract public function __construct( array $conf );
/**
* Create a new load balancer object. The resulting object will be untracked,
* @param bool|string $wiki Wiki ID, or false for the current wiki
* @return LoadBalancer
*/
- public abstract function newMainLB( $wiki = false );
+ abstract public function newMainLB( $wiki = false );
/**
* Get a cached (tracked) load balancer object.
* @param bool|string $wiki Wiki ID, or false for the current wiki
* @return LoadBalancer
*/
- public abstract function getMainLB( $wiki = false );
+ abstract public function getMainLB( $wiki = false );
/**
* Create a new load balancer for external storage. The resulting object will be
* @param bool|string $wiki Wiki ID, or false for the current wiki
* @return LoadBalancer
*/
- protected abstract function newExternalLB( $cluster, $wiki = false );
+ abstract protected function newExternalLB( $cluster, $wiki = false );
/**
* Get a cached (tracked) load balancer for external storage
* @param bool|string $wiki Wiki ID, or false for the current wiki
* @return LoadBalancer
*/
- public abstract function &getExternalLB( $cluster, $wiki = false );
+ abstract public function &getExternalLB( $cluster, $wiki = false );
/**
* Execute a function for each tracked load balancer
* @param callable $callback
* @param array $params
*/
- public abstract function forEachLB( $callback, array $params = array() );
+ abstract public function forEachLB( $callback, array $params = array() );
/**
* Prepare all tracked load balancers for shutdown
* @param array $args
*/
private function forEachLBCallMethod( $methodName, array $args = array() ) {
- $this->forEachLB( function( LoadBalancer $loadBalancer, $methodName, array $args ) {
+ $this->forEachLB( function ( LoadBalancer $loadBalancer, $methodName, array $args ) {
call_user_func_array( array( $loadBalancer, $methodName ), $args );
}, array( $methodName, $args ) );
}
/**
* @param array $loads
* @param bool|string $wiki Wiki to get non-lagged for
+ * @param float $maxLag Restrict the maximum allowed lag to this many seconds
* @return bool|int|string
*/
- private function getRandomNonLagged( array $loads, $wiki = false ) {
- # Unset excessively lagged servers
+ private function getRandomNonLagged( array $loads, $wiki = false, $maxLag = INF ) {
$lags = $this->getLagTimes( $wiki );
+
+ # Unset excessively lagged servers
foreach ( $lags as $i => $lag ) {
if ( $i != 0 ) {
+ $maxServerLag = $maxLag;
+ if ( isset( $this->mServers[$i]['max lag'] ) ) {
+ $maxServerLag = min( $maxServerLag, $this->mServers[$i]['max lag'] );
+ }
if ( $lag === false ) {
wfDebugLog( 'replication', "Server #$i is not replicating" );
unset( $loads[$i] );
- } elseif ( isset( $this->mServers[$i]['max lag'] ) && $lag > $this->mServers[$i]['max lag'] ) {
+ } elseif ( $lag > $maxServerLag ) {
wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
unset( $loads[$i] );
}
if ( $wgReadOnly || $this->mAllowLagged || $laggedSlaveMode ) {
$i = ArrayUtils::pickRandom( $currentLoads );
} else {
- $i = $this->getRandomNonLagged( $currentLoads, $wiki );
+ $i = false;
+ if ( $this->mWaitForPos && $this->mWaitForPos->asOfTime() ) {
+ # ChronologyProtecter causes mWaitForPos to be set via sessions.
+ # This triggers doWait() after connect, so it's especially good to
+ # avoid lagged servers so as to avoid just blocking in that method.
+ $ago = microtime( true ) - $this->mWaitForPos->asOfTime();
+ # Aim for <= 1 second of waiting (being too picky can backfire)
+ $i = $this->getRandomNonLagged( $currentLoads, $wiki, $ago + 1 );
+ }
+ if ( $i === false ) {
+ # Any server with less lag than it's 'max lag' param is preferable
+ $i = $this->getRandomNonLagged( $currentLoads, $wiki );
+ }
if ( $i === false && count( $currentLoads ) != 0 ) {
# All slaves lagged. Switch to read-only mode
wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" );
* @throws MWException
* @return DatabaseBase
*/
- public function &getConnection( $i, $groups = array(), $wiki = false ) {
+ public function getConnection( $i, $groups = array(), $wiki = false ) {
wfProfileIn( __METHOD__ );
if ( $i === null || $i === false ) {
$wiki = false;
}
- # Query groups
+ $groups = ( $groups === false || $groups === array() )
+ ? array( false ) // check one "group": the generic pool
+ : (array)$groups;
+
if ( $i == DB_MASTER ) {
$i = $this->getWriterIndex();
- } elseif ( !is_array( $groups ) ) {
- $groupIndex = $this->getReaderIndex( $groups, $wiki );
- if ( $groupIndex !== false ) {
- $serverName = $this->getServerName( $groupIndex );
- wfDebug( __METHOD__ . ": using server $serverName for group $groups\n" );
- $i = $groupIndex;
- }
} else {
+ # Try to find an available server in any the query groups (in order)
foreach ( $groups as $group ) {
$groupIndex = $this->getReaderIndex( $group, $wiki );
if ( $groupIndex !== false ) {
# Operation-based index
if ( $i == DB_SLAVE ) {
$this->mLastError = 'Unknown error'; // reset error string
- $i = $this->getReaderIndex( false, $wiki );
+ # Try the general server pool if $groups are unavailable.
+ $i = in_array( false, $groups, true )
+ ? false // don't bother with this if that is what was tried above
+ : $this->getReaderIndex( false, $wiki );
# Couldn't find a working server in getReaderIndex()?
if ( $i === false ) {
$this->mLastError = 'No working slave server: ' . $this->mLastError;
if ( !isset( $this->singletons['handlers'][$name] ) ) {
$spec = $this->config['handlers'][$name];
$handler = ObjectFactory::getObjectFromSpec( $spec );
- $handler->setFormatter( $this->getFormatter( $spec['formatter'] ) );
+ if ( isset( $spec['formatter'] ) ) {
+ $handler->setFormatter(
+ $this->getFormatter( $spec['formatter'] )
+ );
+ }
$this->singletons['handlers'][$name] = $handler;
}
return $this->singletons['handlers'][$name];
$this->mRecursive = $recursive;
- wfRunHooks( 'LinksUpdateConstructed', array( &$this ) );
+ Hooks::run( 'LinksUpdateConstructed', array( &$this ) );
}
/**
* Update link tables with outgoing links from an updated article
*/
public function doUpdate() {
- wfRunHooks( 'LinksUpdate', array( &$this ) );
+ Hooks::run( 'LinksUpdate', array( &$this ) );
$this->doIncrementalUpdate();
- wfRunHooks( 'LinksUpdateComplete', array( &$this ) );
+ Hooks::run( 'LinksUpdateComplete', array( &$this ) );
}
protected function doIncrementalUpdate() {
}
if ( count( $insertions ) ) {
$this->mDb->insert( $table, $insertions, __METHOD__, 'IGNORE' );
- wfRunHooks( 'LinksUpdateAfterInsert', array( $this, $table, $insertions ) );
+ Hooks::run( 'LinksUpdateAfterInsert', array( $this, $table, $insertions ) );
}
}
wfProfileIn( __METHOD__ );
- $page = WikiPage::newFromId( $this->id, WikiPage::READ_LATEST );
+ $page = WikiPage::newFromID( $this->id, WikiPage::READ_LATEST );
foreach ( SearchEngine::getSearchTypes() as $type ) {
$search = SearchEngine::create( $type );
$samePage = true;
$oldHeader = '';
} else {
- wfRunHooks( 'DiffViewHeader', array( $this, $this->mOldRev, $this->mNewRev ) );
+ Hooks::run( 'DiffViewHeader', array( $this, $this->mOldRev, $this->mNewRev ) );
if ( $this->mNewPage->equals( $this->mOldPage ) ) {
$out->setPageTitle( $this->msg( 'difference-title', $this->mNewPage->getPrefixedText() ) );
$rdel = $this->revisionDeleteLink( $this->mNewRev );
# Allow extensions to define their own revision tools
- wfRunHooks( 'DiffRevisionTools', array( $this->mNewRev, &$revisionTools, $this->mOldRev ) );
+ Hooks::run( 'DiffRevisionTools', array( $this->mNewRev, &$revisionTools, $this->mOldRev ) );
$formattedRevisionTools = array();
// Put each one in parentheses (poor man's button)
foreach ( $revisionTools as $key => $tool ) {
<h2 class='diff-currentversion-title'>{$revHeader}</h2>\n" );
# Page content may be handled by a hooked call instead...
# @codingStandardsIgnoreStart Ignoring long lines.
- if ( wfRunHooks( 'ArticleContentOnDiff', array( $this, $out ) ) ) {
+ if ( Hooks::run( 'ArticleContentOnDiff', array( $this, $out ) ) ) {
$this->loadNewText();
$out->setRevisionId( $this->mNewid );
$out->setRevisionTimestamp( $this->mNewRev->getTimestamp() );
$out->addParserOutputContent( $po );
}
}
- } elseif ( !wfRunHooks( 'ArticleContentViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+ } elseif ( !Hooks::run( 'ArticleContentViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
// Handled by extension
} elseif ( !ContentHandler::runLegacyHooks( 'ArticleViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
// NOTE: deprecated hook, B/C only
$difftext = $this->generateContentDiffBody( $this->mOldContent, $this->mNewContent );
// Save to cache for 7 days
- if ( !wfRunHooks( 'AbortDiffCache', array( &$this ) ) ) {
+ if ( !Hooks::run( 'AbortDiffCache', array( &$this ) ) ) {
wfIncrStats( 'diff_uncacheable' );
} elseif ( $key !== false && $difftext !== false ) {
wfIncrStats( 'diff_cache_miss' );
$this->mNewid = 0;
}
- wfRunHooks(
+ Hooks::run(
'NewDifferenceEngine',
array( $this->getTitle(), &$this->mOldid, &$this->mNewid, $old, $new )
);
*/
class MWExceptionHandler {
+ protected static $reservedMemory;
+ protected static $fatalErrorTypes = array(
+ E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR,
+ /* HHVM's FATAL_ERROR level */ 16777217,
+ );
+
/**
* Install handlers with PHP.
*/
public static function installHandler() {
set_exception_handler( array( 'MWExceptionHandler', 'handleException' ) );
set_error_handler( array( 'MWExceptionHandler', 'handleError' ) );
+
+ // Reserve 16k of memory so we can report OOM fatals
+ self::$reservedMemory = str_repeat( ' ', 16384 );
+ register_shutdown_function(
+ array( 'MWExceptionHandler', 'handleFatalError' )
+ );
}
/**
case E_USER_DEPRECATED:
$levelName = 'Deprecated';
break;
+ case /* HHVM's FATAL_ERROR */ 16777217:
+ $levelName = 'Fatal';
+ break;
default:
$levelName = 'Unknown error';
break;
return false;
}
+
+ /**
+ * Look for a fatal error as the cause of the request termination and log
+ * as an exception.
+ *
+ * Special handling is included for missing class errors as they may
+ * indicate that the user needs to install 3rd-party libraries via
+ * Composer or other means.
+ *
+ * @since 1.25
+ */
+ public static function handleFatalError() {
+ self::$reservedMemory = null;
+ $lastError = error_get_last();
+
+ if ( $lastError &&
+ isset( $lastError['type'] ) &&
+ in_array( $lastError['type'], self::$fatalErrorTypes )
+ ) {
+ $msg = "Fatal Error: {$lastError['message']}";
+ // HHVM: Class undefined: foo
+ // PHP5: Class 'foo' not found
+ if ( preg_match( "/Class (undefined: \w+|'\w+' not found)/",
+ $lastError['message']
+ ) ) {
+ $msg = <<<TXT
+{$msg}
+
+MediaWiki or an installed extension requires this class but it is not embedded directly in MediaWiki's git repository and must be installed separately by the end user.
+
+Please see <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">mediawiki.org</a> for help on installing the required components.
+TXT;
+ }
+ $e = new ErrorException( $msg, 0, $lastError['type'] );
+ self::logError( $e );
+ }
+ }
+
/**
* Generate a string representation of an exception's stack trace
*
wfDebugLog( 'FSFileBackend', __METHOD__ . ": cannot create directory $dir" );
$status->fatal( 'directorycreateerror', $params['dir'] ); // fails on races
} elseif ( !is_writable( $dir ) ) {
- wfDebugLog( 'FSFileBackend', __METHOD__ . ": directory $dir is read-only" );
+ wfDebugLog( 'FSFileBackend', __METHOD__ . ": directory $dir is read-only" );
$status->fatal( 'directoryreadonlyerror', $params['dir'] );
} elseif ( !is_readable( $dir ) ) {
- wfDebugLog( 'FSFileBackend', __METHOD__ . ": directory $dir is not readable" );
+ wfDebugLog( 'FSFileBackend', __METHOD__ . ": directory $dir is not readable" );
$status->fatal( 'directorynotreadableerror', $params['dir'] );
}
$this->untrapWarnings();
/**
* Check that a set of files are consistent across all internal backends
- * and re-synchronize those files againt the "multi master" if needed.
+ * and re-synchronize those files against the "multi master" if needed.
*
* @param array $paths List of storage paths
* @return Status
/**
* Construct a new instance from configuration.
*
- * @param array $config Paramaters include:
+ * @param array $config Parameters include:
* - dbServers : Associative array of DB names to server configuration.
* Configuration is an associative array that includes:
* - host : DB server name
/**
* Construct a new instance from configuration
*
- * @param array $config Paramaters include:
+ * @param array $config Parameters include:
* - domain : Domain (usually wiki ID) that all resources are relative to [optional]
* - lockTTL : Age (in seconds) at which resource locks should expire.
* This only applies if locks are not tied to a connection/process.
/**
* Construct a new instance from configuration.
*
- * @param array $config Paramaters include:
+ * @param array $config Parameters include:
* - lockServers : Associative array of server names to "<IP>:<port>" strings.
* - srvsByBucket : Array of 1-16 consecutive integer keys, starting from 0,
* each having an odd-numbered list of server names (peers) as values.
/** @var Title */
protected $redirectTitle;
- /** @var bool Wether the output of transform() for this file is likely to be valid. */
+ /** @var bool Whether the output of transform() for this file is likely to be valid. */
protected $canRender;
- /** @var bool Wether this media file is in a format that is unlikely to
+ /** @var bool Whether this media file is in a format that is unlikely to
* contain viruses or malicious content
*/
protected $isSafeFile;
sort( $sortedBuckets );
foreach ( $sortedBuckets as $bucket ) {
- if ( $bucket > $imageWidth ) {
+ if ( $bucket >= $imageWidth ) {
return false;
}
$thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $transformParams, $flags );
}
// Give extensions a chance to do something with this thumbnail...
- wfRunHooks( 'FileTransformed', array( $this, $thumb, $tmpThumbPath, $thumbPath ) );
+ Hooks::run( 'FileTransformed', array( $this, $thumb, $tmpThumbPath, $thumbPath ) );
}
// Purge. Useful in the event of Core -> Squid connection failure or squid
/**
* Get the path of the file relative to the public zone root.
- * This function is overriden in OldLocalFile to be like getArchiveRel().
+ * This function is overridden in OldLocalFile to be like getArchiveRel().
*
* @return string
*/
/**
* Get urlencoded path of the file relative to the public zone root.
- * This function is overriden in OldLocalFile to be like getArchiveUrl().
+ * This function is overridden in OldLocalFile to be like getArchiveUrl().
*
* @return string
*/
/** getURL inherited */
/** getViewURL inherited */
/** getPath inherited */
- /** isVisible inhereted */
+ /** isVisible inherited */
/**
* @return bool
$files = $this->getThumbnails( $archiveName );
// Purge any custom thumbnail caches
- wfRunHooks( 'LocalFilePurgeThumbnails', array( $this, $archiveName ) );
+ Hooks::run( 'LocalFilePurgeThumbnails', array( $this, $archiveName ) );
$dir = array_shift( $files );
$this->purgeThumbList( $dir, $files );
}
// Purge any custom thumbnail caches
- wfRunHooks( 'LocalFilePurgeThumbnails', array( $this, false ) );
+ Hooks::run( 'LocalFilePurgeThumbnails', array( $this, false ) );
$dir = array_shift( $files );
$this->purgeThumbList( $dir, $files );
$opts['ORDER BY'] = "oi_timestamp $order";
$opts['USE INDEX'] = array( 'oldimage' => 'oi_name_timestamp' );
- wfRunHooks( 'LocalFile::getHistory', array( &$this, &$tables, &$fields,
+ Hooks::run( 'LocalFile::getHistory', array( &$this, &$tables, &$fields,
&$conds, &$opts, &$join_conds ) );
$res = $dbr->select( $tables, $fields, $conds, __METHOD__, $opts, $join_conds );
if ( !is_null( $nullRevision ) ) {
$nullRevision->insertOn( $dbw );
- wfRunHooks( 'NewRevisionFromEditComplete', array( $wikiPage, $nullRevision, $latest, $user ) );
+ Hooks::run( 'NewRevisionFromEditComplete', array( $wikiPage, $nullRevision, $latest, $user ) );
$wikiPage->updateRevisionOn( $dbw, $nullRevision );
}
}
# Hooks, hooks, the magic of hooks...
wfProfileIn( __METHOD__ . '-hooks' );
- wfRunHooks( 'FileUpload', array( $this, $reupload, $descTitle->exists() ) );
+ Hooks::run( 'FileUpload', array( $this, $reupload, $descTitle->exists() ) );
wfProfileOut( __METHOD__ . '-hooks' );
# Invalidate cache for all pages using this file
/** @var array Items to be processed in the deletion batch */
private $deletionBatch;
- /** @var bool Wether to suppress all suppressable fields when deleting */
+ /** @var bool Whether to suppress all suppressable fields when deleting */
private $suppress;
/** @var FileRepoStatus */
wfProfileIn( __METHOD__ );
$this->file->lock();
- // Leave private files alone
- $privateFiles = array();
- list( $oldRels, ) = $this->getOldRels();
- $dbw = $this->file->repo->getMasterDB();
-
- if ( !empty( $oldRels ) ) {
- $res = $dbw->select( 'oldimage',
- array( 'oi_archive_name' ),
- array( 'oi_name' => $this->file->getName(),
- 'oi_archive_name' => array_keys( $oldRels ),
- $dbw->bitAnd( 'oi_deleted', File::DELETED_FILE ) => File::DELETED_FILE ),
- __METHOD__ );
- foreach ( $res as $row ) {
- $privateFiles[$row->oi_archive_name] = 1;
- }
- }
// Prepare deletion batch
$hashes = $this->getHashes();
$this->deletionBatch = array();
$dotExt = $ext === '' ? '' : ".$ext";
foreach ( $this->srcRels as $name => $srcRel ) {
- // Skip files that have no hash (missing source).
- // Keep private files where they are.
- if ( isset( $hashes[$name] ) && !array_key_exists( $name, $privateFiles ) ) {
+ // Skip files that have no hash (e.g. missing DB record, or sha1 field and file source)
+ if ( isset( $hashes[$name] ) ) {
$hash = $hashes[$name];
$key = $hash . $dotExt;
$dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key;
$this->doDBInserts();
// Removes non-existent file from the batch, so we don't get errors.
+ // This also handles files in the 'deleted' zone deleted via revision deletion.
$checkStatus = $this->removeNonexistentFiles( $this->deletionBatch );
if ( !$checkStatus->isGood() ) {
$this->status->merge( $checkStatus );
/** @var bool Add all revisions of the file */
private $all;
- /** @var bool Wether to remove all settings for suppressed fields */
+ /** @var bool Whether to remove all settings for suppressed fields */
private $unsuppress = false;
/**
'packed-overlay' => 'PackedOverlayImageGallery',
);
// Allow extensions to make a new gallery format.
- wfRunHooks( 'GalleryGetModes', self::$modeMapping );
+ Hooks::run( 'GalleryGetModes', self::$modeMapping );
}
}
if ( $this->mParser instanceof Parser ) {
# Give extensions a chance to select the file revision for us
$options = array();
- wfRunHooks( 'BeforeParserFetchFileAndTitle',
+ Hooks::run( 'BeforeParserFetchFileAndTitle',
array( $this->mParser, $nt, &$options, &$descQuery ) );
# Fetch and register the file (file title may be different via hooks)
list( $img, $nt ) = $this->mParser->fetchFileAndTitle( $nt, $options );
$this->maintenance->setDB( $db );
$this->initOldGlobals();
$this->loadExtensions();
- wfRunHooks( 'LoadExtensionSchemaUpdates', array( $this ) );
+ Hooks::run( 'LoadExtensionSchemaUpdates', array( $this ) );
}
/**
$out = $wgProfiler['output'];
if ( $out === 'db' ) {
$profileToDb = true;
- } elseif( is_array( $out ) && in_array( 'db', $out ) ) {
+ } elseif ( is_array( $out ) && in_array( 'db', $out ) ) {
$profileToDb = true;
}
}
</div>
<?php
$message = wfMessage( 'config-sidebar' )->plain();
- foreach( explode( '----', $message ) as $section ) {
+ foreach ( explode( '----', $message ) as $section ) {
echo '<div class="portal"><div class="body">';
echo $this->parent->parse( $section, true );
echo '</div></div>';
"config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] е инсталиран",
"config-no-cache": "'''Предупреждение:''' Не бяха открити [http://www.php.net/apc APC] [http://xcache.lighttpd.net/ XCache] или [http://www.iis.net/download/WinCacheForPhp WinCache].\nОбектното кеширане не е включено.",
"config-diff3-bad": "GNU diff3 не беше намерен.",
+ "config-git-bad": "Не е намерен софтуер за контрол на версиите Git.",
"config-imagemagick": "Открит е ImageMagick: <code>$1</code>.\nПреоразмеряването на картинки ще бъде включено ако качването на файлове бъде разрешено.",
"config-gd": "Открита е вградена графичната библиотека GD.\nАко качването на файлове бъде включено, ще бъде включена възможността за преоразмеряване на картинки.",
"config-no-scaling": "Не са открити библиотеките GD или ImageMagick.\nПреоразмеряването на картинки ще бъде изключено.",
"config-extensions": "Разширения",
"config-extensions-help": "Разширенията от списъка по-горе бяха открити в директорията <code>./extensions</code>.\n\nВъзможно е те да изискват допълнително конфигуриране, но сега могат да бъдат включени.",
"config-skins": "Облици",
+ "config-skins-use-as-default": "Използване на този облик по подразбиране",
"config-install-alreadydone": "'''Предупреждение:''' Изглежда вече сте инсталирали МедияУики и се опитвате да го инсталирате отново.\nПродължете към следващата страница.",
"config-install-begin": "Инсталацията на МедияУики ще започне след натискане на бутона „{{int:config-continue}}“.\nВ случай, че е необходимо да се направят промени, използва се бутона „{{int:config-back}}“.",
"config-install-step-done": "готово",
"Bellayet",
"Wikitanvir",
"Aftab1995",
- "Tauhid16"
+ "Tauhid16",
+ "Aftabuzzaman"
]
},
"config-desc": "মিডিয়াউইকির জন্য ইন্সটলার",
"config-db-name": "উপাত্তসংগ্রহশালা নামঃ",
"config-db-install-account": "ইন্সটলের জন্য ব্যবহারকারী অ্যাকাউন্ট",
"config-db-username": "ডেটাবেজের ব্যবহারকারী নাম:",
- "config-db-password": "ডà§\87à¦\9fাবà§\87à¦\9cà§\87র শবà§\8dদà¦\9aাবি:",
+ "config-db-password": "ডà§\87à¦\9fাবà§\87à¦\9cà§\87র পাসà¦\93য়ারà§\8dড:",
"config-db-username-empty": "আপনাকে অবশ্যই \"{{int:config-db-username}}\"-এর জন্য একটি মান প্রবেশ করাতে হবে।",
"config-db-wiki-account": "সাধারণ অভিযানের জন্য ব্যবহারকারী একাউন্ট",
"config-db-prefix": "উপাত্তশালা ছক প্রিফিক্স:",
"config-missing-db-name": "আপনাকে অবশ্যই \"{{int:config-db-name}}\"-এর জন্য একটি মান প্রবেশ করাতে হবে।",
"config-missing-db-host": "আপনাকে অবশ্যই \"{{int:config-db-host}}\"-এর জন্য একটি মান প্রবেশ করাতে হবে।",
"config-missing-db-server-oracle": "আপনাকে অবশ্যই \"{{int:config-db-host-oracle}}\"-এর জন্য একটি মান প্রবেশ করাতে হবে।",
- "config-connection-error": "$1।\n\n\nদয়া à¦\95রà§\87 পà§\8dরসà§\8dতাবà¦\95ারà§\80, বà§\8dযবহারà¦\95ারà§\80 নাম à¦\93 শবà§\8dদà¦\9aাবি দেখুন এবং পুনরায় চেষ্টা করুন।",
+ "config-connection-error": "$1।\n\n\nদয়া à¦\95রà§\87 পà§\8dরসà§\8dতাবà¦\95ারà§\80, বà§\8dযবহারà¦\95ারà§\80 নাম à¦\93 পাসà¦\93য়ারà§\8dড দেখুন এবং পুনরায় চেষ্টা করুন।",
"config-mysql-engine": "সংরক্ষণ ইঞ্জিন:",
"config-mysql-innodb": "ইনোডিবি",
"config-mysql-myisam": "মাইআইএসএএম",
"config-ns-other-default": "মাইউইকি",
"config-admin-box": "প্রশাসক অ্যাকাউন্ট",
"config-admin-name": "আপনার ব্যবহারকারী নাম:",
- "config-admin-password": "শবà§\8dদà¦\9aাবি:",
- "config-admin-password-confirm": "শবà§\8dদà¦\9aাবি আবারও প্রবেশ করান:",
+ "config-admin-password": "পাসà¦\93য়ারà§\8dড:",
+ "config-admin-password-confirm": "পাসà¦\93য়ারà§\8dড আবারও প্রবেশ করান:",
"config-admin-name-blank": "একটি প্রশাসক ব্যবহারকারী নাম প্রবেশ করান",
"config-admin-password-blank": "প্রশাসক অ্যাকাউন্টের জন্য পাসওয়ার্ড প্রবেশ করান।",
- "config-admin-password-mismatch": "à¦\86পনি যà§\87 দà§\81à¦\9fি শবà§\8dদà¦\9aাবি দিয়েছেন তারা পরস্পর মেলেনি।",
+ "config-admin-password-mismatch": "à¦\86পনি যà§\87 দà§\81à¦\9fি পাসà¦\93য়ারà§\8dড দিয়েছেন তারা পরস্পর মেলেনি।",
"config-admin-email": "ইমেইল ঠিকানা:",
"config-optional-continue": "আরও প্রশ্ন জিজ্ঞেস করুন।",
"config-optional-skip": "আমি ইতিমধ্যেই বিরক্ত হয়ে গেছি, উইকিটি ইন্সটল করো।",
"config-mssql-sqlauth": "Autenticació de l’SQL Server",
"config-mssql-windowsauth": "Autenticació del Windows",
"config-site-name": "Nom del wiki:",
+ "config-site-name-help": "Això apareixerà en la barra de títol del navegador i en altres llocs diferents.",
"config-site-name-blank": "Introduïu un nom per al lloc.",
"config-project-namespace": "Espai de noms del projecte:",
"config-ns-generic": "Projecte",
"config-admin-password-blank": "Introduïu una contrasenya per al compte d'administrador.",
"config-admin-password-mismatch": "Les dues contrasenyes que heu introduït no coincideixen.",
"config-admin-email": "Adreça electrònica:",
+ "config-admin-error-user": "S'ha produït un error intern en crear un administrador amb el nom «<nowiki>$1</nowiki>».",
+ "config-admin-error-password": "S'ha produït un error intern en definir una contrasenya per a l'administrador «<nowiki>$1</nowiki>»: <pre>$2</pre>",
"config-admin-error-bademail": "Heu introduït una adreça electrònica no vàlida.",
"config-almost-done": "Gairebé ja heu acabat!\nPodeu ometre el que queda de la configuració i procedir amb la instal·lació del wiki.",
"config-optional-continue": "Fes-me més preguntes.",
"config-cache-help": "L'encauament d'objectes s'utilitza per a millorar la rapidesa del MediaWiki afegint a la memòria cau les dades que s'utilitzen de forma freqüent. És recomanable que els llocs web mitjans o grans ho habilitin. També els llocs web petits en veuran els beneficis.",
"config-cache-none": "Sense encauament (no se suprimeix cap funcionalitat, però la velocitat pot veure's afectada en els llocs wiki més grans)",
"config-memcached-servers": "Servidors de Memcache:",
+ "config-memcache-badip": "Heu introduït una adreça IP no vàlida per al Memcached: $1.",
+ "config-memcache-noport": "No heu especificat un port per utilitzar el servidor Memcached: $1.\nSi no coneixeu el port, per defecte és 11211.",
"config-extensions": "Extensions",
"config-skins": "Aparences",
+ "config-skins-use-as-default": "Utilitza aquest tema per defecte",
+ "config-skins-missing": "No s'ha trobat cap tema; MediaWiki utilitzarà el tema per defecte fins que hi instal·leu alguns adequats.",
+ "config-skins-must-enable-some": "Heu de triar com a mínim un tema per habilitar.",
+ "config-skins-must-enable-default": "Cal habilitar el tema triat per defecte.",
"config-install-step-done": "fet",
"config-install-step-failed": "ha fallat",
"config-install-extensions": "S'estan incloent les extensions",
"config-install-pg-schema-not-exist": "No existeix un esquema PostgreSQL.",
"config-install-pg-schema-failed": "La creació de les taules ha fallat.\nAssegureu-vos que l'usuari «$1» pot escriure a l'esquema «$2».",
"config-install-pg-commit": "S'estan trametent els canvis",
+ "config-pg-no-create-privs": "El compte que heu especificat per a la instal·lació no té suficients permisos per crear un compte.",
"config-install-user": "S'està creant l'usuari de la base de dades",
"config-install-user-alreadyexists": "L'usuari «$1» ja existeix",
"config-install-user-create-failed": "La creació de l'usuari «$1» ha fallat: $2",
"config-install-interwiki-exists": "'''Avís:''' La taula d'interwiki sembla que ja té entrades. S'omet la llista per defecte.",
"config-install-stats": "S'estan inicialitzant les estadístiques",
"config-install-keys": "S'estan generant les claus secretes",
+ "config-install-updates": "Evita que s'executin actualitzacions no necessàries",
"config-install-sysop": "S'està creant un compte d'usuari d'administrador",
"config-install-subscribe-fail": "No s'ha pogut subscriure a mediawiki-announce: $1",
"config-install-subscribe-notpossible": "El cURL no està instal·lat i <code>allow_url_fopen</code> no està disponible.",
"config-db-install-account": "Benutzerkonto für die Installation",
"config-db-username": "Name des Datenbankbenutzers:",
"config-db-password": "Passwort des Datenbankbenutzers:",
- "config-db-password-empty": "Bitte ein Passwort für den neuen Datenbankbenutzer angeben: $1\nObzwar es möglich ist, Datenbankbenutzer ohne Passwort anzulegen, so ist dies aber nicht sicher.",
+ "config-db-password-empty": "Bitte ein Passwort für den neuen Datenbankbenutzer angeben: $1\nObwohl es möglich ist, Datenbankbenutzer ohne Passwort anzulegen, so ist dies nicht sicher.",
"config-db-username-empty": "Du musst einen Wert für „{{int:config-db-username}}“ eingeben",
"config-db-install-username": "Den Benutzernamen angeben, der für die Verbindung mit der Datenbank während des Installationsvorgangs genutzt werden soll. Es handelt sich dabei nicht um den Benutzernamen für das MediaWiki-Konto, sondern um den Benutzernamen der vorgesehenen Datenbank.",
"config-db-install-password": "Das Passwort angeben, das für die Verbindung mit der Datenbank während des Installationsvorgangs genutzt werden soll. Es handelt sich dabei nicht um das Passwort für das MediaWiki-Konto, sondern um das Passwort der vorgesehenen Datenbank.",
"Lliehu",
"Syreeni",
"Stryn",
- "SMAUG"
+ "SMAUG",
+ "SuperPete"
]
},
"config-desc": "MediaWiki-asennin",
"config-apc": "[http://www.php.net/apc APC] on asennettu.",
"config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] on asennettu",
"config-diff3-bad": "GNU diff3:a ei löytynyt.",
+ "config-git": "Löydetty Git versionhallintaohjelmisto: <code>$1</code>",
+ "config-git-bad": "Git versionhallintaohjelmistoa ei löydy.",
"config-imagemagick": "Löydettiin ImageMagick: <code>$1</code>.\nKuvien esikatselukuvat otetaan samalla käyttöön jos otetaan tiedostojen tallennus.",
+ "config-gd": "Löydettiin sisäänrakennettu GD-grafiikkakirjasto.\nKuvista luodaan esikatseluversiot automaattisesti, jos otat käyttöön tiedostojen lähettämisen.",
+ "config-no-scaling": "GD-kirjastoa tai ImageMagick-ohjelmaa ei löydy. \nKuvista ei luoda esikatseluversioita.",
+ "config-no-uri": "Virhe: Tämänhetkistä URIa ei tunnisteta. Asennus keskeytetään.",
+ "config-no-cli-uri": "<strong>Varoitus:</strong> <code>--scriptpath</code> määrittämättä, käytetään oletusta: <code>$1</code>",
"config-using-server": "Palvelimen nimenä käytetään \"<nowiki>$1</nowiki>\".",
"config-using-uri": "Palvelinen URL-osoitteena käytetään \"<nowiki>$1$2</nowiki>\".",
+ "config-uploads-not-safe": "<strong>Varoitus:</strong> Tiedostojen lähetyshakemistoa <code>$1</code> ei ole suojattu haitalliselta koodilta. MediaWiki tarkistaa kaikki lähetetyt tiedostot, mutta suosittelemme toimimaan ohjeen [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security close this security vulnerability] mukaan ennen kuin tiedostojen lähetys otetaan käyttöön.",
+ "config-no-cli-uploads-check": "<strong>Varoitus:</strong> Tiedostojen lähetyshakemistoa (<code>$1</code>) ei ole tarkistettu haavoittuvuuksien varalta komentoriviasennuksen aikana.",
+ "config-brokenlibxml": "Järjestelmässäsi on käytössä PHP:n ja libxml2:n versioyhdistelmä, joka ei toimi kunnolla ja voi aiheuttaa tiedon vahingoittumista MediaWikissä ja muissa web-sovelluksissa.\nPäivitä libxml2 versioon 2.7.3 tai uudempaan ([https://bugs.php.net/bug.php?id=45996 bug filed with PHP]).\nAsennus keskeytetty.",
+ "config-suhosin-max-value-length": "Suhosin on asennettu ja se rajoittaa GET-parametrin <code>length</code> $1 tavuun.\nMediaWikin ResourceLoader-komponentti pystyy toimimaan tämän kanssa, mutta ohjelmiston suorituskyky heikkenee.\nMikäli mahdollista, aseta muuttuja <code>suhosin.get.max_value_length</code> arvoon 1024 (tai suurempaan) tiedostossa <code>php.ini</code> ja aseta myös <code>$wgResourceLoaderMaxQueryLength</code> samaksi arvoksi tiedostossa <code>LocalSettings.php</code>.",
"config-db-type": "Tietokannan tyyppi",
"config-db-host": "Tietokantapalvelin",
+ "config-db-host-help": "Jos tietokantapalvelimesi sijaitsee eri palvelimella, syötä palvelimen nimi tai ip-osoite tähän.\n\nJos käytössäsi on ulkoinen palveluntarjoaja, pitäisi palvelimen nimen löytyä yrityksen ohjesivuilta.\n\nJos asennat MediaWikiä Windows-palvelimelle ja käytät MySQL:ää ei palvelimen nimi \"localhost\" välttämättä toimi. Tässä tapauksessa koita käyttää osoitetta 127.0.0.1.\n\nJos käytät PostgreSQL:ää jätä tämä kenttä tyhjäksi.",
+ "config-db-host-oracle": "Tietokannan TNS:",
"config-db-wiki-settings": "Identifioi tämä wiki",
"config-db-name": "Tietokannan nimi",
+ "config-db-name-help": "Valitse wikiäsi kuvaava nimi.\nNimessä ei saa olla välilyöntejä.\n\nMikäli et pysty itse hallitsemaan tietokantojasi, pyydä palveluntarjoajaasi luomaan tietokanta tai tee se palveluntarjoajasi hallintapaneelissa.",
+ "config-db-name-oracle": "Tietokannan rakenne:",
"config-db-install-account": "Asennuksessa käytettävä käyttäjätili",
"config-db-username": "Tietokannan käyttäjätunnus",
"config-db-password": "Tietokannan salasana",
"config-db-password-empty": "Syötä salasana uudelle tietokannan käyttäjälle: $1.\nVaikka käyttäjä voidaan luoda ilman salasanaa, se ei ole turvallista.",
+ "config-db-username-empty": "Syötä arvo tiedolle \"{{int:config-db-username}}\".",
"config-db-install-username": "Syötä käyttäjänimi jota käytetään muodostettaessa yhteys tietokantaan asennuksen aikana.\nTämä ei ole MediaWiki tilin käyttäjänimi; tämä on tietokannan käyttäjänimi.",
"config-db-install-password": "Syötä salasana jota käytetään muodostettaessa yhteys tietokantaan asennuksen aikana.\nTämä ei ole MediaWiki tilin salasana; tämä on tietokannan salasana.",
"config-db-install-help": "Anna käyttäjätunnus ja salasana, joita käytetään asennuksen aikana.",
"config-charset-mysql4": "MySQL 4.0, taaksepäin yhteensopiva UTF-8",
"config-mysql-old": "MediaWiki tarvitsee MySQL:n version $1 tai uudemman. Nykyinen versio on $2.",
"config-db-port": "Tietokannan portti:",
+ "config-db-schema": "MediaWikin rakenne:",
+ "config-db-schema-help": "Tämä rakenne on normaalisti toimiva.\nMuuta rakennetta vain, mikäli on pakko ja tiedät, mitä teet.",
"config-pg-test-error": "Tietokantaan <strong>$1 ei voida muodostaa yhteyttä</strong>: $2",
+ "config-sqlite-dir": "SQLiten datahakemisto:",
+ "config-sqlite-dir-help": "SQLite tallentaa kaiken sisällön yhteen tiedostoon.\n\nPalvelimen pitää pystyä kirjoittamaan tietoa hakemistoon asennuksen aikana.\n\nHakemiston <strong>ei</strong> tulisi olla nähtävissä www-selaimella. Siksi hakemisto on eri kuin missä PHP-tiedostot sijaitsevat.\n\nAsennusohjelma luo <code>.htaccess</code>-tiedoston, mutta jos sen luomisessa ilmenee ongelmia joku voi päästä käsiksi tietokantaasi. \nTietokannassa on kaikki sähköpostiosoitteet, salasanat, poistetut versiot ja kaikki muu tieto, joka ei näy wikissä.\n\nSuosittelemme tallentamaan tietokannan eri hakemistoon, esimerkiksi <code>/var/lib/mediawiki/yourwiki</code>.",
"config-type-mysql": "MySQL (tai yhteensopiva)",
"config-type-postgres": "PostgreSQL",
"config-type-sqlite": "SQLite",
"config-extensions": "Laajennukset",
"config-extensions-help": "Yllä luetellut laajennukset löytyvät <code>./extensions</code> hakemistosta.\n\nNe saattavat vaatia lisäasetuksia, mutta voit ottaa ne käyttöön nyt.",
"config-skins": "Ulkoasut",
+ "config-skins-help": "Seuraavat teemat löydettiin hakemistosta <code>./skins</code>. Ota käyttöön vähintään yksi teema ja aseta se oletukseksi.",
+ "config-skins-use-as-default": "Käytä tätä teemaa oletuksena.",
+ "config-skins-missing": "Teemoja ei löytynyt; MediaWiki käyttää väliaikaista teemaa, kunnes asennat toimivia.",
"config-skins-must-enable-some": "Sinut täytyy valita ainakin yksi ulkoasu.",
+ "config-skins-must-enable-default": "Oletusteeman pitää olla käytössä.",
"config-install-alreadydone": "<strong>Varoitus:</strong> MediaWiki on jo asennettu ja yrität asentaa sitä uudestaan.\nSiirry seuraavalle sivulle.",
"config-install-begin": "Painamalla \"{{int:config-continue}}\", aloitetaan MediaWikin asentaminen. \nJos haluat vielä tehdä muutoksia, paina \"{{int:config-back}}\".",
"config-install-step-done": "valmis",
"config-install-step-failed": "epäonnistui",
"config-install-extensions": "Sisällytetään laajennukset",
"config-install-database": "Asennetaan tietokantaa",
+ "config-install-schema": "Luodaan rakennetta",
+ "config-install-pg-schema-not-exist": "PostgreSQL-rakennetta ei ole olemassa.",
+ "config-install-pg-schema-failed": "Taulun luominen epäonnistui.\nVarmista, että käyttäjätunnus \"$1\" pystyy kirjoittamaan rakenteeseen \"$2\".",
+ "config-install-pg-commit": "Muutoksia tallennetaan",
+ "config-install-pg-plpgsql": "Tarkistetaan PL/pgSQL:n kieltä.",
+ "config-pg-no-plpgsql": "PL/pgSQL-kieli pitää asentaa tietokantaan $1",
"config-pg-no-create-privs": "Määrittelemälläsi tilillä ei ole riittävästi oikeuksia luoda tiliä.",
+ "config-pg-not-in-role": "Määrittelemäsi web-käyttäjän tili on jo olemassa.\nMäärittelemälläsi käyttäjätilillä ei ole pääkäyttäjäoikeuksia eikä se toimi web-käyttäjän roolissa. Käyttäjätili ei pysty luomaan tarvittavia objekteja.\n\nMediaWiki vaatii, että web-käyttäjän pitää pystyä hallitsemaan tauluja. Anna toinen web-käyttäjätunnus tai klikkaa \"takaisin\" ja määrittele käyttäjätunnus, joka toimii asennuksessa.",
"config-install-user": "Luodaan tietokannalle käyttäjää",
"config-install-user-alreadyexists": "Käyttäjä $1 on jo olemassa",
"config-install-user-create-failed": "Käyttäjän \"$1\" luonti epäonnistui: $2",
"config-install-tables": "Luodaan tauluja",
"config-install-tables-exist": "<strong>Varoitus:</strong> MediaWiki taulut ovat jo olemassa.\nOhitetaan taulujen luonti.",
"config-install-tables-failed": "<strong>Virhe:</strong> Taulujen luominen epäonnistui seuraavaan virheen takia: $1",
+ "config-install-interwiki": "Luodaan oletustaulua interwikille",
"config-install-interwiki-list": "Tiedostoa <code>interwiki.list</code> ei voitu lukea.",
+ "config-install-interwiki-exists": "<strong>Varoitus:</strong> interwiki-taulussa on jo tietueita, ohitetaan oletuslista.",
+ "config-install-stats": "Alustetaan tilastoja",
"config-install-keys": "Muodostetaan salausavaimia",
+ "config-install-updates": "Estä tarpeettomien päivitysten asennus",
"config-install-sysop": "Luodaan ylläpitäjän tiliä",
"config-install-subscribe-fail": "Liittyminen mediawiki-announce listalle epäonnistui: $1",
+ "config-install-subscribe-notpossible": "cURL-ohjelmaa ei ole asennettu eikä <code>allow_url_fopen</code> ole saatavilla.",
"config-install-mainpage": "Luodaan etusivu oletussisällöllä",
"config-install-extension-tables": "Luodaan tauluja käyttöönotetuille laajuennuksille",
"config-install-mainpage-failed": "Etusivun lisääminen ei onnistunut: $1",
+ "config-install-done": "<strong>Onnittelut!</strong>\nMediaWiki on asennettu onnistuneesti\n\nAsennusohjelma on luonut <code>LocalSettings.php</code> -tiedoston.\nSiinä on kaikki MediaWikin asetukset.\n\nLataa tiedosto ja laita se MediaWikin asennushakemistoon (sama kuin missä on index.php). Lataamisen olisi pitänyt alkaa automaattisesti.\n\nMikäli keskeytit latauksen, käynnistä se uudestaan tästä linkistä:\n\n$3\n\n<strong>HUOM!</strong> Mikäli et nyt lataa tiedostoa, joudut aloittamaan asennuksen alusta.\n\nKun olet laittanut tiedoston oikeaan paikkaan voit <strong>[$2 mennä wikiisi]</strong>.",
"config-download-localsettings": "Lataa <code>LocalSettings.php</code>",
"config-help": "ohje",
+ "config-help-tooltip": "Klikkaa laajentaaksesi",
"config-nofile": "Tiedostoa \"$1\" ei löytynyt. Onko se poistettu?",
"config-extension-link": "Tiesitkö että wiki tukee [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions laajennuksia]?\n\nLaajennuksia voi hakea myös [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category luokittain].",
"mainpagetext": "'''MediaWiki on onnistuneesti asennettu.'''",
"config-env-good": "పర్యావరణాన్ని పరీక్షించాం.\nఇక మీరు MediaWiki ని స్థాపించుకోవచ్చు.",
"config-env-bad": "పర్యావరణాన్ని పరీక్షించాం.\nమీరు MediaWiki ని స్థాపించలేరు.",
"config-env-php": "PHP $1 స్థాపించబడింది.",
- "config-env-php-toolow": "PHP $1 స్థాపించబడింది.\nఅయితే, MediaWiki కి PHP $2 గానీ ఆ పైది గానీ కావాలి.",
"config-unicode-using-utf8": "యూనికోడు నార్మలైజేషన్ కోసం బ్రయాన్ విబర్ గారి utf8_normalize.so ను వాడుతున్నాం.",
"config-unicode-using-intl": "యూనికోడు నార్మలైజేషన్ కోసం [http://pecl.php.net/intl intl PECL పొడిగింత] ను వాడుతున్నాం.",
"config-outdated-sqlite": "<strong>హెచ్చరిక:</strong> మీ వద్ద SQLite $1 ఉంది. అదికావలసిన వెర్షను $2 కంటే దిగువది. SQLite అందుబాటులో ఉండదు.",
"config-memcache-badport": "Memcached పోర్టు సఖ్యలు $1, $2 ల మధ్య ఉండాలి.",
"config-extensions": "పొడిగింతలు",
"config-extensions-help": "పైన చూపిన పొడిగింతలు మీ <code>./extensions</code> డైరెక్టరీలో ఉన్నాయి.\n\nవాటికి అదనంగా కాన్ఫిగరేషన్ అవసరం కావచ్చు. అయితే మీరు వాటిని చేతనం చెయ్యవచ్చు.",
+ "config-skins": "అలంకారాలు",
"config-install-alreadydone": "<strong>హెచ్చరిక:</strong> మీరు ఈసరికే MediaWiki ని స్థాపించినట్లుగా అనిపిస్తోంది. మళ్ళీ స్థాపించే ప్రయత్నం చేస్తున్నట్లున్నారు.\nతరువాత పేజీకి వెళ్ళండి.",
"config-install-begin": "\"{{int:config-continue}}\" నొక్కి, MediaWiki స్థాపనను మొదలుపెట్టవచ్చు.\nఇంకా మార్పులు చెయ్యదలిస్తే, \"{{int:config-back}}\" నొక్కండి.",
"config-install-step-done": "పూర్తయింది",
"authors": [
"පසිඳු කාවින්ද",
"Minh Nguyen",
- "Withoutaname"
+ "Withoutaname",
+ "Dinhxuanduyet"
]
},
"config-desc": "Trình cài đặt MediaWiki",
"config-title": "Cài đặt MediaWiki $1",
"config-information": "Thông tin",
+ "config-localsettings-upgrade": "Một file <code>LocalSettings.php</code> đã được phát hiện.\nĐể nâng cấp cài đặt này, xin nhập giá trị của <code>$wgUpgradeKey</code> trong hộp thoại bên dưới đây.\nBạn sẽ tìm thấy nó trong<code>LocalSettings.php</code>.",
+ "config-localsettings-cli-upgrade": "Một file <code>LocalSettings.php</code> đã được phát hiện.\nĐể nâng cấp cài đặt này, hãy chạy <code>update.php</code>",
"config-localsettings-key": "Chìa khóa nâng cấp:",
"config-localsettings-badkey": "Bạn đã cung cấp một chìa khóa sai.",
+ "config-upgrade-key-missing": "Có một bản cài đặt của MediaWiki sẵn trước đó đã được phát hiện.\nĐể nâng cấp cài đặt này, hãy đặt dòng sau vào dưới của của <code>LocalSettings.php</code>:\n\n$1",
"config-session-error": "Lỗi khi bắt đầu phiên làm việc: $1",
"config-your-language": "Ngôn ngữ của bạn:",
"config-your-language-help": "Chọn một ngôn ngữ để sử dụng trong quá trình cài đặt.",
"config-license-gfdl": "GNU 自由文件授權條款 1.3 或更高版本",
"config-license-pd": "公共領域",
"config-license-cc-choose": "請選擇一個自訂的創作共用授權條款",
- "config-license-help": "許多開放式 Wiki 會以 [http://freedomdefined.org/Definition 自由授權條款] 的方式釋放出編者的所有貢獻,這有助於構建社群的所有權,並且能鼓勵長期貢獻。對於封閉式的 Wiki 或公司 Wiki 則是非必要的。\n\n如果您希望使用來自維基百科(Wikipedia)的內容,並希望維基百科能接受您的 Wiki 內容,請應選擇 <strong>{{int:config-license-cc-by-sa}}</strong> 授權條款。\n\n維基百科̽(Wikipedia)先前是使用 GNU 自由文件授權條款,\n但該授權條款的內容較難理解,因此較難再利用在該條款底下的內容。",
+ "config-license-help": "許多開放式 Wiki 會以 [http://freedomdefined.org/Definition 自由授權條款] 的方式釋放出編者的所有貢獻,這有助於構建社群的所有權,並且能鼓勵長期貢獻。對於封閉式的 Wiki 或公司 Wiki 則是非必要的。\n\n如果您希望使用來自維基百科(Wikipedia)的內容,並希望維基百科能接受您的 Wiki 內容,請應選擇 <strong>{{int:config-license-cc-by-sa}}</strong> 授權條款。\n\n維基百科(Wikipedia)先前是使用 GNU 自由文件授權條款,\n但該授權條款的內容較難理解,因此較難再利用在該條款底下的內容。",
"config-email-settings": "E-mail 設定",
"config-enable-email": "開啟外寄電子郵件",
"config-enable-email-help": "如果您要使用電子郵件功能,請正確設定 [http://www.php.net/manual/en/mail.configuration.php PHP 的郵件設定]。\n如果您不需要使用電子郵件功能,請在此處關閉。",
global $wgMemc, $wgInterwikiExpiry;
$iwData = array();
- if ( !wfRunHooks( 'InterwikiLoadPrefix', array( $prefix, &$iwData ) ) ) {
+ if ( !Hooks::run( 'InterwikiLoadPrefix', array( $prefix, &$iwData ) ) ) {
return Interwiki::loadFromArray( $iwData );
}
* have explicitly defined sections.
* - configByPartition : Map of queue partition names to configuration arrays.
* These configuration arrays are passed to JobQueue::factory().
- * The options set here are overriden by those passed to this
+ * The options set here are overridden by those passed to this
* the federated queue itself (e.g. 'order' and 'claimTTL').
* - partitionsNoPush : List of partition names that can handle pop() but not push().
* This can be used to migrate away from a certain partition.
*
* @param mixed $value
*
- * @return boolean
+ * @return bool
*/
protected function hasValidType( $value ) {
$class = $this->getObjectType();
* @param integer|string $index
* @param mixed $value
*
- * @return boolean
+ * @return bool
*/
protected function preSetElement( $index, $value ) {
return true;
*
* @since 1.20
*
- * @return boolean
+ * @return bool
*/
public function isEmpty() {
return $this->count() === 0;
* Match an IP address against the set
*
* @param string $ip string IPv[46] address
- * @return boolean true is match success, false is match failure
+ * @return bool true is match success, false is match failure
*
* If $ip is unparseable, inet_pton may issue an E_WARNING to that effect
*/
* @throws InvalidArgumentException when object specification does not
* contain 'class' or 'factory' keys
* @throws ReflectionException when 'args' are supplied and 'class'
- * constructor is non-public or non-existant
+ * constructor is non-public or non-existent
*/
public static function getObjectFromSpec( $spec ) {
$args = isset( $spec['args'] ) ? $spec['args'] : array();
class ScopedCallback {
/** @var callable */
protected $callback;
+ /** @var array */
+ protected $params;
/**
* @param callable $callback
+ * @param array $params Callback arguments (since 1.25)
* @throws Exception
*/
- public function __construct( $callback ) {
+ public function __construct( $callback, array $params = array() ) {
if ( !is_callable( $callback ) ) {
throw new InvalidArgumentException( "Provided callback is not valid." );
}
$this->callback = $callback;
+ $this->params = $params;
}
/**
*/
function __destruct() {
if ( $this->callback !== null ) {
- call_user_func( $this->callback );
+ call_user_func_array( $this->callback, $this->params );
}
}
}
foreach ( $stats as $name => $value ) {
if ( $value instanceof RunningStat ) {
$total = $value->m1 * $value->n;
+ $percent = ( isset( $main[$name] ) && $main[$name] )
+ ? 100 * $total / $main[$name]
+ : 0;
$this->inclusive[$func][$name] = array(
'total' => $total,
'min' => $value->min,
'mean' => $value->m1,
'max' => $value->max,
'variance' => $value->m2,
- 'percent' => 100 * $total / $main[$name],
+ 'percent' => $percent,
);
}
}
* SAX element handler event. This gives you access to the element
* namespace, name, attributes, and text contents.
* Filter should return 'true' to toggle on $this->filterMatch
- * @param boolean $isFile (optional) indicates if the first parameter is a
+ * @param bool $isFile (optional) indicates if the first parameter is a
* filename (default, true) or if it is a string (false)
* @param array $options list of additional parsing options:
* processing_instruction_handler: Callback for xml_set_processing_instruction_handler
} else {
// Allow extensions to add their own extra inputs
$input = '';
- wfRunHooks( 'LogEventsListGetExtraInputs', array( $types[0], $this, &$input ) );
+ Hooks::run( 'LogEventsListGetExtraInputs', array( $types[0], $this, &$input ) );
return $input;
}
}
}
/* hook can return false, if we don't want the message to be emitted (Wikia BugId:7093) */
- if ( wfRunHooks( 'LogEventsListShowLogExtract', array( &$s, $types, $page, $user, $param ) ) ) {
+ if ( Hooks::run( 'LogEventsListShowLogExtract', array( &$s, $types, $page, $user, $param ) ) ) {
// $out can be either an OutputPage object or a String-by-reference
if ( $out instanceof OutputPage ) {
$out->addHTML( $s );
$params = $this->entry->getParameters();
- wfRunHooks( 'LogLine', array( $type, $subtype, $title, $params,
+ Hooks::run( 'LogLine', array( $type, $subtype, $title, $params,
&$this->comment, &$this->revert, $this->entry->getTimestamp() ) );
return $this->revert;
$formattedPageStatus = array( 'deleted', 'created', 'moved', 'restored', 'changed' );
- wfRunHooks( 'UpdateUserMailerFormattedPageStatus', array( &$formattedPageStatus ) );
+ Hooks::run( 'UpdateUserMailerFormattedPageStatus', array( &$formattedPageStatus ) );
if ( !in_array( $this->pageStatus, $formattedPageStatus ) ) {
wfProfileOut( __METHOD__ );
throw new MWException( 'Not a valid page status!' );
&& $watchingUser->isEmailConfirmed()
&& $watchingUser->getID() != $userTalkId
) {
- if ( wfRunHooks( 'SendWatchlistEmailNotification', array( $watchingUser, $title, $this ) ) ) {
+ if ( Hooks::run( 'SendWatchlistEmailNotification', array( $watchingUser, $title, $this ) ) ) {
$this->compose( $watchingUser );
}
}
) {
if ( !$targetUser->isEmailConfirmed() ) {
wfDebug( __METHOD__ . ": talk page owner doesn't have validated email\n" );
- } elseif ( !wfRunHooks( 'AbortTalkPageEmailNotification', array( $targetUser, $title ) ) ) {
+ } elseif ( !Hooks::run( 'AbortTalkPageEmailNotification', array( $targetUser, $title ) ) ) {
wfDebug( __METHOD__ . ": talk page update notification is aborted for this user\n" );
} else {
wfDebug( __METHOD__ . ": sending talk page update notification\n" );
$extraParams = $wgAdditionalMailParams;
// Hook to generate custom VERP address for 'Return-Path'
- wfRunHooks( 'UserMailerChangeReturnPath', array( $to, &$returnPath ) );
+ Hooks::run( 'UserMailerChangeReturnPath', array( $to, &$returnPath ) );
# Add the envelope sender address using the -f command line option when PHP mail() is used.
# Will default to the $from->address when the UserMailerChangeReturnPath hook fails and the
# generated VERP address when the hook runs effectively.
$headers['Content-transfer-encoding'] = '8bit';
}
- $ret = wfRunHooks( 'AlternateUserMailer', array( $headers, $to, $from, $subject, $body ) );
+ $ret = Hooks::run( 'AlternateUserMailer', array( $headers, $to, $from, $subject, $body ) );
if ( $ret === false ) {
// the hook implementation will return false to skip regular mail sending
return Status::newGood();
/ ( $params['srcWidth'] + $params['srcHeight'] )
< $wgSharpenReductionThreshold
) {
- // Hack, since $wgSharpenParamater is written specifically for the command line convert
+ // Hack, since $wgSharpenParameter is written specifically for the command line convert
list( $radius, $sigma ) = explode( 'x', $wgSharpenParameter );
$im->sharpenImage( $radius, $sigma );
}
$src_image = call_user_func( $loader, $params['srcPath'] );
- $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ? $this->getRotation( $image ) : 0;
+ $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ? $this->getRotation( $image ) : 0;
list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
$dst_image = imagecreatetruecolor( $width, $height );
$cachedValue = $wgMemc->get( $cacheKey );
if (
$cachedValue
- && wfRunHooks( 'ValidateExtendedMetadataCache', array( $cachedValue['timestamp'], $file ) )
+ && Hooks::run( 'ValidateExtendedMetadataCache', array( $cachedValue['timestamp'], $file ) )
) {
$extendedMetadata = $cachedValue['data'];
} else {
) {
wfProfileIn( __METHOD__ );
- wfRunHooks( 'GetExtendedMetadata', array(
+ Hooks::run( 'GetExtendedMetadata', array(
&$extendedMetadata,
$file,
$this->getContext(),
*/
static function getMetadataVersion() {
$version = array( '2' ); // core metadata version
- wfRunHooks( 'GetMetadataVersion', array( &$version ) );
+ Hooks::run( 'GetMetadataVersion', array( &$version ) );
return implode( ';', $version );
}
$query = isset( $options['desc-query'] ) ? $options['desc-query'] : '';
+ $attribs = array(
+ 'alt' => $alt,
+ 'src' => $this->url,
+ );
+
if ( !empty( $options['custom-url-link'] ) ) {
$linkAttribs = array( 'href' => $options['custom-url-link'] );
if ( !empty( $options['title'] ) ) {
$linkAttribs = array( 'href' => $this->file->getURL() );
} else {
$linkAttribs = false;
+ if ( !empty( $options['title'] ) ) {
+ $attribs['title'] = $options['title'];
+ }
}
- $attribs = array(
- 'alt' => $alt,
- 'src' => $this->url,
- );
-
if ( empty( $options['no-dimensions'] ) ) {
$attribs['width'] = $this->width;
$attribs['height'] = $this->height;
$attribs['srcset'] = Html::srcSet( $this->responsiveUrls );
}
- wfRunHooks( 'ThumbnailBeforeProduceHTML', array( $this, &$attribs, &$linkAttribs ) );
+ Hooks::run( 'ThumbnailBeforeProduceHTML', array( $this, &$attribs, &$linkAttribs ) );
return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
}
# Check if the file is smaller than the maximum image area for thumbnailing
# For historical reasons, hook starts with BitmapHandler
$checkImageAreaHookResult = null;
- wfRunHooks(
+ Hooks::run(
'BitmapHandlerCheckImageArea',
array( $image, &$params, &$checkImageAreaHookResult )
);
# Try a hook. Called "Bitmap" for historical reasons.
/** @var $mto MediaTransformOutput */
$mto = null;
- wfRunHooks( 'BitmapHandlerTransform', array( $this, $image, &$scalerParams, &$mto ) );
+ Hooks::run( 'BitmapHandlerTransform', array( $this, $image, &$scalerParams, &$mto ) );
if ( !is_null( $mto ) ) {
wfDebug( __METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n" );
$scaler = 'hookaborted';
$data = $this->results;
- wfRunHooks( 'XMPGetResults', array( &$data ) );
+ Hooks::run( 'XMPGetResults', array( &$data ) );
if ( isset( $data['xmp-special']['AuthorsPosition'] )
&& is_string( $data['xmp-special']['AuthorsPosition'] )
if ( !self::$ranHooks ) {
// This is for if someone makes a custom metadata extension.
// For example, a medical wiki might want to decode DICOM xmp properties.
- wfRunHooks( 'XMPGetInfo', array( &self::$items ) );
+ Hooks::run( 'XMPGetInfo', array( &self::$items ) );
self::$ranHooks = true; // Only want to do this once.
}
}
$page = null;
- wfRunHooks( 'ArticleFromTitle', array( &$title, &$page, $context ) );
+ Hooks::run( 'ArticleFromTitle', array( &$title, &$page, $context ) );
if ( !$page ) {
switch ( $title->getNamespace() ) {
case NS_FILE:
);
$this->mRevIdFetched = $this->mRevision->getId();
- wfRunHooks( 'ArticleAfterFetchContentObject', array( &$this, &$this->mContentObject ) );
+ Hooks::run( 'ArticleAfterFetchContentObject', array( &$this, &$this->mContentObject ) );
wfProfileOut( __METHOD__ );
while ( !$outputDone && ++$pass ) {
switch ( $pass ) {
case 1:
- wfRunHooks( 'ArticleViewHeader', array( &$this, &$outputDone, &$useParserCache ) );
+ Hooks::run( 'ArticleViewHeader', array( &$this, &$outputDone, &$useParserCache ) );
break;
case 2:
# Early abort if the page doesn't exist
wfDebug( __METHOD__ . ": showing CSS/JS source\n" );
$this->showCssOrJsPage();
$outputDone = true;
- } elseif ( !wfRunHooks( 'ArticleContentViewCustom',
+ } elseif ( !Hooks::run( 'ArticleContentViewCustom',
array( $this->fetchContentObject(), $this->getTitle(), $outputPage ) ) ) {
# Allow extensions do their own custom view for certain pages
if ( isset( $this->mRedirectedFrom ) ) {
// This is an internally redirected page view.
// We'll need a backlink to the source page for navigation.
- if ( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) {
+ if ( Hooks::run( 'ArticleViewRedirect', array( &$this ) ) ) {
$redir = Linker::linkKnown(
$this->mRedirectedFrom,
null,
// Show a footer allowing the user to patrol the shown revision or page if possible
$patrolFooterShown = $this->showPatrolFooter();
- wfRunHooks( 'ArticleViewFooter', array( $this, $patrolFooterShown ) );
+ Hooks::run( 'ArticleViewFooter', array( $this, $patrolFooterShown ) );
}
/**
}
}
- wfRunHooks( 'ShowMissingArticle', array( $this ) );
+ Hooks::run( 'ShowMissingArticle', array( $this ) );
// Give extensions a chance to hide their (unrelated) log entries
$logTypes = array( 'delete', 'move' );
$conds = array( "log_action != 'revision'" );
- wfRunHooks( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) );
+ Hooks::run( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) );
# Show delete and move logs
LogEventsList::showLogExtract( $outputPage, $logTypes, $title, '',
$outputPage->setIndexPolicy( $policy['index'] );
$outputPage->setFollowPolicy( $policy['follow'] );
- $hookResult = wfRunHooks( 'BeforeDisplayNoArticleText', array( $this ) );
+ $hookResult = Hooks::run( 'BeforeDisplayNoArticleText', array( $this ) );
if ( !$hookResult ) {
return;
* @param int $oldid Revision ID of this article revision
*/
public function setOldSubtitle( $oldid = 0 ) {
- if ( !wfRunHooks( 'DisplayOldSubtitle', array( &$this, &$oldid ) ) ) {
+ if ( !Hooks::run( 'DisplayOldSubtitle', array( &$this, &$oldid ) ) ) {
return;
}
}
$outputPage->addWikiMsg( 'confirmdeletetext' );
- wfRunHooks( 'ArticleConfirmDelete', array( $this, $outputPage, &$reason ) );
+ Hooks::run( 'ArticleConfirmDelete', array( $this, $outputPage, &$reason ) );
$user = $this->getContext()->getUser();
$outputPage->addWikiMsg( 'deletedtext', wfEscapeWikiText( $deleted ), $loglink );
- wfRunHooks( 'ArticleDeleteAfterSuccess', array( $this->getTitle(), $outputPage ) );
+ Hooks::run( 'ArticleDeleteAfterSuccess', array( $this->getTitle(), $outputPage ) );
$outputPage->returnToMain( false );
} else {
&& !$this->mRedirectedFrom && !$this->getTitle()->isRedirect();
// Extension may have reason to disable file caching on some pages.
if ( $cacheable ) {
- $cacheable = wfRunHooks( 'IsFileCacheable', array( &$this ) );
+ $cacheable = Hooks::run( 'IsFileCacheable', array( &$this ) );
}
}
return;
}
- if ( !wfRunHooks( 'CategoryPageView', array( &$this ) ) ) {
+ if ( !Hooks::run( 'CategoryPageView', array( &$this ) ) ) {
return;
}
$this->fileLoaded = true;
$this->displayImg = $img = false;
- wfRunHooks( 'ImagePageFindFile', array( $this, &$img, &$this->displayImg ) );
+ Hooks::run( 'ImagePageFindFile', array( $this, &$img, &$this->displayImg ) );
if ( !$img ) { // not set by hook?
$img = wfFindFile( $this->getTitle() );
if ( !$img ) {
# Allow extensions to add something after the image links
$html = '';
- wfRunHooks( 'ImagePageAfterImageLinks', array( $this, &$html ) );
+ Hooks::run( 'ImagePageAfterImageLinks', array( $this, &$html ) );
if ( $html ) {
$out->addHTML( $html );
}
$r[] = '<li><a href="#metadata">' . wfMessage( 'metadata' )->escaped() . '</a></li>';
}
- wfRunHooks( 'ImagePageShowTOC', array( $this, &$r ) );
+ Hooks::run( 'ImagePageShowTOC', array( $this, &$r ) );
return '<ul id="filetoc">' . implode( "\n", $r ) . '</ul>';
}
$filename = wfEscapeWikiText( $this->displayImg->getName() );
$linktext = $filename;
- wfRunHooks( 'ImageOpenShowImageInlineBefore', array( &$this, &$out ) );
+ Hooks::run( 'ImageOpenShowImageInlineBefore', array( &$this, &$out ) );
if ( $this->displayImg->allowInlineDisplay() ) {
# image
}
$rowClass = null;
- wfRunHooks( 'ImagePageFileHistoryLine', array( $this, $file, &$row, &$rowClass ) );
+ Hooks::run( 'ImagePageFileHistoryLine', array( $this, $file, &$row, &$rowClass ) );
$classAttr = $rowClass ? " class='$rowClass'" : '';
return "<tr{$classAttr}>{$row}</tr>\n";
protected function pageData( $dbr, $conditions, $options = array() ) {
$fields = self::selectFields();
- wfRunHooks( 'ArticlePageDataBefore', array( &$this, &$fields ) );
+ Hooks::run( 'ArticlePageDataBefore', array( &$this, &$fields ) );
$row = $dbr->selectRow( 'page', $fields, $conditions, __METHOD__, $options );
- wfRunHooks( 'ArticlePageDataAfter', array( &$this, &$row ) );
+ Hooks::run( 'ArticlePageDataAfter', array( &$this, &$row ) );
return $row;
}
public function doPurge() {
global $wgUseSquid;
- if ( !wfRunHooks( 'ArticlePurge', array( &$this ) ) ) {
+ if ( !Hooks::run( 'ArticlePurge', array( &$this ) ) ) {
return false;
}
$hook_args = array( &$this, &$user, &$content, &$summary,
$flags & EDIT_MINOR, null, null, &$flags, &$status );
- if ( !wfRunHooks( 'PageContentSave', $hook_args )
+ if ( !Hooks::run( 'PageContentSave', $hook_args )
|| !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args ) ) {
wfDebug( __METHOD__ . ": ArticleSave or ArticleSaveContent hook aborted save!\n" );
$summary = $handler->getAutosummary( $old_content, $content, $flags );
}
- $editInfo = $this->prepareContentForEdit( $content, null, $user, $serialFormat, true );
+ $editInfo = $this->prepareContentForEdit( $content, null, $user, $serialFormat );
$serialized = $editInfo->pst;
/**
return $status;
}
- wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
+ Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
// Update recentchanges
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
// Mark as patrolled if the user can do so
// Update the page record with revision data
$this->updateRevisionOn( $dbw, $revision, 0 );
- wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
+ Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
// Update recentchanges
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
$flags & EDIT_MINOR, null, null, &$flags, $revision );
ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $hook_args );
- wfRunHooks( 'PageContentInsertComplete', $hook_args );
+ Hooks::run( 'PageContentInsertComplete', $hook_args );
}
// Do updates right now unless deferral was requested
$flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
- wfRunHooks( 'PageContentSaveComplete', $hook_args );
+ Hooks::run( 'PageContentSaveComplete', $hook_args );
// Promote user to any groups they meet the criteria for
$dbw->onTransactionIdle( function () use ( $user ) {
* @since 1.21
*/
public function prepareContentForEdit(
- Content $content, $revid = null, User $user = null, $serialFormat = null, $useCache = false
+ Content $content, $revid = null, User $user = null, $serialFormat = null, $useCache = true
) {
global $wgContLang, $wgUser;
: false;
$popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
- wfRunHooks( 'ArticlePrepareTextForEdit', array( $this, $popts ) );
+ Hooks::run( 'ArticlePrepareTextForEdit', array( $this, $popts ) );
$edit = (object)array();
if ( $cachedEdit ) {
DataUpdate::runUpdates( $updates );
}
- wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
+ Hooks::run( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
- if ( wfRunHooks( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
+ if ( Hooks::run( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
if ( 0 == mt_rand( 0, 99 ) ) {
// Flush old entries from the `recentchanges` table; we do this on
// random requests so as to avoid an increase in writes for no good reason
wfDebug( __METHOD__ . ": invalid username\n" );
} else {
// Allow extensions to prevent user notification when a new message is added to their talk page
- if ( wfRunHooks( 'ArticleEditUpdateNewTalk', array( &$this, $recipient ) ) ) {
+ if ( Hooks::run( 'ArticleEditUpdateNewTalk', array( &$this, $recipient ) ) ) {
if ( User::isIP( $shortTitle ) ) {
// An anonymous user
$recipient->setNewtalk( true, $revision );
$revision->insertOn( $dbw );
$this->updateRevisionOn( $dbw, $revision );
- wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
+ Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
wfProfileOut( __METHOD__ );
}
$logRelationsField = null;
if ( $id ) { // Protection of existing page
- if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
+ if ( !Hooks::run( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
return Status::newGood();
}
__METHOD__
);
- wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $nullRevision, $latest, $user ) );
- wfRunHooks( 'ArticleProtectComplete', array( &$this, &$user, $limit, $reason ) );
+ Hooks::run( 'NewRevisionFromEditComplete', array( $this, $nullRevision, $latest, $user ) );
+ Hooks::run( 'ArticleProtectComplete', array( &$this, &$user, $limit, $reason ) );
} else { // Protection of non-existing page (also known as "title protection")
// Cascade protection is meaningless in this case
$cascade = false;
}
$user = is_null( $user ) ? $wgUser : $user;
- if ( !wfRunHooks( 'ArticleDelete', array( &$this, &$user, &$reason, &$error, &$status ) ) ) {
+ if ( !Hooks::run( 'ArticleDelete', array( &$this, &$user, &$reason, &$error, &$status ) ) ) {
if ( $status->isOK() ) {
// Hook aborted but didn't set a fatal status
$status->fatal( 'delete-hook-aborted' );
$this->doDeleteUpdates( $id, $content );
- wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id, $content, $logEntry ) );
+ Hooks::run( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id, $content, $logEntry ) );
$status->value = $logid;
return $status;
}
$revId = $status->value['revision']->getId();
- wfRunHooks( 'ArticleRollbackComplete', array( $this, $guser, $target, $current ) );
+ Hooks::run( 'ArticleRollbackComplete', array( $this, $guser, $target, $current ) );
$resultDetails = array(
'summary' => $summary,
foreach ( $added as $catName ) {
$cat = Category::newFromName( $catName );
- wfRunHooks( 'CategoryAfterPageAdded', array( $cat, $that ) );
+ Hooks::run( 'CategoryAfterPageAdded', array( $cat, $that ) );
}
foreach ( $deleted as $catName ) {
$cat = Category::newFromName( $catName );
- wfRunHooks( 'CategoryAfterPageRemoved', array( $cat, $that ) );
+ Hooks::run( 'CategoryAfterPageRemoved', array( $cat, $that ) );
}
}
);
$updates = $content->getDeletionUpdates( $this );
}
- wfRunHooks( 'WikiPageDeletionUpdates', array( $this, $content, &$updates ) );
+ Hooks::run( 'WikiPageDeletionUpdates', array( $this, $content, &$updates ) );
return $updates;
}
}
}
if ( count( $linkcolour_ids ) ) {
//pass an array of page_ids to an extension
- wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
+ Hooks::run( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
}
wfProfileOut( __METHOD__ . '-check' );
}
}
}
- wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
+ Hooks::run( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
// rebuild the categories in original order (if there are replacements)
if ( count( $varCategories ) > 0 ) {
$wrappedtext = $wrapper->getWrapped( $text );
$retVal = null;
- $correctedtext = self::clean( $wrappedtext, false, $retVal );
+ list( $correctedtext, $errors ) = self::clean( $wrappedtext, $retVal );
if ( $retVal < 0 ) {
wfDebug( "Possible tidy configuration error!\n" );
return $text . "\n<!-- Tidy was unable to run -->\n";
- } elseif ( is_null( $correctedtext ) ) {
+ } elseif ( $correctedtext === '' && $text !== '' ) {
wfDebug( "Tidy error detected!\n" );
return $text . "\n<!-- Tidy found serious XHTML errors -->\n";
}
*/
public static function checkErrors( $text, &$errorStr = null ) {
$retval = 0;
- $errorStr = self::clean( $text, true, $retval );
+ list( $outputStr, $errorStr ) = self::clean( $text, $retval );
return ( $retval < 0 && $errorStr == '' ) || $retval == 0;
}
/**
* Perform a clean/repair operation
* @param string $text HTML to check
- * @param bool $stderr Whether to read result from STDERR rather than STDOUT
* @param int &$retval Exit code (-1 on internal error)
* @return string|null
*/
- private static function clean( $text, $stderr = false, &$retval = null ) {
+ private static function clean( $text, &$retval = null ) {
global $wgTidyInternal;
if ( $wgTidyInternal ) {
- if ( wfIsHHVM() ) {
- if ( $stderr ) {
- throw new MWException( __METHOD__.": error text return from HHVM tidy is not supported" );
- }
- return self::hhvmClean( $text, $retval );
- } else {
- return self::phpClean( $text, $stderr, $retval );
- }
+ return self::internalClean( $text, $retval );
} else {
- return self::externalClean( $text, $stderr, $retval );
+ return self::externalClean( $text, $retval );
}
}
* Also called in OutputHandler.php for full page validation
*
* @param string $text HTML to check
- * @param bool $stderr Whether to read result from STDERR rather than STDOUT
* @param int &$retval Exit code (-1 on internal error)
* @return string|null
*/
- private static function externalClean( $text, $stderr = false, &$retval = null ) {
+ private static function externalClean( $text, &$retval = null ) {
global $wgTidyConf, $wgTidyBin, $wgTidyOpts;
wfProfileIn( __METHOD__ );
- $cleansource = '';
$opts = ' -utf8';
- if ( $stderr ) {
- $descriptorspec = array(
- 0 => array( 'pipe', 'r' ),
- 1 => array( 'file', wfGetNull(), 'a' ),
- 2 => array( 'pipe', 'w' )
- );
- } else {
- $descriptorspec = array(
- 0 => array( 'pipe', 'r' ),
- 1 => array( 'pipe', 'w' ),
- 2 => array( 'file', wfGetNull(), 'a' )
- );
- }
+ $descriptorspec = array(
+ 0 => array( 'pipe', 'r' ),
+ 1 => array( 'pipe', 'w' ),
+ 2 => array( 'pipe', 'w' ),
+ );
- $readpipe = $stderr ? 2 : 1;
+ $outputBuffer = '';
+ $errorBuffer = '';
$pipes = array();
$process = proc_open(
// for tidyParseStdin and tidySaveStdout in console/tidy.c
fwrite( $pipes[0], $text );
fclose( $pipes[0] );
- while ( !feof( $pipes[$readpipe] ) ) {
- $cleansource .= fgets( $pipes[$readpipe], 1024 );
+
+ while ( !feof( $pipes[1] ) ) {
+ $outputBuffer .= fgets( $pipes[1], 1024 );
}
- fclose( $pipes[$readpipe] );
+ fclose( $pipes[1] );
+
+ while ( !feof( $pipes[2] ) ) {
+ $errorBuffer .= fgets( $pipes[2], 1024 );
+ }
+ fclose( $pipes[2] );
+
$retval = proc_close( $process );
} else {
wfWarn( "Unable to start external tidy process" );
$retval = -1;
}
- if ( !$stderr && $cleansource == '' && $text != '' ) {
- // Some kind of error happened, so we couldn't get the corrected text.
- // Just give up; we'll use the source text and append a warning.
- $cleansource = null;
- }
-
wfProfileOut( __METHOD__ );
- return $cleansource;
+ return array( $outputBuffer, $errorBuffer );
}
/**
* saving the overhead of spawning a new process.
*
* @param string $text HTML to check
- * @param bool $stderr Whether to read result from error status instead of output
* @param int &$retval Exit code (-1 on internal error)
* @return string|null
*/
- private static function phpClean( $text, $stderr = false, &$retval = null ) {
+ private static function internalClean( $text, &$retval = null ) {
global $wgTidyConf, $wgDebugTidy;
wfProfileIn( __METHOD__ );
- if ( !class_exists( 'tidy' ) ) {
+ if ( ( !wfIsHHVM() && !class_exists( 'tidy' ) ) ||
+ ( wfIsHHVM() && !function_exists( 'tidy_repair_string' ) )
+ ) {
wfWarn( "Unable to load internal tidy class." );
$retval = -1;
return null;
}
- $tidy = new tidy;
- $tidy->parseString( $text, $wgTidyConf, 'utf8' );
-
- if ( $stderr ) {
- $retval = $tidy->getStatus();
-
- wfProfileOut( __METHOD__ );
- return $tidy->errorBuffer;
- }
-
- $tidy->cleanRepair();
- $retval = $tidy->getStatus();
- if ( $retval == 2 ) {
- // 2 is magic number for fatal error
- // http://www.php.net/manual/en/function.tidy-get-status.php
- $cleansource = null;
+ $outputBuffer = '';
+ $errorBuffer = '';
+
+ if ( wfIsHHVM() ) {
+ // Use the tidy extension for HHVM from
+ // https://github.com/wikimedia/mediawiki-php-tidy
+ //
+ // This currently does not support the object-oriented interface, but
+ // tidy_repair_string() can be used for the most common tasks.
+ $result = tidy_repair_string( $text, $wgTidyConf, 'utf8' );
+ $outputBuffer .= $result;
+ $retval = $result === false ? -1 : 0;
} else {
- $cleansource = tidy_get_output( $tidy );
- if ( $wgDebugTidy && $retval > 0 ) {
- $cleansource .= "<!--\nTidy reports:\n" .
- str_replace( '-->', '-->', $tidy->errorBuffer ) .
- "\n-->";
+ $tidy = new tidy;
+ $tidy->parseString( $text, $wgTidyConf, 'utf8' );
+ $tidy->cleanRepair();
+ $retval = $tidy->getStatus();
+ $outputBuffer .= tidy_get_output( $tidy );
+ if ( $retval > 0 ) {
+ $errorBuffer .= $tidy->errorBuffer;
}
}
- wfProfileOut( __METHOD__ );
- return $cleansource;
- }
-
- /**
- * Use the tidy extension for HHVM from
- * https://github.com/wikimedia/mediawiki-php-tidy
- *
- * This currently does not support the object-oriented interface, but
- * tidy_repair_string() can be used for the most common tasks.
- *
- * @param string $text HTML to check
- * @param int &$retval Exit code (-1 on internal error)
- * @return string|null
- */
- private static function hhvmClean( $text, &$retval ) {
- global $wgTidyConf;
- wfProfileIn( __METHOD__ );
- $cleansource = tidy_repair_string( $text, $wgTidyConf, 'utf8' );
- if ( $cleansource === false ) {
- $cleansource = null;
- $retval = -1;
- } else {
- $retval = 0;
+ if ( $wgDebugTidy && $errorBuffer && $retval > 0 ) {
+ $outputBuffer .= "<!--\nTidy reports:\n" .
+ str_replace( '-->', '-->', $tidy->errorBuffer ) .
+ "\n-->";
}
+
wfProfileOut( __METHOD__ );
- return $cleansource;
+ return array( $outputBuffer, $errorBuffer );
}
}
unset( $tmp );
}
- wfRunHooks( 'ParserCloned', array( $this ) );
+ Hooks::run( 'ParserCloned', array( $this ) );
}
/**
CoreTagHooks::register( $this );
$this->initialiseVariables();
- wfRunHooks( 'ParserFirstCallInit', array( &$this ) );
+ Hooks::run( 'ParserFirstCallInit', array( &$this ) );
wfProfileOut( __METHOD__ );
}
$this->mProfiler = new SectionProfiler();
- wfRunHooks( 'ParserClearState', array( &$this ) );
+ Hooks::run( 'ParserClearState', array( &$this ) );
wfProfileOut( __METHOD__ );
}
$this->mRevisionSize = null;
}
- wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
# No more strip!
- wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
$text = $this->internalParse( $text );
- wfRunHooks( 'ParserAfterParse', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserAfterParse', array( &$this, &$text, &$this->mStripState ) );
$text = $this->internalParseHalfParsed( $text, true, $linestart );
$this->mOutput->setLimitReportData( 'limitreport-expensivefunctioncount',
array( $this->mExpensiveFunctionCount, $this->mOptions->getExpensiveParserFunctionLimit() )
);
- wfRunHooks( 'ParserLimitReportPrepare', array( $this, $this->mOutput ) );
+ Hooks::run( 'ParserLimitReportPrepare', array( $this, $this->mOutput ) );
$limitReport = "NewPP limit report\n";
if ( $wgShowHostnames ) {
$limitReport .= 'Parsed by ' . wfHostname() . "\n";
}
foreach ( $this->mOutput->getLimitReportData() as $key => $value ) {
- if ( wfRunHooks( 'ParserLimitReportFormat',
+ if ( Hooks::run( 'ParserLimitReportFormat',
array( $key, &$value, &$limitReport, false, false )
) ) {
$keyMsg = wfMessage( $key )->inLanguage( 'en' )->useDatabase( false );
// Since we're not really outputting HTML, decode the entities and
// then re-encode the things that need hiding inside HTML comments.
$limitReport = htmlspecialchars_decode( $limitReport );
- wfRunHooks( 'ParserLimitReport', array( $this, &$limitReport ) );
+ Hooks::run( 'ParserLimitReport', array( $this, &$limitReport ) );
// Sanitize for comment. Note '‐' in the replacement is U+2010,
// which looks much like the problematic '-'.
// Add on template profiling data
$dataByFunc = $this->mProfiler->getFunctionStats();
- uasort( $dataByFunc, function( $a, $b ) {
+ uasort( $dataByFunc, function ( $a, $b ) {
return $a['real'] < $b['real']; // descending order
} );
$profileReport = "Transclusion expansion time report (%,ms,calls,template)\n";
foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
$profileReport .= sprintf( "%6.2f%% %8.3f %6d - %s\n",
$item['%real'], $item['real'], $item['calls'],
- htmlspecialchars($item['name'] ) );
+ htmlspecialchars( $item['name'] ) );
}
$text .= "\n<!-- \n$profileReport-->\n";
*/
public function recursiveTagParse( $text, $frame = false ) {
wfProfileIn( __METHOD__ );
- wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
- wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
$text = $this->internalParse( $text, false, $frame );
wfProfileOut( __METHOD__ );
return $text;
if ( $revid !== null ) {
$this->mRevisionId = $revid;
}
- wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
- wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
$text = $this->replaceVariables( $text, $frame );
$text = $this->mStripState->unstripBoth( $text );
wfProfileOut( __METHOD__ );
$origText = $text;
# Hook to suspend the parser in this state
- if ( !wfRunHooks( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) ) ) {
+ if ( !Hooks::run( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) ) ) {
wfProfileOut( __METHOD__ );
return $text;
}
$text = $this->replaceVariables( $text );
}
- wfRunHooks( 'InternalParseBeforeSanitize', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'InternalParseBeforeSanitize', array( &$this, &$text, &$this->mStripState ) );
$text = Sanitizer::removeHTMLtags(
$text,
array( &$this, 'attributeStripCallback' ),
false,
array_keys( $this->mTransparentTagHooks )
);
- wfRunHooks( 'InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState ) );
+ Hooks::run( 'InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState ) );
# Tables need to come after variable replacement for things to work
# properly; putting them before other transformations should keep
$text = $this->mStripState->unstripNoWiki( $text );
if ( $isMain ) {
- wfRunHooks( 'ParserBeforeTidy', array( &$this, &$text ) );
+ Hooks::run( 'ParserBeforeTidy', array( &$this, &$text ) );
}
$text = $this->replaceTransparentTags( $text );
}
if ( $isMain ) {
- wfRunHooks( 'ParserAfterTidy', array( &$this, &$text ) );
+ Hooks::run( 'ParserAfterTidy', array( &$this, &$text ) );
}
return $text;
'!(?: # Start cases
(<a[ \t\r\n>].*?</a>) | # m[1]: Skip link text
(<.*?>) | # m[2]: Skip stuff inside HTML elements' . "
- (\\b(?i:$prots)$urlChar+) | # m[3]: Free external links" . '
- (?:RFC|PMID)\s+([0-9]+) | # m[4]: RFC or PMID, capture number
- ISBN\s+(\b # m[5]: ISBN, capture number
+ (\b(?i:$prots)$urlChar+) | # m[3]: Free external links" . '
+ \b(?:RFC|PMID)\s+([0-9]+)\b |# m[4]: RFC or PMID, capture number
+ \bISBN\s+( # m[5]: ISBN, capture number
(?: 97[89] [\ \-]? )? # optional 13-digit ISBN prefix
(?: [0-9] [\ \-]? ){9} # 9 digits with opt. delimiters
[0-9Xx] # check digit
- \b)
+ )\b
)!xu', array( &$this, 'magicLinkCallback' ), $text );
wfProfileOut( __METHOD__ );
return $text;
# Give extensions a chance to select the file revision for us
$options = array();
$descQuery = false;
- wfRunHooks( 'BeforeParserFetchFileAndTitle',
+ Hooks::run( 'BeforeParserFetchFileAndTitle',
array( $this, $nt, &$options, &$descQuery ) );
# Fetch and register the file (file title may be different via hooks)
list( $file, $nt ) = $this->fetchFileAndTitle( $nt, $options );
* Some of these require message or data lookups and can be
* expensive to check many times.
*/
- if ( wfRunHooks( 'ParserGetVariableValueVarCache', array( &$this, &$this->mVarCache ) ) ) {
+ if ( Hooks::run( 'ParserGetVariableValueVarCache', array( &$this, &$this->mVarCache ) ) ) {
if ( isset( $this->mVarCache[$index] ) ) {
return $this->mVarCache[$index];
}
}
$ts = wfTimestamp( TS_UNIX, $this->mOptions->getTimestamp() );
- wfRunHooks( 'ParserGetVariableValueTs', array( &$this, &$ts ) );
+ Hooks::run( 'ParserGetVariableValueTs', array( &$this, &$ts ) );
$pageLang = $this->getFunctionLang();
break;
default:
$ret = null;
- wfRunHooks(
+ Hooks::run(
'ParserGetVariableValueSwitch',
array( &$this, &$this->mVarCache, &$index, &$ret, &$frame )
);
for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) {
# Give extensions a chance to select the revision instead
$id = false; # Assume current
- wfRunHooks( 'BeforeParserFetchTemplateAndtitle',
+ Hooks::run( 'BeforeParserFetchTemplateAndtitle',
array( $parser, $title, &$skip, &$id ) );
if ( $skip ) {
* &$sectionContent : ref to the content of the section
* $showEditLinks : boolean describing whether this section has an edit link
*/
- wfRunHooks( 'ParserSectionCreate', array( $this, $i, &$sections[$i], $showEditLink ) );
+ Hooks::run( 'ParserSectionCreate', array( $this, $i, &$sections[$i], $showEditLink ) );
$i++;
}
}
$ig->setAdditionalOptions( $params );
- wfRunHooks( 'BeforeParserrenderImageGallery', array( &$this, &$ig ) );
+ Hooks::run( 'BeforeParserrenderImageGallery', array( &$this, &$ig ) );
$lines = StringUtils::explode( "\n", $text );
foreach ( $lines as $line ) {
# file (which potentially could be of a different type and have different handler).
$options = array();
$descQuery = false;
- wfRunHooks( 'BeforeParserFetchFileAndTitle',
+ Hooks::run( 'BeforeParserFetchFileAndTitle',
array( $this, $title, &$options, &$descQuery ) );
# Don't register it now, as ImageGallery does that later.
$file = $this->fetchFileNoRegister( $title, $options );
$ig->add( $title, $label, $alt, $link, $handlerOptions );
}
$html = $ig->toHTML();
- wfRunHooks( 'AfterParserFetchFileAndTitle', array( $this, $ig, &$html ) );
+ Hooks::run( 'AfterParserFetchFileAndTitle', array( $this, $ig, &$html ) );
wfProfileOut( __METHOD__ );
return $html;
}
# Give extensions a chance to select the file revision for us
$options = array();
$descQuery = false;
- wfRunHooks( 'BeforeParserFetchFileAndTitle',
+ Hooks::run( 'BeforeParserFetchFileAndTitle',
array( $this, $title, &$options, &$descQuery ) );
# Fetch and register the file (file title may be different via hooks)
list( $file, $title ) = $this->fetchFileAndTitle( $title, $options );
$params['frame']['title'] = $this->stripAltText( $caption, $holders );
}
- wfRunHooks( 'ParserMakeImageParams', array( $title, $file, &$params, $this ) );
+ Hooks::run( 'ParserMakeImageParams', array( $title, $file, &$params, $this ) );
# Linker does the rest
$time = isset( $options['time'] ) ? $options['time'] : false;
wfProfileIn( __METHOD__ );
+ // *UPDATE* ParserOptions::matches() if any of this changes as needed
$this->mInterwikiMagic = $wgInterwikiMagic;
$this->mAllowExternalImages = $wgAllowExternalImages;
$this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
wfProfileOut( __METHOD__ );
}
+ /**
+ * Check if these options match that of another options set
+ *
+ * This ignores report limit settings that only affect HTML comments
+ *
+ * @return bool
+ * @since 1.25
+ */
+ public function matches( ParserOptions $other ) {
+ $fields = array_keys( get_class_vars( __CLASS__ ) );
+ $fields = array_diff( $fields, array(
+ 'mEnableLimitReport', // only effects HTML comments
+ 'onAccessCallback', // only used for ParserOutput option tracking
+ ) );
+ foreach ( $fields as $field ) {
+ if ( !is_object( $this->$field ) && $this->$field !== $other->$field ) {
+ return false;
+ }
+ }
+ // Check the object and lazy-loaded options
+ return (
+ $this->mUserLang->getCode() === $other->mUserLang->getCode() &&
+ $this->getDateFormat() === $other->getDateFormat()
+ );
+ }
+
/**
* Registers a callback for tracking which ParserOptions which are used.
* This is a private API with the parser.
// Give a chance for extensions to modify the hash, if they have
// extra options or other effects on the parser cache.
- wfRunHooks( 'PageRenderingHash', array( &$confstr, $this->getUser(), &$forOptions ) );
+ Hooks::run( 'PageRenderingHash', array( &$confstr, $this->getUser(), &$forOptions ) );
// Make it a valid memcached key fragment
$confstr = str_replace( ' ', '_', $confstr );
* This makes filtering them out easier and follows the xhprof style.
*
* @return array List of method entries arrays, each having:
- * - name : method name
- * - calls : the number of invoking calls
- * - real : real time ellapsed (ms)
- * - %real : percent real time
- * - cpu : CPU time ellapsed (ms)
- * - %cpu : percent CPU time
- * - memory : memory used (bytes)
- * - %memory : percent memory used
+ * - name : method name
+ * - calls : the number of invoking calls
+ * - real : real time ellapsed (ms)
+ * - %real : percent real time
+ * - cpu : CPU time ellapsed (ms)
+ * - %cpu : percent CPU time
+ * - memory : memory used (bytes)
+ * - %memory : percent memory used
+ * - min_real : min real time in a call (ms)
+ * - max_real : max real time in a call (ms)
* @since 1.25
*/
abstract public function getFunctionStats();
$this->profileIn( $section );
$that = $this;
- return new ScopedCallback( function() use ( $that, $section ) {
+ return new ScopedCallback( function () use ( $that, $section ) {
$that->profileOut( $section );
} );
}
$this->close(); // set "-total" entry
if ( $this->collateOnly ) {
- return; // already collated as methods exited
+ // already collated as methods exited
+ $this->sortCollated();
+ return;
}
$this->collated = array();
}
$this->collated['-overhead-total']['count'] = $profileCount;
- arsort( $this->collated, SORT_NUMERIC );
+ $this->sortCollated();
+ }
+
+ protected function sortCollated() {
+ uksort( $this->collated, function ( $a, $b ) {
+ $ca = $this->collated[$a]['real'];
+ $cb = $this->collated[$b]['real'];
+ if ( $ca > $cb ) {
+ return -1;
+ } elseif ( $cb > $ca ) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } );
}
/**
'%cpu' => $totalCpu ? 100 * $data['cpu'] / $totalCpu : 0,
'memory' => $data['memory'],
'%memory' => $totalMem ? 100 * $data['memory'] / $totalMem : 0,
- 'min' => $data['min_real'] * 1000,
- 'max' => $data['max_real'] * 1000
+ 'min_real' => $data['min_real'] * 1000,
+ 'max_real' => $data['max_real'] * 1000
);
}
}
public function scopedProfileIn( $section ) {
- return new ScopedCallback( function() {
+ return new ScopedCallback( function () {
// no-op
} );
}
* @see https://github.com/facebook/hhvm/blob/master/hphp/doc/profiling.md
*/
class ProfilerXhprof extends Profiler {
-
/**
* @var Xhprof $xhprof
*/
protected $xhprof;
/**
- * Type of report to send when logData() is called.
- * @var string $logType
- */
- protected $logType;
-
- /**
- * Should profile report sent to in page content be visible?
- * @var bool $visible
+ * Profiler for explicit, arbitrary, frame labels
+ * @var SectionProfiler
*/
- protected $visible;
+ protected $sprofiler;
/**
* @param array $params
* @see Xhprof::__construct()
*/
public function __construct( array $params = array() ) {
- $params = array_merge(
- array(
- 'log' => 'text',
- 'visible' => false
- ),
- $params
- );
parent::__construct( $params );
- $this->logType = $params['log'];
- $this->visible = $params['visible'];
$this->xhprof = new Xhprof( $params );
+ $this->sprofiler = new SectionProfiler();
}
/**
}
public function scopedProfileIn( $section ) {
- static $exists = null;
- // Only HHVM supports this, not the standard PECL extension
- if ( $exists === null ) {
- $exists = function_exists( 'xhprof_frame_begin' );
- }
-
- if ( $exists ) {
- xhprof_frame_begin( $section );
- return new ScopedCallback( function() {
- xhprof_frame_end();
- } );
- }
-
- return new ScopedCallback( function() {
- // no-op
- } );
+ return $this->sprofiler->scopedProfileIn( $section );
}
/**
$metrics = $this->xhprof->getCompleteMetrics();
$profile = array();
+ $main = null; // units in ms
foreach ( $metrics as $fname => $stats ) {
// Convert elapsed times from μs to ms to match ProfilerStandard
- $profile[] = array(
+ $entry = array(
'name' => $fname,
'calls' => $stats['ct'],
'real' => $stats['wt']['total'] / 1000,
'%cpu' => isset( $stats['cpu'] ) ? $stats['cpu']['percent'] : 0,
'memory' => isset( $stats['mu'] ) ? $stats['mu']['total'] : 0,
'%memory' => isset( $stats['mu'] ) ? $stats['mu']['percent'] : 0,
- 'min' => $stats['wt']['min'] / 1000,
- 'max' => $stats['wt']['max'] / 1000
+ 'min_real' => $stats['wt']['min'] / 1000,
+ 'max_real' => $stats['wt']['max'] / 1000
);
+ $profile[] = $entry;
+ if ( $fname === 'main()' ) {
+ $main = $entry;
+ }
+ }
+
+ // Merge in all of the custom profile sections
+ foreach ( $this->sprofiler->getFunctionStats() as $stats ) {
+ // @note: getFunctionStats() values already in ms
+ $stats['%real'] = $stats['real'] / $main['real'];
+ $stats['%cpu'] = $main['cpu'] ? $stats['cpu'] / $main['cpu'] * 100 : 0;
+ $stats['%memory'] = $main['memory'] ? $stats['memory'] / $main['memory'] * 100 : 0;
+ $profile[] = $stats; // assume no section names collide with $metrics
}
return $profile;
* @return string
*/
protected function getFunctionReport() {
- $data = $this->xhprof->getInclusiveMetrics();
- uasort( $data, Xhprof::makeSortFunction( 'wt', 'total' ) );
+ $data = $this->getFunctionStats();
+ usort( $data, function( $a, $b ) {
+ if ( $a['real'] === $b['real'] ) {
+ return 0;
+ }
+ return ( $a['real'] > $b['real'] ) ? -1 : 1; // descending
+ } );
$width = 140;
$nameWidth = $width - 65;
$out[] = sprintf( "%-{$nameWidth}s %6s %9s %9s %9s %9s %7s %9s",
'Name', 'Calls', 'Total', 'Min', 'Each', 'Max', '%', 'Mem'
);
- foreach ( $data as $func => $stats ) {
- $out[] = sprintf( $format,
- $func,
- $stats['ct'],
- $stats['wt']['total'],
- $stats['wt']['min'],
- $stats['wt']['mean'],
- $stats['wt']['max'],
- $stats['wt']['percent'],
- isset( $stats['mu'] ) ? $stats['mu']['total'] : 0
- );
- }
- return implode( "\n", $out );
- }
-
- /**
- * Get a brief report of profiled functions sorted by inclusive wall clock
- * time in descending order.
- *
- * Each line of the report includes this data:
- * - Percentage of total wall clock time spent in function
- * - Total wall clock time spent in function in seconds
- * - Number of times function was called
- * - Function name
- *
- * @param string $header Header text to prepend to report
- * @param string $footer Footer text to append to report
- * @return string
- */
- protected function getSummaryReport( $header = '', $footer = '' ) {
- $data = $this->xhprof->getInclusiveMetrics();
- uasort( $data, Xhprof::makeSortFunction( 'wt', 'total' ) );
-
- $format = '%6.2f%% %3.6f %6d - %s';
- $out = array( $header );
- foreach ( $data as $func => $stats ) {
+ foreach ( $data as $stats ) {
$out[] = sprintf( $format,
- $stats['wt']['percent'],
- $stats['wt']['total'] / 1e6,
- $stats['ct'],
- $func
+ $stats['name'],
+ $stats['calls'],
+ $stats['real'] * 1000,
+ $stats['min_real'] * 1000,
+ $stats['real'] / $stats['calls'] * 1000,
+ $stats['max_real'] * 1000,
+ $stats['%real'],
+ $stats['memory']
);
}
- $out[] = $footer;
return implode( "\n", $out );
}
}
* @since 1.25
*/
class SectionProfiler {
+ /** @var array Map of (mem,real,cpu) */
+ protected $start;
+ /** @var array Map of (mem,real,cpu) */
+ protected $end;
/** @var array List of resolved profile calls with start/end data */
protected $stack = array();
/** @var array Queue of open profile calls with start data */
protected $collated = array();
/** @var bool */
protected $collateDone = false;
+
/** @var bool Whether to collect the full stack trace or just aggregates */
protected $collateOnly = true;
-
/** @var array Cache of a standard broken collation entry */
protected $errorEntry;
+ /** @var callable Cache of a profile out callback */
+ protected $profileOutCallback;
/**
* @param array $params
public function __construct( array $params = array() ) {
$this->errorEntry = $this->getErrorEntry();
$this->collateOnly = empty( $params['trace'] );
+ $this->profileOutCallback = function ( $profiler, $section ) {
+ $profiler->profileOutInternal( $section );
+ };
}
/**
$this->profileInInternal( $section );
$that = $this;
- return new ScopedCallback( function() use ( $that, $section ) {
- $that->profileOutInternal( $section );
- } );
+ return new ScopedCallback( $this->profileOutCallback, array( $that, $section ) );
}
/**
* - %cpu : percent real time
* - memory : memory used (bytes)
* - %memory : percent memory used
+ * - min_real : min real time in a call (ms)
+ * - max_real : max real time in a call (ms)
*/
public function getFunctionStats() {
$this->collateData();
- $totalCpu = 0.0;
- $totalReal = 0.0;
- $totalMem = 0;
- foreach ( $this->collated as $fname => $data ) {
- $totalCpu += $data['cpu'];
- $totalReal += $data['real'];
- $totalMem += $data['memory'];
- }
+ $totalCpu = max( $this->end['cpu'] - $this->start['cpu'], 0 );
+ $totalReal = max( $this->end['real'] - $this->start['real'], 0 );
+ $totalMem = max( $this->end['memory'] - $this->start['memory'], 0 );
$profile = array();
foreach ( $this->collated as $fname => $data ) {
'%cpu' => $totalCpu ? 100 * $data['cpu'] / $totalCpu : 0,
'memory' => $data['memory'],
'%memory' => $totalMem ? 100 * $data['memory'] / $totalMem : 0,
+ 'min_real' => 1000 * $data['min_real'],
+ 'max_real' => 1000 * $data['max_real']
);
}
'%cpu' => 100,
'memory' => $totalMem,
'%memory' => 100,
+ 'min_real' => 1000 * $totalReal,
+ 'max_real' => 1000 * $totalReal
);
return $profile;
}
+ /**
+ * Clear all of the profiling data for another run
+ */
+ public function reset() {
+ $this->start = null;
+ $this->end = null;
+ $this->stack = array();
+ $this->workStack = array();
+ $this->collated = array();
+ $this->collateDone = false;
+ }
+
/**
* @return array Initial collation entry
*/
'cpu' => 0.0,
'real' => 0.0,
'memory' => 0,
- 'count' => 0
+ 'count' => 0,
+ 'min_real' => 0.0,
+ 'max_real' => 0.0
);
}
$entry['real'] += $elapsedReal;
$entry['memory'] += $memChange > 0 ? $memChange : 0;
$entry['count']++;
+ $entry['min_real'] = min( $entry['min_real'], $elapsedReal );
+ $entry['max_real'] = max( $entry['max_real'], $elapsedReal );
}
/**
* @param string $functionname
*/
public function profileInInternal( $functionname ) {
+ // Once the data is collated for reports, any future calls
+ // should clear the collation cache so the next report will
+ // reflect them. This matters when trace mode is used.
+ $this->collateDone = false;
+
+ $cpu = $this->getTime( 'cpu' );
+ $real = $this->getTime( 'wall' );
+ $memory = memory_get_usage();
+
+ if ( $this->start === null ) {
+ $this->start = array( 'cpu' => $cpu, 'real' => $real, 'memory' => $memory );
+ }
+
$this->workStack[] = array(
$functionname,
count( $this->workStack ),
- $this->getTime( 'time' ),
- $this->getTime( 'cpu' ),
- memory_get_usage()
+ $real,
+ $cpu,
+ $memory
);
}
$this->stack[] = array( $message, 0, 0.0, 0.0, 0, 0.0, 0.0, 0 );
}
}
+
$realTime = $this->getTime( 'wall' );
$cpuTime = $this->getTime( 'cpu' );
+ $memUsage = memory_get_usage();
+
if ( $this->collateOnly ) {
$elapsedcpu = $cpuTime - $octime;
$elapsedreal = $realTime - $ortime;
- $memchange = memory_get_usage() - $omem;
+ $memchange = $memUsage - $omem;
$this->updateEntry( $functionname, $elapsedcpu, $elapsedreal, $memchange );
} else {
- $this->stack[] = array_merge( $item,
- array( $realTime, $cpuTime, memory_get_usage() ) );
+ $this->stack[] = array_merge( $item, array( $realTime, $cpuTime, $memUsage ) );
}
+
+ $this->end = array(
+ 'cpu' => $cpuTime,
+ 'real' => $realTime,
+ 'memory' => $memUsage
+ );
}
/**
$this->collated = array();
# Estimate profiling overhead
+ $oldEnd = $this->end;
$profileCount = count( $this->stack );
$this->calculateOverhead( $profileCount );
$subcalls = $this->calltreeCount( $this->stack, $index );
if ( substr( $fname, 0, 9 ) !== '-overhead' ) {
- # Adjust for profiling overhead (except special values with elapsed=0
+ # Adjust for profiling overhead (except special values with elapsed=0)
if ( $elapsed ) {
$elapsed -= $overheadInternal;
$elapsed -= ( $subcalls * $overheadTotal );
$this->collated['-overhead-total']['count'] = $profileCount;
arsort( $this->collated, SORT_NUMERIC );
+
+ // Unclobber the end info map (the overhead checking alters it)
+ $this->end = $oldEnd;
}
/**
// Initialize per-host profiling from config, back-compat if available
if ( isset( $this->params['perHost'] ) ) {
$this->perHost = $this->params['perHost'];
- } elseif( $wgProfilePerHost ) {
+ } elseif ( $wgProfilePerHost ) {
$this->perHost = $wgProfilePerHost;
}
}
// Filter out really tiny entries
$min = $this->thresholdMs;
- $stats = array_filter( $stats, function( $a ) use ( $min ) {
+ $stats = array_filter( $stats, function ( $a ) use ( $min ) {
return $a['real'] > $min;
} );
// Sort descending by time elapsed
- usort( $stats, function( $a, $b ) {
+ usort( $stats, function ( $a, $b ) {
return $a['real'] < $b['real'];
} );
// Initialize port, host, and format from config, back-compat if available
if ( isset( $this->params['udpport'] ) ) {
$this->port = $this->params['udpport'];
- } elseif( $wgUDPProfilerPort ) {
+ } elseif ( $wgUDPProfilerPort ) {
$this->port = $wgUDPProfilerPort;
}
if ( isset( $this->params['udphost'] ) ) {
$this->host = $this->params['udphost'];
- } elseif( $wgUDPProfilerHost ) {
+ } elseif ( $wgUDPProfilerHost ) {
$this->host = $wgUDPProfilerHost;
}
if ( isset( $this->params['udpformat'] ) ) {
$this->format = $this->params['udpformat'];
- } elseif( $wgUDPProfilerFormatString ) {
+ } elseif ( $wgUDPProfilerFormatString ) {
$this->format = $wgUDPProfilerFormatString;
}
}
$query .= '&rcid=' . $attribs['rc_id'];
}
// HACK: We need this hook for WMF's secure server setup
- wfRunHooks( 'IRCLineURL', array( &$url, &$query, $rc ) );
+ Hooks::run( 'IRCLineURL', array( &$url, &$query, $rc ) );
$url .= $query;
}
*/
protected $sources = array();
- /** @var bool */
- protected $hasErrors = false;
+ /**
+ * Errors accumulated during current respond() call.
+ * @var array
+ */
+ protected $errors = array();
/**
* Load information stored in the database about modules.
foreach ( array_keys( $modulesWithoutMessages ) as $name ) {
$module = $this->getModule( $name );
if ( $module ) {
- $module->setMsgBlobMtime( $lang, 0 );
+ $module->setMsgBlobMtime( $lang, 1 );
}
}
}
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
wfDebugLog( 'resourceloader', __METHOD__ . ": minification failed: $e" );
- $this->hasErrors = true;
- // Return exception as a comment
- $result = self::formatException( $e );
+ $this->errors[] = self::formatExceptionNoComment( $e );
}
wfProfileOut( __METHOD__ );
// Register core modules
$this->register( include "$IP/resources/Resources.php" );
// Register extension modules
- wfRunHooks( 'ResourceLoaderRegisterModules', array( &$this ) );
+ Hooks::run( 'ResourceLoaderRegisterModules', array( &$this ) );
$this->register( $config->get( 'ResourceModules' ) );
if ( $config->get( 'EnableJavaScriptTest' ) === true ) {
$testModules = array();
$testModules['qunit'] = array();
// Get other test suites (e.g. from extensions)
- wfRunHooks( 'ResourceLoaderTestModules', array( &$testModules, &$this ) );
+ Hooks::run( 'ResourceLoaderTestModules', array( &$testModules, &$this ) );
// Add the testrunner (which configures QUnit) to the dependencies.
// Since it must be ready before any of the test suites are executed.
ob_start();
wfProfileIn( __METHOD__ );
- $errors = '';
// Find out which modules are missing and instantiate the others
$modules = array();
// This is a security issue, see bug 34907.
if ( $module->getGroup() === 'private' ) {
wfDebugLog( 'resourceloader', __METHOD__ . ": request for private module '$name' denied" );
- $this->hasErrors = true;
- // Add exception to the output as a comment
- $errors .= self::makeComment( "Cannot show private module \"$name\"" );
-
+ $this->errors[] = "Cannot show private module \"$name\"";
continue;
}
$modules[$name] = $module;
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
wfDebugLog( 'resourceloader', __METHOD__ . ": preloading module info failed: $e" );
- $this->hasErrors = true;
- // Add exception to the output as a comment
- $errors .= self::formatException( $e );
+ $this->errors[] = self::formatExceptionNoComment( $e );
}
wfProfileIn( __METHOD__ . '-getModifiedTime' );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
wfDebugLog( 'resourceloader', __METHOD__ . ": calculating maximum modified time failed: $e" );
- $this->hasErrors = true;
- // Add exception to the output as a comment
- $errors .= self::formatException( $e );
+ $this->errors[] = self::formatExceptionNoComment( $e );
}
}
// Generate a response
$response = $this->makeModuleResponse( $context, $modules, $missing );
- // Prepend comments indicating exceptions
- $response = $errors . $response;
-
// Capture any PHP warnings from the output buffer and append them to the
- // response in a comment if we're in debug mode.
+ // error list if we're in debug mode.
if ( $context->getDebug() && strlen( $warnings = ob_get_contents() ) ) {
- $response = self::makeComment( $warnings ) . $response;
- $this->hasErrors = true;
+ $this->errors[] = $warnings;
}
// Save response to file cache unless there are errors
- if ( isset( $fileCache ) && !$errors && !count( $missing ) ) {
- // Cache single modules...and other requests if there are enough hits
+ if ( isset( $fileCache ) && !$this->errors && !count( $missing ) ) {
+ // Cache single modules and images...and other requests if there are enough hits
if ( ResourceFileCache::useFileCache( $context ) ) {
if ( $fileCache->isCacheWorthy() ) {
$fileCache->saveText( $response );
}
// Send content type and cache related headers
- $this->sendResponseHeaders( $context, $mtime, $this->hasErrors );
+ $this->sendResponseHeaders( $context, $mtime, (bool)$this->errors );
// Remove the output buffer and output the response
ob_end_clean();
+
+ if ( $context->getImageObj() && $this->errors ) {
+ // We can't show both the error messages and the response when it's an image.
+ $errorText = '';
+ foreach ( $this->errors as $error ) {
+ $errorText .= $error . "\n";
+ }
+ $response = $errorText;
+ } elseif ( $this->errors ) {
+ // Prepend comments indicating errors
+ $errorText = '';
+ foreach ( $this->errors as $error ) {
+ $errorText .= self::makeComment( $error );
+ }
+ $response = $errorText . $response;
+ }
+
+ $this->errors = array();
echo $response;
wfProfileOut( __METHOD__ );
* Send content type and last modified headers to the client.
* @param ResourceLoaderContext $context
* @param string $mtime TS_MW timestamp to use for last-modified
- * @param bool $errors Whether there are commented-out errors in the response
+ * @param bool $errors Whether there are errors in the response
* @return void
*/
protected function sendResponseHeaders( ResourceLoaderContext $context, $mtime, $errors ) {
$maxage = $rlMaxage['versioned']['client'];
$smaxage = $rlMaxage['versioned']['server'];
}
- if ( $context->getOnly() === 'styles' ) {
+ if ( $context->getImageObj() ) {
+ // Output different headers if we're outputting textual errors.
+ if ( $errors ) {
+ header( 'Content-Type: text/plain; charset=utf-8' );
+ } else {
+ $context->getImageObj()->sendResponseHeaders( $context );
+ }
+ } elseif ( $context->getOnly() === 'styles' ) {
header( 'Content-Type: text/css; charset=utf-8' );
header( 'Access-Control-Allow-Origin: *' );
} else {
* Handle exception display.
*
* @param Exception $e Exception to be shown to the user
- * @return string Sanitized text that can be returned to the user
+ * @return string Sanitized text in a CSS/JS comment that can be returned to the user
*/
public static function formatException( $e ) {
+ return self::makeComment( self::formatExceptionNoComment( $e ) );
+ }
+
+ /**
+ * Handle exception display.
+ *
+ * @since 1.25
+ * @param Exception $e Exception to be shown to the user
+ * @return string Sanitized text that can be returned to the user
+ */
+ protected static function formatExceptionNoComment( $e ) {
global $wgShowExceptionDetails;
if ( $wgShowExceptionDetails ) {
- return self::makeComment( $e->__toString() );
+ return $e->__toString();
} else {
- return self::makeComment( wfMessage( 'internalerror' )->text() );
+ return wfMessage( 'internalerror' )->text();
}
}
array $modules, array $missing = array()
) {
$out = '';
- $exceptions = '';
$states = array();
if ( !count( $modules ) && !count( $missing ) ) {
wfProfileIn( __METHOD__ );
+ $image = $context->getImageObj();
+ if ( $image ) {
+ $data = $image->getImageData( $context );
+ if ( $data === false ) {
+ $data = '';
+ $this->errors[] = 'Image generation failed';
+ }
+ wfProfileOut( __METHOD__ );
+ return $data;
+ }
+
// Pre-fetch blobs
if ( $context->shouldIncludeMessages() ) {
try {
'resourceloader',
__METHOD__ . ": pre-fetching blobs from MessageBlobStore failed: $e"
);
- $this->hasErrors = true;
- // Add exception to the output as a comment
- $exceptions .= self::formatException( $e );
+ $this->errors[] = self::formatExceptionNoComment( $e );
}
} else {
$blobs = array();
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
wfDebugLog( 'resourceloader', __METHOD__ . ": generating module package failed: $e" );
- $this->hasErrors = true;
- // Add exception to the output as a comment
- $exceptions .= self::formatException( $e );
+ $this->errors[] = self::formatExceptionNoComment( $e );
// Respond to client with error-state instead of module implementation
$states[$name] = 'error';
}
} else {
if ( count( $states ) ) {
- $exceptions .= self::makeComment(
- 'Problematic modules: ' . FormatJson::encode( $states, ResourceLoader::inDebugMode() )
- );
+ $this->errors[] = 'Problematic modules: ' .
+ FormatJson::encode( $states, ResourceLoader::inDebugMode() );
}
}
}
wfProfileOut( __METHOD__ );
- return $exceptions . $out;
+ return $out;
}
/* Static Methods */
);
}
+ /**
+ * Remove empty values from the end of an array.
+ *
+ * Values considered empty:
+ *
+ * - null
+ * - empty array
+ *
+ * @param Array $array
+ */
+ private static function trimArray( Array &$array ) {
+ $i = count( $array );
+ while ( $i-- ) {
+ if ( $array[$i] === null || $array[$i] === array() ) {
+ unset( $array[$i] );
+ } else {
+ break;
+ }
+ }
+ }
+
/**
* Returns JS code which calls mw.loader.register with the given
* parameters. Has three calling conventions:
$dependencies = null, $group = null, $source = null, $skip = null
) {
if ( is_array( $name ) ) {
+ // Build module name index
+ $index = array();
+ foreach ( $name as $i => &$module ) {
+ $index[$module[0]] = $i;
+ }
+
+ // Transform dependency names into indexes when possible, they will be resolved by
+ // mw.loader.register on the other end
+ foreach ( $name as &$module ) {
+ if ( isset( $module[2] ) ) {
+ foreach ( $module[2] as &$dependency ) {
+ if ( isset( $index[$dependency] ) ) {
+ $dependency = $index[$dependency];
+ }
+ }
+ }
+ }
+
+ array_walk( $name, array( 'self', 'trimArray' ) );
+
return Xml::encodeJsCall(
'mw.loader.register',
array( $name ),
ResourceLoader::inDebugMode()
);
} else {
- $version = (int)$version > 1 ? (int)$version : 1;
+ $registration = array( $name, $version, $dependencies, $group, $source, $skip );
+ self::trimArray( $registration );
return Xml::encodeJsCall(
'mw.loader.register',
- array( $name, $version, $dependencies, $group, $source, $skip ),
+ $registration,
ResourceLoader::inDebugMode()
);
}
protected $version;
protected $hash;
protected $raw;
+ protected $image;
+ protected $variant;
+ protected $format;
protected $userObj;
+ protected $imageObj;
/* Methods */
$this->only = $request->getVal( 'only' );
$this->version = $request->getVal( 'version' );
$this->raw = $request->getFuzzyBool( 'raw' );
+ // Image requests
+ $this->image = $request->getVal( 'image' );
+ $this->variant = $request->getVal( 'variant' );
+ $this->format = $request->getVal( 'format' );
$skinnames = Skin::getSkinNames();
// If no skin is specified, or we don't recognize the skin, use the default skin
return $this->raw;
}
+ /**
+ * @return string|null
+ */
+ public function getImage() {
+ return $this->image;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getVariant() {
+ return $this->variant;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getFormat() {
+ return $this->format;
+ }
+
+ /**
+ * If this is a request for an image, get the ResourceLoaderImage object.
+ *
+ * @since 1.25
+ * @return ResourceLoaderImage|bool false if a valid object cannot be created
+ */
+ public function getImageObj() {
+ if ( $this->imageObj === null ) {
+ $this->imageObj = false;
+
+ if ( !$this->image ) {
+ return $this->imageObj;
+ }
+
+ $modules = $this->getModules();
+ if ( count( $modules ) !== 1 ) {
+ return $this->imageObj;
+ }
+
+ $module = $this->getResourceLoader()->getModule( $modules[0] );
+ if ( !$module || !$module instanceof ResourceLoaderImageModule ) {
+ return $this->imageObj;
+ }
+
+ $image = $module->getImage( $this->image );
+ if ( !$image ) {
+ return $this->imageObj;
+ }
+
+ $this->imageObj = $image;
+ }
+
+ return $this->imageObj;
+ }
+
/**
* @return bool
*/
if ( !isset( $this->hash ) ) {
$this->hash = implode( '|', array(
$this->getLanguage(), $this->getDirection(), $this->getSkin(), $this->getUser(),
+ $this->getImage(), $this->getVariant(), $this->getFormat(),
$this->getDebug(), $this->getOnly(), $this->getVersion()
) );
}
--- /dev/null
+<?php
+/**
+ * Class encapsulating an image used in a ResourceLoaderImageModule.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Class encapsulating an image used in a ResourceLoaderImageModule.
+ *
+ * @since 1.25
+ */
+class ResourceLoaderImage {
+
+ /**
+ * Map of allowed file extensions to their MIME types.
+ * @var array
+ */
+ protected static $fileTypes = array(
+ 'svg' => 'image/svg+xml',
+ 'png' => 'image/png',
+ 'gif' => 'image/gif',
+ 'jpg' => 'image/jpg',
+ );
+
+ /**
+ * @param string $name Image name
+ * @param string $module Module name
+ * @param string|array $descriptor Path to image file, or array structure containing paths
+ * @param string $basePath Directory to which paths in descriptor refer
+ * @param array $variants
+ * @throws MWException
+ */
+ public function __construct( $name, $module, $descriptor, $basePath, $variants ) {
+ $this->name = $name;
+ $this->module = $module;
+ $this->descriptor = $descriptor;
+ $this->basePath = $basePath;
+ $this->variants = $variants;
+
+ // Ensure that all files have common extension.
+ $extensions = array();
+ $descriptor = (array)$descriptor;
+ array_walk_recursive( $descriptor, function ( $path ) use ( &$extensions ) {
+ $extensions[] = pathinfo( $path, PATHINFO_EXTENSION );
+ } );
+ $extensions = array_unique( $extensions );
+ if ( count( $extensions ) !== 1 ) {
+ throw new MWException( 'Image type for various images differs.' );
+ }
+ $ext = $extensions[0];
+ if ( !isset( self::$fileTypes[$ext] ) ) {
+ throw new MWException( 'Invalid image type; svg, png, gif or jpg required.' );
+ }
+ $this->extension = $ext;
+ }
+
+ /**
+ * Get name of this image.
+ *
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * Get name of the module this image belongs to.
+ *
+ * @return string
+ */
+ public function getModule() {
+ return $this->module;
+ }
+
+ /**
+ * Get the list of variants this image can be converted to.
+ *
+ * @return string[]
+ */
+ public function getVariants() {
+ return array_keys( $this->variants );
+ }
+
+ /**
+ * Get the path to image file for given context.
+ *
+ * @param ResourceLoaderContext $context Any context
+ * @return string
+ */
+ protected function getPath( ResourceLoaderContext $context ) {
+ $desc = $this->descriptor;
+ if ( is_string( $desc ) ) {
+ return $this->basePath . '/' . $desc;
+ } elseif ( isset( $desc['lang'][ $context->getLanguage() ] ) ) {
+ return $this->basePath . '/' . $desc['lang'][ $context->getLanguage() ];
+ } elseif ( isset( $desc[ $context->getDirection() ] ) ) {
+ return $this->basePath . '/' . $desc[ $context->getDirection() ];
+ } else {
+ return $this->basePath . '/' . $desc['default'];
+ }
+ }
+
+ /**
+ * Get the extension of the image.
+ *
+ * @param string $format Format to get the extension for, 'original' or 'rasterized'
+ * @return string Extension without leading dot, e.g. 'png'
+ */
+ public function getExtension( $format = 'original' ) {
+ if ( $format === 'rasterized' && $this->extension === 'svg' ) {
+ return 'png';
+ } else {
+ return $this->extension;
+ }
+ }
+
+ /**
+ * Get the MIME type of the image.
+ *
+ * @param string $format Format to get the MIME type for, 'original' or 'rasterized'
+ * @return string
+ */
+ public function getMimeType( $format = 'original' ) {
+ $ext = $this->getExtension( $format );
+ return self::$fileTypes[$ext];
+ }
+
+ /**
+ * Get the load.php URL that will produce this image.
+ *
+ * @param ResourceLoaderContext $context Any context
+ * @param string $script URL to load.php
+ * @param string|null $variant Variant to get the URL for
+ * @param string $format Format to get the URL for, 'original' or 'rasterized'
+ * @return string
+ */
+ public function getUrl( ResourceLoaderContext $context, $script, $variant, $format ) {
+ $query = array(
+ 'modules' => $this->getModule(),
+ 'image' => $this->getName(),
+ 'variant' => $variant,
+ 'format' => $format,
+ 'lang' => $context->getLanguage(),
+ 'version' => $context->getVersion(),
+ );
+
+ return wfExpandUrl( wfAppendQuery( $script, $query ), PROTO_RELATIVE );
+ }
+
+ /**
+ * Get the data: URI that will produce this image.
+ *
+ * @param ResourceLoaderContext $context Any context
+ * @param string|null $variant Variant to get the URI for
+ * @param string $format Format to get the URI for, 'original' or 'rasterized'
+ * @return string
+ */
+ public function getDataUri( ResourceLoaderContext $context, $variant, $format ) {
+ $type = $this->getMimeType( $format );
+ $contents = $this->getImageData( $context, $variant, $format );
+ return CSSMin::encodeStringAsDataURI( $contents, $type );
+ }
+
+ /**
+ * Get actual image data for this image. This can be saved to a file or sent to the browser to
+ * produce the converted image.
+ *
+ * Call getExtension() or getMimeType() with the same $format argument to learn what file type the
+ * returned data uses.
+ *
+ * @param ResourceLoaderContext $context Image context, or any context of $variant and $format
+ * given.
+ * @param string|null $variant Variant to get the data for. Optional, if given, overrides the data
+ * from $context.
+ * @param string $format Format to get the data for, 'original' or 'rasterized'. Optional, if
+ * given, overrides the data from $context.
+ * @return string|false Possibly binary image data, or false on failure
+ */
+ public function getImageData( ResourceLoaderContext $context, $variant = false, $format = false ) {
+ if ( $variant === false ) {
+ $variant = $context->getVariant();
+ }
+ if ( $format === false ) {
+ $format = $context->getFormat();
+ }
+
+ if ( $this->getExtension() !== 'svg' ) {
+ return file_get_contents( $this->getPath( $context ) );
+ }
+
+ if ( $variant && isset( $this->variants[$variant] ) ) {
+ $data = $this->variantize( $this->variants[$variant], $context );
+ } else {
+ $data = file_get_contents( $this->getPath( $context ) );
+ }
+
+ if ( $format === 'rasterized' ) {
+ $data = $this->rasterize( $data );
+ }
+
+ return $data;
+ }
+
+ /**
+ * Send response headers (using the header() function) that are necessary to correctly serve the
+ * image data for this image, as returned by getImageData().
+ *
+ * Note that the headers are independent of the language or image variant.
+ *
+ * @param ResourceLoaderContext $context Image context
+ */
+ public function sendResponseHeaders( ResourceLoaderContext $context ) {
+ $format = $context->getFormat();
+ $mime = $this->getMimeType( $format );
+ $filename = $this->getName() . '.' . $this->getExtension( $format );
+
+ header( 'Content-Type: ' . $mime );
+ header( 'Content-Disposition: ' .
+ FileBackend::makeContentDisposition( 'inline', $filename ) );
+ }
+
+ /**
+ * Convert this image, which is assumed to be SVG, to given variant.
+ *
+ * @param array $variantConf Array with a 'color' key, its value will be used as fill color
+ * @param ResourceLoaderContext $context Image context
+ * @return string New SVG file data
+ */
+ protected function variantize( $variantConf, ResourceLoaderContext $context ) {
+ $dom = new DomDocument;
+ $dom->load( $this->getPath( $context ) );
+ $root = $dom->documentElement;
+ $wrapper = $dom->createElement( 'g' );
+ while ( $root->firstChild ) {
+ $wrapper->appendChild( $root->firstChild );
+ }
+ $root->appendChild( $wrapper );
+ $wrapper->setAttribute( 'fill', $variantConf['color'] );
+ return $dom->saveXml();
+ }
+
+ /**
+ * Massage the SVG image data for converters which doesn't understand some path data syntax.
+ *
+ * This is necessary for rsvg and ImageMagick when compiled with rsvg support.
+ * Upstream bug is https://bugzilla.gnome.org/show_bug.cgi?id=620923, fixed 2014-11-10, so
+ * this will be needed for a while. (T76852)
+ *
+ * @param string $svg SVG image data
+ * @return string Massaged SVG image data
+ */
+ protected function massageSvgPathdata( $svg ) {
+ $dom = new DomDocument;
+ $dom->loadXml( $svg );
+ foreach ( $dom->getElementsByTagName( 'path' ) as $node ) {
+ $pathData = $node->getAttribute( 'd' );
+ // Make sure there is at least one space between numbers, and that leading zero is not omitted.
+ // rsvg has issues with syntax like "M-1-2" and "M.445.483" and especially "M-.445-.483".
+ $pathData = preg_replace( '/(-?)(\d*\.\d+|\d+)/', ' ${1}0$2 ', $pathData );
+ // Strip unnecessary leading zeroes for prettiness, not strictly necessary
+ $pathData = preg_replace( '/([ -])0(\d)/', '$1$2', $pathData );
+ $node->setAttribute( 'd', $pathData );
+ }
+ return $dom->saveXml();
+ }
+
+ /**
+ * Convert passed image data, which is assumed to be SVG, to PNG.
+ *
+ * @param string $svg SVG image data
+ * @return string|bool PNG image data, or false on failure
+ */
+ protected function rasterize( $svg ) {
+ // This code should be factored out to a separate method on SvgHandler, or perhaps a separate
+ // class, with a separate set of configuration settings.
+ //
+ // This is a distinct use case from regular SVG rasterization:
+ // * we can skip many sanity and security checks (as the images come from a trusted source,
+ // rather than from the user)
+ // * we need to provide extra options to some converters to achieve acceptable quality for very
+ // small images, which might cause performance issues in the general case
+ // * we need to directly pass image data to the converter instead of a file path
+ //
+ // See https://phabricator.wikimedia.org/T76473#801446 for examples of what happens with the
+ // default settings.
+ //
+ // For now, we special-case rsvg (used in WMF production) and do a messy workaround for other
+ // converters.
+
+ global $wgSVGConverter, $wgSVGConverterPath;
+
+ $svg = $this->massageSvgPathdata( $svg );
+
+ if ( $wgSVGConverter === 'rsvg' ) {
+ $command = 'rsvg-convert'; // Should be just 'rsvg'? T76476
+ if ( $wgSVGConverterPath ) {
+ $command = wfEscapeShellArg( "$wgSVGConverterPath/" ) . $command;
+ }
+
+ $process = proc_open(
+ $command,
+ array( 0 => array( 'pipe', 'r' ), 1 => array( 'pipe', 'w' ) ),
+ $pipes
+ );
+
+ if ( is_resource( $process ) ) {
+ fwrite( $pipes[0], $svg );
+ fclose( $pipes[0] );
+ $png = stream_get_contents( $pipes[1] );
+ fclose( $pipes[1] );
+ proc_close( $process );
+
+ return $png ?: false;
+ }
+ return false;
+
+ } else {
+ // Write input to and read output from a temporary file
+ $tempFilenameSvg = tempnam( wfTempDir(), 'ResourceLoaderImage' );
+ $tempFilenamePng = tempnam( wfTempDir(), 'ResourceLoaderImage' );
+
+ file_put_contents( $tempFilenameSvg, $svg );
+
+ $metadata = SVGMetadataExtractor::getMetadata( $tempFilenameSvg );
+ if ( !isset( $metadata['width'] ) || !isset( $metadata['height'] ) ) {
+ return false;
+ }
+
+ $handler = new SvgHandler;
+ $handler->rasterize( $tempFilenameSvg, $tempFilenamePng, $metadata['width'], $metadata['height'] );
+
+ $png = file_get_contents( $tempFilenamePng );
+
+ unlink( $tempFilenameSvg );
+ unlink( $tempFilenamePng );
+
+ return $png ?: false;
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * Resource loader module for generated and embedded images.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Trevor Parscal
+ */
+
+/**
+ * Resource loader module for generated and embedded images.
+ *
+ * @since 1.25
+ */
+class ResourceLoaderImageModule extends ResourceLoaderModule {
+
+ /**
+ * Local base path, see __construct()
+ * @var string
+ */
+ protected $localBasePath = '';
+
+ protected $origin = self::ORIGIN_CORE_SITEWIDE;
+
+ protected $images = array();
+ protected $variants = array();
+ protected $prefix = array();
+ protected $targets = array( 'desktop', 'mobile' );
+
+ /**
+ * Constructs a new module from an options array.
+ *
+ * @param array $options List of options; if not given or empty, an empty module will be
+ * constructed
+ * @param string $localBasePath Base path to prepend to all local paths in $options. Defaults
+ * to $IP
+ *
+ * Below is a description for the $options array:
+ * @par Construction options:
+ * @code
+ * array(
+ * // Base path to prepend to all local paths in $options. Defaults to $IP
+ * 'localBasePath' => [base path],
+ * // CSS class prefix to use in all style rules
+ * 'prefix' => [CSS class prefix],
+ * // List of variants that may be used for the image files
+ * 'variants' => array(
+ * // ([image type] is a string, used in generated CSS class names and to match variants to images)
+ * [image type] => array(
+ * [variant name] => array(
+ * 'color' => [color string, e.g. '#ffff00'],
+ * 'global' => [boolean, if true, this variant is available for all images of this type],
+ * ),
+ * )
+ * ),
+ * // List of image files and their options
+ * 'images' => array(
+ * [image type] => array(
+ * [file path string],
+ * [file path string] => array(
+ * 'name' => [image name string, defaults to file name],
+ * 'variants' => [array of variant name strings, variants available for this image],
+ * ),
+ * )
+ * ),
+ * )
+ * @endcode
+ * @throws MWException
+ */
+ public function __construct( $options = array(), $localBasePath = null ) {
+ $this->localBasePath = self::extractLocalBasePath( $options, $localBasePath );
+
+ if ( !isset( $options['prefix'] ) || !$options['prefix'] ) {
+ throw new MWException(
+ "Required 'prefix' option not given or empty."
+ );
+ }
+
+ foreach ( $options as $member => $option ) {
+ switch ( $member ) {
+ case 'images':
+ if ( !is_array( $option ) ) {
+ throw new MWException(
+ "Invalid collated file path list error. '$option' given, array expected."
+ );
+ }
+ foreach ( $option as $key => $value ) {
+ if ( !is_string( $key ) ) {
+ throw new MWException(
+ "Invalid collated file path list key error. '$key' given, string expected."
+ );
+ }
+ $this->{$member}[$key] = (array)$value;
+ }
+ break;
+
+ case 'variants':
+ if ( !is_array( $option ) ) {
+ throw new MWException(
+ "Invalid variant list error. '$option' given, array expected."
+ );
+ }
+ $this->{$member} = $option;
+ break;
+
+ case 'prefix':
+ $this->{$member} = (string)$option;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get CSS class prefix used by this module.
+ * @return string
+ */
+ public function getPrefix() {
+ return $this->prefix;
+ }
+
+ /**
+ * Get a ResourceLoaderImage object for given image.
+ * @param string $name Image name
+ * @return ResourceLoaderImage|null
+ */
+ public function getImage( $name ) {
+ $images = $this->getImages();
+ return isset( $images[$name] ) ? $images[$name] : null;
+ }
+
+ /**
+ * Get ResourceLoaderImage objects for all images.
+ * @return ResourceLoaderImage[] Array keyed by image name
+ */
+ public function getImages() {
+ if ( !isset( $this->imageObjects ) ) {
+ $this->imageObjects = array();
+
+ foreach ( $this->images as $type => $list ) {
+ foreach ( $list as $name => $options ) {
+ $imageDesc = is_string( $options ) ? $options : $options['image'];
+
+ $allowedVariants = array_merge(
+ isset( $options['variants'] ) ? $options['variants'] : array(),
+ $this->getGlobalVariants( $type )
+ );
+ $variantConfig = array_intersect_key(
+ $this->variants[$type],
+ array_fill_keys( $allowedVariants, true )
+ );
+
+ $image = new ResourceLoaderImage( $name, $this->getName(), $imageDesc, $this->localBasePath, $variantConfig );
+ $this->imageObjects[ $image->getName() ] = $image;
+ }
+ }
+ }
+
+ return $this->imageObjects;
+ }
+
+ /**
+ * Get list of variants in this module that are 'global' for given type of images, i.e., available
+ * for every image of given type regardless of image options.
+ * @param string $type Image type
+ * @return string[]
+ */
+ public function getGlobalVariants( $type ) {
+ if ( !isset( $this->globalVariants[$type] ) ) {
+ $this->globalVariants[$type] = array();
+
+ foreach ( $this->variants[$type] as $name => $config ) {
+ if ( isset( $config['global'] ) && $config['global'] ) {
+ $this->globalVariants[$type][] = $name;
+ }
+ }
+ }
+
+ return $this->globalVariants[$type];
+ }
+
+ /**
+ * Get the type of given image.
+ * @param string $imageName Image name
+ * @return string
+ */
+ public function getImageType( $imageName ) {
+ foreach ( $this->images as $type => $list ) {
+ foreach ( $list as $key => $value ) {
+ $file = is_int( $key ) ? $value : $key;
+ $options = is_array( $value ) ? $value : array();
+ $name = isset( $options['name'] ) ? $options['name'] : pathinfo( $file, PATHINFO_FILENAME );
+ if ( $name === $imageName ) {
+ return $type;
+ }
+ }
+ }
+ }
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return array
+ */
+ public function getStyles( ResourceLoaderContext $context ) {
+ // Build CSS rules
+ $rules = array();
+ $script = $context->getResourceLoader()->getLoadScript( $this->getSource() );
+ $prefix = $this->getPrefix();
+
+ foreach ( $this->getImages() as $name => $image ) {
+ $type = $this->getImageType( $name );
+
+ $declarations = $this->getCssDeclarations(
+ $image->getDataUri( $context, null, 'original' ),
+ $image->getUrl( $context, $script, null, 'rasterized' )
+ );
+ $declarations = implode( "\n\t", $declarations );
+ $rules[] = ".$prefix-$type-$name {\n\t$declarations\n}";
+
+ // TODO: Get variant configurations from $context->getSkin()
+ foreach ( $image->getVariants() as $variant ) {
+ $declarations = $this->getCssDeclarations(
+ $image->getDataUri( $context, $variant, 'original' ),
+ $image->getUrl( $context, $script, $variant, 'rasterized' )
+ );
+ $declarations = implode( "\n\t", $declarations );
+ $rules[] = ".$prefix-$type-$name-$variant {\n\t$declarations\n}";
+ }
+ }
+
+ $style = implode( "\n", $rules );
+ if ( $this->getFlip( $context ) ) {
+ $style = CSSJanus::transform( $style, true, false );
+ }
+ return array( 'all' => $style );
+ }
+
+ /**
+ * @param string $primary Primary URI
+ * @param string $fallback Fallback URI
+ * @return string[] CSS declarations to use given URIs as background-image
+ */
+ protected function getCssDeclarations( $primary, $fallback ) {
+ // SVG support using a transparent gradient to guarantee cross-browser
+ // compatibility (browsers able to understand gradient syntax support also SVG).
+ // http://pauginer.tumblr.com/post/36614680636/invisible-gradient-technique
+ return array(
+ "background-image: url($fallback);",
+ "background-image: -webkit-linear-gradient(transparent, transparent), url($primary);",
+ "background-image: linear-gradient(transparent, transparent), url($primary);",
+ );
+ }
+
+ /**
+ * @return bool
+ */
+ public function supportsURLLoading() {
+ return false;
+ }
+
+ /**
+ * Extract a local base path from module definition information.
+ *
+ * @param array $options Module definition
+ * @param string $localBasePath Path to use if not provided in module definition. Defaults
+ * to $IP
+ * @return string Local base path
+ */
+ public static function extractLocalBasePath( $options, $localBasePath = null ) {
+ global $IP;
+
+ if ( $localBasePath === null ) {
+ $localBasePath = $IP;
+ }
+
+ if ( array_key_exists( 'localBasePath', $options ) ) {
+ $localBasePath = (string)$options['localBasePath'];
+ }
+
+ return $localBasePath;
+ }
+}
* Get the last modification timestamp of the message blob for this
* module in a given language.
* @param string $lang Language code
- * @return int UNIX timestamp, or 0 if the module doesn't have messages
+ * @return int UNIX timestamp
*/
public function getMsgBlobMtime( $lang ) {
if ( !isset( $this->msgBlobMtime[$lang] ) ) {
if ( !count( $this->getMessages() ) ) {
- return 0;
+ return 1;
}
$dbr = wfGetDB( DB_SLAVE );
* Set a preloaded message blob last modification timestamp. Used so we
* can load this information for all modules at once.
* @param string $lang Language code
- * @param int $mtime UNIX timestamp or 0 if there is no such blob
+ * @param int $mtime UNIX timestamp
*/
public function setMsgBlobMtime( $lang, $mtime ) {
$this->msgBlobMtime[$lang] = $mtime;
* @return int UNIX timestamp
*/
public function getModifiedTime( ResourceLoaderContext $context ) {
- // 0 would mean now
return 1;
}
* Helper method for calculating when the module's hash (if it has one) changed.
*
* @param ResourceLoaderContext $context
- * @return int UNIX timestamp or 0 if no hash was provided
- * by getModifiedHash()
+ * @return int UNIX timestamp
*/
public function getHashMtime( ResourceLoaderContext $context ) {
$hash = $this->getModifiedHash( $context );
if ( !is_string( $hash ) ) {
- return 0;
+ return 1;
}
$cache = wfGetCache( CACHE_ANYTHING );
return $data['timestamp'];
}
- $timestamp = wfTimestamp();
+ $timestamp = time();
$cache->set( $key, array(
'hash' => $hash,
'timestamp' => $timestamp,
* @since 1.23
*
* @param ResourceLoaderContext $context
- * @return int UNIX timestamp or 0 if no definition summary was provided
- * by getDefinitionSummary()
+ * @return int UNIX timestamp
*/
public function getDefinitionMtime( ResourceLoaderContext $context ) {
wfProfileIn( __METHOD__ );
$summary = $this->getDefinitionSummary( $context );
if ( $summary === null ) {
wfProfileOut( __METHOD__ );
- return 0;
+ return 1;
}
$hash = md5( json_encode( $summary ) );
* Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist
* but returns 1 instead.
* @param string $filename File name
- * @return int UNIX timestamp, or 1 if the file doesn't exist
+ * @return int UNIX timestamp
*/
protected static function safeFilemtime( $filename ) {
- if ( file_exists( $filename ) ) {
- return filemtime( $filename );
- } else {
- // We only ever map this function on an array if we're gonna call max() after,
- // so return our standard minimum timestamps here. This is 1, not 0, because
- // wfTimestamp(0) == NOW
+ if ( !file_exists( $filename ) ) {
return 1;
}
+ return filemtime( $filename );
}
}
/**
* @param $context ResourceLoaderContext
- * @return boolean
+ * @return bool
*/
public function isKnownEmpty( ResourceLoaderContext $context ) {
// Regardless of whether the files are specified, we always
'wgResourceLoaderStorageEnabled' => $conf->get( 'ResourceLoaderStorageEnabled' ),
);
- wfRunHooks( 'ResourceLoaderGetConfigVars', array( &$vars ) );
+ Hooks::run( 'ResourceLoaderGetConfigVars', array( &$vars ) );
$this->configVars[$hash] = $vars;
return $this->configVars[$hash];
}
/**
- * Optimize the dependency tree in $this->modules and return it.
+ * Optimize the dependency tree in $this->modules.
*
* The optimization basically works like this:
* Given we have module A with the dependencies B and C
* Now we don't have to tell the client to explicitly fetch module
* C as that's already included in module B.
*
- * This way we can reasonably reduce the amout of module registration
+ * This way we can reasonably reduce the amount of module registration
* data send to the client.
*
* @param array &$registryData Modules keyed by name with properties:
- * - string 'version'
+ * - number 'version'
* - array 'dependencies'
* - string|null 'group'
* - string 'source'
continue;
}
- // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always
- // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX
+ // Coerce module timestamp to UNIX timestamp.
+ // getModifiedTime() is supposed to return a UNIX timestamp, but custom implementations
+ // might forget. TODO: Maybe emit warning?
$moduleMtime = wfTimestamp( TS_UNIX, $module->getModifiedTime( $context ) );
- $mtime = max( $moduleMtime, wfTimestamp( TS_UNIX, $this->getConfig()->get( 'CacheEpoch' ) ) );
-
- // FIXME: Convert to numbers, wfTimestamp always gives us stings, even for TS_UNIX
$skipFunction = $module->getSkipFunction();
if ( $skipFunction !== null && !ResourceLoader::inDebugMode() ) {
);
}
+ $mtime = max(
+ $moduleMtime,
+ wfTimestamp( TS_UNIX, $this->getConfig()->get( 'CacheEpoch' ) )
+ );
+
$registryData[$name] = array(
- 'version' => $mtime,
+ // Convert to numbers as wfTimestamp always returns a string, even for TS_UNIX
+ 'version' => (int) $mtime,
'dependencies' => $module->getDependencies(),
'group' => $module->getGroup(),
'source' => $module->getSource(),
if ( $data['loader'] !== false ) {
$out .= ResourceLoader::makeCustomLoaderScript(
$name,
- wfTimestamp( TS_ISO_8601_BASIC, $data['version'] ),
+ $data['version'],
$data['dependencies'],
$data['group'],
$data['source'],
continue;
}
- if (
- !count( $data['dependencies'] ) &&
- $data['group'] === null &&
- $data['source'] === 'local' &&
- $data['skip'] === null
- ) {
- // Modules with no dependencies, group, foreign source or skip function;
- // call mw.loader.register(name, timestamp)
- $registrations[] = array( $name, $data['version'] );
- } elseif (
- $data['group'] === null &&
- $data['source'] === 'local' &&
- $data['skip'] === null
- ) {
- // Modules with dependencies but no group, foreign source or skip function;
- // call mw.loader.register(name, timestamp, dependencies)
- $registrations[] = array( $name, $data['version'], $data['dependencies'] );
- } elseif (
- $data['source'] === 'local' &&
- $data['skip'] === null
- ) {
- // Modules with a group but no foreign source or skip function;
- // call mw.loader.register(name, timestamp, dependencies, group)
- $registrations[] = array(
- $name,
- $data['version'],
- $data['dependencies'],
- $data['group']
- );
- } elseif ( $data['skip'] === null ) {
- // Modules with a foreign source but no skip function;
- // call mw.loader.register(name, timestamp, dependencies, group, source)
- $registrations[] = array(
- $name,
- $data['version'],
- $data['dependencies'],
- $data['group'],
- $data['source']
- );
- } else {
- // Modules with a skip function;
- // call mw.loader.register(name, timestamp, dependencies, group, source, skip)
- $registrations[] = array(
- $name,
- $data['version'],
- $data['dependencies'],
- $data['group'],
- $data['source'],
- $data['skip']
- );
- }
+ // Call mw.loader.register(name, timestamp, dependencies, group, source, skip)
+ $registrations[] = array(
+ $name,
+ $data['version'],
+ $data['dependencies'],
+ $data['group'],
+ // Swap default (local) for null
+ $data['source'] === 'local' ? null : $data['source'],
+ $data['skip']
+ );
}
// Register modules
// Get the latest version
$loader = $context->getResourceLoader();
- $version = 0;
+ $version = 1;
foreach ( $moduleNames as $moduleName ) {
$version = max( $version,
$loader->getModule( $moduleName )->getModifiedTime( $context )
public function getGroup() {
return 'private';
}
-
- /**
- * @return array
- */
- public function getDependencies() {
- return array( 'mediawiki.user' );
- }
}
--- /dev/null
+<?php
+/**
+ * Resource loader module for default user preferences.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Ori Livneh
+ */
+
+/**
+ * Module for default user preferences.
+ */
+class ResourceLoaderUserDefaultsModule extends ResourceLoaderModule {
+
+ /* Protected Members */
+
+ protected $targets = array( 'desktop', 'mobile' );
+
+ /* Methods */
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return string Hash
+ */
+ public function getModifiedHash( ResourceLoaderContext $context ) {
+ return md5( serialize( User::getDefaultOptions() ) );
+ }
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return int
+ */
+ public function getModifiedTime( ResourceLoaderContext $context ) {
+ return $this->getHashMtime( $context );
+ }
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return string
+ */
+ public function getScript( ResourceLoaderContext $context ) {
+ return Xml::encodeJsCall( 'mw.user.options.set', array( User::getDefaultOptions() ) );
+ }
+}
/* Methods */
+ /**
+ * @return array List of module names as strings
+ */
+ public function getDependencies() {
+ return array( 'user.defaults' );
+ }
+
/**
* @param ResourceLoaderContext $context
- * @return array|int|mixed
+ * @return int
*/
public function getModifiedTime( ResourceLoaderContext $context ) {
$hash = $context->getHash();
*/
public function getScript( ResourceLoaderContext $context ) {
return Xml::encodeJsCall( 'mw.user.options.set',
- array( $context->getUserObj()->getOptions() ),
+ array( $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS ) ),
ResourceLoader::inDebugMode()
);
}
/**
* @param ResourceLoaderContext $context
- * @return int|mixed
+ * @return int
*/
public function getModifiedTime( ResourceLoaderContext $context ) {
- $modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
+ $modifiedTime = 1;
$titleInfo = $this->getTitleInfo( $context );
if ( count( $titleInfo ) ) {
$mtimes = array_map( function ( $value ) {
* Get the modification times of all titles that would be loaded for
* a given context.
* @param ResourceLoaderContext $context Context object
- * @return array keyed by page dbkey, with value is an array with 'length' and 'timestamp'
- * keys, where the timestamp is a unix one
+ * @return array Keyed by page dbkey. Value is an array with 'length' and 'timestamp'
+ * keys, where the timestamp is a UNIX timestamp
*/
protected function getTitleInfo( ResourceLoaderContext $context ) {
$dbr = $this->getDB();
}
/**
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @return mixed
*/
public function doQuery( $db ) {
}
/**
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @return mixed
*/
public function doQuery( $db ) {
}
/**
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @return mixed
*/
public function doQuery( $db ) {
} else {
$logType = 'delete';
}
- // Add params for effected page and ids
+ // Add params for affected page and ids
$logParams = $this->getLogParams( $params );
// Actually add the deletion log entry
$log = new LogPage( $logType );
}
/**
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @return mixed
*/
public function doQuery( $db ) {
}
/**
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @return mixed
*/
public function doQuery( $db ) {
public function doPostCommitUpdates() {
$this->title->purgeSquid();
// Extensions that require referencing previous revisions may need this
- wfRunHooks( 'ArticleRevisionVisibilitySet', array( &$this->title ) );
+ Hooks::run( 'ArticleRevisionVisibilitySet', array( &$this->title ) );
return Status::newGood();
}
}
* @param string $name Username
* @param int $userId User id
* @param string $op Operator '|' or '&'
- * @param null|DatabaseBase $dbw If you happen to have one lying around
+ * @param null|IDatabase $dbw If you happen to have one lying around
* @return bool
*/
private static function setUsernameBitfields( $name, $userId, $op, $dbw ) {
if ( !$userId || ( $op !== '|' && $op !== '&' ) ) {
return false; // sanity check
}
- if ( !$dbw instanceof DatabaseBase ) {
+ if ( !$dbw instanceof IDatabase ) {
$dbw = wfGetDB( DB_MASTER );
}
public static function getNearMatch( $searchterm ) {
$title = self::getNearMatchInternal( $searchterm );
- wfRunHooks( 'SearchGetNearMatchComplete', array( $searchterm, &$title ) );
+ Hooks::run( 'SearchGetNearMatchComplete', array( $searchterm, &$title ) );
return $title;
}
}
$titleResult = null;
- if ( !wfRunHooks( 'SearchGetNearMatchBefore', array( $allSearchTerms, &$titleResult ) ) ) {
+ if ( !Hooks::run( 'SearchGetNearMatchBefore', array( $allSearchTerms, &$titleResult ) ) ) {
return $titleResult;
}
return $title;
}
- if ( !wfRunHooks( 'SearchAfterNoDirectMatch', array( $term, &$title ) ) ) {
+ if ( !Hooks::run( 'SearchAfterNoDirectMatch', array( $term, &$title ) ) ) {
return $title;
}
// Give hooks a chance at better match variants
$title = null;
- if ( !wfRunHooks( 'SearchGetNearMatch', array( $term, &$title ) ) ) {
+ if ( !Hooks::run( 'SearchGetNearMatch', array( $term, &$title ) ) ) {
return $title;
}
}
}
}
- wfRunHooks( 'SearchableNamespaces', array( &$arr ) );
+ Hooks::run( 'SearchableNamespaces', array( &$arr ) );
return $arr;
}
$this->mTitle = $title;
if ( !is_null( $this->mTitle ) ) {
$id = false;
- wfRunHooks( 'SearchResultInitFromTitle', array( $title, &$id ) );
+ Hooks::run( 'SearchResultInitFromTitle', array( $title, &$id ) );
$this->mRevision = Revision::newFromTitle(
$this->mTitle, $id, Revision::READ_NORMAL );
if ( $this->mTitle->getNamespace() === NS_FILE ) {
$sites = new SiteList();
// @todo lazy initialize the site objects in the site list (e.g. only when needed to access)
- foreach( $data['sites'] as $siteArray ) {
+ foreach ( $data['sites'] as $siteArray ) {
$sites[] = $this->newSiteFromArray( $siteArray );
}
$site->setExtraData( $data['data'] );
$site->setExtraConfig( $data['config'] );
- foreach( $data['identifiers'] as $identifier ) {
+ foreach ( $data['identifiers'] as $identifier ) {
$site->addLocalId( $identifier['type'], $identifier['key'] );
}
$siteIdentifiers = $this->buildLocalIdentifiers( $site );
$identifiersArray = array();
- foreach( $siteIdentifiers as $identifier ) {
+ foreach ( $siteIdentifiers as $identifier ) {
$identifiersArray[] = $identifier;
}
$toolbox['info']['id'] = 't-info';
}
- wfRunHooks( 'BaseTemplateToolbox', array( &$this, &$toolbox ) );
+ Hooks::run( 'BaseTemplateToolbox', array( &$this, &$toolbox ) );
wfProfileOut( __METHOD__ );
return $toolbox;
}
ob_start();
// We pass an extra 'true' at the end so extensions using BaseTemplateToolbox
// can abort and avoid outputting double toolbox links
- wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this, true ) );
+ Hooks::run( 'SkinTemplateToolboxEnd', array( &$this, true ) );
$hookContents = ob_get_contents();
ob_end_clean();
if ( !trim( $hookContents ) ) {
*/
protected function renderAfterPortlet( $name ) {
$content = '';
- wfRunHooks( 'BaseTemplateAfterPortlet', array( $this, $name, &$content ) );
+ Hooks::run( 'BaseTemplateAfterPortlet', array( $this, $name, &$content ) );
if ( $content !== '' ) {
echo "<div class='after-portlet after-portlet-$name'>$content</div>";
$titles[] = $title->getTalkPage();
}
- wfRunHooks( 'SkinPreloadExistence', array( &$titles, $this ) );
+ Hooks::run( 'SkinPreloadExistence', array( &$titles, $this ) );
if ( count( $titles ) ) {
$lb = new LinkBatch( $titles );
protected function afterContentHook() {
$data = '';
- if ( wfRunHooks( 'SkinAfterContent', array( &$data, $this ) ) ) {
+ if ( Hooks::run( 'SkinAfterContent', array( &$data, $this ) ) ) {
// adding just some spaces shouldn't toggle the output
// of the whole <div/>, so we use trim() here
if ( trim( $data ) != '' ) {
// OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
// up at some point
$bottomScriptText = $this->getOutput()->getBottomScripts();
- wfRunHooks( 'SkinAfterBottomScripts', array( $this, &$bottomScriptText ) );
+ Hooks::run( 'SkinAfterBottomScripts', array( $this, &$bottomScriptText ) );
return $bottomScriptText;
}
$out = $this->getOutput();
$subpages = '';
- if ( !wfRunHooks( 'SkinSubPageSubtitle', array( &$subpages, $this, $out ) ) ) {
+ if ( !Hooks::run( 'SkinSubPageSubtitle', array( &$subpages, $this, $out ) ) ) {
return $subpages;
}
// @todo Remove deprecated $forContent param from hook handlers and then remove here.
$forContent = true;
- wfRunHooks(
+ Hooks::run(
'SkinCopyrightFooter',
array( $this->getTitle(), $type, &$msg, &$link, &$forContent )
);
$url = htmlspecialchars( "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png" );
$text = '<a href="//www.mediawiki.org/"><img src="' . $url
. '" height="31" width="88" alt="Powered by MediaWiki" /></a>';
- wfRunHooks( 'SkinGetPoweredBy', array( &$text, $this ) );
+ Hooks::run( 'SkinGetPoweredBy', array( &$text, $this ) );
return $text;
}
if ( $wgEnableSidebarCache ) {
$cachedsidebar = $wgMemc->get( $key );
if ( $cachedsidebar ) {
- wfRunHooks( 'SidebarBeforeOutput', array( $this, &$cachedsidebar ) );
+ Hooks::run( 'SidebarBeforeOutput', array( $this, &$cachedsidebar ) );
wfProfileOut( __METHOD__ );
return $cachedsidebar;
$bar = array();
$this->addToSidebar( $bar, 'sidebar' );
- wfRunHooks( 'SkinBuildSidebar', array( $this, &$bar ) );
+ Hooks::run( 'SkinBuildSidebar', array( $this, &$bar ) );
if ( $wgEnableSidebarCache ) {
$wgMemc->set( $key, $bar, $wgSidebarCacheExpiry );
}
- wfRunHooks( 'SidebarBeforeOutput', array( $this, &$bar ) );
+ Hooks::run( 'SidebarBeforeOutput', array( $this, &$bar ) );
wfProfileOut( __METHOD__ );
return $bar;
$out = $this->getOutput();
// Allow extensions to disable or modify the new messages alert
- if ( !wfRunHooks( 'GetNewMessagesAlert', array( &$newMessagesAlert, $newtalks, $user, $out ) ) ) {
+ if ( !Hooks::run( 'GetNewMessagesAlert', array( &$newMessagesAlert, $newtalks, $user, $out ) ) ) {
return '';
}
if ( $newMessagesAlert ) {
wfProfileIn( __METHOD__ );
$siteNotice = '';
- if ( wfRunHooks( 'SiteNoticeBefore', array( &$siteNotice, $this ) ) ) {
+ if ( Hooks::run( 'SiteNoticeBefore', array( &$siteNotice, $this ) ) ) {
if ( is_object( $this->getUser() ) && $this->getUser()->isLoggedIn() ) {
$siteNotice = $this->getCachedNotice( 'sitenotice' );
} else {
}
}
- wfRunHooks( 'SiteNoticeAfter', array( &$siteNotice, $this ) );
+ Hooks::run( 'SiteNoticeAfter', array( &$siteNotice, $this ) );
wfProfileOut( __METHOD__ );
return $siteNotice;
}
. '<span class="mw-editsection-bracket">]</span>'
. '</span>';
- wfRunHooks( 'DoEditSectionLink', array( $this, $nt, $section, $tooltip, &$result, $lang ) );
+ Hooks::run( 'DoEditSectionLink', array( $this, $nt, $section, $tooltip, &$result, $lang ) );
return $result;
}
'lang' => $ilInterwikiCodeBCP47,
'hreflang' => $ilInterwikiCodeBCP47,
);
- wfRunHooks(
+ Hooks::run(
'SkinTemplateGetLanguageLink',
array( &$languageLink, $languageLinkTitle, $this->getTitle(), $this->getOutput() )
);
$tpl->set( 'reporttime', wfReportTime() );
// original version by hansm
- if ( !wfRunHooks( 'SkinTemplateOutputPageBeforeExec', array( &$this, &$tpl ) ) ) {
+ if ( !Hooks::run( 'SkinTemplateOutputPageBeforeExec', array( &$this, &$tpl ) ) ) {
wfDebug( __METHOD__ . ": Hook SkinTemplateOutputPageBeforeExec broke outputPage execution!\n" );
}
$personal_urls['login'] = $login_url;
}
- wfRunHooks( 'PersonalUrls', array( &$personal_urls, &$title, $this ) );
+ Hooks::run( 'PersonalUrls', array( &$personal_urls, &$title, $this ) );
wfProfileOut( __METHOD__ );
return $personal_urls;
}
}
$result = array();
- if ( !wfRunHooks( 'SkinTemplateTabAction', array( &$this,
+ if ( !Hooks::run( 'SkinTemplateTabAction', array( &$this,
$title, $message, $selected, $checkEdit,
&$classes, &$query, &$text, &$result ) ) ) {
return $result;
$userCanRead = $title->quickUserCan( 'read', $user );
$preventActiveTabs = false;
- wfRunHooks( 'SkinTemplatePreventOtherActiveTabs', array( &$this, &$preventActiveTabs ) );
+ Hooks::run( 'SkinTemplatePreventOtherActiveTabs', array( &$this, &$preventActiveTabs ) );
// Checks if page is some kind of content
if ( $title->canExist() ) {
}
}
- wfRunHooks( 'SkinTemplateNavigation', array( &$this, &$content_navigation ) );
+ Hooks::run( 'SkinTemplateNavigation', array( &$this, &$content_navigation ) );
if ( $userCanRead && !$wgDisableLangConversion ) {
$pageLang = $title->getPageLanguage();
'context' => 'subject'
);
- wfRunHooks( 'SkinTemplateNavigation::SpecialPage',
+ Hooks::run( 'SkinTemplateNavigation::SpecialPage',
array( &$this, &$content_navigation ) );
}
// Equiv to SkinTemplateContentActions
- wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this, &$content_navigation ) );
+ Hooks::run( 'SkinTemplateNavigation::Universal', array( &$this, &$content_navigation ) );
// Setup xml ids and tooltip info
foreach ( $content_navigation as $section => &$links ) {
}
// Use the copy of revision ID in case this undocumented, shady hook tries to mess with internals
- wfRunHooks( 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink',
+ Hooks::run( 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink',
array( &$this, &$nav_urls, &$revid, &$revid ) );
}
protected function getCustomFilters() {
if ( $this->customFilters === null ) {
$this->customFilters = array();
- wfRunHooks( 'ChangesListSpecialPageFilters', array( $this, &$this->customFilters ) );
+ Hooks::run( 'ChangesListSpecialPageFilters', array( $this, &$this->customFilters ) );
}
return $this->customFilters;
}
protected function runMainQueryHook( &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) {
- return wfRunHooks(
+ return Hooks::run(
'ChangesListSpecialPageQuery',
array( $this->getName(), &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts )
);
}
/**
- * Return a DatabaseBase object for reading
+ * Return a IDatabase object for reading
*
- * @return DatabaseBase
+ * @return IDatabase
*/
protected function getDB() {
return wfGetDB( DB_SLAVE );
$this->alterForm( $form );
// Give hooks a chance to alter the form, adding extra fields or text etc
- wfRunHooks( 'SpecialPageBeforeFormDisplay', array( $this->getName(), &$form ) );
+ Hooks::run( 'SpecialPageBeforeFormDisplay', array( $this->getName(), &$form ) );
return $form;
}
*
* @param OutputPage $out OutputPage to print to
* @param Skin $skin User skin to use [unused]
- * @param DatabaseBase $dbr (read) connection to use
+ * @param IDatabase $dbr (read) connection to use
* @param ResultWrapper $res Result pointer
* @param int $num Number of available result rows
* @param int $offset Paging offset
* like page existence and information for stub color and redirect hints.
* This should be done for live data and cached data.
*
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @param ResultWrapper $res
*/
public function preprocessResults( $db, $res ) {
array( 'UnusedtemplatesPage', 'Unusedtemplates' ),
array( 'WithoutInterwikiPage', 'Withoutinterwiki' ),
);
- wfRunHooks( 'wgQueryPages', array( &$qp ) );
+ Hooks::run( 'wgQueryPages', array( &$qp ) );
}
return $qp;
/**
* Get a DB connection to be used for slow recache queries
- * @return DatabaseBase
+ * @return IDatabase
*/
function getRecacheDB() {
return wfGetDB( DB_SLAVE, array( $this->getName(), 'QueryPage::recache', 'vslow' ) );
*
* @param OutputPage $out OutputPage to print to
* @param Skin $skin User skin to use
- * @param DatabaseBase $dbr Database (read) connection to use
+ * @param IDatabase $dbr Database (read) connection to use
* @param ResultWrapper $res Result pointer
* @param int $num Number of available result rows
* @param int $offset Paging offset
/**
* Do any necessary preprocessing of the result object.
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @param ResultWrapper $res
*/
function preprocessResults( $db, $res ) {
'ctype', 'maxage', 'smaxage',
);
- wfRunHooks( "RedirectSpecialArticleRedirectParams", array( &$redirectParams ) );
+ Hooks::run( "RedirectSpecialArticleRedirectParams", array( &$redirectParams ) );
$this->mAllowedRedirectParams = $redirectParams;
}
}
/**
* Helper function for implementations of prefixSearchSubpages() that
- * filter the values in memory (as oppposed to making a query).
+ * filter the values in memory (as opposed to making a query).
*
* @since 1.24
* @param string $search
* @param SpecialPage $this
* @param string|null $subPage
*/
- wfRunHooks( 'SpecialPageBeforeExecute', array( $this, $subPage ) );
+ Hooks::run( 'SpecialPageBeforeExecute', array( $this, $subPage ) );
$this->beforeExecute( $subPage );
$this->execute( $subPage );
* @param SpecialPage $this
* @param string|null $subPage
*/
- wfRunHooks( 'SpecialPageAfterExecute', array( $this, $subPage ) );
+ Hooks::run( 'SpecialPageAfterExecute', array( $this, $subPage ) );
}
/**
// Run hooks
// This hook can be used to remove undesired built-in special pages
- wfRunHooks( 'SpecialPage_initList', array( &self::$list ) );
+ Hooks::run( 'SpecialPage_initList', array( &self::$list ) );
wfProfileOut( __METHOD__ );
}
/**
* Cache page existence for performance
- * @param DatabaseBase $db
+ * @param IDatabase $db
* @param ResultWrapper $res
*/
function preprocessResults( $db, $res ) {
* @note This will only be run if the page is cached (ie $wgMiserMode = true)
* unless forceExistenceCheck() is true.
* @since 1.24
- * @return boolean
+ * @return bool
*/
protected function existenceCheck( Title $title ) {
return $title->isKnown();
$this->maybeAlterFormDefaults( $a );
// Allow extensions to add more fields
- wfRunHooks( 'SpecialBlockModifyFormFields', array( $this, &$a ) );
+ Hooks::run( 'SpecialBlockModifyFormFields', array( $this, &$a ) );
return $a;
}
$otherBlockMessages = array();
if ( $this->target !== null ) {
# Get other blocks, i.e. from GlobalBlocking or TorBlock extension
- wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockMessages, $this->target ) );
+ Hooks::run( 'OtherBlockLogLink', array( &$otherBlockMessages, $this->target ) );
if ( count( $otherBlockMessages ) ) {
$s = Html::rawElement(
# permission anyway, although the code does allow for it.
# Note: Important to use $target instead of $data['Target']
# since both $data['PreviousTarget'] and $target are normalized
- # but $data['target'] gets overriden by (non-normalized) request variable
+ # but $data['target'] gets overridden by (non-normalized) request variable
# from previous request.
if ( $target === $performer->getName() &&
( $data['PreviousTarget'] !== $target || !$data['Confirm'] )
$block->mHideName = $data['HideUser'];
$reason = array( 'hookaborted' );
- if ( !wfRunHooks( 'BlockIp', array( &$block, &$performer, &$reason ) ) ) {
+ if ( !Hooks::run( 'BlockIp', array( &$block, &$performer, &$reason ) ) ) {
return $reason;
}
$logaction = 'block';
}
- wfRunHooks( 'BlockIpComplete', array( $block, $performer ) );
+ Hooks::run( 'BlockIpComplete', array( $block, $performer ) );
# Set *_deleted fields if requested
if ( $data['HideUser'] ) {
# Check for other blocks, i.e. global/tor blocks
$otherBlockLink = array();
- wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockLink, $this->target ) );
+ Hooks::run( 'OtherBlockLogLink', array( &$otherBlockLink, $this->target ) );
$out = $this->getOutput();
# Hook to allow extensions to insert additional HTML,
# e.g. for API-interacting plugins and so on
- wfRunHooks( 'BookInformation', array( $this->isbn, $this->getOutput() ) );
+ Hooks::run( 'BookInformation', array( $this->isbn, $this->getOutput() ) );
# Check for a local page such as Project:Book_sources and use that if available
$page = $this->msg( 'booksources' )->inContentLanguage()->text();
return $status;
}
- wfRunHooks( 'PrefsEmailAudit', array( $user, $oldaddr, $newaddr ) );
+ Hooks::run( 'PrefsEmailAudit', array( $user, $oldaddr, $newaddr ) );
$user->saveSettings();
}
$extraFields = array();
- wfRunHooks( 'ChangePasswordForm', array( &$extraFields ) );
+ Hooks::run( 'ChangePasswordForm', array( &$extraFields ) );
foreach ( $extraFields as $extra ) {
list( $name, $label, $type, $default ) = $extra;
$fields[$name] = array(
}
if ( $newpass !== $retype ) {
- wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'badretype' ) );
+ Hooks::run( 'PrefsPasswordAudit', array( $user, $newpass, 'badretype' ) );
throw new PasswordError( $this->msg( 'badretype' )->text() );
}
// @todo Make these separate messages, since the message is written for both cases
if ( !$user->checkTemporaryPassword( $oldpass ) && !$user->checkPassword( $oldpass ) ) {
- wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) );
+ Hooks::run( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) );
throw new PasswordError( $this->msg( 'resetpass-wrong-oldpass' )->text() );
}
// Do AbortChangePassword after checking mOldpass, so we don't leak information
// by possibly aborting a new password before verifying the old password.
$abortMsg = 'resetpass-abort-generic';
- if ( !wfRunHooks( 'AbortChangePassword', array( $user, $oldpass, $newpass, &$abortMsg ) ) ) {
- wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'abortreset' ) );
+ if ( !Hooks::run( 'AbortChangePassword', array( $user, $oldpass, $newpass, &$abortMsg ) ) ) {
+ Hooks::run( 'PrefsPasswordAudit', array( $user, $newpass, 'abortreset' ) );
throw new PasswordError( $this->msg( $abortMsg )->text() );
}
try {
$user->setPassword( $newpass );
- wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) );
+ Hooks::run( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) );
} catch ( PasswordError $e ) {
- wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) );
+ Hooks::run( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) );
throw new PasswordError( $e->getMessage() );
}
// Add RSS/atom links
$this->addFeedLinks( $feedParams );
- if ( wfRunHooks( 'SpecialContributionsBeforeMainOutput', array( $id, $userObj, $this ) ) ) {
+ if ( Hooks::run( 'SpecialContributionsBeforeMainOutput', array( $id, $userObj, $this ) ) ) {
if ( !$this->including() ) {
$out->addHTML( $this->getForm() );
}
);
}
- wfRunHooks( 'ContributionsToolLinks', array( $id, $userpage, &$tools ) );
+ Hooks::run( 'ContributionsToolLinks', array( $id, $userpage, &$tools ) );
return $tools;
}
$msgs = array(
'diff',
'hist',
- 'newarticle',
'pipe-separator',
- 'rev-delundel',
- 'rollbacklink',
'uctop'
);
/**
* This method basically executes the exact same code as the parent class, though with
- * a hook added, to allow extentions to add additional queries.
+ * a hook added, to allow extensions to add additional queries.
*
* @param string $offset Index offset, inclusive
* @param int $limit Exact query limit
$data = array( $this->mDb->select(
$tables, $fields, $conds, $fname, $options, $join_conds
) );
- wfRunHooks(
+ Hooks::run(
'ContribsPager::reallyDoQuery',
array( &$data, $pager, $offset, $limit, $descending )
);
$this->tagFilter
);
- wfRunHooks( 'ContribsPager::getQueryInfo', array( &$this, &$queryInfo ) );
+ Hooks::run( 'ContribsPager::getQueryInfo', array( &$this, &$queryInfo ) );
return $queryInfo;
}
}
// Let extensions add data
- wfRunHooks( 'ContributionsLineEnding', array( $this, &$ret, $row, &$classes ) );
+ Hooks::run( 'ContributionsLineEnding', array( $this, &$ret, $row, &$classes ) );
if ( $classes === array() && $ret === '' ) {
wfDebug( "Dropping Special:Contribution row that could not be formatted\n" );
);
}
- wfRunHooks( 'ContributionsToolLinks', array( $id, $nt, &$tools ) );
+ Hooks::run( 'ContributionsToolLinks', array( $id, $nt, &$tools ) );
$links = $this->getLanguage()->pipeList( $tools );
// Do a batch existence check
$batch = new LinkBatch();
if ( count( $titles ) >= 100 ) {
- $output = wfMessage( 'watchlistedit-too-many' )->parse();
+ $output = $this->msg( 'watchlistedit-too-many' )->parse();
return;
}
foreach ( $titles as $title ) {
);
$page = WikiPage::factory( $title );
- wfRunHooks( 'UnwatchArticleComplete', array( $this->getUser(), &$page ) );
+ Hooks::run( 'UnwatchArticleComplete', array( $this->getUser(), &$page ) );
}
}
}
// Allow subscribers to manipulate the list of watched pages (or use it
// to preload lots of details at once)
$watchlistInfo = $this->getWatchlistInfo();
- wfRunHooks(
+ Hooks::run(
'WatchlistEditorBeforeFormRender',
array( &$watchlistInfo )
);
);
}
- wfRunHooks(
+ Hooks::run(
'WatchlistEditorBuildRemoveLine',
array( &$tools, $title, $title->isRedirect(), $this->getSkin(), &$link )
);
$form->setWrapperLegendMsg( 'email-legend' );
$form->loadData();
- if ( !wfRunHooks( 'EmailUserForm', array( &$form ) ) ) {
+ if ( !Hooks::run( 'EmailUserForm', array( &$form ) ) ) {
return;
}
$hookErr = false;
- wfRunHooks( 'UserCanSendEmail', array( &$user, &$hookErr ) );
- wfRunHooks( 'EmailUserPermissionsErrors', array( $user, $editToken, &$hookErr ) );
+ Hooks::run( 'UserCanSendEmail', array( &$user, &$hookErr ) );
+ Hooks::run( 'EmailUserPermissionsErrors', array( $user, $editToken, &$hookErr ) );
if ( $hookErr ) {
return $hookErr;
$from->name, $to->name )->inContentLanguage()->text();
$error = '';
- if ( !wfRunHooks( 'EmailUser', array( &$to, &$from, &$subject, &$text, &$error ) ) ) {
+ if ( !Hooks::run( 'EmailUser', array( &$to, &$from, &$subject, &$text, &$error ) ) ) {
return $error;
}
if ( $data['CCMe'] && $to != $from ) {
$cc_subject = $context->msg( 'emailccsubject' )->rawParams(
$target->getName(), $subject )->text();
- wfRunHooks( 'EmailUserCC', array( &$from, &$from, &$cc_subject, &$text ) );
+ Hooks::run( 'EmailUserCC', array( &$from, &$from, &$cc_subject, &$text ) );
$ccStatus = UserMailer::send( $from, $from, $cc_subject, $text );
$status->merge( $ccStatus );
}
- wfRunHooks( 'EmailUserComplete', array( $to, $from, $subject, $text ) );
+ Hooks::run( 'EmailUserComplete', array( $to, $from, $subject, $text ) );
return $status;
}
$page = WikiPage::factory( $title );
# Update page record
$page->updateRevisionOn( $dbw, $nullRevision );
- wfRunHooks(
+ Hooks::run(
'NewRevisionFromEditComplete',
array( $page, $nullRevision, $latest, $this->getUser() )
);
'conds' => $conds
);
- wfRunHooks( 'SpecialListusersQueryInfo', array( $this, &$query ) );
+ Hooks::run( 'SpecialListusersQueryInfo', array( $this, &$query ) );
return $query;
}
' ' . $this->msg( 'listusers-blocked', $userName )->escaped() :
'';
- wfRunHooks( 'SpecialListusersFormatRow', array( &$item, $row ) );
+ Hooks::run( 'SpecialListusersFormatRow', array( &$item, $row ) );
return Html::rawElement( 'li', array(), "{$item}{$edits}{$created}{$blocked}" );
}
);
$out .= '<br />';
- wfRunHooks( 'SpecialListusersHeaderForm', array( $this, &$out ) );
+ Hooks::run( 'SpecialListusersHeaderForm', array( $this, &$out ) );
# Submit button and form bottom
$out .= Html::hidden( 'limit', $this->mLimit );
$out .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() );
- wfRunHooks( 'SpecialListusersHeader', array( $this, &$out ) );
+ Hooks::run( 'SpecialListusersHeader', array( $this, &$out ) );
$out .= Xml::closeElement( 'fieldset' ) .
Xml::closeElement( 'form' );
if ( $this->requestedUser != '' ) {
$query['username'] = $this->requestedUser;
}
- wfRunHooks( 'SpecialListusersDefaultQuery', array( $this, &$query ) );
+ Hooks::run( 'SpecialListusersDefaultQuery', array( $this, &$query ) );
return $query;
}
}
} else {
// Allow extensions to add relations to their search types
- wfRunHooks( 'SpecialLogAddLogSearchRelations', array( $opts->getValue( 'type' ), $this->getRequest(), &$qc ) );
+ Hooks::run( 'SpecialLogAddLogSearchRelations', array( $opts->getValue( 'type' ), $this->getRequest(), &$qc ) );
}
# Some log types are only for a 'User:' title but we might have been given
# only the username instead of the full title 'User:username'. This part try
# to lookup for a user by that name and eventually fix user input. See bug 1697.
- wfRunHooks( 'GetLogTypesOnUser', array( &$this->typeOnUser ) );
+ Hooks::run( 'GetLogTypesOnUser', array( &$this->typeOnUser ) );
if ( in_array( $opts->getValue( 'type' ), $this->typeOnUser ) ) {
# ok we have a type of log which expect a user title.
$target = Title::newFromText( $opts->getValue( 'page' ) );
);
// Allow extensions to modify the query
- wfRunHooks( 'LonelyPagesQuery', array( &$tables, &$conds, &$joinConds ) );
+ Hooks::run( 'LonelyPagesQuery', array( &$tables, &$conds, &$joinConds ) );
return array(
'tables' => $tables,
$targetTitle->getPrefixedText(), $destTitle->getPrefixedText() )->numParams(
$count )->text() );
- wfRunHooks( 'ArticleMergeComplete', array( $targetTitle, $destTitle ) );
+ Hooks::run( 'ArticleMergeComplete', array( $targetTitle, $destTitle ) );
return true;
}
$newLink )->params( $oldText, $newText )->parseAsBlock() );
$out->addWikiMsg( $msgName );
- wfRunHooks( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) );
+ Hooks::run( 'SpecialMovepageAfterMove', array( &$this, &$ot, &$nt ) );
# Now we move extra pages we've been asked to move: subpages and talk
# pages. First, if the old page or the new page is a talk page, we
$opts->add( 'invert', false );
$this->customFilters = array();
- wfRunHooks( 'SpecialNewPagesFilters', array( $this, &$this->customFilters ) );
+ Hooks::run( 'SpecialNewPagesFilters', array( $this, &$this->customFilters ) );
foreach ( $this->customFilters as $key => $params ) {
$opts->add( $key, $params['default'] );
}
'tagFilter' => array(
'type' => 'tagfilter',
'name' => 'tagfilter',
- 'label-raw' => wfMessage( 'tag-filter' )->parse(),
+ 'label-raw' => $this->msg( 'tag-filter' )->parse(),
'default' => $tagFilterVal,
),
'username' => array(
);
$join_conds = array( 'page' => array( 'INNER JOIN', 'page_id=rc_cur_id' ) );
- wfRunHooks( 'SpecialNewpagesConditions',
+ Hooks::run( 'SpecialNewpagesConditions',
array( &$this, $this->opts, &$conds, &$tables, &$fields, &$join_conds ) );
$options = array();
public function alterForm( HTMLForm $form ) {
$form->setDisplayFormat( 'vform' );
$form->setWrapperLegend( false );
- wfRunHooks( 'LanguageSelector', array( $this->getOutput(), 'mw-languageselector' ) );
+ Hooks::run( 'LanguageSelector', array( $this->getOutput(), 'mw-languageselector' ) );
}
/**
// Check for hooks (captcha etc), and allow them to modify the users list
$error = array();
- if ( !wfRunHooks( 'SpecialPasswordResetOnSubmit', array( &$users, $data, &$error ) ) ) {
+ if ( !Hooks::run( 'SpecialPasswordResetOnSubmit', array( &$users, $data, &$error ) ) ) {
return array( $error );
}
return array( 'badipaddress' );
}
$caller = $this->getUser();
- wfRunHooks( 'User::mailPasswordInternal', array( &$caller, &$ip, &$firstUser ) );
+ Hooks::run( 'User::mailPasswordInternal', array( &$caller, &$ip, &$firstUser ) );
$username = $caller->getName();
$msg = IP::isValid( $username )
? 'passwordreset-emailtext-ip'
$randstr = wfRandom();
$title = null;
- if ( !wfRunHooks(
+ if ( !Hooks::run(
'SpecialRandomGetRandomTitle',
array( &$randstr, &$this->isRedir, &$this->namespaces, &$this->extra, &$title )
) ) {
protected function getCustomFilters() {
if ( $this->customFilters === null ) {
$this->customFilters = parent::getCustomFilters();
- wfRunHooks( 'SpecialRecentChangesFilters', array( $this, &$this->customFilters ), '1.23' );
+ Hooks::run( 'SpecialRecentChangesFilters', array( $this, &$this->customFilters ), '1.23' );
}
return $this->customFilters;
protected function runMainQueryHook( &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) {
return parent::runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts )
- && wfRunHooks(
+ && Hooks::run(
'SpecialRecentChangesQuery',
array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$fields ),
'1.23'
// Don't fire the hook for subclasses. (Or should we?)
if ( $this->getName() === 'Recentchanges' ) {
- wfRunHooks( 'SpecialRecentChangesPanel', array( &$extraOpts, $opts ) );
+ Hooks::run( 'SpecialRecentChangesPanel', array( &$extraOpts, $opts ) );
}
return $extraOpts;
$tokens = array(
array( 'preference' => 'watchlisttoken', 'label-message' => 'resettokens-watchlist-token' ),
);
- wfRunHooks( 'SpecialResetTokensTokens', array( &$tokens ) );
+ Hooks::run( 'SpecialResetTokensTokens', array( &$tokens ) );
$hiddenPrefs = $this->getConfig()->get( 'HiddenPrefs' );
$tokens = array_filter( $tokens, function ( $tok ) use ( $hiddenPrefs ) {
# No match, generate an edit URL
$title = Title::newFromText( $term );
if ( !is_null( $title ) ) {
- wfRunHooks( 'SpecialSearchNogomatch', array( &$title ) );
+ Hooks::run( 'SpecialSearchNogomatch', array( &$title ) );
}
$this->showResults( $term );
}
$search->prefix = $this->mPrefix;
$term = $search->transformSearchTerm( $term );
- wfRunHooks( 'SpecialSearchSetupEngine', array( $this, $this->profile, $search ) );
+ Hooks::run( 'SpecialSearchSetupEngine', array( $this, $this->profile, $search ) );
$this->setupPage( $term );
. $this->msg( 'search-suggest' )->rawParams( $suggestLink )->text() . '</div>';
}
- if ( !wfRunHooks( 'SpecialSearchResultsPrepend', array( $this, $out, $term ) ) ) {
+ if ( !Hooks::run( 'SpecialSearchResultsPrepend', array( $this, $out, $term ) ) ) {
# Hook requested termination
return;
}
);
}
}
- wfRunHooks( 'SpecialSearchResults', array( $term, &$titleMatches, &$textMatches ) );
+ Hooks::run( 'SpecialSearchResults', array( $term, &$titleMatches, &$textMatches ) );
$out->parserOptions()->setEditSection( false );
if ( $titleMatches ) {
wfEscapeWikiText( $title->getPrefixedText() ),
Message::numParam( $num )
);
- wfRunHooks( 'SpecialSearchCreateLink', array( $title, &$params ) );
+ Hooks::run( 'SpecialSearchCreateLink', array( $title, &$params ) );
// Extensions using the hook might still return an empty $messageName
if ( $messageName ) {
$link_t = clone $title;
- wfRunHooks( 'ShowSearchHitTitle',
+ Hooks::run( 'ShowSearchHitTitle',
array( &$link_t, &$titleSnippet, $result, $terms, $this ) );
$link = Linker::linkKnown(
$html = null;
$score = '';
- if ( wfRunHooks( 'ShowSearchHit', array(
+ if ( Hooks::run( 'ShowSearchHit', array(
$this, $result, $terms,
&$link, &$redirect, &$section, &$extract,
&$score, &$size, &$date, &$related,
$showSections = array( 'namespaceTables' => $namespaceTables );
- wfRunHooks( 'SpecialSearchPowerBox', array( &$showSections, $term, $opts ) );
+ Hooks::run( 'SpecialSearchPowerBox', array( &$showSections, $term, $opts ) );
$hidden = '';
foreach ( $opts as $key => $value ) {
$user = $this->getUser();
if ( $user->isLoggedIn() ) {
$remember .= Xml::checkLabel(
- wfMessage( 'powersearch-remember' )->text(),
+ $this->msg( 'powersearch-remember' )->text(),
'nsRemember',
'mw-search-powersearch-remember',
false,
)
);
- wfRunHooks( 'SpecialSearchProfiles', array( &$profiles ) );
+ Hooks::run( 'SpecialSearchProfiles', array( &$profiles ) );
foreach ( $profiles as &$data ) {
if ( !is_array( $data['namespaces'] ) ) {
$out .= $this->powerSearchBox( $term, $opts );
} else {
$form = '';
- wfRunHooks( 'SpecialSearchProfileForm', array( $this, &$form, $this->profile, $term, $opts ) );
+ Hooks::run( 'SpecialSearchProfileForm', array( $this, &$form, $this->profile, $term, $opts ) );
$out .= $form;
}
# Statistic - other
$extraStats = array();
- if ( wfRunHooks( 'SpecialStatsAddExtra', array( &$extraStats ) ) ) {
+ if ( Hooks::run( 'SpecialStatsAddExtra', array( &$extraStats ) ) ) {
$text .= $this->getOtherStats( $extraStats );
}
$logEntry->setTarget( $this->title );
$logEntry->setComment( $reason );
- wfRunHooks( 'ArticleUndeleteLogEntry', array( $this, &$logEntry, $user ) );
+ Hooks::run( 'ArticleUndeleteLogEntry', array( $this, &$logEntry, $user ) );
$logid = $logEntry->insert();
$logEntry->publish( $logid );
$revision->insertOn( $dbw );
$restored++;
- wfRunHooks( 'ArticleRevisionUndeleted', array( &$this->title, $revision, $row->ar_page_id ) );
+ Hooks::run( 'ArticleRevisionUndeleted', array( &$this->title, $revision, $row->ar_page_id ) );
}
# Now that it's safely stored, take it out of the archive
$dbw->delete( 'archive',
);
}
- wfRunHooks( 'ArticleUndelete', array( &$this->title, $created, $comment, $oldPageId ) );
+ Hooks::run( 'ArticleUndelete', array( &$this->title, $created, $comment, $oldPageId ) );
if ( $this->title->getNamespace() == NS_FILE ) {
$update = new HTMLCacheUpdate( $this->title, 'imagelinks' );
}
$archive = new PageArchive( $this->mTargetObj, $this->getConfig() );
- if ( !wfRunHooks( 'UndeleteForm::showRevision', array( &$archive, $this->mTargetObj ) ) ) {
+ if ( !Hooks::run( 'UndeleteForm::showRevision', array( &$archive, $this->mTargetObj ) ) ) {
return;
}
$rev = $archive->getRevision( $timestamp );
$out->addHTML( $this->msg( 'undelete-revision' )->rawParams( $link )->params(
$time )->rawParams( $userLink )->params( $d, $t )->parse() . '</div>' );
- if ( !wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) ) ) {
+ if ( !Hooks::run( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) ) ) {
return;
}
);
$archive = new PageArchive( $this->mTargetObj, $this->getConfig() );
- wfRunHooks( 'UndeleteForm::showHistory', array( &$archive, $this->mTargetObj ) );
+ Hooks::run( 'UndeleteForm::showHistory', array( &$archive, $this->mTargetObj ) );
/*
$text = $archive->getLastRevisionText();
if( is_null( $text ) ) {
$out = $this->getOutput();
$archive = new PageArchive( $this->mTargetObj, $this->getConfig() );
- wfRunHooks( 'UndeleteForm::undelete', array( &$archive, $this->mTargetObj ) );
+ Hooks::run( 'UndeleteForm::undelete', array( &$archive, $this->mTargetObj ) );
$ok = $archive->undelete(
$this->mTargetTimestamp,
$this->mComment,
if ( is_array( $ok ) ) {
if ( $ok[1] ) { // Undeleted file count
- wfRunHooks( 'FileUndeleteComplete', array(
+ Hooks::run( 'FileUndeleteComplete', array(
$this->mTargetObj, $this->mFileVersions,
$this->getUser(), $this->mComment ) );
}
$this->processUpload();
} else {
# Backwards compatibility hook
- if ( !wfRunHooks( 'UploadForm:initial', array( &$this ) ) ) {
+ if ( !Hooks::run( 'UploadForm:initial', array( &$this ) ) ) {
wfDebug( "Hook 'UploadForm:initial' broke output of the upload form\n" );
return;
return;
}
- if ( !wfRunHooks( 'UploadForm:BeforeProcessing', array( &$this ) ) ) {
+ if ( !Hooks::run( 'UploadForm:BeforeProcessing', array( &$this ) ) ) {
wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file.\n" );
// This code path is deprecated. If you want to break upload processing
// do so by hooking into the appropriate hooks in UploadBase::verifyUpload
// Success, redirect to description page
$this->mUploadSuccessful = true;
- wfRunHooks( 'SpecialUploadComplete', array( &$this ) );
+ Hooks::run( 'SpecialUploadComplete', array( &$this ) );
$this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
}
}
return '<li>' .
- wfMessage( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
+ $this->msg( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
$gallery->toHTML() . "</li>\n";
}
+ $this->getDescriptionSection()
+ $this->getOptionsSection();
- wfRunHooks( 'UploadFormInitDescriptor', array( &$descriptor ) );
+ Hooks::run( 'UploadFormInitDescriptor', array( &$descriptor ) );
parent::__construct( $descriptor, $context, 'upload' );
# Add a link to edit MediaWik:Licenses
'checked' => $selectedSourceType == 'url',
);
}
- wfRunHooks( 'UploadFormSourceDescriptors', array( &$descriptor, &$radio, $selectedSourceType ) );
+ Hooks::run( 'UploadFormSourceDescriptors', array( &$descriptor, &$radio, $selectedSourceType ) );
$descriptor['Extensions'] = array(
'type' => 'info',
static $messages = null;
if ( !$messages ) {
$messages = self::$validErrorMessages;
- wfRunHooks( 'LoginFormValidErrorMessages', array( &$messages ) );
+ Hooks::run( 'LoginFormValidErrorMessages', array( &$messages ) );
}
return $messages;
$u->saveSettings();
$result = $this->mailPasswordInternal( $u, false, 'createaccount-title', 'createaccount-text' );
- wfRunHooks( 'AddNewAccount', array( $u, true ) );
+ Hooks::run( 'AddNewAccount', array( $u, true ) );
$u->addNewUserLogEntry( 'byemail', $this->mReason );
$out = $this->getOutput();
// which is needed or the personal links will be
// wrong.
$this->getContext()->setUser( $u );
- wfRunHooks( 'AddNewAccount', array( $u, false ) );
+ Hooks::run( 'AddNewAccount', array( $u, false ) );
$u->addNewUserLogEntry( 'create' );
if ( $this->hasSessionCookie() ) {
$this->successfulCreation();
$out->setPageTitle( $this->msg( 'accountcreated' ) );
$out->addWikiMsg( 'accountcreatedtext', $u->getName() );
$out->addReturnTo( $this->getPageTitle() );
- wfRunHooks( 'AddNewAccount', array( $u, false ) );
+ Hooks::run( 'AddNewAccount', array( $u, false ) );
$u->addNewUserLogEntry( 'create2', $this->mReason );
}
$abortError = '';
$abortStatus = null;
- if ( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError, &$abortStatus ) ) ) {
+ if ( !Hooks::run( 'AbortNewAccount', array( $u, &$abortError, &$abortStatus ) ) ) {
// Hook point to add extra creation throttles and blocks
wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" );
if ( $abortStatus === null ) {
}
// Hook point to check for exempt from account creation throttle
- if ( !wfRunHooks( 'ExemptFromAccountCreationThrottle', array( $ip ) ) ) {
+ if ( !Hooks::run( 'ExemptFromAccountCreationThrottle', array( $ip ) ) ) {
wfDebug( "LoginForm::exemptFromAccountCreationThrottle: a hook " .
"allowed account creation w/o throttle\n" );
} else {
// Give extensions a way to indicate the username has been updated,
// rather than telling the user the account doesn't exist.
- if ( !wfRunHooks( 'LoginUserMigrated', array( $u, &$msg ) ) ) {
+ if ( !Hooks::run( 'LoginUserMigrated', array( $u, &$msg ) ) ) {
$this->mAbortLoginErrorMsg = $msg;
return self::USER_MIGRATED;
}
// Give general extensions, such as a captcha, a chance to abort logins
$abort = self::ABORTED;
$msg = null;
- if ( !wfRunHooks( 'AbortLogin', array( $u, $this->mPassword, &$abort, &$msg ) ) ) {
+ if ( !Hooks::run( 'AbortLogin', array( $u, $this->mPassword, &$abort, &$msg ) ) ) {
$this->mAbortLoginErrorMsg = $msg;
return $abort;
if ( $isAutoCreated ) {
// Must be run after $wgUser is set, for correct new user log
- wfRunHooks( 'AuthPluginAutoCreate', array( $u ) );
+ Hooks::run( 'AuthPluginAutoCreate', array( $u ) );
}
$retval = self::SUCCESS;
}
- wfRunHooks( 'LoginAuthenticateAudit', array( $u, $this->mPassword, $retval ) );
+ Hooks::run( 'LoginAuthenticateAudit', array( $u, $this->mPassword, $retval ) );
return $retval;
}
}
$abortError = '';
- if ( !wfRunHooks( 'AbortAutoAccount', array( $user, &$abortError ) ) ) {
+ if ( !Hooks::run( 'AbortAutoAccount', array( $user, &$abortError ) ) ) {
// Hook point to add extra creation throttles and blocks
wfDebug( "LoginForm::attemptAutoCreate: a hook blocked creation: $abortError\n" );
$this->mAbortLoginErrorMsg = $abortError;
*/
protected function resetLoginForm( Message $msg ) {
// Allow hooks to explain this password reset in more detail
- wfRunHooks( 'LoginPasswordResetMessage', array( &$msg, $this->mUsername ) );
+ Hooks::run( 'LoginPasswordResetMessage', array( &$msg, $this->mUsername ) );
$reset = new SpecialChangePassword();
$derivative = new DerivativeContext( $this->getContext() );
$derivative->setTitle( $reset->getPageTitle() );
}
$currentUser = $this->getUser();
- wfRunHooks( 'User::mailPasswordInternal', array( &$currentUser, &$ip, &$u ) );
+ Hooks::run( 'User::mailPasswordInternal', array( &$currentUser, &$ip, &$u ) );
$np = $u->randomPassword();
$u->setNewpassword( $np, $throttle );
# Run any hooks; display injected HTML if any, else redirect
$currentUser = $this->getUser();
$injected_html = '';
- wfRunHooks( 'UserLoginComplete', array( &$currentUser, &$injected_html ) );
+ Hooks::run( 'UserLoginComplete', array( &$currentUser, &$injected_html ) );
if ( $injected_html !== '' ) {
$this->displaySuccessfulAction( 'success', $this->msg( 'loginsuccesstitle' ),
$injected_html = '';
$welcome_creation_msg = 'welcomecreation-msg';
- wfRunHooks( 'UserLoginComplete', array( &$currentUser, &$injected_html ) );
+ Hooks::run( 'UserLoginComplete', array( &$currentUser, &$injected_html ) );
/**
* Let any extensions change what message is shown.
* @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforeWelcomeCreation
* @since 1.18
*/
- wfRunHooks( 'BeforeWelcomeCreation', array( &$welcome_creation_msg, &$injected_html ) );
+ Hooks::run( 'BeforeWelcomeCreation', array( &$welcome_creation_msg, &$injected_html ) );
$this->displaySuccessfulAction(
'signup',
}
// Allow modification of redirect behavior
- wfRunHooks( 'PostLoginRedirect', array( &$returnTo, &$returnToQuery, &$type ) );
+ Hooks::run( 'PostLoginRedirect', array( &$returnTo, &$returnToQuery, &$type ) );
$returnToTitle = Title::newFromText( $returnTo );
if ( !$returnToTitle ) {
'mediawiki.special.userlogin.signup.styles'
) );
- $template = new UsercreateTemplate();
+ $template = new UsercreateTemplate( $this->getConfig() );
// Must match number of benefits defined in messages
$template->set( 'benefitCount', 3 );
'mediawiki.special.userlogin.login.styles'
) );
- $template = new UserloginTemplate();
+ $template = new UserloginTemplate( $this->getConfig() );
$q = 'action=submitlogin&type=login';
$linkq = 'type=signup';
// Give authentication and captcha plugins a chance to modify the form
$wgAuth->modifyUITemplate( $template, $this->mType );
if ( $this->mType == 'signup' ) {
- wfRunHooks( 'UserCreateForm', array( &$template ) );
+ Hooks::run( 'UserCreateForm', array( &$template ) );
} else {
- wfRunHooks( 'UserLoginForm', array( &$template ) );
+ Hooks::run( 'UserLoginForm', array( &$template ) );
}
$out->disallowUserJs(); // just in case...
// Hook.
$injected_html = '';
- wfRunHooks( 'UserLogoutComplete', array( &$user, &$injected_html, $oldName ) );
+ Hooks::run( 'UserLogoutComplete', array( &$user, &$injected_html, $oldName ) );
$out->addHTML( $injected_html );
$out->returnToMain();
wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) . "\n" );
wfDebug( 'newGroups: ' . print_r( $newGroups, true ) . "\n" );
- wfRunHooks( 'UserRights', array( &$user, $add, $remove ) );
+ Hooks::run( 'UserRights', array( &$user, $add, $remove ) );
if ( $newGroups != $oldGroups ) {
$this->addLogEntry( $user, $oldGroups, $newGroups, $reason );
$software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
// Allow a hook to add/remove items.
- wfRunHooks( 'SoftwareInfo', array( &$software ) );
+ Hooks::run( 'SoftwareInfo', array( &$software ) );
$out = Xml::element(
'h2',
private static function getwgVersionLinked() {
global $wgVersion;
$versionUrl = "";
- if ( wfRunHooks( 'SpecialVersionVersionUrl', array( $wgVersion, &$versionUrl ) ) ) {
+ if ( Hooks::run( 'SpecialVersionVersionUrl', array( $wgVersion, &$versionUrl ) ) ) {
$versionParts = array();
preg_match( "/^(\d+\.\d+)/", $wgVersion, $versionParts );
$versionUrl = "https://www.mediawiki.org/wiki/MediaWiki_{$versionParts[1]}";
'other' => wfMessage( 'version-other' )->text(),
);
- wfRunHooks( 'ExtensionTypes', array( &self::$extensionTypes ) );
+ Hooks::run( 'ExtensionTypes', array( &self::$extensionTypes ) );
}
return self::$extensionTypes;
* Convert an array or object to a string for display.
*
* @param mixed $list Will convert an array to string if given and return
- * the paramater unaltered otherwise
+ * the parameter unaltered otherwise
*
* @return mixed
*/
* Use wfFindFile so we still think file namespace pages without
* files are missing, but valid file redirects and foreign files are ok.
*
- * @return boolean
+ * @return bool
*/
protected function existenceCheck( Title $title ) {
return (bool)wfFindFile( $title );
)
);
// Replacement for the WantedPages::getSQL hook
- wfRunHooks( 'WantedPages::getQueryInfo', array( &$this, &$query ) );
+ Hooks::run( 'WantedPages::getQueryInfo', array( &$this, &$query ) );
return $query;
}
protected function getCustomFilters() {
if ( $this->customFilters === null ) {
$this->customFilters = parent::getCustomFilters();
- wfRunHooks( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ), '1.23' );
+ Hooks::run( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ), '1.23' );
}
return $this->customFilters;
} else {
# Top log Ids for a page are not stored
$nonRevisionTypes = array( RC_LOG );
- wfRunHooks( 'SpecialWatchlistGetNonRevisionTypes', array( &$nonRevisionTypes ) );
+ Hooks::run( 'SpecialWatchlistGetNonRevisionTypes', array( &$nonRevisionTypes ) );
if ( $nonRevisionTypes ) {
$conds[] = $dbr->makeList(
array(
&$join_conds, $opts
) {
return parent::runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts )
- && wfRunHooks(
+ && Hooks::run(
'SpecialWatchlistQuery',
array( &$conds, &$tables, &$join_conds, &$fields, $opts ),
'1.23'
$props[] = $msgcache['isimage'];
}
- wfRunHooks( 'WhatLinksHereProps', array( $row, $nt, $target, &$props ) );
+ Hooks::run( 'WhatLinksHereProps', array( $row, $nt, $target, &$props ) );
if ( count( $props ) ) {
$propsText = $this->msg( 'parentheses' )
// Give hooks the chance to handle this request
$className = null;
- wfRunHooks( 'UploadCreateFromRequest', array( $type, &$className ) );
+ Hooks::run( 'UploadCreateFromRequest', array( $type, &$className ) );
if ( is_null( $className ) ) {
$className = 'UploadFrom' . $type;
wfDebug( __METHOD__ . ": class name: $className\n" );
}
$error = '';
- if ( !wfRunHooks( 'UploadVerification',
+ if ( !Hooks::run( 'UploadVerification',
array( $this->mDestName, $this->mTempPath, &$error ) )
) {
wfProfileOut( __METHOD__ );
}
}
- wfRunHooks( 'UploadVerifyFile', array( $this, $mime, &$status ) );
+ Hooks::run( 'UploadVerifyFile', array( $this, $mime, &$status ) );
if ( $status !== true ) {
wfProfileOut( __METHOD__ );
WatchedItem::IGNORE_USER_RIGHTS
);
}
- wfRunHooks( 'UploadComplete', array( &$this ) );
+ Hooks::run( 'UploadComplete', array( &$this ) );
$this->postProcessUpload();
}
public static function isAllowedUrl( $url ) {
if ( !isset( self::$allowedUrls[$url] ) ) {
$allowed = true;
- wfRunHooks( 'IsUploadAllowedFromUrl', array( $url, &$allowed ) );
+ Hooks::run( 'IsUploadAllowedFromUrl', array( $url, &$allowed ) );
self::$allowedUrls[$url] = $allowed;
}
if ( is_string( $token ) ) {
return;
}
- switch( $token[0] ) {
+ switch ( $token[0] ) {
case T_NAMESPACE:
case T_CLASS:
case T_INTERFACE:
* @param array
*/
protected function tryEndExpect( $token ) {
- switch( $this->startToken[0] ) {
+ switch ( $this->startToken[0] ) {
case T_NAMESPACE:
if ( $token === ';' || $token === '{' ) {
$this->namespace = $this->implodeTokens() . '\\';
*/
public static function isTrustedProxy( $ip ) {
$trusted = self::isConfiguredProxy( $ip );
- wfRunHooks( 'IsTrustedProxy', array( &$ip, &$trusted ) );
+ Hooks::run( 'IsTrustedProxy', array( &$ip, &$trusted ) );
return $trusted;
}
# Re-order by namespace ID number...
ksort( $this->namespaceNames );
- wfRunHooks( 'LanguageGetNamespaces', array( &$this->namespaceNames ) );
+ Hooks::run( 'LanguageGetNamespaces', array( &$this->namespaceNames ) );
}
return $this->namespaceNames;
if ( $inLanguage ) {
# TODO: also include when $inLanguage is null, when this code is more efficient
- wfRunHooks( 'LanguageGetTranslatedLanguageNames', array( &$names, $inLanguage ) );
+ Hooks::run( 'LanguageGetTranslatedLanguageNames', array( &$names, $inLanguage ) );
}
$mwNames = $wgExtraLanguageNames + $coreLanguageNames;
}
$this->mMagicHookDone = true;
wfProfileIn( 'LanguageGetMagic' );
- wfRunHooks( 'LanguageGetMagic', array( &$this->mMagicExtensions, $this->getCode() ) );
+ Hooks::run( 'LanguageGetMagic', array( &$this->mMagicExtensions, $this->getCode() ) );
wfProfileOut( 'LanguageGetMagic' );
}
// Initialise array
$this->mExtendedSpecialPageAliases =
self::$dataCache->getItem( $this->mCode, 'specialPageAliases' );
- wfRunHooks( 'LanguageGetSpecialPageAliases',
+ Hooks::run( 'LanguageGetSpecialPageAliases',
array( &$this->mExtendedSpecialPageAliases, $this->getCode() ) );
}
// the string does not have any number part. Eg: .12345
return $sign . $groupedNumber;
}
- $start = $end = strlen( $integerPart[0] );
+ $start = $end = ($integerPart) ? strlen( $integerPart[0] ) : 0;
while ( $start > 0 ) {
$match = $matches[0][$numMatches - 1];
$matchLen = strlen( $match );
public static function getMessagesFileName( $code ) {
global $IP;
$file = self::getFileName( "$IP/languages/messages/Messages", $code, '.php' );
- wfRunHooks( 'Language::getMessagesFileName', array( $code, &$file ) );
+ Hooks::run( 'Language::getMessagesFileName', array( $code, &$file ) );
return $file;
}
* This does not affect untranslated messages.
*
* NOTE: It returns a valid title, because there are some poorly written
- * extentions that assume the contents of some messages are valid.
+ * extensions that assume the contents of some messages are valid.
*
* @ingroup Language
*/
"Test Create account",
"Kuwaity26",
"Calak",
- "Omda4wady"
+ "Omda4wady",
+ "Bibas"
]
},
"tog-underline": "سطر تحت الوصلات:",
"tog-shownumberswatching": "اعرض عدد المستخدمين المراقبين",
"tog-oldsig": "التوقيع الحالي:",
"tog-fancysig": "وضع الوصلة يدويا واستعمال نص الويكي",
- "tog-uselivepreview": "استعمال المعاينة المباشرة (تجريبي)",
+ "tog-uselivepreview": "استعمال المعاينة المباشرة",
"tog-forceeditsummary": "نبهني عند عدم إدخال ملخص تعديل",
"tog-watchlisthideown": "أخف تعديلاتي من قائمة المراقبة",
"tog-watchlisthidebots": "أخف تعديلات البوتات من قائمة المراقبة",
"filerenameerror": "تعذّر تغيير اسم الملف \"$1\" إلى \"$2\".",
"filedeleteerror": "تعذّر حذف الملف \"$1\".",
"directorycreateerror": "تعذّر إنشاء الدليل \"$1\".",
+ "directoryreadonlyerror": "المجلد «$1» للقراءة فقط.",
+ "directorynotreadableerror": "المجلد «$1» لا يمكن قراءته.",
"filenotfound": "تعذّر إيجاد الملف \"$1\".",
"unexpected": "قيمة غير متوقعة: \"$1\"=\"$2\".",
"formerror": "عطل: تعذّر إيداع الاستمارة",
"content-model-text": "نص عادي",
"content-model-javascript": "جافاسكربت",
"content-model-css": "CSS",
+ "duplicate-args-category": "صفحات تستعمل قالبا ببيانات مكررة",
"expensive-parserfunction-warning": "'''تحذير:''' هذه الصفحة تحتوي على استدعاءات دالة محلل كثيرة مكلفة.\n\nينبغي أن تكون أقل من {{PLURAL:$2||استدعاء واحد|استدعاءين|$2 استدعاءات|$2 استدعاء}}، يوجد الآن {{PLURAL:$1|استدعاء واحد|استدعاءان|$2 استدعاءات|$2 استدعاء}}.",
"expensive-parserfunction-category": "تجاوزات الدوال المكلفة",
"post-expand-template-inclusion-warning": "'''تحذير:''' حجم تضمين القالب كبير جدا.\nبعض القوالب لن تضمن.",
"revdelete-show-file-confirm": "هل أنت متأكد أنك تريد رؤية مراجعة محذوفة للملف \"<nowiki>$1</nowiki>\" بتاريخ $2 الساعة $3؟",
"revdelete-show-file-submit": "نعم",
"revdelete-selected-text": "{{PLURAL:$1|نسخة مختارة|نسخ مختارة}} ل[[:$2]]:",
+ "revdelete-selected-file": "{{PLURAL:$1|النسخة المختارة من الملف|النسخ المختارة من الملف}} لـ [[:$2]]:",
"logdelete-selected": "{{PLURAL:$1|حدث السجل المختار|أحداث السجل المختارة}}:",
+ "revdelete-text-text": "المراجعات المحذوفة ستظل تظهر في تاريخ الصفحة، ولكن أجزاءا من محتواها سيكون محجوبا عن الجميع.",
"revdelete-text-others": "سيتمكن الإداريون الآخرون على {{SITENAME}} من الوصول إلى المحتوى المخفي وإلغاء حذفه مجددا من خلال ذات الواجهة ما لم تطبق قيود إضافية.",
"revdelete-confirm": "الإداريون الآخرون في {{SITENAME}} سيظل بإمكانهم رؤية المحتوى المخفي ويمكنهم استرجاعه مجددا من خلال هذه الواجهة نفسها، مالم يتم وضع قيود إضافية.\nمن فضلك أكد أنك تنوي فعل هذا، وأنك تفهم العواقب، وأنك تفعل هذا بالتوافق مع [[{{MediaWiki:Policy-url}}|السياسة]].",
"revdelete-suppress-text": "ينبغي للإخفاء أن يستخدم '''فقط''' في الحالات التالية:\n* معلومات يحتمل أن تكون تشهيرية\n* معلومات شخصية غير ملائمة\n*: ''عناوين المنازل وأرقام الهواتف وأرقام الهويات الوطنية إلى آخره.''",
"unwatchedpages": "صفحات غير مراقبة",
"listredirects": "عرض التحويلات",
"listduplicatedfiles": "قائمة الملفات مع المكررات",
+ "listduplicatedfiles-entry": "[[:File:$1|$1]] مكرر في [[$3|{{PLURAL:$2||مكان آخر واحد|مكانين آخرين اثنين|$2 أماكن أخرى|$2 مكاناً آخر|$2مكان آخر}}]].",
"unusedtemplates": "قوالب غير مستخدمة",
"unusedtemplatestext": "هذه الصفحة تعرض كل الصفحات في نطاق {{ns:template}} غير المضمنة في صفحة أخرى.\nتذكر بأن تتحقق من الوصلات الأخرى للقوالب قبل حذفها.",
"unusedtemplateswlh": "وصلات أخرى",
"suppress": "أوفرسايت",
"querypage-disabled": "تم تعطيل هذه الصفحة الخاصة لأسباب تتعلق بالأداء.",
"apihelp": "مساعدة API",
+ "apihelp-no-such-module": "الوحدة \"$1\" غير موجودة.",
"booksources": "مصادر كتاب",
"booksources-search-legend": "البحث عن مصادر الكتب",
"booksources-isbn": "ردمك:",
"listgrouprights-removegroup-self-all": "يمكنه إزالة كل المجموعات من حسابه الخاص",
"listgrouprights-namespaceprotection-header": "قيود النطاق",
"listgrouprights-namespaceprotection-namespace": "النطاق",
+ "listgrouprights-namespaceprotection-restrictedto": "الصلاحيات التي تسمح للمستخدم بالتعديل",
"trackingcategories": "تصانيف التتبع",
"trackingcategories-summary": "تسرد هذه الصفحة تصانيف التتبع التي ينشئها برنامج ميدياويكي. يمكن تغيير أسمائها بتغيير رسائل النظام في نطاق {{ns:8}}.",
"trackingcategories-msg": "تصانيف التتبع",
"delete-edit-reasonlist": "عدل أسباب الحذف",
"delete-toobig": "لهذه الصفحة تاريخ تعديل طويل، أكثر من {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}}.\nقُيّد محذف مثل هذه الصفحات لمنع الاضطراب المفاجئة في {{SITENAME}}.",
"delete-warning-toobig": "لهذه الصفحة تاريخ تعديل طويل، أكثر من {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}}.\nقد يؤدي حذفها إلى اضطراب عمليات قاعدة البيانات في {{SITENAME}}؛\nاستمر مع الحذر.",
+ "deleteprotected": "لا يمكنك حذف هذه الصفحة لأنها محمية.",
"deleting-backlinks-warning": "[[Special:WhatLinksHere/{{FULLPAGENAME}}|تتصل صفحات أخرى]] بالصفحة التي تريد حذفها.",
"rollback": "استرجاع التعديلات",
"rollback_short": "استرجع",
"sp-contributions-newbies-sub": "للحسابات الجديدة",
"sp-contributions-newbies-title": "مساهمات المستخدم للحسابات الجديدة",
"sp-contributions-blocklog": "سجل المنع",
+ "sp-contributions-suppresslog": "مساهمات المستخدم المحذوفة",
"sp-contributions-deleted": "مساهمات المستخدم المحذوفة",
"sp-contributions-uploads": "مرفوعات",
"sp-contributions-logs": "سجلات",
"import-logentry-upload": "استورد [[$1]] بواسطة رفع ملف",
"import-logentry-upload-detail": "{{PLURAL:$1|لا مراجعات|مراجعة واحدة|مراجعتان|$1 مراجعات|$1 مراجعة}}",
"import-logentry-interwiki": "استورد عبر الويكي $1",
- "import-logentry-interwiki-detail": "{{PLURAL:$1||مراجعة واحدة|مراجعتان|$1 مراجعات|$1 مراجعة}} من $2",
+ "import-logentry-interwiki-detail": "تم استيراد {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}} من $2",
"javascripttest": "اختبار جافاسكربت",
"javascripttest-title": "تشغيل أختبارات $1",
"javascripttest-pagetext-noframework": "هذه الصفحة محجوزة لإجراء أختبارات الجافا سكريبت.",
"revdelete-uname-unhid": "اسم المستخدم غير مخفي",
"revdelete-restricted": "طبق الضوابط لمديري النظام",
"revdelete-unrestricted": "أزال الضوابط لمديري النظام",
+ "logentry-merge-merge": "{{GENDER:$2|دمج|دمجت}} $1 $3 إلى $4 (المراجعات حتى $5).",
"logentry-move-move": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4",
"logentry-move-move-noredirect": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4 دون ترك تحويلة",
"logentry-move-move_redir": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4 على تحويلة",
"logentry-rights-rights": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3 من $4 إلى $5",
"logentry-rights-rights-legacy": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3",
"logentry-rights-autopromote": "تمت تلقائيا ترقية {{GENDER:$2|المستخدم|المستخدمة}} $1 من $4 إلى $5",
+ "logentry-upload-upload": " {{GENDER:$2|رفع|رفعت}} $1 $3",
+ "logentry-upload-overwrite": "{{GENDER:$2|رفع|رفعت}} $1 نسخة جديدة من $3",
+ "logentry-upload-revert": "{{GENDER:$2|رفع|رفعت}} $1 $3",
"rightsnone": "(لا شيء)",
"revdelete-summary": "ملخص التعديل",
"feedback-bugornote": "إن كنت مستعدا لشرح مشكلة تقنية بالتفصيل، رجاءا [$1 قدم تقريرا بالخلل].\nبخلاف ذلك، يمكنك أستخدام الطريقة الأسهل أسفله، سيتم إضافة تعليقك للصفحة \"[$3 $2]\"، بالإضافة إلى اسم المستخدم و نوع المتصفح الذي تستخدمه حاليا.",
"right-pagelang": "تغيير لغة الصفحة",
"action-pagelang": "تغيير لغة الصفحة",
"log-name-pagelang": "تغيير سجل الصفحة",
+ "logentry-pagelang-pagelang": " {{GENDER:$2|غيّر|غيّرت}} $1 لغة الصفحة «$3» من $4 إلى $5.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (مفعل)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''معطل''')",
"mediastatistics": "إحصاءات الميديا",
"tog-shownumberswatching": "Паказваць колькасьць назіральнікаў",
"tog-oldsig": "Цяперашні подпіс:",
"tog-fancysig": "Апрацоўваць подпіс як вікітэкст (без аўтаматычнай спасылкі)",
- "tog-uselivepreview": "Выкарыстоўваць хуткі папярэдні прагляд (экспэрымэнтальна)",
+ "tog-uselivepreview": "Выкарыстоўваць хуткі папярэдні прагляд",
"tog-forceeditsummary": "Папярэджваць пра адсутнасьць кароткага апісаньня зьменаў",
"tog-watchlisthideown": "Хаваць мае праўкі ў сьпісе назіраньня",
"tog-watchlisthidebots": "Хаваць праўкі робатаў у сьпісе назіраньня",
"filecopyerror": "Немагчыма cкапіяваць файл «$1» у «$2».",
"filerenameerror": "Немагчыма перайменаваць файл «$1» у «$2».",
"filedeleteerror": "Немагчыма выдаліць файл «$1».",
- "directorycreateerror": "Ð\9dемагÑ\87Ñ\8bма Ñ\81Ñ\82ваÑ\80Ñ\8bÑ\86Ñ\8c дÑ\8bÑ\80Ñ\8dкÑ\82оÑ\80Ñ\8bÑ\8e «$1».",
+ "directorycreateerror": "Ð\9dемагÑ\87Ñ\8bма Ñ\81Ñ\82ваÑ\80Ñ\8bÑ\86Ñ\8c каÑ\82алÑ\91г «$1».",
"directoryreadonlyerror": "Тэчка «$1» толькі для чытаньня.",
"directorynotreadableerror": "Тэчка «$1» не чытаецца.",
"filenotfound": "Немагчыма знайсьці файл «$1».",
"unexpected": "Нечаканае значэньне: «$1»=«$2».",
- "formerror": "Памылка: не атрымалася адаслаць зьвесткі формы",
+ "formerror": "Памылка: не атрымалася адаслаць зьвесткі формы.",
"badarticleerror": "Гэтае дзеяньне немагчыма выканаць на гэтай старонцы.",
"cannotdelete": "Немагчыма выдаліць старонку альбо файл «$1». Магчыма, яна ўжо выдаленая кімсьці іншым.",
"cannotdelete-title": "Немагчыма выдаліць старонку «$1»",
"anoneditwarning": "<strong>Папярэджаньне</strong>: вы не ўвайшлі ў сыстэму. Ваш IP-адрас будзе бачны ўсім, калі вы адрэдагуеце старонку. Калі вы <strong>[$1 ўвойдзеце]</strong> або <strong>[$2 створыце рахунак]</strong>, вашыя рэдагаваньні будуць зьвязаныя з вашым імем карыстальніка, а таксама вам будуць даступныя дадатковыя перавагі.",
"anonpreviewwarning": "''Вы не ўвайшлі ў сыстэму. Падчас захаваньня Ваш IP-адрас будзе дададзены ў гісторыю рэдагаваньняў старонкі.''",
"missingsummary": "'''Напамін:''' Вы не пазначылі кароткае апісаньне зьменаў.\nКалі Вы націсьніце кнопку «Запісаць» яшчэ раз, Вашае рэдагаваньне будзе запісанае без апісаньня.",
+ "selfredirect": "<strong>Папярэджаньне:</strong> вы ствараеце перанакіраваньне на гэты самы артыкул.\nКалі вы націсьніце «{{int:savearticle}}» яшчэ раз, перанакіраваньне будзе створанае.",
"missingcommenttext": "Калі ласка, увядзіце камэнтар ніжэй.",
"missingcommentheader": "'''Напамін:''' Вы не пазначылі загаловак камэнтара.\nКалі Вы націсьніце кнопку «{{int:savearticle}}» яшчэ раз, Ваш камэнтар захаваецца бяз тэмы.",
"summary-preview": "Папярэдні прагляд апісаньня:",
"Usarker",
"Wikitanvir",
"Zaheen",
- "לערי ריינהארט"
+ "לערי ריינהארט",
+ "Aftabuzzaman"
]
},
"tog-underline": "সংযোগগুলির নিচে দাগ দেখানো হোক:",
"tog-shownumberswatching": "নজরদারী করছে, এমন ব্যবহারকারীর সংখ্যা দেখানো হোক",
"tog-oldsig": "বর্তমান স্বাক্ষর:",
"tog-fancysig": "স্বাক্ষরকে উইকিটেক্সট হিসেবে মনে করুন (কোন সয়ংক্রিয় লিঙ্ক ছাড়া)",
- "tog-uselivepreview": "তাৎক্ষণিক প্রাকদর্শনের ক্ষমতা চালু করা হোক (পরীক্ষামূলক)",
+ "tog-uselivepreview": "তাৎক্ষণিক প্রাকদর্শন ব্যবহার করো",
"tog-forceeditsummary": "খালি সম্পাদনা সারাংশ প্রবেশ করানোর সময় আমাকে জানানো হোক",
"tog-watchlisthideown": "আমার সম্পাদনাগুলি আমার নজরতালিকায় না দেখানো হোক",
"tog-watchlisthidebots": "বটের করা সম্পাদনাগুলি নজরতালিকায় না দেখানো হোক",
"login-userblocked": "এই ব্যবহারকারীকে বাধা দেওয়া হয়েছে। লগ-ইন সম্ভব নয়।",
"wrongpassword": "আপনি ভুল পাসওয়ার্ড ব্যবহার করেছেন। অনুগ্রহ করে আবার চেষ্টা করুন।",
"wrongpasswordempty": "পাসওয়ার্ড প্রবেশের ঘরটি খালি ছিল। দয়া করে আবার চেষ্টা করুন।",
- "passwordtooshort": "পাসà¦\93য়ারà§\8dড à¦\85বশà§\8dযà¦\87 {{PLURAL:$1|১ à¦\85à¦\95à§\8dষরà§\87র|$1 à¦\85à¦\95à§\8dষরà§\87র}} হতà§\87 হবà§\87।",
+ "passwordtooshort": "পাসà¦\93য়ারà§\8dড à¦\95মপà¦\95à§\8dষà§\87 {{PLURAL:$1|১ à¦\85à¦\95à§\8dষরà§\87র|$1 à¦\85à¦\95à§\8dষরà§\87র}} হতà§\87 হবà§\87।",
"password-name-match": "আপনার পাসওয়ার্ড আপনার ব্যবহারকারী নাম থেকে আলাদা হতে হবে।",
"password-login-forbidden": "এই ব্যবহারকারীর নাম এবং পাসওয়ার্ডটি ব্যবহার নিষিদ্ধ করা হয়েছে।",
"mailmypassword": "পাসওয়ার্ড রিসেট",
"showhideselectedversions": "নির্বাচিত সংশোধনগুলো দেখাও/লুকাও",
"editundo": "পূর্বাবস্থায় আনো",
"diff-empty": "(কোন পার্থক্য নেই)",
+ "diff-multi-sameuser": "(একই ব্যবহারকারী দ্বারা সম্পাদিত {{PLURAL:$1|একটি মধ্যবর্তী সংশোধন|$1টি মধ্যবর্তী সংশোধন}} দেখানো হচ্ছে না)",
+ "diff-multi-otherusers": "({{PLURAL:$2|একজন|$2 জন}} ব্যবহারকারী দ্বারা সম্পাদিত {{PLURAL:$1|একটি|$1টি}} মধ্যবর্তী সংশোধন দেখানো হচ্ছে না)",
"diff-multi-manyusers": "($2 জন {{PLURAL:$2|ব্যবহারাকারীর}} সম্পাদিত {{PLURAL:$1|একটি সাম্প্রতিক সংস্করণ|$1 টি সাম্প্রতিক সংস্করণ}} প্রদর্শিত হচ্ছে না)",
"difference-missing-revision": "$1 পার্থক্যের {{PLURAL:$2|একটি সংস্করণ|$2টি সংস্করণসমূহ}} খুজে পাওয়া যাচ্ছে না।\n\nসাধারণত মুছে ফেলা হয়েছে এমন পাতার মেয়াদ উত্তীর্ণ ইতিহাস পাতার লিংক ওপেন করার কারণে এটি হতে পারে। \n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অপসারণ লগে] বিস্তারিত তথ্য জানা যাবে।",
"searchresults": "অনুসন্ধানের ফলাফল",
"action-viewmywatchlist": "আপনার নজরতালিকা দেখুন",
"action-viewmyprivateinfo": "আপনার ব্যক্তিগত তথ্য দেখুন",
"action-editmyprivateinfo": "আপনার ব্যক্তিগত তথ্য সম্পাদনা করুন",
- "nchanges": "$1 {{PLURAL:$1|পরিবর্তন|পরিবর্তনসমূহ}}",
+ "nchanges": "$1টি {{PLURAL:$1|পরিবর্তন}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|সর্বশেষ প্রদর্শনের পর}}",
"enhancedrc-history": "ইতিহাস",
"recentchanges": "সাম্প্রতিক পরিবর্তনসমূহ",
"activeusers-hidesysops": "প্রশাসক লুকাও",
"activeusers-noresult": "কোনো ব্যবহারকারী পাওয়া যায়নি।",
"listgrouprights": "দলগত ব্যবহারকারী অধিকার",
- "listgrouprights-summary": "এই উইকির ব্যবহারকারীদের একটি গ্রুপগুলোর তালিকা দেখানো হচ্ছে, সাথে গ্রুপের কার্যপরিধিও উল্লেখ করা হয়েছে।\nনির্দিষ্ট গ্রুপের কার্যপরিধি সম্পর্কে জানতে দেখুন [[{{MediaWiki:Listgrouprights-helppage}}|additional information]]।",
+ "listgrouprights-summary": "এই উইকির ব্যবহারকারীদের একটি গ্রুপগুলোর তালিকা দেখানো হচ্ছে, সাথে গ্রুপের কার্যপরিধিও উল্লেখ করা হয়েছে।\nনির্দিষ্ট গ্রুপের কার্যপরিধি সম্পর্কে জানতে [[{{MediaWiki:Listgrouprights-helppage}}|অতিরিক্ত তথ্য]] দেখুন।",
"listgrouprights-key": "লিজেন্ড:\n* <span class=\"listgrouprights-granted\">অনুমোদিত অধিকার</span>\n* <span class=\"listgrouprights-revoked\">বাধাপ্রাপ্ত অধিকার</span>",
"listgrouprights-group": "দল",
"listgrouprights-rights": "অধিকারসমূহ",
"tags-active-yes": "হ্যাঁ",
"tags-active-no": "না",
"tags-edit": "সম্পাদনা",
- "tags-hitcount": "$1 {{PLURAL:$1|পরিবর্তন|পরিবর্তনসমূহ}}",
+ "tags-hitcount": "$1টি {{PLURAL:$1|পরিবর্তন}}",
"comparepages": "পাতার তুলনা",
"compare-page1": "পাতা ১",
"compare-page2": "পাতা ২",
"tog-shownumberswatching": "Prikaži broj korisnika koji prate",
"tog-oldsig": "Postojeći potpis:",
"tog-fancysig": "Smatraj potpis kao wikitekst (bez automatskog linka)",
- "tog-uselivepreview": "Koristite pregled uživo (eksperimentalno)",
+ "tog-uselivepreview": "Koristite pregled uživo",
"tog-forceeditsummary": "Opomeni me pri unosu praznog sažetka",
"tog-watchlisthideown": "Sakrij moje izmjene sa spiska praćenih članaka",
"tog-watchlisthidebots": "Sakrij izmjene botova sa spiska praćenih članaka",
"december-date": "$1. decembar",
"pagecategories": "{{PLURAL:$1|Kategorija|Kategorije}}",
"category_header": "Članci u kategoriji \"$1\"",
- "subcategories": "Potkategorije",
+ "subcategories": "Podkategorije",
"category-media-header": "Datoteke u kategoriji \"$1\"",
"category-empty": "''Ova kategorija trenutno ne sadrži članke ni medije.''",
"hidden-categories": "{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}}",
- "hidden-category-category": "Sakrivene kategorije",
+ "hidden-category-category": "Skrivene kategorije",
"category-subcat-count": "{{PLURAL:$2|Ova kategorija ima sljedeću podkategoriju.|Ova kategorija ima {{PLURAL:$1|sljedeću podkategoriju|sljedeće $1 podkategorije|sljedećih $1 podkategorija}}, od $2 ukupno.}}",
"category-subcat-count-limited": "Ova kategorija sadrži {{PLURAL:$1|slijedeću $1 podkategoriju|slijedeće $1 podkategorije|slijedećih $1 podkategorija}}.",
"category-article-count": "{{PLURAL:$2|U ovoj kategoriji nalazi se $1 članak.|{{PLURAL:$1|Prikazan je $1 članak|Prikazana su $1 članka|Prikazano je $1 članaka}} od ukupno $2 u ovoj kategoriji.}}",
"otherlanguages": "Na drugim jezicima",
"redirectedfrom": "(Preusmjereno sa $1)",
"redirectpagesub": "Preusmjeri stranicu",
+ "redirectto": "Preusmjerenje na:",
"lastmodifiedat": "Ova stranica je posljednji put izmijenjena $2, $1",
"viewcount": "Ovoj stranici je pristupljeno {{PLURAL:$1|$1 put|$1 puta}}.",
"protectedpage": "Zaštićena stranica",
"filerenameerror": "Ne može se promjeniti ime datoteke \"$1\" u \"$2\".",
"filedeleteerror": "Ne može se izbrisati datoteka \"$1\".",
"directorycreateerror": "Nije moguće napraviti direktorijum \"$1\".",
+ "directorynotreadableerror": "Direktorij \"$1\" nije čitljiv.",
"filenotfound": "Ne može se naći datoteka \"$1\".",
"unexpected": "Neočekivana vrijednost: \"$1\"=\"$2\".",
"formerror": "Greška: ne može se poslati upitnik",
"createacct-imgcaptcha-ph": "Unesite tekst koji vidite iznad",
"createacct-submit": "Napravite svoj korisnički račun",
"createacct-another-submit": "Napravi još jedan korisnički račun",
- "createacct-benefit-heading": "{{SITENAME}} je napravljen od strane ljudi kao što ste Vi.",
+ "createacct-benefit-heading": "{{SITENAME}} je napravljena od strane ljudi kao što ste Vi.",
"createacct-benefit-body1": "{{PLURAL:$1|izmjena|izmjene}}",
"createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice|stranica}}",
- "createacct-benefit-body3": "nedavni {{PLURAL:$1|doprinosa}}",
+ "createacct-benefit-body3": "nedavnih {{PLURAL:$1|doprinosa}}",
"badretype": "Šifre koje ste unijeli se ne poklapaju.",
"userexists": "Korisničko ime koje ste unijeli je već u upotrebi.\nMolimo Vas da izaberete drugo ime.",
"loginerror": "Greška pri prijavljivanju",
"accountcreated": "Korisnički račun je napravljen",
"accountcreatedtext": "Korisnički račun za [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|razgovor]]) je napravljen.",
"createaccount-title": "Pravljenje korisničkog računa za {{SITENAME}}",
- "createaccount-text": "Neko je napravio korisnički račun za vašu e-mail adresu na {{SITENAME}} ($4) sa imenom \"$2\", i sa šifrom \"$3\".\nTrebali biste se prijaviti i promjeniti šifru.\n\nMožete ignorisati ovu poruku, ako je korisnički račun napravljen greškom.",
+ "createaccount-text": "Neko je napravio korisnički račun za vašu e-mail adresu na {{SITENAME}} ($4) sa imenom \"$2\", i sa šifrom \"$3\".\nTrebali biste se prijaviti i promijeniti šifru.\n\nMožete ignorisati ovu poruku, ako je korisnički račun napravljen greškom.",
"login-throttled": "Previše puta ste se pokušali prijaviti.\nMolimo Vas da sačekate $1 prije nego što pokušate ponovo.",
"login-abort-generic": "Vaša prijava nije bila uspješna – Prekinuto",
"loginlanguagelabel": "Jezik: $1",
"revdelete-hide-text": "Tekst revizije",
"revdelete-hide-image": "Sakrij sadržaj datoteke",
"revdelete-hide-name": "Sakrij akciju i cilj",
- "revdelete-hide-comment": "Sakrij izmjene komentara",
+ "revdelete-hide-comment": "Uredi sažetak",
"revdelete-hide-user": "Korisničko ime urednika/IP",
"revdelete-hide-restricted": "Ograniči podatke za administratore kao i za druge korisnike",
"revdelete-radio-same": "(ne mijenjaj)",
"search-result-category-size": "{{PLURAL:$1|1 član|$1 člana|$1 članova}} ({{PLURAL:$2|1 podkategorija|$2 podkategorije|$2 podkategorija}}, {{PLURAL:$3|1 datoteka|$3 datoteke|$3 datoteka}})",
"search-redirect": "(preusmjeravanje $1)",
"search-section": "(sekcija $1)",
+ "search-category": "(kategorija $1)",
"search-suggest": "Da li ste mislili: $1",
"search-interwiki-caption": "Srodni projekti",
"search-interwiki-default": "$1 rezultati:",
"invalid-chunk-offset": "Neispravna polazna tačka",
"img-auth-accessdenied": "Pristup onemogućen",
"img-auth-nopathinfo": "Nedostaje PATH_INFO.\nVaš server nije postavljen da daje ovu informaciju.\nMožda je zasnovan na CGI koji ne podržava img_auth.\nPogledajte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
- "img-auth-notindir": "Zahtjevana putanje nije u direktorijumu podešenom za postavljanje.",
+ "img-auth-notindir": "Zahtjevana putanja nije u direktoriju podešenom za postavljanje.",
"img-auth-badtitle": "Ne mogu napraviti valjani naslov iz \"$1\".",
"img-auth-nologinnWL": "Niste prijavljeni i \"$1\" nije na spisku dozvoljenih.",
"img-auth-nofile": "Datoteka \"$1\" ne postoji.",
- "img-auth-isdir": "Pokušavate pristupiti direktorijumu \"$1\".\nDozvoljen je samo pristup datotekama.",
+ "img-auth-isdir": "Pokušavate pristupiti direktoriju \"$1\".\nDozvoljen je samo pristup datotekama.",
"img-auth-streaming": "Tok \"$1\".",
"img-auth-public": "Funkcija img_auth.php služi za izlaz datoteka sa privatnih wikija.\nOva wiki je postavljena kao javna wiki.\nZa optimalnu sigurnost, img_auth.php je onemogućena.",
"img-auth-noread": "Korisnik nema pristup za čitanje \"$1\".",
"querypage-disabled": "Ova posebna stranica je onemogućena jer smanjuje performanse.",
"booksources": "Štampani izvori",
"booksources-search-legend": "Traži književne izvore",
+ "booksources-search": "Traži",
"booksources-text": "Ispod se nalazi spisak vanjskih linkova na ostale stranice koje prodaju nove ili korištene knjige kao i stranice koje mogu da imaju važnije podatke o knjigama koje tražite:",
"booksources-invalid-isbn": "Navedeni ISBN broj nije validan; molimo da provjerite da li je došlo do greške pri kopiranju iz prvobitnog izvora.",
"specialloguserlabel": "Izvršilac:",
"listgrouprights-addgroup-self-all": "Može dodati sve grupe na svoj račun",
"listgrouprights-removegroup-self-all": "Može ukloniti sve grupe sa svog računa",
"listgrouprights-namespaceprotection-namespace": "Imenski prostor",
+ "trackingcategories-name": "Ime poruke",
"trackingcategories-nodesc": "Opis nije dostupan.",
"mailnologin": "Nema adrese za slanje",
"mailnologintext": "Morate biti [[Special:UserLogin|prijavljeni]]\ni imati ispravnu adresu e-pošte u vašim [[Special:Preferences|podešavanjima]]\nda biste slali e-poštu drugim korisnicima.",
"tooltip-feed-atom": "Atom za ovu stranicu",
"tooltip-t-contributions": "Pogledajte spisak doprinosa ovog korisnika",
"tooltip-t-emailuser": "Pošaljite pismo ovom korisniku",
+ "tooltip-t-info": "Više informacija o ovoj stranici",
"tooltip-t-upload": "Postavi slike i druge medije",
"tooltip-t-specialpages": "Spisak svih posebnih stranica",
"tooltip-t-print": "Verzija ove stranice za štampanje",
"confirm-watch-top": "Dodajte ovu stranu na Vaš spisak praćenih članaka",
"confirm-unwatch-button": "U redu",
"confirm-unwatch-top": "Izbrišite ovu stranu sa Vašeg spiska praćenih članaka",
+ "quotation-marks": "\"$1\"",
"imgmultipageprev": "← prethodna stranica",
"imgmultipagenext": "slijedeća stranica →",
"imgmultigo": "Idi!",
"imgmultigoto": "Idi na stranicu $1",
+ "img-lang-default": "(podrazumijevani jezik)",
+ "img-lang-info": "Prikaži ovu sliku u $1. $2",
"img-lang-go": "Idi",
"ascending_abbrev": "rast",
"descending_abbrev": "opad",
"autosumm-replace": "Zamjena stranice sa '$1'",
"autoredircomment": "Preusmjereno na [[$1]]",
"autosumm-new": "Napravljena stranica sa '$1'",
+ "autosumm-newblank": "Napravljena prazna stranica",
"size-bytes": "$1 B",
"size-kilobytes": "$1 KB",
"size-megabytes": "$1 MB",
"watchlistedit-raw-done": "Vaš spisak praćenja je ažuriran.",
"watchlistedit-raw-added": "{{PLURAL:$1|1 naslov je dodan|$1 naslova su dodana|$1 naslova je dodano}}:",
"watchlistedit-raw-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova je uklonjeno}}:",
+ "watchlisttools-clear": "Očisti spisak nadgledanja",
"watchlisttools-view": "Pregled promjena praćenih stranica",
"watchlisttools-edit": "Pogledaj i uredi listu praćenih članaka.",
"watchlisttools-raw": "Uređivanje praćenih stranica u okviru praćenja.",
"version-version": "(Verzija $1)",
"version-license": "Licenca",
"version-ext-license": "Licenca",
+ "version-ext-colheader-name": "Proširenje",
+ "version-skin-colheader-name": "Izgled",
"version-ext-colheader-version": "Verzija",
"version-ext-colheader-license": "Licenca",
"version-ext-colheader-description": "Opis",
"specialpages-group-wiki": "Podaci i alati",
"specialpages-group-redirects": "Preusmjeravanje posebnih stranica",
"specialpages-group-spam": "Alati za spam",
+ "specialpages-group-developer": "Razvojni alati",
"blankpage": "Prazna stranica",
"intentionallyblankpage": "Ova stranica je namjerno ostavljena prazna",
"external_image_whitelist": " #Ostavite ovu liniju onakva kakva je<pre>\n#Stavite obične fragmente opisa (samo dio koji ide između //) ispod\n#Ovi će biti spojeni sa URLovima sa vanjskih (eksternih) slika\n#One koji se spoje biće prikazane kao slike, u suprotnom će se prikazati samo link\n#Linije koje počinju sa # se tretiraju kao komentari\n#Ovo ne razlikuje velika i mala slova\n\n#Stavite sve regex fragmente iznad ove linije. Ostavite ovu liniju onakvu kakva je</pre>",
"duration-centuries": "$1 {{PLURAL:$1|vijek|vijeka|vijekova}}",
"duration-millennia": "$1 {{PLURAL:$1|milenij|milenija}}",
"rotate-comment": "Slika rotirana za $1 {{PLURAL:$1|stepen|stepeni}} u smjeru kazaljke na satu",
+ "limitreport-walltime": "Korištenje u realnom vremenu",
"limitreport-walltime-value": "$1 {{PLURAL:$1|sekunda|sekunde|sekundi}}",
"expandtemplates": "Proširi šablone",
"expand_templates_intro": "Ova posebna stranica uzima neki tekst i proširuje sve šablone u njemu rekurzivno.\nOna također proširuje parserske funkcije poput\n<nowiki>{{</nowiki>#language:…}} i varijable poput\n<nowiki>{{</nowiki>CURRENTDAY}}—u principu gotovo sve između dvostrukih zagrada.\nOvo se uradi putem poziva relevantnog parserskog nivoa iz same MediaWiki.",
"expand_templates_preview": "Pregled",
"pagelang-name": "Stranica",
"pagelang-language": "Jezik",
- "pagelang-select-lang": "Izaberi jezik"
+ "pagelang-select-lang": "Izaberi jezik",
+ "mediastatistics-header-unknown": "Nepoznato",
+ "json-error-syntax": "Sintaksna greška"
}
"Calak",
"F3RaN",
"ESM",
- "Loupeter"
+ "Loupeter",
+ "Macofe"
]
},
"tog-underline": "Subratlla els enllaços:",
"tog-shownumberswatching": "Mostra el nombre d'usuaris que hi vigilen",
"tog-oldsig": "Signatura actual:",
"tog-fancysig": "Tractar la signatura com a text wiki (sense enllaç automàtic)",
- "tog-uselivepreview": "Utilitza la previsualització automàtica (cal JavaScript) (experimental)",
+ "tog-uselivepreview": "Utilitza la previsualització automàtica",
"tog-forceeditsummary": "Avisa'm en deixar el resum de la modificació en blanc",
"tog-watchlisthideown": "Amaga les meues edicions de la llista de seguiment",
"tog-watchlisthidebots": "Amaga de la llista de seguiment les edicions fetes per usuaris bots",
"viewsourcetext": "Podeu visualitzar i copiar el codi font d’aquesta pàgina:",
"viewyourtext": "Vostè pot veure i copiar la font de ' ' les modificacions ' ' d'aquesta pàgina:",
"protectedinterface": "Aquesta pàgina proporciona el text de la interfície del software d'aquest wiki i està protegida per evitar els abusos.\nPer afegir o canviar les traduccions per a tots els wikis, feu servir [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
- "editinginterface": "'''Avís:''' Esteu editant una pàgina que conté cadenes de text per a la interfície d'aquest programari. Tingueu en compte que els canvis que es fan a aquesta pàgina afecten a l'aparença de la interfície d'altres usuaris. Per afegir o modificar traduccions a totes les wikis, plantegeu-vos utilitzar la [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
+ "editinginterface": "'''Avís:''' esteu editant una pàgina que s'utilitza per proporcionar text d'interfície per al programari. Els canvis que es facin a la pàgina afectaran l'aparença de la interfície d'altres usuaris del wiki.",
"translateinterface": "Per afegir o canviar traduccions per a tots els wikis, utilitzeu [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
"cascadeprotected": "Aquesta pàgina està protegida i no es pot modificar perquè està inclosa en {{PLURAL:$1|la següent pàgina, que té|les següents pàgines, que tenen}} activada l'opció de «protecció en cascada»:\n$2",
"namespaceprotected": "No teniu permís per a modificar pàgines en l'espai de noms '''$1'''.",
"tog-underline": "下劃綫鏈接",
"tog-hideminor": "囥起最近改變其過幼修改",
"tog-hidepatrolled": "囥起最近改變其巡邏修改",
+ "tog-newpageshidepatrolled": "共巡邏視頁趁新建頁列表𡅏囥起去",
"tog-extendwatchlist": "敆擴展監視單單臺中顯示所有其更改,伓啻最近其更改",
+ "tog-usenewrc": "按頁顯示最近修改共監視列表臺中其群組改變",
"tog-numberheadings": "自動編號其標題",
"tog-showtoolbar": "顯示編輯工具欄",
"tog-editondblclick": "雙擊就修改頁面",
"tog-watchdefault": "添加我編輯其頁面共文件遘我其監視單",
"tog-watchmoves": "添加我移動其頁面共文件遘我其監視單",
"tog-watchdeletion": "添加我刪掉其頁面共文件遘我其監視單",
+ "tog-watchrollback": "敆我其監視列表臺中添加我做過回滚其頁面",
"tog-minordefault": "默認共所有其編輯都當作過幼修改",
"tog-previewontop": "敆編輯框以前顯示預覽",
"tog-previewonfirst": "敆頭蜀回編輯時候看預覽",
"tog-enotifwatchlistpages": "我其監視單有變時候,發電子郵件乞我",
"tog-enotifusertalkpages": "我其討論頁有變時候,發電子郵件乞我",
"tog-enotifminoredits": "就㑚講是過幼編輯,也着發電子郵件乞我",
+ "tog-enotifrevealaddr": "敆通知郵件臺中顯示我其電子郵件地址",
"tog-shownumberswatching": "顯示監視用戶其數量",
"tog-oldsig": "存在其簽名",
"tog-fancysig": "共簽名當成維基文本(無自動鏈接)",
"tog-watchlisthideown": "趁監視單𡅏囥起我其修改",
"tog-watchlisthidebots": "囥起監視單其機器人其修改",
"tog-watchlisthideminor": "囥起監視單其過幼修改",
- "tog-watchlisthideliu": "共已經躒底其用戶其編輯趁監視單𡅏囥起咯",
+ "tog-watchlisthideliu": "共已經登錄其用戶其編輯趁監視單𡅏囥起咯",
"tog-watchlisthideanons": "共匿名其用戶其編輯趁監視單𡅏囥起咯",
"tog-watchlisthidepatrolled": "共巡查其編輯趁監視單𡅏囥起咯",
"tog-ccmeonemails": "共我發乞其他用戶其電子郵件其備份發乞我。",
"tog-showhiddencats": "㪗藏類別",
"tog-norollbackdiff": "敆回滾其時候,無叕𣍐蜀様其地方",
"tog-useeditwarning": "我編輯頁面其時候離開,起動警告我蜀下",
+ "tog-prefershttps": "登錄以後全程使用安全連接",
"underline-always": "直頭",
"underline-never": "頭𡅏無",
"underline-default": "皮膚或者瀏覽器默認其",
"mytalk": "我其討論",
"anontalk": "茲隻IP其討論頁",
"navigation": "引導",
- "and": " and",
+ "and": " 共",
"qbfind": "討",
"qbbrowse": "覷蜀覷",
"qbedit": "修改",
"permalink": "永久鏈接",
"print": "拍印",
"view": "覷蜀覷",
+ "view-foreign": "敆$1𡅏看",
"edit": "修改",
+ "edit-local": "編輯當地描述",
"create": "創建",
+ "create-local": "添加當地描述",
"editthispage": "修改茲頁",
"create-this-page": "創建茲蜀頁",
"delete": "刪除",
"categorypage": "看分類頁",
"viewtalkpage": "看討論",
"otherlanguages": "其它其語言",
- "redirectedfrom": "(由$1重定向過來)",
+ "redirectedfrom": "(趁$1重定向過來)",
"redirectpagesub": "重定向頁",
+ "redirectto": "重定向遘",
"lastmodifiedat": "茲蜀頁是着$1 $2其辰候最後修改其。",
"viewcount": "茲蜀頁已經乞訪問$1回了。{{PLURAL:$1}}",
"protectedpage": "保護頁",
"jumptonavigation": "引導:",
"jumptosearch": "尋討",
"view-pool-error": "對不住,服務器茲蜀萆時候已弳過載了。\n過価用戶敆𡅏覷茲蜀頁。\n起動等仂久再來覷茲蜀頁。\n\n$1",
+ "generic-pool-error": "對不住,現刻時服務器過載了。\n實在過価用戶敆𡅏訪問茲蜀萆資源。\n起動汝等蜀刻再訪問茲蜀萆資源。",
"pool-timeout": "等待鎖定其時間遘了",
"pool-queuefull": "隊列池已經滿了",
"pool-errorunknown": "𣍐八什乇鄭咯",
"aboutsite": "關於{{SITENAME}}",
"aboutpage": "Project:關於",
- "copyright": "å\85§å®¹æ\95\86$1ä¸\8båº\95æ\9c\83使ç\8d²å¾\97。",
+ "copyright": "å\85§å®¹æ\9c\83使æ\95\86$1ä¸\8båº\95æ\9c\83使ç\8d²å¾\97é\81\98ï¼\8cè\8b¥ç\84¡æ\9c\83給å\87ºå\85¶å®\83æ\8f\90示。",
"copyrightpage": "{{ns:project}}:版權",
"currentevents": "大樹下",
"currentevents-url": "Project:大樹下",
"youhavenewmessages": "汝有$1($2)。",
"youhavenewmessagesfromusers": "汝有趁$3用戶($2)來其$1萆信息{{PLURAL:$3}}",
"youhavenewmessagesmanyusers": "汝有趁雅価用戶($2)其$1信息",
- "newmessageslinkplural": "$1條新其信息{{PLURAL:$1}}",
- "newmessagesdifflinkplural": "最後其改變{{PLURAL:$1}}",
+ "newmessageslinkplural": "{{PLURAL:$1|蜀條新其消息|999=新其消息}}",
+ "newmessagesdifflinkplural": "最後{{PLURAL:$1|回改變|999=回改變}}",
"youhavenewmessagesmulti": "汝有趁$1來其新信息",
"editsection": "修改",
"editold": "修改",
"hidetoc": "囥起",
"collapsible-collapse": "隱",
"collapsible-expand": "現",
+ "confirmable-confirm": "汝會確定𣍐?",
+ "confirmable-yes": "是",
+ "confirmable-no": "伓是",
"thisisdeleted": "卜看或者恢復$1?",
"viewdeleted": "看$1?",
"restorelink": "$1萆乞刪掉其修改{{PLURAL:$1}}",
"nospecialpagetext": "<strong>汝請求蜀萆𣍐合法其特殊頁面。</strong>\n\n合法其特殊頁面清單會使敆[[Special:SpecialPages|{{int:特殊頁面}}]]頁面討著",
"error": "鄭咯",
"databaseerror": "數據庫有綻",
+ "databaseerror-text": "數據庫查詢發生錯誤。\n嚽可能是軟件底裡其程序缺陷。",
+ "databaseerror-textcl": "數據庫查詢發生錯誤。",
+ "databaseerror-query": "查詢語句:$1",
+ "databaseerror-function": "函數名:$1",
+ "databaseerror-error": "錯誤信息:$1",
"laggedslavemode": "'''警告:'''頁面可能無最近其更新。",
"readonly": "數據庫乞鎖起咯",
+ "enterlockreason": "拍底汝鎖定數據庫其原因,包括汝估計其釋放鎖其時間",
"readonlytext": "Só-gé̤ṳ-kó cī-buàng ké̤ṳk nè̤ng sō̤ kī lāu, mâ̤-sāi siā sĭng dèu-mĕ̤k hĕ̤k có̤ siŭ-gāi, ô kō̤-nèng sê ôi-lāu nĭk-siòng mì-hô, cĭ-hâiu cêu â̤ ciáng-siòng.\n\nSō̤ kī só-gé̤ṳ-kó gì guāng-lī-uòng cūng-kuāng gāi-sék: $1",
+ "missing-article": "數據庫未討遘本身應當著討遘其名叫\"$1\"其頁面$2其文本。\n\n嚽可能是下底其過時其diff或者已經删除其歴史鏈接造成其。\n\n如果伓是茲兩種情況,汝可能發現著蜀萆服務器其缺陷。\n起動汝共茲蜀萆缺陷匯報乞[[Special:ListUsers/sysop|管理員]],附上網址。",
+ "missingarticle-rev": "(版本#:$1)",
"missingarticle-diff": "(比並:$1、$2)",
+ "readonly_lag": "從數據庫跟上主數據庫其辰候,數據庫已經自動鎖定",
"internalerror": "內部錯誤",
"internalerror_info": "內部錯誤:$1",
"filecopyerror": "𣍐使趁「$1」𡅏複製文件遘「$2」。",
"filerenameerror": "𣍐使共「$1」其名字改去「$2」。",
"filedeleteerror": "𣍐使刪掉文件「$1」。",
"directorycreateerror": "𣍐使刪掉目錄「$1」。",
+ "directoryreadonlyerror": "目錄$1是只讀目錄。",
+ "directorynotreadableerror": "目錄$1是禁讀目錄。",
"filenotfound": "討𣍐著文件「$1」。",
"unexpected": "伓是卜挃其值:「$1」=「$2」。",
"formerror": "賺:𣍐使提交表單。",
+ "badarticleerror": "不允許敆茲蜀萆做茲蜀種行為。",
"cannotdelete": "無能耐刪掉頁面或者文件「$1」。\n可能茲已經共別儂刪掉咯了。",
"cannotdelete-title": "無辦法刪掉頁面「$1」",
"delete-hook-aborted": "刪除乞鉤子拍斷咯。\n無給出解釋。",
+ "no-null-revision": "𣍐使敆頁面$1𡅏新建空操作。",
"badtitle": "獃其標題",
"perfcached": "下底其數據乞緩存固加可能伓是最新其。{{PLURAL:$1|$1條結果}}會敆緩存臺中討著。",
"perfcachedts": "下底其數據已經緩存過了,最後更新遘$1。{{PLURAL:$4|$4條結果}}會敆緩存臺中討著。",
"protectedpagetext": "茲頁已經乞保護起咯,𣍐使修改或者其它行動。",
"viewsourcetext": "汝會使看共複製茲蜀頁其源代碼:",
"viewyourtext": "汝會使覷蜀覷或者複製茲頁'''汝其修改'''其源代碼:",
- "editinginterface": "'''警告:'''汝敆𡅏修改其頁面廮𡅏提供茲蜀萆軟件其界面文本。\n茲蜀頁其改變會影響遘其它用戶其用戶界面其顯示。\n如果卜想修改維基其翻譯,起動遘MediaWiki本地化計劃[//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net]。",
+ "editinginterface": "<strong>警告:</strong>汝敆𡅏修改其頁面廮𡅏提供茲蜀萆軟件其界面文本。\n茲蜀頁其改變會影響遘其它用戶其用戶界面其顯示。",
+ "cascadeprotected": "茲蜀頁受保護,𣍐使編辑,因為茲蜀頁包含敆下底{{PLURAL:$1|頁|頁}}開起“級聯”選項其受保護頁面底裡。\n$2",
"namespaceprotected": "汝𣍐使修改敆'''$1'''命名空間其頁面。",
"customcssprotected": "汝𣍐使修改茲蜀萆CSS頁面,因為伊有別蜀隻用戶其設定。",
"customjsprotected": "汝𣍐使修改茲蜀萆JavaScript頁面,因為伊有別蜀隻用戶其設定。",
"mycustomcssprotected": "汝𣍐使修改茲蜀萆CSS頁面。",
"mycustomjsprotected": "汝𣍐使修改茲蜀萆JavaScript頁面。",
+ "myprivateinfoprotected": "汝無權限编輯汝其私人信息。",
+ "mypreferencesprotected": "汝無權限編輯偏好。",
"ns-specialprotected": "𣍐使修改特殊頁面。",
"titleprotected": "茲蜀萆標題共[[User:$1|$1]]保護其咯。\n原因是「''$2''」。",
- "exception-nologin": "未躒底其",
- "exception-nologin-text": "茲蜀頁其行動卜挃汝躒底茲蜀萆維基百科。",
+ "exception-nologin": "未登錄",
+ "exception-nologin-text": "起動汝登錄以後再訪問茲蜀頁,或者做茲蜀萆操作。",
+ "exception-nologin-text-manual": "起動汝$1,以後才會使訪問茲蜀頁,或者做茲蜀萆行為。",
"virus-badscanner": "獃其配置:𣍐八其病毒掃描器:''$1''",
"virus-scanfailed": "掃描失敗(代碼$1)",
"virus-unknownscanner": "𣍐八其反病毒:",
- "logouttext": "'''汝現在躒出了。'''\n\n汝會使使無名方式繼續覷{{SITENAME}},或者汝會使蜀様或者𣍐蜀様其用戶<span class='plainlinks'>[$1 再躒底其]</span>。\n注意有其頁面可能繼續顯示真像汝應經躒底其了,除開汝清理汝其瀏覽器緩存。",
+ "logouttext": "<strong>汝現在退出了。</strong>\n\n注意有其頁面可能繼續顯示真像汝已經登錄了,除開汝清理瀏覽器緩存。",
"welcomeuser": "歡迎,$1!",
"welcomecreation-msg": "汝其賬戶已經開好了。\n伓嗵𣍐記改蜀改汝其[[Special:Preferences|{{SITENAME}}設定]]。",
"yourname": "用戶名:",
"userlogin-yourname": "用戶名",
"userlogin-yourname-ph": "輸底汝其用戶名",
+ "createacct-another-username-ph": "輸底汝其用戶名",
"yourpassword": "密碼:",
"userlogin-yourpassword": "密碼",
"userlogin-yourpassword-ph": "輸底汝其密碼",
"yourdomainname": "汝其域名:",
"password-change-forbidden": "汝𣍐使敆茲蜀萆維基百科𡅏修改密碼。",
"externaldberror": "可能是驗證數據庫綻咯,或者是汝𣍐使升級汝其外部賬戶。",
- "login": "躒底",
- "nav-login-createaccount": "躒底/開賬戶",
- "userlogin": "躒底/開賬戶",
- "userloginnocreate": "躒底",
- "logout": "躒出",
- "userlogout": "躒出",
- "notloggedin": "未躒底",
+ "login": "登錄",
+ "nav-login-createaccount": "登錄/開賬戶",
+ "userlogin": "登錄/開賬戶",
+ "userloginnocreate": "登錄",
+ "logout": "退出",
+ "userlogout": "退出",
+ "notloggedin": "未登錄",
"userlogin-noaccount": "汝無賬戶?",
"userlogin-joinproject": "共{{SITENAME}}加底其",
"nologin": "汝無賬戶?$1",
"nologinlink": "開蜀隻賬戶",
"createaccount": "開賬戶",
"gotaccount": "已經有賬戶了?'''$1'''。",
- "gotaccountlink": "躒底",
- "userlogin-resetlink": "躒底其資料𣍐記咯?",
+ "gotaccountlink": "登錄",
+ "userlogin-resetlink": "登錄其資料𣍐記咯?",
"userlogin-resetpassword-link": "密码𣍐記?",
- "userlogin-helplink2": "對手汝躒底",
+ "userlogin-helplink2": "對手汝登錄",
+ "userlogin-loggedin": "汝已經使$1登錄過了。\n卜想使其他用戶登錄,請使下底其表格來登錄。",
+ "userlogin-createanother": "新建另外蜀萆賬號",
"createacct-emailrequired": "電子郵件地址",
"createacct-emailoptional": "電子郵件地址(愛寫就寫)",
"createacct-email-ph": "輸底汝其電子郵件地址",
+ "createacct-another-email-ph": "輸底電子郵件地址",
"createaccountmail": "使臨時其隨機密碼,共伊送遘指定其電子郵件地址",
"createacct-realname": "實際其名字(愛寫就寫)",
"createaccountreason": "原因:",
"createacct-captcha": "安全檢查",
"createacct-imgcaptcha-ph": "輸底汝敆懸頂看見其文字",
"createacct-submit": "開賬戶",
+ "createacct-another-submit": "新建另外蜀萆賬號",
"createacct-benefit-heading": "{{SITENAME}}是共汝蜀様其儂做其。",
"createacct-benefit-body1": "{{PLURAL:$1|修改}}",
"createacct-benefit-body2": "{{PLURAL:$1|頁面}}",
"loginerror": "躒底有鄭",
"createacct-error": "賬戶開出毛病咯",
"createaccounterror": "無能獃開賬戶:$1",
+ "nocookiesnew": "用戶賬號已經創建好了,但是汝未登錄。\n{{SITENAME}}使cookie來記錄已經登錄其用戶。\n但是汝禁用了cookie。\n起動汝開啟cookie,然後再使汝其新用戶共密碼來登錄。",
+ "nocookieslogin": "{{SITENAME}}使cookies來記錄已經登錄其用戶。\n但是汝禁用了cookie。\n起動汝開起cookie,然後再試蜀試。",
"noname": "汝未指定蜀萆合法其用戶名。",
"loginsuccesstitle": "躒底成功",
"loginsuccess": "'''汝現在已經「$1」其成功躒底{{SITENAME}}了。'''",
"passwordsent": "新密碼已經寄遘「$1」註冊其電子郵件地址了。\n收遘後,請再躒底蜀頭部。",
"mailerror": "發電子郵件有賺:$1",
"acct_creation_throttle_hit": "使汝其IP訪問茲蜀萆維基百科訪問者其已經敆最後蜀日創建{{PLURAL:$1|$1萆賬戶}}去了。茲蜀段時間最価若允許創建茲滿価萆賬戶。故此講使茲蜀萆IP訪問其儂敆現刻時𣍐使再開賬戶了。",
- "emailauthenticated": "汝其電子郵件地址已經敆$2$3驗證過了。",
+ "emailauthenticated": "汝其電子郵件地址已經敆$2$3確定過了。",
+ "emailnotauthenticated": "汝其電子郵件固未確定過。\n下底其所有特性都𣍐發電子郵件乞汝。",
"emailconfirmlink": "確認汝其電子郵件地址",
"emaildisabled": "茲萆站點𣍐使發電子郵件。",
"accountcreated": "賬戶創建了",
"createaccount-title": "{{SITENAME}}其開賬戶",
"login-abort-generic": "汝其躒底𣍐成功——放棄去了",
"loginlanguagelabel": "語言:$1",
+ "pt-login": "登錄",
+ "pt-login-button": "登錄",
+ "pt-createaccount": "開新賬號",
+ "pt-userlogout": "退出",
"php-mail-error-unknown": "PHP其mail()函數,𣍐八什乇賺去。",
"changepassword": "改變密碼",
"resetpass_header": "改變賬戶其密碼",
"preview": "預覽",
"showpreview": "顯示預覽",
"showdiff": "看改變其部分",
- "anoneditwarning": "'''警告:'''汝未躒底。\n汝其IP地址會乞記着茲頁面其修改歷史裏勢。",
+ "anoneditwarning": "<strong>警告:</strong>汝未登錄。\n如果汝做修改,汝其IP地址會敆編輯歷史底裡公開。如果你<strong>[$1登錄]</strong>或者<strong>[$2註册新賬號]</strong>,汝其修改記錄會顯示汝其用戶名,固有其它其好處。",
+ "anonpreviewwarning": "<em>汝未登錄。如果汝保存茲蜀頁其修改,汝其IP地址會記錄敆茲蜀頁其編輯歴史臺中。</em>",
"missingcommenttext": "起動敆下底輸底蜀條評論。",
"summary-preview": "總結預覽:",
"blockedtitle": "用戶乞封鎖了",
"loginreqlink": "躒底",
"loginreqpagetext": "著$1才會使看其它頁面。",
"accmailtitle": "密碼寄出了",
- "accmailtext": "共[[User talk:$1|$1]]用戶其臨時產生其密碼已經發$2了。\n\n茲蜀萆新其賬戶其密碼會使敆用戶躒底以後著''[[Special:ChangePassword|改密碼]]''頁面𡅏改變。",
+ "accmailtext": "共[[User talk:$1|$1]]用戶隨機生成其密碼已經發遘$2了。汝登錄以後會使敆[[Special:ChangePassword|修改密碼]]頁面修改茲蜀萆密碼。",
"newarticle": "(新)",
"newarticletext": "汝已經跟鏈接跟遘無存在其頁面了。\n卜想創建頁面,敆下底其框框𡅏拍字(覷蜀覷[$1 幫助頁面]有無更更価其幫助)。\n如果汝是無注意來遘茲蜀萆頁面,篤囇汝其瀏覽器上其「返回」按鈕。",
"anontalkpagetext": "''茲是未躒底其用戶討論頁面。''\n故此儂家著使數字IP來確定伊。\n總款其IP地址會乞雅価用戶共享。\n如果蜀隻未躒底其用戶見覺無關係其評論指向汝,起動[[Special:UserLogin/signup|開賬戶]]或者[[Special:UserLogin|躒底]]來避免以後共其它未躒底其用戶混蜀堆。",
"noarticletext": "現在敆茲蜀頁𡅏無文字。汝會使敆其它其頁面𡅏[[Special:Search/{{PAGENAME}}|討蜀討茲蜀萆標題]],<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 討相關其記錄],或者[{{fullurl:{{FULLPAGENAME}}|action=edit}}編輯茲蜀頁]</span>。",
"clearyourcache": "'''注意:'''保存以後,汝可能固著刷新汝其瀏覽器緩存來看遘變化。\n* '''火狐/Safari:'''擪下''Shift''篤蜀篤''重新載入'',或者擪蜀擪''Ctrl+F5''或者''Ctrl+R'' (''⌘-R''敆Mac懸頂)\n* '''Google Chrome:'''擪''Ctrl+Shift+R''(敆Mac𡅏使''⌘-Shift-R'')\n* '''Internet Explorer:'''擪''Ctrl''其時候篤蜀篤''刷新'',或者擪''Ctrl+F5''\n* '''Opera:'''敆''工具→首選項''𡅏清除緩存",
+ "note": "<strong>注意:</strong>",
"previewnote": "'''記定茲若是蜀萆預覽。'''\n汝其改變固𡅏未保存!",
"continue-editing": "行去編輯區",
"editing": "修改 $1",
"template-protected": "(保護)",
"template-semiprotected": "(半保護)",
"recreate-moveddeleted-warn": "'''注意:汝敆𡅏重新創建舊底已經乞刪唻其頁面。'''\n\n汝應該考慮蜀下繼續去編輯茲蜀頁到底是伓是合適其。茲蜀頁其刪除記錄共移動記錄都敆嚽塊:",
+ "edit-conflict": "編輯衝突",
+ "content-model-wikitext": "維基文本",
+ "content-model-text": "純文本",
+ "content-model-javascript": "JavaScript",
+ "content-model-css": "CSS",
"undo-summary": "取消[[Special:Contributions/$2|$2]]([[User talk:$2|Tō̤-lâung]])其$1修改",
"cantcreateaccounttitle": "無能獃開賬戶",
"viewpagelogs": "看茲頁其歷史",
"rclistfrom": "顯示由$3 $2開始其新其改變",
"rcshowhideminor": "$1過幼修改",
"rcshowhidebots": "$1機器人",
- "rcshowhideliu": "$1躒底用戶",
+ "rcshowhideliu": "$1已註冊其用戶",
"rcshowhideanons": "$1無名用戶",
"rcshowhidemine": "$1我其修改",
"rclinks": "顯示$2日以內產生其$1回改變<br />$3",
"filesource": "來源:",
"ignorewarning": "無視警告保存文件",
"ignorewarnings": "無視警告",
- "fileexists": "名字蜀樣其文件已經存在去了。如果汝𣍐確定汝是伓是卜想刪掉伊,起動檢查蜀下<strong>[[:$1]]</strong>。\n[[$1|thumb]]",
+ "fileexists": "名字蜀樣其文件已經存在去了。如果{{GENDER:|汝}}𣍐確定汝是伓是卜想刪掉伊,起動檢查蜀下<strong>[[:$1]]</strong>。\n[[$1|thumb]]",
"uploadwarning": "上傳警告",
"savefile": "保存文件",
"uploadvirus": "茲文件有病毒!\n細底:$1",
"watchthispage": "監視茲頁",
"unwatch": "伓使監視",
"unwatchthispage": "停止監視",
- "watchlist-details": "{{PLURAL:$1}}$1頁敆汝其監視單𡅏,無算討論頁。",
+ "watchlist-details": "{{PLURAL:$1|$1頁|$1頁}}敆汝其監視單𡅏,無單獨算討論頁。",
"wlshowlast": "顯示最$1點鐘$2日",
"watchlist-options": "監視單選項",
"watching": "監視...",
"excontent": "乇是:「$1」",
"excontentauthor": "乇是:「$1」(並且作者囇有「[[Special:Contributions/$2|$2]]」)",
"exbeforeblank": "空白以前其乇是:「$1」",
- "historywarning": "'''警告:'''汝卜想刪掉其頁面有蜀段大概$1隻{{PLURAL:$1|版本}}其它歷史:",
+ "historywarning": "<strong>警告:</strong>汝卜想刪掉其頁面有$1隻{{PLURAL:$1|版本|版本}}其蜀段歷史:",
"confirmdeletetext": "汝準備全隻頁面共文章連伊敆蜀塊其歷史全部刪掉。\n請汝確認:汝當真卜想總款做,汝瞭解總款做其後果,並且汝總款做事符合[[{{MediaWiki:Policy-url}}]]其。",
"actioncomplete": "行動成功",
"actionfailed": "操作失敗",
"whatlinkshere-hidelinks": "$1鏈接",
"whatlinkshere-hideimages": "$1 文件鏈接",
"whatlinkshere-filters": "過濾器",
- "blockip": "封鎖用戶",
+ "blockip": "封鎖{{GENDER:$1|用戶}}",
"blockiptext": "使下底其表單來封鎖趁指定IP地址或者用戶名其寫入訪問。茲囇使廮𡅏防止破壞,固加著符合[[{{MediaWiki:Policy-url}}|政策]]。敆下底填底指定其原因(比如講:引用乞破壞其頁面)。",
"ipaddressorusername": "IP地址或者用戶名:",
"ipbexpiry": "過期:",
"tog-enotifrevealaddr": "Гайта сан зlе оцу хаамаш барехь",
"tog-shownumberswatching": "Гайта декъашхойн терахь, агӀо латийна болу шай тергаме могӀанан юкъа",
"tog-oldsig": "Карара куьгтаӀорна:",
- "tog-fancysig": "Шен вики-кÑ\8aаÑ\81Ñ\82аман кÑ\83Ñ\8cгÑ\82аÓ\80даÑ\80 (Ñ\88а Ñ\88еÑ\85 Ñ\85Ñ\8cажоÑ\80аг йоÑ\86Ñ\83Ñ\88)",
+ "tog-fancysig": "Шен вики-къастаман куьгтаӀдар (ша шех хьажорг йоцуш)",
"tog-uselivepreview": "Лелайа чехка хьалха хьажа (JavaScript, муха ю хьажарна)",
"tog-forceeditsummary": "Дага даийта, нагахь нисйарх лаьцна чохь язйина яцахь",
"tog-watchlisthideown": "Къайлаяха ас нисйинарш тергаме могӀам чура",
"anontalk": "Дийцаре хӀокху IP-адресна",
"navigation": "Навигаци",
"and": " а",
- "qbfind": "Лаха",
+ "qbfind": "Лахар",
"qbbrowse": "Хьажар",
"qbedit": "Нисъе",
"qbpageoptions": "Агlо нисйар",
"returnto": "ЮхагӀо оцу агӀоне $1.",
"tagline": "Гlирс хlокхуьна бу {{grammar:genitive|{{SITENAME}}}}",
"help": "ГӀо",
- "search": "Лаха",
+ "search": "Лахар",
"searchbutton": "Лаха",
"go": "Дехьа гӀо",
"searcharticle": "Дехьа гӀо",
"history_short": "Истори",
"updatedmarker": "Керла яккхина сона гинчултӀаьхьа",
"printableversion": "Зорба туху верси",
- "permalink": "Ð\94аиман йолÑ\83 Ñ\85Ñ\8cажоÑ\80аг",
+ "permalink": "Даиман йолу хьажорг",
"print": "Зорба тоха",
"view": "Хьажа",
"view-foreign": "Сайтехь $1 хьажа",
"readonly": "Блоктоьхна дӀайаздар хаамийн бухе",
"enterlockreason": "Билгалде блоктохаран бахьна а и чекх йолу хан а.",
"readonlytext": "АгӀонаш тӀетохар а кхин хийцамаш барна а блоктоьхна:\nБлокоьхначо биттина хаам: $1.",
- "missing-article": "Ð¥Ó\80окÑ\85Ñ\83 Ñ\87оÑ\85Ñ\8c каÑ\80оезаÑ\88 йолÑ\83 Ñ\85Ñ\8cан деÑ\85аÑ\80Ñ\86а йозан агÓ\80онаÑ\88 Ñ\86акаÑ\80ийна «$1» $2.\n\nÐ\98Ñ\88Ñ\82наÑ\80г наггаÑ\85Ñ\8c Ñ\85Ñ\83Ñ\8cлÑ\83 Ñ\85Ñ\8cажоÑ\80аг дÓ\80аÑ\8fÑ\8cккÑ\85ина елаÑ\85Ñ\8c Ñ\8f Ñ\85ийÑ\86ам бина Ñ\82иÑ\88а Ñ\85Ñ\8cажоÑ\80агца дехьа гӀо гӀоьртича.\n\nНагахьсан гӀулкх цуьнах доьзна дацахь, хьуна карийна гӀирс латточехь гӀалат.\nДехар до, хаам бе оцуьнах [[Special:ListUsers/sysop|куьйгалхога]], гойтуш URL.",
+ "missing-article": "Ð¥Ó\80окÑ\85Ñ\83 Ñ\87оÑ\85Ñ\8c каÑ\80оезаÑ\88 йолÑ\83 Ñ\85Ñ\8cан деÑ\85аÑ\80Ñ\86а йозан агÓ\80онаÑ\88 Ñ\86акаÑ\80ийна «$1» $2.\n\nÐ\98Ñ\88Ñ\82наÑ\80г наггаÑ\85Ñ\8c Ñ\85Ñ\83Ñ\8cлÑ\83 Ñ\85Ñ\8cажоÑ\80г дÓ\80аÑ\8fÑ\8cккÑ\85ина елаÑ\85Ñ\8c Ñ\8f Ñ\85ийÑ\86ам бина Ñ\82иÑ\88а Ñ\85Ñ\8cажоÑ\80гца дехьа гӀо гӀоьртича.\n\nНагахьсан гӀулкх цуьнах доьзна дацахь, хьуна карийна гӀирс латточехь гӀалат.\nДехар до, хаам бе оцуьнах [[Special:ListUsers/sysop|куьйгалхога]], гойтуш URL.",
"missingarticle-rev": "(верси № $1)",
"missingarticle-diff": "(башхалла: $1, $2)",
"readonly_lag": "Хаамашан базина цхьана хан блоктоьхна, хаамашан базан сервераш нисялца.",
"italic_sample": "Сеттан до йоза",
"italic_tip": "Сеттан до йоза",
"link_sample": "Хьажориган коьрта могlа",
- "link_tip": "ЧоÑ\8cÑ\85Ñ\8cа Ñ\85Ñ\8cажоÑ\80аг",
- "extlink_sample": "http://www.example.com Ñ\85Ñ\8cажоÑ\80аг коÑ\80Ñ\82а",
- "extlink_tip": "Ð\90Ñ\80аÑ\85Ñ\8cаÑ\80а Ñ\85Ñ\8cажоÑ\80аг (йиÑ\86 ма йе Ñ\85Ó\80оÑ\82Ñ\82алÑ\83Ñ\88еÑ\80г http://)",
+ "link_tip": "Чоьхьа хьажорг",
+ "extlink_sample": "http://www.example.com хьажорг корта",
+ "extlink_tip": "Арахьара хьажорг (йиц ма йе хӀотталушерг http://)",
"headline_sample": "Йозан корта",
"headline_tip": "Корта 2-гlа локхаллийца",
"nowiki_sample": "Чудиллийша кхузе барамхlоттонза йоза.",
"image_sample": "Example.jpg",
"image_tip": "Чохь йолу файл",
"media_sample": "Example.ogg",
- "media_tip": "Ð¥Ñ\8cажоÑ\80аг медиа-Ñ\84айлан Ñ\82Ó\80е",
+ "media_tip": "Хьажорг медиа-файлан тӀе",
"sig_tip": "Хьан куьгтаlор аъ хlоттина хан",
"hr_tip": "Ана сиз (сих сиха ма леладайша)",
"summary": "Хийцамех лаьцна:",
"note": "'''Билгалдаккхар:'''",
"previewnote": "'''ХӀара хьлха хьажар ду, йоза хӀинца язданза ду!'''",
"continue-editing": "Кхин дӀа тадар",
- "session_fail_preview": "СеÑ\80веÑ\80 лаÑ\80а Ñ\86а йиÑ\80а аÑ\85Ñ\8cа бина Ñ\85ийÑ\86амаÑ\88 дÓ\80аÑ\8fзба. Ð\9aÑ\85иÑ\8a Ñ\86кÑ\8aа а гÓ\80оÑ\80Ñ\82аÑ\85Ñ\8c.\nÐ\9dагаÑ\85Ñ\8c Ñ\81анна Ñ\85Ó\80аÑ\80а гÓ\80алаÑ\82 Ñ\8eÑ\85а а далаÑ\85Ñ\8c, [[Special:UserLogout|Ñ\81еанÑ\81 дÓ\80а а кÑ\8aоÑ\8cвлин]], Ñ\8eÑ\85а а Ñ\81иÑ\81Ñ\82емин Ñ\87Ñ\83вала/Ñ\8fла Ñ\85Ñ\8cажа.",
+ "session_fail_preview": "СеÑ\80веÑ\80 лаÑ\80а Ñ\86а йиÑ\80а аÑ\85Ñ\8cа бина Ñ\85ийÑ\86амаÑ\88 дÓ\80аÑ\8fзба. Ð\9aÑ\85иÑ\8a Ñ\86кÑ\8aа а гÓ\80оÑ\80Ñ\82аÑ\85Ñ\8c.\nÐ\9dагаÑ\85Ñ\8c Ñ\81анна Ñ\85Ó\80аÑ\80а гÓ\80алаÑ\82 Ñ\8eÑ\85а а далаÑ\85Ñ\8c, [[Special:UserLogout|Ñ\81еанÑ\81 дÓ\80а а кÑ\8aоÑ\8cвлин]], Ñ\8eÑ\85а а Ñ\81иÑ\81Ñ\82емин Ñ\87Ñ\83гÓ\80о.",
"edit_form_incomplete": "'''Цхьайолу тадаран формаш серверан тӀекхаьчча яц. Тидаме хьажа хьай нисдарш доьхна дуй, ТӀакха южу гӀорта.'''",
"editing": "Тадар: $1",
"creating": "АгӀо кхоллар «$1»",
"diff-multi-sameuser": "(ца {{PLURAL:$1|гайтина юккъера цхьа верси|гайтина юккъера цхьа версеш}} оьцу декъашхочун)",
"diff-multi-otherusers": "(ца {{PLURAL:$1|гайтина юккъера верси|гайтина юккъера версеш}} {{PLURAL:$2|кхин цхьан декъашхочун|$2 декъашхойн}})",
"diff-multi-manyusers": "({{PLURAL:$1|гайтина яц $1 юккъера верси, йина|не показаны $1 юккъера версеш, йина}} {{PLURAL:$2|$2 декъашхочо|$2 декъашхоша}})",
- "searchresults": "Ð\9bаÑ\85аÑ\80на Ñ\85илам",
- "searchresults-title": "Лаха «$1»",
+ "searchresults": "Ð\9aаÑ\80ийнаÑ\80Ñ\88",
+ "searchresults-title": "Лахар «$1»",
"titlematches": "АгӀонийн цӀераш цхьаьнанисялар",
"textmatches": "АгӀонийн йоза цхьаьнанисдалар",
"notextmatches": "АгӀонаш чура йозанашца цхьатера йогlуш яц",
"searchall": "массо",
"showingresults": "Лахахьа {{PLURAL:$1|гойту}} <strong>$1</strong> {{PLURAL:$1|хилам}}, дӀаболало кху № <strong>$2</strong>.",
"showingresultsinrange": "Лахахь гайтина {{PLURAL:$1|<strong>1</strong> хилам}} диапазонехь <strong>$2</strong> тӀера <strong>$3</strong> кхаччалц.",
- "search-showingresults": "{{PLURAL:$4|Хилам <strong>$1</strong> <strong>$3</strong> наÑ\85}}",
+ "search-showingresults": "{{PLURAL:$4|Ð\9aаÑ\80ийна <strong>$1</strong> â\80\94 Ñ\86Ñ\85Ñ\8cаÑ\8a агÓ\80о|Ð\9aаÑ\80ийна <strong>$3</strong> агÓ\80о, Ñ\86аÑ\80аÑ\85 агÓ\80онгаÑ\85Ñ\8c гойÑ\82Ñ\83 $2 агÓ\80о}}",
"search-nonefound": "Дехаре терра цхьа хӀума ца карийна.",
- "powersearch-legend": "Шуьро лахар",
+ "powersearch-legend": "Шуьйра лахар",
"powersearch-ns": "ЦӀерийн меттигашкахь лахар:",
"powersearch-togglelabel": "Билгалдан:",
"powersearch-toggleall": "Массо",
"prefs-editing": "Тадар",
"rows": "МогӀанаш:",
"columns": "БӀогӀамаш:",
- "searchresultshead": "Лаха",
+ "searchresultshead": "Лахар",
"stub-threshold": "Кеч яран доза <a href=\"#\" class=\"stub\">коьртамогӀамна хьажоргаш</a> (байташках):",
"stub-threshold-disabled": "ДӀадайина",
"recentchangesdays": "Керла нисдар гайта динахь:",
"recentchangeslinked-title": "Кхуьнца долу нисдарш $1",
"recentchangeslinked-summary": "ХӀара хийцам биначу агӀонийн могӀам бу, тӀетовжар долуш хьагучу агӀон (я хьагойтуш йолучу категорена).\nАгӀонаш юькъа йогӀуш йолу хьан [[Special:Watchlist|тергаме могӀам чохь]] '''къастийна ю'''.",
"recentchangeslinked-page": "АгӀон цӀе:",
- "recentchangeslinked-to": "Ð\9aÑ\85еÑ\87Ñ\83 агÓ\80оÑ\80, гайÑ\82а Ñ\85ийÑ\86амаÑ\88 агÓ\80онаÑ\88Ñ\86а, Ñ\85Ó\80оÑ\82Ñ\82ийнаÑ\87Ñ\83 агÓ\80онÑ\82Ó\80е Ñ\85Ñ\8cажоÑ\80аг йолÑ\83Ñ\88",
+ "recentchangeslinked-to": "Кхечу агӀор, гайта хийцамаш агӀонашца, хӀоттийначу агӀонтӀе хьажорг йолуш",
"upload": "Файл чуяккхар",
"uploadbtn": "Файл чуяккхар",
"reuploaddesc": "Юху гӀо файл чуйоккху агӀоне",
"uploadnologintext": "Серверан чу файлаш яха хьо $1.",
"uploaderror": "Файл чуяккхаран гӀалат",
"upload-recreate-warning": "'''Тегам бе: иштта цӀе йолу файл дӀаяьккхина я цӀе хийцина.'''\n\nЛахахьа гойтуш ю хӀокху агӀона тептар:",
- "uploadtext": "Ð\9bелайе Ñ\85Ó\80аÑ\80а агÓ\80о Ñ\81еÑ\80веÑ\80 Ñ\87Ñ\83 Ñ\84айлаÑ\88 йоÑ\85Ñ\83Ñ\88.\nÐ¥Ñ\8cалÑ\85о Ñ\87Ñ\83Ñ\8fÑ\8cÑ\85на Ñ\84айлаÑ\88 Ñ\85Ñ\8cажа, [[Special:FileList|кÑ\85Ñ\83заÑ\85Ñ\8c]]. Ð\9aÑ\85ин Ñ\87Ñ\83Ñ\8fÑ\8cÑ\85на Ñ\84айлаÑ\88 дÓ\80аÑ\8fзло [[Special:Log/upload|Ñ\87Ñ\83Ñ\8fÑ\85аÑ\80ан Ñ\82епÑ\82аÑ\80 Ñ\87оÑ\85Ñ\8c]], дÓ\80аÑ\8fÑ\8cÑ\85на Ñ\84айлаÑ\88 каÑ\80о йиÑ\88 Ñ\8e [[Special:Log/delete|кÑ\85Ñ\83заÑ\85Ñ\8c]].\n\nФайл агÓ\80она Ñ\87Ñ\83йилла лелабе лаÑ\85аÑ\80а могÓ\80анаÑ\88:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' Ñ\84айла Файлан Ñ\8eÑ\8cззина веÑ\80Ñ\81и Ñ\87Ñ\83йиллÑ\83Ñ\88;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|Ñ\86Ñ\83наÑ\85Ñ\8c лаÑ\8cÑ\86на Ñ\85аам]]</nowiki></code>''' 200 пикÑ\81елÑ\8c баÑ\80амеÑ\85Ñ\8c Ñ\84айл Ñ\87Ñ\83йилаÑ\80 бÑ\83Ñ\85аÑ\85Ñ\8c Ñ\86Ñ\83наÑ\85Ñ\8c лаÑ\8cÑ\86на могÓ\80а а болÑ\83Ñ\88;\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' Ñ\84айлан Ñ\82Ó\80е Ñ\85Ñ\8cажоÑ\80аг Ñ\85Ó\80оÑ\82айо Ñ\84айл агÓ\80онгаÑ\85Ñ\8c Ñ\86а гÑ\83Ñ\88.",
+ "uploadtext": "Лелайе хӀара агӀо сервер чу файлаш йохуш.\nХьалхо чуяьхна файлаш хьажа, [[Special:FileList|кхузахь]]. Кхин чуяьхна файлаш дӀаязло [[Special:Log/upload|чуяхаран тептар чохь]], дӀаяьхна файлаш каро йиш ю [[Special:Log/delete|кхузахь]].\n\nФайл агӀона чуйилла лелабе лахара могӀанаш:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' файла Файлан юьззина верси чуйиллуш;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|цунахь лаьцна хаам]]</nowiki></code>''' 200 пиксель барамехь файл чуйилар бухахь цунахь лаьцна могӀа а болуш;\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' файлан тӀе хьажорг хӀотайо файл агӀонгахь ца гуш.",
"upload-permitted": "Магийна файлийн тайпанаш: $1.",
"upload-preferred": "Магийна файлийн тайпанаш: $1.",
"upload-prohibited": "Магийна доцу файлийн тайпанаш: $1.",
"randomredirect": "Цахууш нисделла дIасахьажор",
"randomredirect-nopages": "«$1» цӀерийн меттиган чохь дӀасахьажораш яц.",
"statistics": "Статистика",
- "statistics-header-pages": "АгӀонийн жамӀ",
+ "statistics-header-pages": "АгӀонийн статистика",
"statistics-header-edits": "Нисдарийн статистика",
"statistics-header-users": "Декъашхойн статистика",
"statistics-header-hooks": "Кхин статистика",
"pageswithprop-legend": "АгӀонаш цхьадолу къастамашца",
"pageswithprop-text": "Кхузахь гойтуш ю агӀонаш цхьадолу къастамаш куьйга юху билгал даьхнарш.",
"pageswithprop-prop": "Къастаман цӀе:",
- "pageswithprop-submit": "Ð\9bаÑ\85а",
+ "pageswithprop-submit": "Ð\9aаÑ\80о",
"pageswithprop-prophidden-long": "деха йозан хӀуман маьӀна хьулйина ($1)",
"pageswithprop-prophidden-binary": "шалха маьӀна долу хӀума хьулйина ($1)",
"doubleredirects": "Шалха дIасахьажийнарш",
"fewestrevisions": "ЧӀогӀа кӀезиг версеш йолу агӀонаш",
"nbytes": "$1 {{PLURAL:$1|байт}}",
"ncategories": "$1 {{PLURAL:$1|категори|категореш}}",
- "ninterwikis": "$1 {{PLURAL:$1|1=Ñ\8eкÑ\8aаÑ\80вики-Ñ\85Ñ\8cажоÑ\80аг|Ñ\8eкÑ\8aаÑ\80вики-Ñ\85Ñ\8cажоÑ\80гаÑ\88}}",
+ "ninterwikis": "$1 {{PLURAL:$1|1=юкъарвики-хьажорг|юкъарвики-хьажоргаш}}",
"nlinks": "$1 {{PLURAL:$1|хьажорг}}",
"nmembers": "$1 {{PLURAL:$1|хӀума|хӀумнаш}}",
"nmemberschanged": "$1 → $2 {{PLURAL:$2|хӀума|хӀумнаш}}",
"listusers": "Декъашхойн могӀам",
"listusers-editsonly": "Цхаъ мукъане а хийцам бина декъашхой гайта",
"listusers-creationsort": "Кхоьллина хене хьаьжна нисъяр",
- "listusers-desc": "Харжа къезиг хиларца",
+ "listusers-desc": "Харжа кӀезиг хиларца",
"usereditcount": "$1 {{PLURAL:$1|нисдар|нисдарш}}",
"usercreated": "{{GENDER:$3|дӀавазвелла|дӀаязелла}} $1 $2",
"newpages": "Керла агӀонаш",
"ancientpages": "ТӀехьара терахьца тадар дина яззамаш",
"move": "ЦӀе хийца",
"movethispage": "ХӀокху агӀон цӀе хийца",
- "unusedimagestext": "Ð\94еÑ\85аÑ\80 до, Ñ\82идаме Ñ\8dÑ\86а, кÑ\85ин йолÑ\83 дÑ\83Ñ\8cнана маÑ\88ан-меÑ\82Ñ\82игаÑ\88 а лелоÑ\88 Ñ\85ила мега нийÑ\81Ñ\81а йогÓ\80Ñ\83 Ñ\85Ñ\8cажоÑ\80аг (URL) Ñ\85Ó\80окÑ\85Ñ\83 Ñ\85Ó\80Ñ\83ман, Ñ\85Ó\80окÑ\85Ñ\83 могÓ\80аме йогÓ\80Ñ\83Ñ\88 Ñ\8fлаÑ\85Ñ\8c Ñ\8fÑ\86аÑ\85Ñ\8c а иза Ñ\85ила мега жигаÑ\80а лелоÑ\88.",
+ "unusedimagestext": "Дехар до, тидаме эца, кхин йолу дуьнана машан-меттигаш а лелош хила мега нийсса йогӀу хьажорг (URL) хӀокху хӀуман, хӀокху могӀаме йогӀуш ялахь яцахь а иза хила мега жигара лелош.",
"unusedcategoriestext": "ХӀокху категорешан чохь агӀонаш я кхин категореш яц.",
"notargettitle": "Ӏалашо билгал йина яц",
"notargettext": "И кхочушдан ахьа билгал йина яц Ӏалашонан агӀо я декъашхо.",
"deletedcontributions": "Декъашхочун дӀабяккхина къинхьегам",
"deletedcontributions-title": "ДӀабаьккхина къинхьегам",
"sp-deletedcontributions-contribs": "къинхьегам",
- "linksearch": "Ð\90Ñ\80аÑ\85Ñ\8cаÑ\80а Ñ\85Ñ\8cажоÑ\80аг",
- "linksearch-pat": "Ð\9bаÑ\85а кеп:",
+ "linksearch": "Арахьара хьажорг",
+ "linksearch-pat": "Ð\9bеÑ\85аÑ\80на кеп:",
"linksearch-ns": "ЦӀерийн ана:",
"linksearch-ok": "Лаха",
"linksearch-text": "Лело мега хӀоттош йолу символаш, масала, <code>*.wikipedia.org</code>.\nЛакхара даржан домен мукъа хила еза , масала<code>*.org</code><br />\nЛовш йолу {{PLURAL:$2|1=протокол|протоколаш}}: <code>$1</code> (Iад йитарца http://, протокол бакъалла язъен яцахь).",
- "linksearch-line": "$2 â\80\94 Ñ\85Ñ\8cажоÑ\80аг кÑ\85Ñ\83 $1",
+ "linksearch-line": "$2 — хьажорг кху $1",
"listusersfrom": "Гучé баха декъашхой, болалуш болу тӀера:",
"listusers-submit": "Гайта",
"listusers-noresult": "Декъашхой цакарий.",
"nolinkshere-ns": "Хаьржинчу анахь яц '''[[:$1]]''' цӀе йолу агӀонаш",
"isredirect": "агӀо-дӀасахьажорг",
"istemplate": "юкъаялийнарш",
- "isimage": "Файлан Ñ\85Ñ\8cажоÑ\80аг",
+ "isimage": "Файлан хьажорг",
"whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайодарг|хьалхайодарш}} $1",
"whatlinkshere-next": "{{PLURAL:$1|тӀаьхьайогӀург|тӀаьхьайогӀурш}} $1",
"whatlinkshere-links": "← хьажоргаш",
"blocklist-by": "Цунна блоктоьхана куьйгалхо",
"blocklist-params": "Блоктохаран параметраш",
"blocklist-reason": "Бахьна:",
- "ipblocklist-submit": "Лаха",
+ "ipblocklist-submit": "Лахар",
"ipblocklist-localblock": "Локальни блоктохар",
"ipblocklist-otherblocks": "{{PLURAL:$1|Кхин блоктохар|Кхин блоктохарш}}",
"infiniteblock": "хан чаккхе йоцуш",
"lockedbyandtime": "($1 $2 $3)",
"move-page": "$1 — цӀе хийцар",
"move-page-legend": "ЦӀe хийца яр",
- "movepagetext": "Ð\91Ñ\83Ñ\85аÑ\85Ñ\8c йолÑ\83 Ñ\84оÑ\80манÑ\86а агÓ\80он Ñ\86Ó\80е Ñ\85ийÑ\86ало. ЦÑ\83л Ñ\81овнаÑ\85 Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аман Ñ\82епÑ\82аÑ\80 кÑ\85оÑ\8cÑ\87Ñ\83 меÑ\82Ñ\82е доккÑ\85а. Ð¥Ñ\8cалÑ\85алеÑ\80а Ñ\86Ó\80аÑ\80аÑ\85Ñ\8c Ñ\85иÑ\80Ñ\8aÑ\8e кеÑ\80ла кÑ\85оÑ\8cллина агÓ\80онан Ñ\85Ñ\8cажоÑ\80аг.\n\nÐ¥Ñ\8cовÑ\81алаÑ\88 [[Special:DoubleRedirects|Ñ\88алÑ\85а]] а [[Special:BrokenRedirects|йоÑ\85на Ñ\85Ñ\8cажоÑ\80гаÑ\88]] Ñ\8eй Ñ\82еÑ\85Ñ\8c аÑ\8cлла.\n\nШÑ\83 жоÑ\8cпеÑ\85Ñ\8c дÑ\83 Ñ\85Ñ\8cажоÑ\80гаÑ\88 нийÑ\81а некÑ\8a гойÑ\82Ñ\83Ñ\88 Ñ\85илаÑ\80ан.\n\nТидам бе Ñ\85Ñ\8cалÑ\85алеÑ\80а агÓ\80он Ñ\86Ó\80е â\80\98â\80\99â\80\99Ñ\85ийÑ\86алÑ\83Ñ\80 Ñ\8fÑ\86â\80\99â\80\99â\80\99 иÑ\88Ñ\82Ñ\82а Ñ\86Ó\80е йолÑ\83 агÓ\80о йолÑ\83Ñ\88 елаÑ\85Ñ\8c. ЮкÑ\8aаÑ\80даккÑ\85аÑ\80: йолÑ\83Ñ\88 йолÑ\83 агÓ\80о кÑ\85оÑ\8cÑ\87Ñ\83Ñ\85Ñ\8cа Ñ\85Ñ\8cажоÑ\80аг елаÑ\85Ñ\8c, Ñ\8f еÑ\81а елаÑ\85Ñ\8c а, Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аме иÑ\81Ñ\82оÑ\80и Ñ\8fÑ\86аÑ\85Ñ\8c а.\n\nÐ\98 боÑ\85Ñ\83Ñ\80г дÑ\83 Ñ\88Ñ\83н агÓ\80онан Ñ\86Ó\80е Ñ\8eÑ\85а а Ñ\85Ñ\8cалÑ\85а Ñ\85иллаÑ\80гÑ\87Ñ\83нтӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
- "movepagetext-noredirectfixer": "Ð\91Ñ\83Ñ\85аÑ\85Ñ\8c йолÑ\83 Ñ\84оÑ\80манÑ\86а агÓ\80он Ñ\86Ó\80е Ñ\85ийÑ\86ало. ЦÑ\83л Ñ\81овнаÑ\85 Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аман Ñ\82епÑ\82аÑ\80 кÑ\85оÑ\8cÑ\87Ñ\83 меÑ\82Ñ\82е доккÑ\85а. Ð¥Ñ\8cалÑ\85алеÑ\80а Ñ\86Ó\80аÑ\80аÑ\85Ñ\8c Ñ\85иÑ\80Ñ\8aÑ\8e кеÑ\80ла кÑ\85оÑ\8cллина агÓ\80онан Ñ\85Ñ\8cажоÑ\80аг.\n\nÐ¥Ñ\8cовÑ\81алаÑ\88 [[Special:DoubleRedirects|Ñ\88алÑ\85а]] а [[Special:BrokenRedirects|йоÑ\85на Ñ\85Ñ\8cажоÑ\80гаÑ\88]] Ñ\8eй Ñ\82еÑ\85Ñ\8c аÑ\8cлла.\n\nШÑ\83 жоÑ\8cпеÑ\85Ñ\8c дÑ\83 Ñ\85Ñ\8cажоÑ\80гаÑ\88 нийÑ\81а некÑ\8a гойÑ\82Ñ\83Ñ\88 Ñ\85илаÑ\80ан.\n\nТидам бе Ñ\85Ñ\8cалÑ\85алеÑ\80а агÓ\80он Ñ\86Ó\80е â\80\98â\80\99â\80\99Ñ\85ийÑ\86алÑ\83Ñ\80 Ñ\8fÑ\86â\80\99â\80\99â\80\99 иÑ\88Ñ\82Ñ\82а Ñ\86Ó\80е йолÑ\83 агÓ\80о йолÑ\83Ñ\88 елаÑ\85Ñ\8c. ЮкÑ\8aаÑ\80даккÑ\85аÑ\80: йолÑ\83Ñ\88 йолÑ\83 агÓ\80о кÑ\85оÑ\8cÑ\87Ñ\83Ñ\85Ñ\8cа Ñ\85Ñ\8cажоÑ\80аг елаÑ\85Ñ\8c, Ñ\8f еÑ\81а елаÑ\85Ñ\8c а, Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аме иÑ\81Ñ\82оÑ\80и Ñ\8fÑ\86аÑ\85Ñ\8c а.\n\nÐ\98 боÑ\85Ñ\83Ñ\80г дÑ\83 Ñ\88Ñ\83н агÓ\80онан Ñ\86Ó\80е Ñ\8eÑ\85а а Ñ\85Ñ\8cалÑ\85а Ñ\85иллаÑ\80гÑ\87Ñ\83нтӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
+ "movepagetext": "Ð\91Ñ\83Ñ\85аÑ\85Ñ\8c йолÑ\83 Ñ\84оÑ\80манÑ\86а агÓ\80он Ñ\86Ó\80е Ñ\85ийÑ\86ало. ЦÑ\83л Ñ\81овнаÑ\85 Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аман Ñ\82епÑ\82аÑ\80 кÑ\85оÑ\8cÑ\87Ñ\83 меÑ\82Ñ\82е доккÑ\85а. Ð¥Ñ\8cалÑ\85алеÑ\80а Ñ\86Ó\80аÑ\80аÑ\85Ñ\8c Ñ\85иÑ\80Ñ\8aÑ\8e кеÑ\80ла кÑ\85оÑ\8cллина агÓ\80онан Ñ\85Ñ\8cажоÑ\80г.\n\nÐ¥Ñ\8cовÑ\81алаÑ\88 [[Special:DoubleRedirects|Ñ\88алÑ\85а]] а [[Special:BrokenRedirects|йоÑ\85на Ñ\85Ñ\8cажоÑ\80гаÑ\88]] Ñ\8eй Ñ\82еÑ\85Ñ\8c аÑ\8cлла.\n\nШÑ\83 жоÑ\8cпеÑ\85Ñ\8c дÑ\83 Ñ\85Ñ\8cажоÑ\80гаÑ\88 нийÑ\81а некÑ\8a гойÑ\82Ñ\83Ñ\88 Ñ\85илаÑ\80ан.\n\nТидам бе Ñ\85Ñ\8cалÑ\85алеÑ\80а агÓ\80он Ñ\86Ó\80е â\80\98â\80\99â\80\99Ñ\85ийÑ\86алÑ\83Ñ\80 Ñ\8fÑ\86â\80\99â\80\99â\80\99 иÑ\88Ñ\82Ñ\82а Ñ\86Ó\80е йолÑ\83 агÓ\80о йолÑ\83Ñ\88 елаÑ\85Ñ\8c. ЮкÑ\8aаÑ\80даккÑ\85аÑ\80: йолÑ\83Ñ\88 йолÑ\83 агÓ\80о кÑ\85оÑ\8cÑ\87Ñ\83Ñ\85Ñ\8cа Ñ\85Ñ\8cажоÑ\80г елаÑ\85Ñ\8c, Ñ\8f еÑ\81а елаÑ\85Ñ\8c а, Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аме иÑ\81Ñ\82оÑ\80и Ñ\8fÑ\86аÑ\85Ñ\8c а.\n\nÐ\98 боÑ\85Ñ\83Ñ\80г дÑ\83 Ñ\88Ñ\83н агÓ\80онан Ñ\86Ó\80е Ñ\8eÑ\85а а Ñ\85Ñ\8cалÑ\85а Ñ\85иллаÑ\87Ñ\83н тӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
+ "movepagetext-noredirectfixer": "Ð\91Ñ\83Ñ\85аÑ\85Ñ\8c йолÑ\83 Ñ\84оÑ\80манÑ\86а агÓ\80он Ñ\86Ó\80е Ñ\85ийÑ\86ало. ЦÑ\83л Ñ\81овнаÑ\85 Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аман Ñ\82епÑ\82аÑ\80 кÑ\85оÑ\8cÑ\87Ñ\83 меÑ\82Ñ\82е доккÑ\85а. Ð¥Ñ\8cалÑ\85алеÑ\80а Ñ\86Ó\80аÑ\80аÑ\85Ñ\8c Ñ\85иÑ\80Ñ\8aÑ\8e кеÑ\80ла кÑ\85оÑ\8cллина агÓ\80онан Ñ\85Ñ\8cажоÑ\80г.\n\nÐ¥Ñ\8cовÑ\81алаÑ\88 [[Special:DoubleRedirects|Ñ\88алÑ\85а]] а [[Special:BrokenRedirects|йоÑ\85на Ñ\85Ñ\8cажоÑ\80гаÑ\88]] Ñ\8eй Ñ\82еÑ\85Ñ\8c аÑ\8cлла.\n\nШÑ\83 жоÑ\8cпеÑ\85Ñ\8c дÑ\83 Ñ\85Ñ\8cажоÑ\80гаÑ\88 нийÑ\81а некÑ\8a гойÑ\82Ñ\83Ñ\88 Ñ\85илаÑ\80ан.\n\nТидам бе Ñ\85Ñ\8cалÑ\85алеÑ\80а агÓ\80он Ñ\86Ó\80е â\80\98â\80\99â\80\99Ñ\85ийÑ\86алÑ\83Ñ\80 Ñ\8fÑ\86â\80\99â\80\99â\80\99 иÑ\88Ñ\82Ñ\82а Ñ\86Ó\80е йолÑ\83 агÓ\80о йолÑ\83Ñ\88 елаÑ\85Ñ\8c. ЮкÑ\8aаÑ\80даккÑ\85аÑ\80: йолÑ\83Ñ\88 йолÑ\83 агÓ\80о кÑ\85оÑ\8cÑ\87Ñ\83Ñ\85Ñ\8cа Ñ\85Ñ\8cажоÑ\80г елаÑ\85Ñ\8c, Ñ\8f еÑ\81а елаÑ\85Ñ\8c а, Ñ\86Ñ\83Ñ\8cна Ñ\85ийÑ\86аме иÑ\81Ñ\82оÑ\80и Ñ\8fÑ\86аÑ\85Ñ\8c а.\n\nÐ\98 боÑ\85Ñ\83Ñ\80г дÑ\83 Ñ\88Ñ\83н агÓ\80онан Ñ\86Ó\80е Ñ\8eÑ\85а а Ñ\85Ñ\8cалÑ\85а Ñ\85иллаÑ\87Ñ\83н тӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
"movepagetalktext": "ТӀе хӀоьттина йолу дийцаре агӀо ишта цӀе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''\n\n*Йаьсса йоцу дийцаре агӀо йолуш ю оцу цӀарца йа\n*Ахьа къастаман харжам цабиняхь а къастам хӀотточехь.\n\nИшта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хӀоттайар, нагахь иза хьашт йалахь.",
- "movearticle": "ЦӀе хийца хӀокху агӀон",
+ "movearticle": "ЦӀе хийца агӀон",
"moveuserpage-warning": "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
"movecategorypage-warning": "<strong>ДӀахьедар:</strong> Хьо категорин агӀон цӀе хийца гӀерта. Дехар до, терго йе, хӀокху агӀона бен цӀе хуьйцур яц, шира чу категори чура массо агӀонаш керла категори чу йохур <em>яц</em>.",
"movenologintext": "АгӀона цӀе хийца [[Special:UserLogin|системин чугӀо]].",
"protectedpagemovewarning": "'''ДӀахьедар.''' ХӀара агӀо гӀаролла йина ю; цӀе хийца я нисйа а бакъо йолуш куьйгалхой бе бац.\nЛахахьа тептаро балийна тӀаьхьаралера дӀаязбина хаам:",
"semiprotectedpagemovewarning": "'''ДӀахьедо.''' ХӀара агӀо гӀаролла йина ю; дӀабазбиначу декъашхошка бе цӀе хийцалуш яц.\nЛахахьа тептаро балийна тӀаьхьаралера дӀаязбина хаам:",
"export": "АгӀонаш араяхар",
- "exporttext": "ШÑ\83Ñ\8cга далÑ\83Ñ\80 дÑ\83 кÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80а Ñ\87Ñ\83даÑ\85аÑ\80Ñ\88, йоза а Ñ\85ийÑ\86аме Ñ\82епÑ\82аÑ\80Ñ\88 билгалла йолÑ\83 агÓ\80онаÑ\88 йа гÑ\83лдина йолÑ\83 агÓ\80онаÑ\88 Ñ\85Ó\80окÑ\85 XML баÑ\80амÑ\86а, Ñ\8eÑ\85а Ñ\82Ó\80Ñ\8fÑ\85Ñ\8cа Ñ\87Ñ\83Ñ\80а [[Special:Import|Ñ\85Ñ\8cаÑ\8dÑ\86алÑ\83Ñ\80долÑ\88]] кÑ\85еÑ\87Ñ\83 вики-Ñ\85Ñ\8cалÑ\85ен, болÑ\85 беÑ\88 йолÑ\83 Ñ\85lокÑ\85Ñ\83 MediaWiki гlиÑ\80Ñ\81аÑ\86а.\n\nÐ\9aÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80а Ñ\8fззамаÑ\88 Ñ\87Ñ\83йаÑ\85а, Ñ\87Ñ\83Ñ\8fзйе Ñ\86Ó\80е Ñ\82адеÑ\87Ñ\83 меÑ\82Ñ\82е, Ñ\86Ó\80Ñ\85Ñ\8cа могÓ\80ан Ñ\86Ó\80е могÓ\80аÑ\80Ñ\88каÑ\85Ñ\8c, Ñ\8eÑ\85а Ñ\85аÑ\80жа лаÑ\8cи Ñ\88Ñ\83на Ð\9aÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80 Ñ\87Ñ\83йаÑ\85а маÑ\81Ñ\81о Ñ\8fззамаÑ\88на иÑ\81Ñ\82оÑ\80и Ñ\85ийÑ\86амбаÑ\80Ñ\88 йа Ñ\82Ó\80Ñ\8fÑ\85Ñ\8cаÑ\80алеÑ\80а Ñ\8fззамна баÑ\88Ñ\85о.\n\nШÑ\83Ñ\8cга кÑ\85и даландеÑ\80г, лелаеÑ\88 йолÑ\83 меÑ\82Ñ\82иг кÑ\8aаÑ\81Ñ\82аман маÑ\88ан Ñ\85Ñ\8cажоÑ\80аг кÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80 Ñ\87Ñ\83даÑ\85а Ñ\82Ó\80аÑ\8cÑ\85Ñ\8cаÑ\80леÑ\80аÑ\87Ñ\83 баÑ\88Ñ\85он Ñ\8fззамаÑ\88. Ð\9cаÑ\81ала оÑ\86Ñ\83 Ñ\8fззамна [[{{MediaWiki:Mainpage}}]] Ñ\85Ó\80аÑ\80а Ñ\85иÑ\80а Ñ\8e Ñ\85Ñ\8cажоÑ\80аг [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]].",
+ "exporttext": "ШÑ\83Ñ\8cга далÑ\83Ñ\80 дÑ\83 кÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80а Ñ\87Ñ\83даÑ\85аÑ\80Ñ\88, йоза а Ñ\85ийÑ\86аме Ñ\82епÑ\82аÑ\80Ñ\88 билгалла йолÑ\83 агÓ\80онаÑ\88 йа гÑ\83лдина йолÑ\83 агÓ\80онаÑ\88 Ñ\85Ó\80окÑ\85 XML баÑ\80амÑ\86а, Ñ\8eÑ\85а Ñ\82Ó\80Ñ\8fÑ\85Ñ\8cа Ñ\87Ñ\83Ñ\80а [[Special:Import|Ñ\85Ñ\8cаÑ\8dÑ\86алÑ\83Ñ\80долÑ\88]] кÑ\85еÑ\87Ñ\83 вики-Ñ\85Ñ\8cалÑ\85ен, болÑ\85 беÑ\88 йолÑ\83 Ñ\85lокÑ\85Ñ\83 MediaWiki гlиÑ\80Ñ\81аÑ\86а.\n\nÐ\9aÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80а Ñ\8fззамаÑ\88 Ñ\87Ñ\83йаÑ\85а, Ñ\87Ñ\83Ñ\8fзйе Ñ\86Ó\80е Ñ\82адеÑ\87Ñ\83 меÑ\82Ñ\82е, Ñ\86Ó\80Ñ\85Ñ\8cа могÓ\80ан Ñ\86Ó\80е могÓ\80аÑ\80Ñ\88каÑ\85Ñ\8c, Ñ\8eÑ\85а Ñ\85аÑ\80жа лаÑ\8cи Ñ\88Ñ\83на Ð\9aÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80 Ñ\87Ñ\83йаÑ\85а маÑ\81Ñ\81о Ñ\8fззамаÑ\88на иÑ\81Ñ\82оÑ\80и Ñ\85ийÑ\86амбаÑ\80Ñ\88 йа Ñ\82Ó\80Ñ\8fÑ\85Ñ\8cаÑ\80алеÑ\80а Ñ\8fззамна баÑ\88Ñ\85о.\n\nШÑ\83Ñ\8cга кÑ\85и даландеÑ\80г, лелаеÑ\88 йолÑ\83 меÑ\82Ñ\82иг кÑ\8aаÑ\81Ñ\82аман маÑ\88ан Ñ\85Ñ\8cажоÑ\80г кÑ\85еÑ\87Ñ\83 меÑ\82Ñ\82еÑ\80 Ñ\87Ñ\83даÑ\85а Ñ\82Ó\80аÑ\8cÑ\85Ñ\8cаÑ\80леÑ\80аÑ\87Ñ\83 баÑ\88Ñ\85он Ñ\8fззамаÑ\88. Ð\9cаÑ\81ала оÑ\86Ñ\83 Ñ\8fззамна [[{{MediaWiki:Mainpage}}]] Ñ\85Ó\80аÑ\80а Ñ\85иÑ\80а Ñ\8e Ñ\85Ñ\8cажоÑ\80г [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]].",
"exportall": "Массо агӀонаш экспорт ян",
"exportcuronly": "Карара верси бен юкъа ма тоха, юзийна хьалхалерра истори йоцуш",
"export-submit": "Экспорт ян",
"tooltip-t-upload": "Чуйаха файлаш",
"tooltip-t-specialpages": "Белха агӀонанийн могӀам",
"tooltip-t-print": "Хlокху агlонна зорба туху башхо",
- "tooltip-t-permalink": "Ð\94аима йолÑ\83 Ñ\85Ñ\8cажоÑ\80аг Ñ\85Ó\80окÑ\85Ñ\83 баÑ\88Ñ\85а агÓ\80онна",
+ "tooltip-t-permalink": "Даима йолу хьажорг хӀокху башха агӀонна",
"tooltip-ca-nstab-main": "Яззамна чулацам",
"tooltip-ca-nstab-user": "ХӀора декъашхочун долахь йолу агӀо ю",
"tooltip-ca-nstab-media": "Медиа-файл",
"creditspage": "Баркаллаш",
"nocredits": "Бац декъашхойн могӀам хӀокху яззамца",
"spamprotectiontitle": "Совбиларна литтар",
- "spamprotectiontext": "Ð¥Ñ\8cо дÓ\80аÑ\8fзÑ\8aÑ\8fн гÓ\80еÑ\80Ñ\82а агÓ\80о Ñ\81пам-лиÑ\82Ñ\82аÑ\80о дÓ\80акÑ\8aоÑ\8cвлина.\nЦÑ\83на баÑ\85Ñ\8cна Ñ\85ила Ñ\82ам бÑ\83 агÓ\80она Ñ\87оÑ\85Ñ\8c зÑ\83лам лиÑ\82Ñ\82аÑ\80ан Ñ\87Ñ\83Ñ\82оÑ\8cÑ\85на йолÑ\83 Ñ\85Ñ\8cажоÑ\80аг Ñ\85илаÑ\80.",
+ "spamprotectiontext": "Хьо дӀаязъян гӀерта агӀо спам-литтаро дӀакъоьвлина.\nЦуна бахьна хила там бу агӀона чохь зулам литтаран чутоьхна йолу хьажорг хилар.",
"spambot_username": "Спам дӀацӀаняр",
"pageinfo-title": "Хаамаш цу «$1»",
"pageinfo-not-current": "Шира версийн оьцу хааме хьажа таро яц.",
"newimages-legend": "Литтар",
"newimages-showbots": "Гайта боташ чуяьхна файлаш",
"noimages": "Суьрташ дац.",
- "ilsubmit": "Лаха",
+ "ilsubmit": "Лахар",
"bydate": "терахьашца",
"sp-newimages-showfrom": "Гайта керла файлаш $2, $1 тӀера дуьйна",
"seconds-abbrev": "$1 оцу",
"saturday-at": "шот дийнахь $1",
"sunday-at": "кӀиранан дийнахь $1",
"yesterday-at": "селхана $1 даьлча",
- "bad_image_list": "Ð\91аÑ\80ам Ñ\85ила беза иÑ\88Ñ\82а:\n\nÐ\9bоÑ\80аÑ\88 Ñ\85иÑ\80а Ñ\8e могÓ\80амÑ\8fÑ\85Ñ\8c йолÑ\83 Ñ\85Ó\80Ñ\83мнаÑ\88 (могÓ\80ийн, йола лÑ\83Ñ\88 йолÑ\83 Ñ\81имвол Ñ\82Ó\80иÑ\80а *).\nÐ\94Ñ\83Ñ\8cÑ\85Ñ\85Ñ\8cаÑ\80алеÑ\80а Ñ\85Ñ\8cажоÑ\80аг магÓ\80аÑ\80Ñ\88и Ñ\85ила беза Ñ\85Ñ\8cажоÑ\80аг кÑ\85Ñ\83 Ñ\86амагдо Ñ\81Ñ\83Ñ\80Ñ\82 дÑ\83Ñ\8cлаÑ\87е.\nТÓ\80Ñ\8fÑ\85Ñ\8cа йогÓ\80Ñ\83Ñ\88 йолÑ\83 Ñ\85Ñ\8cажоÑ\80аг оцу могӀарехь хира ю магóш, билгалла аьлча яззамаш долуче, сурт хьаллаточехь.",
+ "bad_image_list": "Ð\91аÑ\80ам Ñ\85ила беза иÑ\88Ñ\82а:\n\nÐ\9bоÑ\80аÑ\88 Ñ\85иÑ\80а Ñ\8e могÓ\80амÑ\8fÑ\85Ñ\8c йолÑ\83 Ñ\85Ó\80Ñ\83мнаÑ\88 (могÓ\80ийн, йола лÑ\83Ñ\88 йолÑ\83 Ñ\81имвол Ñ\82Ó\80иÑ\80а *).\nÐ\94Ñ\83Ñ\8cÑ\85Ñ\85Ñ\8cаÑ\80алеÑ\80а Ñ\85Ñ\8cажоÑ\80г магÓ\80анийн Ñ\85ила беза Ñ\85Ñ\8cажоÑ\80г кÑ\85Ñ\83 Ñ\86амагдо Ñ\81Ñ\83Ñ\80Ñ\82 дÑ\83Ñ\8cлаÑ\87е.\nТÓ\80Ñ\8fÑ\85Ñ\8cа йогÓ\80Ñ\83Ñ\88 йолÑ\83 Ñ\85Ñ\8cажоÑ\80г оцу могӀарехь хира ю магóш, билгалла аьлча яззамаш долуче, сурт хьаллаточехь.",
"metadata": "Метахаамаш",
"metadata-help": "ХӀокху файлаца кхин тӀе хаам бу, даиман чуйоккхуш йолу терахьца чоьнашца йа тӀейоккхучуьнца. Нагахь файлан тӀаьхьа хийцам биняхь, тӀаккха цӀхьаболу барам цӀхьаьна ца ба мега хӀинцалера суьртаца.",
"metadata-expand": "Гайта кхин тlе болу хаам",
"redirect-legend": "Файлан я агӀона тӀера дӀасхьажор",
"redirect-summary": "ХӀара агӀо лело йиш ю файлан я агӀона тӀера дӀасхьажош.",
"redirect-submit": "Дехьа гӀо",
- "redirect-lookup": "Лаха:",
+ "redirect-lookup": "Лахар:",
"redirect-value": "МаьӀна:",
"redirect-user": "Декъашхочун ID",
"redirect-page": "АгӀона ID",
"fileduplicatesearch-summary": "Лаха цхьатера йолу файлаш хэш-кодаца.",
"fileduplicatesearch-legend": "Цхьатера ерш лахар",
"fileduplicatesearch-filename": "Файлан цӀе:",
- "fileduplicatesearch-submit": "Лаха",
+ "fileduplicatesearch-submit": "Лахар",
"fileduplicatesearch-info": "$1 × $2 пиксель<br />Файлан барам: $3<br />MIME-тайп: $4",
"fileduplicatesearch-result-1": "«$1» файлах тера хӀума яц.",
"fileduplicatesearch-noresults": "ЦӀе «$1» йолуш файл цакарий.",
"tog-shownumberswatching": "Zobrazovat počet sledujících uživatelů",
"tog-oldsig": "Stávající podpis:",
"tog-fancysig": "Používat v podpisu wikitext (bez automatického odkazu)",
- "tog-uselivepreview": "Používat rychlý náhled (experimentální)",
+ "tog-uselivepreview": "Používat rychlý náhled",
"tog-forceeditsummary": "Upozornit, když nevyplním shrnutí editace",
"tog-watchlisthideown": "Na seznamu sledovaných stránek skrýt moje editace",
"tog-watchlisthidebots": "Na seznamu sledovaných stránek skrýt editace botů",
"anoneditwarning": "'''Varování:''' Nejste přihlášen(a). Pokud uložíte jakoukoli editaci, bude vaše IP adresa zveřejněna v historii této stránky. Pokud se <strong>[$1 přihlásíte]</strong> nebo si <strong>[$2 vytvoříte účet]</strong>, budou vaše editace připsány vašemu uživatelskému jménu a získáte i další výhody.",
"anonpreviewwarning": "''Nejste přihlášen(a). Uložením zveřejníte svou IP adresu v historii této stránky.''",
"missingsummary": "'''Připomenutí:''' Nezadali jste shrnutí editace. Pokud ještě jednou kliknete na Uložit změny, bude vaše editace zapsána bez shrnutí.",
+ "selfredirect": "<strong>Upozornění:</strong> Vytváříte přesměrování na týž článek. Pokud ještě jednou kliknete na „{{int:savearticle}}“, bude přesměrování vytvořeno.",
"missingcommenttext": "Zadejte komentář",
"missingcommentheader": "'''Připomenutí:''' Nezadali jste předmět/nadpis pro tento komentář.\nPokud ještě jednou kliknete na „{{int:savearticle}}“, bude vaše editace zapsána i bez toho.",
"summary-preview": "Náhled shrnutí:",
"log-name-pagelang": "Kniha změn jazyků",
"log-description-pagelang": "Toto je protokol změn jazyků stránek.",
"logentry-pagelang-pagelang": "$1 {{GENDER:$2|změnil|změnila}} jazyk stránky $3 z $4 na $5.",
- "default-skin-not-found": "Jejda! Výchozí vzhled vaší wiki, definovaný ve <code dir=\"ltr\">$wgDefaultSkin</code> jako <code>$1</code>, není dostupný.\n\nVaše instalace zřejmě obsahuje následující vzhledy. Informace o tom, jak je povolit a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].\n\n$2\n\n; Pokud jste právě nainstalovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalace v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code dir=\"ltr\">skins/</code>, nebo\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code>skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář.\n\n; Pokud jste právě aktualizovali MediaWiki:\n: MediaWiki 1.24 a novější již automaticky nepovolují nainstalované vzhledy (vizte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_autodiscovery/cs Manual:Skin autodiscovery]). Pro povolení všech právě nainstalovaných vzhledů vlepte následující řádky do <code>LocalSettings.php</code>:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Pokud jste právě upravili <code>LocalSettings.php</code>:\n: Překontrolujte případné překlepy v názvech vzhledů.",
- "default-skin-not-found-no-skins": "Jejda! Výchozí vzhled vaší wiki, definovaný ve <code dir=\"ltr\">$wgDefaultSkin</code> jako <code>$1</code>, není dostupný.\n\nNemáte nainstalovány žádné vzhledy.\n\n; Pokud jste právě nainstalovali nebo aktualizovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. MediaWiki 1.24 a novější již v hlavním repozitáři neobsahují žádné vzhledy. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalace v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code>skins/</code>, nebo\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code dir=\"ltr\">skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář. Informace o tom, jak povolit vzhledy a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].",
+ "default-skin-not-found": "Jejda! Výchozí vzhled vaší wiki, definovaný ve <code dir=\"ltr\">$wgDefaultSkin</code> jako <code>$1</code>, není dostupný.\n\nVaše instalace zřejmě obsahuje následující vzhledy. Informace o tom, jak je povolit a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].\n\n$2\n\n; Pokud jste právě nainstalovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalaci v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code dir=\"ltr\">skins/</code>.\n:* Nebo si můžete stáhnout tarbally jednotlivých vzhledů z [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code>skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář.\n\n; Pokud jste právě aktualizovali MediaWiki:\n: MediaWiki 1.24 a novější již automaticky nepovolují nainstalované vzhledy (vizte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_autodiscovery/cs Manual:Skin autodiscovery]). Pro povolení všech právě nainstalovaných vzhledů vlepte následující řádky do <code>LocalSettings.php</code>:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Pokud jste právě upravili <code>LocalSettings.php</code>:\n: Překontrolujte případné překlepy v názvech vzhledů.",
+ "default-skin-not-found-no-skins": "Jejda! Výchozí vzhled vaší wiki, definovaný ve <code dir=\"ltr\">$wgDefaultSkin</code> jako <code>$1</code>, není dostupný.\n\nNemáte nainstalovány žádné vzhledy.\n\n; Pokud jste právě nainstalovali nebo aktualizovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. MediaWiki 1.24 a novější již v hlavním repozitáři neobsahují žádné vzhledy. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalaci v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code>skins/</code>.\n:* Nebo si můžete stáhnout tarbally jednotlivých vzhledů z [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code dir=\"ltr\">skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář. Informace o tom, jak povolit vzhledy a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (povolený)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''zakázaný''')",
"mediastatistics": "Statistika souborů",
"tog-shownumberswatching": "Anzahl der beobachtenden Benutzer anzeigen",
"tog-oldsig": "Vorhandene Signatur:",
"tog-fancysig": "Signatur als Wikitext behandeln (ohne automatische Verlinkung)",
- "tog-uselivepreview": "Vorschau sofort anzeigen (experimentell)",
+ "tog-uselivepreview": "Vorschau sofort anzeigen",
"tog-forceeditsummary": "Warnen, sofern beim Speichern die Zusammenfassung fehlt",
"tog-watchlisthideown": "Eigene Bearbeitungen in der Beobachtungsliste ausblenden",
"tog-watchlisthidebots": "Bearbeitungen durch Bots in der Beobachtungsliste ausblenden",
"anoneditwarning": "<strong>Warnung:</strong> Du bist nicht angemeldet. Deine IP-Adresse wird öffentlich sichtbar, falls du Bearbeitungen durchführst. Wenn du dich <strong>[$1 anmeldest]</strong> oder <strong>[$2 ein Benutzerkonto erstellst]</strong>, werden deine Bearbeitungen zusammen mit anderen Beiträgen deinem Benutzernamen zugeordnet.",
"anonpreviewwarning": "''Du bist nicht angemeldet. Beim Speichern wird deine IP-Adresse in der Versionsgeschichte aufgezeichnet.''",
"missingsummary": "'''Hinweis:''' Du hast keine Zusammenfassung angegeben. Wenn du erneut auf „{{int:savearticle}}“ klickst, wird deine Änderung ohne Zusammenfassung übernommen.",
+ "selfredirect": "<strong>Warnung:</strong> Du erstellst eine Weiterleitung auf den gleichen Artikel.\nWenn du erneut auf „{{int:savearticle}}“ klickst, wird die Weiterleitung erstellt.",
"missingcommenttext": "Dein Abschnitt enthält keinen Text.",
"missingcommentheader": "'''Achtung:''' Du hast kein Betreff/Überschrift eingegeben. Wenn du erneut auf „{{int:savearticle}}“ klickst, wird deine Bearbeitung ohne Überschrift gespeichert.",
"summary-preview": "Vorschau der Zusammenfassungszeile:",
"ninterwikis": "{{PLURAL:$1|Ein Interwikilink|$1 Interwikilinks}}",
"nlinks": "{{PLURAL:$1|1 Link|$1 Links}}",
"nmembers": "{{PLURAL:$1|1 Eintrag|$1 Einträge}}",
- "nmemberschanged": "$1 → {{PLURAL:$2|Ein Mitglied|$2 Mitglieder}}",
+ "nmemberschanged": "$1 → $2 {{PLURAL:$2|Mitglied|Mitglieder}}",
"nrevisions": "{{PLURAL:$1|1 Bearbeitung|$1 Bearbeitungen}}",
"nviews": "{{PLURAL:$1|1 Abfrage|$1 Abfragen}}",
"nimagelinks": "Verwendet auf {{PLURAL:$1|einer Seite|$1 Seiten}}",
"tog-shownumberswatching": "Fà vèder al nómer ed j utèint che gh'àn la pàgina sòta uservasiòun",
"tog-oldsig": "La fîrma 'd adèsa",
"tog-fancysig": "Trâta la fîrma cme wikitèst (sèinsa colegamèint avtomâtich)",
- "tog-uselivepreview": "Permèt la funsiòun \"Live preview\" (guêrda préma 'd salvêr dal vîv - in sperimèint)",
+ "tog-uselivepreview": "Permèt la funsiòun \"Live preview\" (guêrda préma 'd salvêr in dirèta)",
"tog-forceeditsummary": "Dmânda s'l'è vèira che al câmp argumèint l' é vōd",
"tog-watchlisthideown": "Lōga al mé mudéfichi int i tgnû 'd ôc specêl",
"tog-watchlisthidebots": "Lōga al mudéfichi di bot int i tgnû 'd ôc specêl",
"anoneditwarning": "<strong>Atèinti:</strong> An n'é mìa stê fât l'ingrès. S' ét farê dal mudéfichi al tó indirés IP al srà vést da tót. Se <strong>[$1 và dèinter]</strong> o <strong>[$2 fà 'n' utèinsa]</strong>, al tô mudéfichi a srân sgnêdi al tó nòm utèint, insèm a êter benefési.",
"anonpreviewwarning": "\"An n'é mìa stê fât l'ingrès. Mèinter es sêlva la pàgina, l'indirés IP al srà sgnê int la stòria 'd la pàgina.\"",
"missingsummary": "'''Atensiòun:''' an n'é mìa stê precişê al mutîv de sté mudéfica. S'es tōrna a clichêr insém a \"{{int:savearticle}}\" la mudéfica la gnirà salvêda cun al mutîv vōd.",
+ "selfredirect": "<strong>Ateinti:</strong>t'é drē fêr un rinvéi a l'istèsa vōş. S'ét fê cléch incòra in sém a \"{{int:savearticle}}\", al rinvéi al gnirà fât",
"missingcommenttext": "Scréver un cumèint ché sòta.",
"missingcommentheader": "'''Atensiòun:''' an n'é mìa stê precişê al mutîv/al tétol de sté mudéfica. S'es tōrna a clichêr insém a \"{{int:savearticle}}\" la mudéfica la gnirà salvêda sèinsa tétol.",
"summary-preview": "Guêrda préma sûnt:",
"right-protect": "Câmbia i livē 'd prutesiòun e mudéfica 'l pàgini prutèti in ripetisiòun",
"right-editprotected": "Mudéfica 'l pàgini prutèti cun \"{{int:protect-level-sysop}}\"",
"right-editsemiprotected": "Mudéfica 'l pàgini prutèti cun \"{{int:protect-level-autoconfirmed}}\"",
+ "right-editcontentmodel": "Mudéfica al mudèl ed còl ché dèinter int 'na pàgina.",
"right-editinterface": "Mudéfica al colegamèint tra sistēma e utèint",
"right-editusercssjs": "Mudéfica i file CSS e JS 'd êter utèint",
"right-editusercss": "Mudéfica i file CSS 'd êter utèint",
"right-editmyprivateinfo": "Câmbia 'l tō infurmasiòun personêli (per eşèimpi: indirés ed pôsta eletrônica, nòm vèira)",
"right-editmyoptions": "Câmbia al tō preferèinsi",
"right-rollback": "Scanşèla a la şvêlta al mudéfichi ed l'ûltèint ch'l'à mudifichê 'na pàgina pariculêra",
+ "right-markbotedits": "Sègna al mudéfichi da turnêr a mèter cme préma cme fâti da 'na mâchina in avtomâtich",
+ "right-noratelimit": "An n'é mìa ublighê al lémit 'd asiòun",
+ "right-import": "Côpia dal pàgini da 'd j êter wiki",
"newuserlogpage": "Utèint nōv",
"action-read": "lēzer cla pàgina ché",
"action-edit": "Mudifichêr cla pàgina ché",
"permalink": "Σταθερός σύνδεσμος",
"print": "Εκτύπωση",
"view": "Προβολή",
- "view-foreign": "Î\94είÏ\84ε στο $1",
+ "view-foreign": "Î Ï\81οβολή στο $1",
"edit": "Επεξεργασία",
"edit-local": "Επεξεργασία τοπικής περιγραφής",
"create": "Δημιουργία",
- "create-local": "Î Ï\81οÏ\83θÎÏ\83Ï\84ε Ï\84οÏ\80ική Ï\80εÏ\81ιγÏ\81αÏ\86ή",
+ "create-local": "Î Ï\81οÏ\83θήκη Ï\84οÏ\80ικήÏ\82 Ï\80εÏ\81ιγÏ\81αÏ\86ήÏ\82",
"editthispage": "Επεξεργασία αυτής της σελίδας",
"create-this-page": "Δημιουργία αυτής της σελίδας",
"delete": "Διαγραφή",
"filepage-nofile-link": "Δεν υπάρχει τέτοιο αρχείο, αλλἀ μπορείτε να [$1 το επιφορτώσετε].",
"uploadnewversion-linktext": "Φορτώστε μια νέα έκδοση αυτού του αρχείου",
"shared-repo-from": "από το $1",
- "shared-repo": "Îνα κοινÏ\8c εναÏ\80οθεÏ\84ήÏ\81ιο",
+ "shared-repo": "κοινό εναποθετήριο",
"shared-repo-name-wikimediacommons": "Wikimedia Commons",
"upload-disallowed-here": "Δεν μπορείτε να αντικαταστήσετε αυτό το αρχείο.",
"filerevert": "Επαναφορά $1",
"tog-shownumberswatching": "Show the number of watching users",
"tog-oldsig": "Existing signature:",
"tog-fancysig": "Treat signature as wikitext (without an automatic link)",
- "tog-uselivepreview": "Use live preview (experimental)",
+ "tog-uselivepreview": "Use live preview",
"tog-forceeditsummary": "Prompt me when entering a blank edit summary",
"tog-watchlisthideown": "Hide my edits from the watchlist",
"tog-watchlisthidebots": "Hide bot edits from the watchlist",
"anoneditwarning": "<strong>Warning:</strong> You are not logged in. Your IP address will be publicly visible if you make any edits. If you <strong>[$1 log in]</strong> or <strong>[$2 create an account]</strong>, your edits will be attributed to your username, along with other benefits.",
"anonpreviewwarning": "<em>You are not logged in. Saving will record your IP address in this page's edit history.</em>",
"missingsummary": "<strong>Reminder:</strong> You have not provided an edit summary.\nIf you click \"{{int:savearticle}}\" again, your edit will be saved without one.",
+ "selfredirect": "<strong>Warning:</strong> You are creating redirect to the same article.\nIf you click \"{{int:savearticle}}\" again, the redirect will be created.",
"missingcommenttext": "Please enter a comment below.",
"missingcommentheader": "<strong>Reminder:</strong> You have not provided a subject/headline for this comment.\nIf you click \"{{int:savearticle}}\" again, your edit will be saved without one.",
"summary-preview": "Summary preview:",
"tog-shownumberswatching": "Mostrar el número de usuarios que la vigilan",
"tog-oldsig": "Firma actual:",
"tog-fancysig": "Tratar la firma como wikitexto (sin un enlace automático)",
- "tog-uselivepreview": "Usar previsualización dinámica (experimental)",
+ "tog-uselivepreview": "Usar previsualización dinámica",
"tog-forceeditsummary": "Avisarme cuando grabe la página sin introducir un resumen de edición",
"tog-watchlisthideown": "Ocultar mis ediciones en la lista de seguimiento",
"tog-watchlisthidebots": "Ocultar las ediciones de bots en la lista de seguimiento",
"right-protect": "Cambiar niveles de protección y editar páginas protegidas en cascada",
"right-editprotected": "Editar páginas protegidas como «{{int:protect-level-sysop}}»",
"right-editsemiprotected": "Editar páginas protegidas como «{{int:protect-level-autoconfirmed}}»",
+ "right-editcontentmodel": "Editar el modelo de contenido de una página",
"right-editinterface": "Editar la interfaz de usuario",
"right-editusercssjs": "Editar las páginas de CSS y JavaScript de otros usuarios",
"right-editusercss": "Editar las páginas de CSS de otros usuarios",
"action-viewmywatchlist": "Ver tu lista de seguimiento",
"action-viewmyprivateinfo": "ver tu información privada",
"action-editmyprivateinfo": "Editar tu información privada",
+ "action-editcontentmodel": "editar el modelo de contenido de una página",
"nchanges": "$1 {{PLURAL:$1|cambio|cambios}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde la última visita}}",
"enhancedrc-history": "historial",
"unknown_extension_tag": "Etiqueta desconocida «$1»",
"duplicate-defaultsort": "'''Atención:''' La clave de ordenamiento predeterminada «$2» anula la clave de ordenamiento anterior «$1».",
"duplicate-displaytitle": "<strong>Advertencia:</strong> El título visualizado \"$2\" sobreescribe al anterior \"$1\".",
+ "invalid-indicator-name": "<strong>Error:</strong> el atributo <code>name</code> de los indicadores de estado de página no debe estar vacío.",
"version": "Versión",
"version-extensions": "Extensiones instaladas",
"version-skins": "Temas instalados",
"specialpages": "Páginas especiales",
"specialpages-note-top": "Leyenda",
"specialpages-note": "* Páginas especiales normales\n* <span class=\"mw-specialpagerestricted\">Páginas especiales restringidas.</span>\n* <span class=\"mw-specialpagecached\">Páginas especiales en caché (podrían ser obsoletas).</span>",
- "specialpages-group-maintenance": "Reportes de mantenimiento",
+ "specialpages-group-maintenance": "Informes de mantenimiento",
"specialpages-group-other": "Otras páginas especiales",
"specialpages-group-login": "Acceder/crear cuenta",
"specialpages-group-changes": "Cambios recientes y registros",
"virus-badscanner": "Viga konfiguratsioonis: tundmatu viirusetõrje: ''$1''",
"virus-scanfailed": "skaneerimine ebaõnnestus (veakood $1)",
"virus-unknownscanner": "tundmatu viirusetõrje:",
- "logouttext": "'''Oled nüüd välja loginud.'''\n\nPane tähele, et seni kuni sa pole oma võrgulehitseja puhvrit tühjendanud, võidakse mõni lehekülg endiselt kuvada nii nagu oleksid ikka sisse logitud.",
+ "logouttext": "<strong>Oled nüüd välja loginud.</strong>\n\nPane tähele, et seni, kuni sa pole veebilehitseja puhvrit tühjendanud, võidakse mõni lehekülg endiselt kuvada nii nagu oleksid ikka sisse logitud.",
"welcomeuser": "Tere tulemast, $1!",
"welcomecreation-msg": "Sinu konto on loodud.\nÄra unusta seada oma {{GRAMMAR:genitive|{{SITENAME}}}} [[Special:Preferences|eelistusi]].",
"yourname": "Kasutajanimi:",
"userlogin": "Sisselogimine või kasutajakonto loomine",
"userloginnocreate": "Sisselogimine",
"logout": "Logi välja",
- "userlogout": "Logi välja",
+ "userlogout": "Väljalogimine",
"notloggedin": "Sisse logimata",
"userlogin-noaccount": "Kas sul pole kontot?",
"userlogin-joinproject": "Ühine projektiga {{SITENAME}}",
"Omid.koli",
"Alirezaaa",
"Mogoeilor",
- "Hosseinblue"
+ "Hosseinblue",
+ "فلورانس",
+ "Saeidpourbabak"
]
},
"tog-underline": "خط کشیدن زیر پیوندها:",
"filerenameerror": "نشد پروندهٔ «$1» به «$2» تغییر نام یابد.",
"filedeleteerror": "نشد پروندهٔ «$1» حذف شود.",
"directorycreateerror": "نشد مسیر $1 را ایجاد کرد.",
+ "directoryreadonlyerror": "دایرکتوری \"$1\" فقط خواندنی است.",
+ "directorynotreadableerror": "دایرکتوری \"$1\" قابل خواندن نیست.",
"filenotfound": "پروندهٔ «$1» یافت نشد.",
"unexpected": "مقدار غیرمنتظره: «$1»=«$2».",
"formerror": "خطا: نمیتوان فرم را فرستاد.",
"right-protect": "تغییر میزان محافظت صفحات و ویرایش صفحات محافظتشده آبشاری",
"right-editprotected": "ویرایش صفحههای محافظتشده بهعنوان «{{int:protect-level-sysop}}»",
"right-editsemiprotected": "ویرایش صفحه حفاظتشده به عنوان \"{{int:protect-level-autoconfirmed}}\"",
+ "right-editcontentmodel": "ویرایش مدل محتوای یک صفحه",
"right-editinterface": "ویرایش واسط کاربری",
"right-editusercssjs": "ویرایش صفحههای CSS و JS دیگر کاربرها",
"right-editusercss": "ویرایش صفحههای CSS دیگر کاربرها",
"action-viewmywatchlist": "فهرست پیگیریهای خود را ببینید",
"action-viewmyprivateinfo": "اطلاعات خصوصی خود را ببینید",
"action-editmyprivateinfo": "اطلاعات خصوصی خود را ویرایش کنید",
+ "action-editcontentmodel": "ویرایش مدل محتوای یک صفحه",
"nchanges": "$1 تغییر",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|از آخرین بازدید}}",
"enhancedrc-history": "تاریخچه",
"move-page": "انتقال $1",
"move-page-legend": "انتقال صفحه",
"movepagetext": "با استفاده از فرم زیر نام صفحه تغییر خواهد کرد، و تمام تاریخچهاش به نام جدید منتقل خواهد شد.\nعنوان قدیمی تبدیل به یک صفحهٔ تغییرمسیر به عنوان جدید خواهد شد.\nشما میتوانید تغییرمسیرهایی که به عنوان اصلی اشاره دارند را به صورت خودکار بهروزرسانی کنید.\nپیوندهای که به عنوان صفحهٔ قدیمی وجود دارند، تغییر نخواهند کرد؛ حتماً تغییرمسیرهای [[Special:DoubleRedirects|دوتایی]] یا [[Special:BrokenRedirects|خراب]] را بررسی کنید.\n'''شما''' مسئول اطمینان از این هستید که پیوندها هنوز به همانجایی که قرار است بروند.\n\nتوجه کنید که اگر از قبل صفحهای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''،\nمگر این آخرین ویرایش تغییرمسیر باشد و در تاریخچهٔ ویرایشی نداشته باشد.\nاین یعنی اگر اشتباه کردید میتوانید صفحه را به همان جایی که از آن منتقل شده بود برگردانید، و این که نمیتوانید روی صفحات موجود بنویسید.\n\n'''هشدار!'''\nانتقال صفحات به نام جدید ممکن است تغییر اساسی و غیرمنتظرهای برای صفحات محبوب باشد؛\nلطفاً مطمئن شوید که قبل از انتقال دادن صفحه، عواقب این کار را درک میکنید.",
- "movepagetext-noredirectfixer": "استفاده از فرم زیر سبب تغییر نام یک صفحه و انتقال تمام تاریخچهٔ آن به نام جدید میشود.\nعنوان پیشین تغییرمسیری به عنوان جدید خواهد شد.\nبه خاطر داشته باشید که [[Special:DoubleRedirects|تغییرمسیرهای دوتایی]] یا [[Special:BrokenRedirects|تغییرمسیرهای خراب]] را بررسی کنید.\nشما مسئولید که مطمئن شوید پیوندها به جایی اشاره میکنند که قرار است بروند.\n\nتوجه کنید که اگر صفحهای تحت عنوان جدید از قبل موجود باشد، انتقال انجام '''نخواهد شد'''، مگر اینکه صفحه خالی و یا تغییرمسیر باشد و تاریخچهٔ ویرایشی دیگری نداشته باشد.\nاین یعنی اگر صفحه را به نامی اشتباه منتقل کردید میتوانید این تغییر را واگردانی کنید، اما نمیتوانید به صفحهای که از قبل موجود است انتقال دهید.\n\n'''هشدار!'''\nانتقال صفحههای پربیننده ممکن است عملی غیرمنتظره باشد؛\nلطفاً پیش از انتقال مطمئن شوید از نتیجهٔ کار آگاهید.",
+ "movepagetext-noredirectfixer": "استفاده از فرم زیر سبب تغییر نام یک صفحه و انتقال تمام تاریخچهٔ آن به نام جدید میشود.\nعنوان پیشین تغییرمسیری به عنوان جدید خواهد شد.\nبه خاطر داشته باشید که [[Special:DoubleRedirects|تغییرمسیرهای دوتایی]] یا [[Special:BrokenRedirects|تغییرمسیرهای خراب]] را بررسی کنید.\nشما مسئولید که مطمئن شوید پس از انتقال، پیوندها به عنوان پیشین به جایی منتهی میشوند که باید.\n\nتوجه کنید که اگر صفحهای تحت عنوان جدید از قبل موجود باشد، انتقال انجام '''نخواهد شد'''، مگر اینکه صفحه خالی و یا تغییرمسیر باشد و تاریخچهٔ ویرایشی دیگری نداشته باشد.\nاین یعنی اگر صفحه را به نامی اشتباه منتقل کردید میتوانید این تغییر را واگردانی کنید، اما نمیتوانید یک صفحه را به صفحهای که از قبل موجود است انتقال دهید.\n\n'''هشدار!'''\nانتقال صفحههای پربیننده ممکن است عملی غیرمنتظره باشد؛\nلطفاً پیش از انتقال مطمئن شوید از نتیجهٔ کار آگاهید.",
"movepagetalktext": "صفحهٔ بحث مربوط، اگر وجود داشته باشد، بطور خودکار همراه با مقالهٔ اصلی منتقل خواهد شد '''مگر اینکه''' :\n* در حال انتقال صفحه از این فضای نام به فضای نام دیگری باشید،\n* یک صفحهٔ بحث غیرخالی تحت این نام جدید وجود داشته باشد، یا\n* جعبهٔ زیر را تیک نزده باشید.\n\nدر این حالات، باید صفحه را بطور دستی انتقال داده و یا محتویات دو صفحه را با ویرایش ادغام کنید.",
"movearticle": "انتقال صفحه:",
"moveuserpage-warning": "'''هشدار:''' شما در حال انتقال دادن یک صفحهٔ کاربر هستید. توجه داشته باشید که تنها صفحه منتقل میشود و نام کاربر تغییر '''نمییابد'''.",
"specialpages-group-wiki": "داده و ابزارها",
"specialpages-group-redirects": "صفحههای ویژهٔ تغییرمسیر دهنده",
"specialpages-group-spam": "ابزارهای هرزنگاری",
+ "specialpages-group-developer": "ابزارهای توسعهدهندگان",
"blankpage": "صفحهٔ خالی",
"intentionallyblankpage": "این صفحه به طور عمدی خالی گذاشته شده است.",
"external_image_whitelist": " #این سطر را همانگونه که هست رها کنید<pre>\n#عبارتهای باقاعده (regex) را در زیر قرار دهید (فقط بخشی که بین // قرار میگیرد)\n#آنها با نشانی اینترنتی تصاویر خارجی پیوند داده شده تطبیق داده میشوند\n#مواردی که مطابق باشند به صورت تصویر نمایش مییابند، و در غیر این صورت تنها یک پیوند به تصویر نمایش مییابد\n#سطرهایی که با # آغاز شوند به عنوان توضیحات در نظر گرفته میشوند\n#این سطرها به کوچکی و بزرگی حروف حساس هستند\n\n#عبارتهای باقاعده (regex) را زیر این سطر قرار دهید. این سطر را همانگونه که هست رها کنید</pre>",
"expand_templates_generate_xml": "نمایش درخت تجزیهٔ XML",
"expand_templates_generate_rawhtml": "نمایش اچتیامال خام",
"expand_templates_preview": "پیشنمایش",
+ "expand_templates_preview_fail_html": "<em>زیرا {{SITENAME}} تا به HTML خام فعال و یک دست رفتن اطلاعات نشست وجود دارد، پیش نمایش به عنوان یک اقدام احتیاطی در برابر حملات جاوا اسکریپت پنهان است.</em>\n\n<strong>اگر این تلاش پیشنمایش مشروع است، لطفا دوباره سعی کنید. اگر هنوز کار نمی کند، سعی کنید [[Special:UserLogout|خروج از سیستم]] را کلیک نموده و دوباره وارد شوید.",
+ "expand_templates_preview_fail_html_anon": "<em>زیرا {{SITENAME}} تا به HTML خام فعال و یک دست رفتن اطلاعات نشست وجود دارد، پیش نمایش به عنوان یک اقدام احتیاطی در برابر حملات جاوا اسکریپت پنهان است.</em>\n\n<strong>اگر این تلاش پیشنمایش مشروع است، لطفا دوباره سعی کنید. اگر هنوز کار نمی کند، سعی کنید [[Special:UserLogout|خروج از سیستم]] را کلیک نموده و دوباره وارد شوید.",
"pagelanguage": "صفحه انتخاب زبان",
"pagelang-name": "صفحه",
"pagelang-language": "زبان",
"아라",
"Syreeni",
"MrTapsa",
- "SMAUG"
+ "SMAUG",
+ "SuperPete"
]
},
"tog-underline": "Linkkien alleviivaus:",
"tog-shownumberswatching": "Näytä sivua tarkkailevien käyttäjien määrä",
"tog-oldsig": "Nykyinen allekirjoitus:",
"tog-fancysig": "Muotoilematon allekirjoitus ilman automaattista linkkiä",
- "tog-uselivepreview": "Käytä välitöntä esikatselua (kokeellinen)",
+ "tog-uselivepreview": "Käytä välitöntä esikatselua",
"tog-forceeditsummary": "Huomauta minua, jos en ole kirjoittanut yhteenvetoa",
"tog-watchlisthideown": "Piilota omat muokkaukset tarkkailulistalta",
"tog-watchlisthidebots": "Piilota bottien muokkaukset tarkkailulistalta",
"anoneditwarning": "<strong>Varoitus:</strong> Et ole kirjautunut sisään. IP-osoitteesi näkyy julkisesti kaikille, jos muokkaat. Jos <strong>[$1 kirjaudut sisään]</strong> tai <strong>[$2 luot tunnuksen]</strong>, muokkauksesi kirjataan käyttäjätunnuksesi tekemiksi ja samalla saat käyttöösi hyödyllisiä välineitä.",
"anonpreviewwarning": "''Et ole kirjautunut sisään. Tallentaminen kirjaa IP-osoitteesi tämän sivun muutoshistoriaan.''",
"missingsummary": "Et ole antanut yhteenvetoa. Jos valitset Tallenna uudelleen, niin muokkauksesi tallennetaan ilman yhteenvetoa.",
+ "selfredirect": "<strong>Varoitus:</strong> Olet tekemässä uudelleenohjausta samaan artikkeliin. Jos painat toimintoa \"{{int:savearticle}}\" uudestaan, tämä ohjaussivu luodaan.",
"missingcommenttext": "Kirjoita viesti alle.",
"missingcommentheader": "Et ole antanut otsikkoa kommentillesi. Napsauta ”{{int:savearticle}}”, jos et halua antaa otsikkoa.",
"summary-preview": "Yhteenvedon esikatselu:",
"content-model-javascript": "JavaScript",
"content-model-css": "CSS",
"duplicate-args-category": "Sivut, jotka käyttävät kaksinkertaisia argumentteja mallinekutsuissa",
+ "duplicate-args-category-desc": "Tämä sivu sisältää sellaisia mallinekutsuja, jotka käyttävät kaksi kertaa samaa argumenttia kuten <nowiki>{{foo|bar=1|bar=2}}</nowiki></code> taikka <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
"expensive-parserfunction-warning": "Tällä sivulla on liian monta hitaiden laajennusfunktioiden kutsua.\nKutsuja pitäisi olla alle $2 {{PLURAL:$2|kappale|kappaletta}}, mutta nyt niitä on $1 {{PLURAL:$1|kappale|kappaletta}}.",
"expensive-parserfunction-category": "Sivut, joissa on liian monta vaativaa jäsenninfunktiota",
"post-expand-template-inclusion-warning": "'''Varoitus:''' Sisällytettyjen mallineiden koko on liian suuri.\nJoitakin mallineita ei ole sisällytetty.",
"right-protect": "Muuttaa suojaustasoja ja muokata tarttuvasti suojattuja sivuja",
"right-editprotected": "Muokata sivuja, jotka on suojattu tasolle \"{{int:protect-level-sysop}}\"",
"right-editsemiprotected": "Muokata sivuja, jotka on suojattu tasolle \"{{int:protect-level-autoconfirmed}}\"",
+ "right-editcontentmodel": "Muokata sivun sisältömallia (content model)",
"right-editinterface": "Muokata käyttöliittymätekstejä",
"right-editusercssjs": "Muokata toisten käyttäjien CSS- ja JavaScript-tiedostoja",
"right-editusercss": "Muokata toisten käyttäjien CSS-tiedostoja",
"action-viewmywatchlist": "tarkastella tarkkailulistaasi",
"action-viewmyprivateinfo": "katsoa omia yksityisiä tietojasi",
"action-editmyprivateinfo": "muokata omia yksityisiä tietojasi",
+ "action-editcontentmodel": "muokata sivun sisältömallia",
"nchanges": "$1 {{PLURAL:$1|muutos|muutosta}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|viimeisen käynnin jälkeen}}",
"enhancedrc-history": "historia",
"specialpages-group-wiki": "Tiedot ja työkalut",
"specialpages-group-redirects": "Ohjaavat toimintosivut",
"specialpages-group-spam": "Roskalinkkien (spam) työkalut",
+ "specialpages-group-developer": "Kehittäjien työkalut",
"blankpage": "Tyhjä sivu",
"intentionallyblankpage": "Tämä sivu on tarkoituksellisesti tyhjä.",
"external_image_whitelist": " #Älä muuta tätä riviä lainkaan.<pre>\n#Laita säännöllisten lausekkeiden palaset (vain osa, joka menee //-merkkien väliin) alle\n#Niitä verrataan ulkoisten (suoralinkitettyjen) kuvien URLeihin\n#Ne jotka sopivat, näytetään kuvina, muutoin kuviin näytetään vain linkit\n#Rivit, jotka alkavat #-merkillä ovat kommentteja\n#Tämä on riippumaton kirjainkoosta\n\n#Laita kaikki säännöllisten lausekkeiden palaset tämän rivit yläpuolelle. Älä muuta tätä riviä lainkaan</pre>",
"expand_templates_generate_xml": "Näytä XML-jäsennyspuu",
"expand_templates_generate_rawhtml": "Näytä raaka HTML",
"expand_templates_preview": "Esikatselu",
+ "expand_templates_preview_fail_html": "<em>Koska sivustolla {{SITENAME}} on käytössä puhdas HTML-koodi ja koska istunnon tiedot ovat kadonneet, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi.</em>\n\n<strong>Jos olet oikealla asialla, yritä uudestaan.</strong>\nJos esikatselu ei vieläkään toimi, kokeile [[Special:UserLogout|kirjautua ulos]] ja sen jälkeen kirjaudu uudestaan sisään.",
+ "expand_templates_preview_fail_html_anon": "<em>Koska sivustolla {{SITENAME}} on käytössä puhdas HTML-koodi ja koska et ole kirjautunut sisään, esikatselu on piilotettu JavaScript-hyökkäyksien torjumiseksi.</em>\n\n<strong>Jos olet oikealla asialla, [[Special:UserLogin|kirjaudu sisään]] ja yritä uudestaan.</strong>",
"pagelanguage": "Sivun kielen valinta",
"pagelang-name": "Sivu",
"pagelang-language": "Kieli",
"log-name-pagelang": "Kielenvaihtoloki",
"log-description-pagelang": "Tämä on loki, johon merkitään muutokset sivujen kieliasetuksissa.",
"logentry-pagelang-pagelang": "$1 {{GENDER:$2|muutti}} sivun kieltä sivulla $3 kielestä $4 kieleksi $5.",
- "default-skin-not-found": "Hupsista! Oletuksena tuleva ulkoasu sinun wikillesi, joka on määritelty koodissa <code dir=\"ltr\">$wgDefaultSkin</code> muotoon <code>$1</code>, ei ole saatavilla.\n\n\n<strong>Alla on ohjeita englanniksi:</strong>\n\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki: \n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: :* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code>skins/</code> directory of your MediaWiki installation. \n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n\n; If you have just upgraded MediaWiki: \n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>: \n: Double-check the skin names for typos.",
- "default-skin-not-found-no-skins": "Hupsista! Oletusulkoasua sinun wikillesi ei ole saatavilla. Se on määritelty ulkoasuksi <code>$1</code> kohteessa <code>$wgDefaultSkin</code>.\n\nSinulla ei ole lainkaan asennettuja ulkoasuja. (You have no installed skins.)\n\nAlla on lisäohjeita englanniksi:\n\n\n; If you have just installed or upgraded MediaWiki: \n\n: You probably installed from git, or directly from the source code using some other method. This is expected. MediaWiki 1.24 and newer doesn't include any skins in the main repository. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: \n\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n\n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code dir=\"ltr\">skins/</code> directory of your MediaWiki installation. \n\n: Doing this should not interfere with your git repository if you're a MediaWiki developer. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable skins and choose the default.",
+ "default-skin-not-found": "Hupsista! Oletuksena tuleva ulkoasu sinun wikillesi, joka on määritelty koodissa <code dir=\"ltr\">$wgDefaultSkin</code> muotoon <code>$1</code>, ei ole saatavilla.\n\n\n<strong>Alla on ohjeita englanniksi:</strong>\n\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki: \n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: :* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n:* Downloading individual skin tarballs from [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code>skins/</code> directory of your MediaWiki installation. \n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n\n; If you have just upgraded MediaWiki: \n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>: \n: Double-check the skin names for typos.",
+ "default-skin-not-found-no-skins": "Hupsista! Oletusulkoasua sinun wikillesi ei ole saatavilla. Se on määritelty ulkoasuksi <code>$1</code> kohteessa <code>$wgDefaultSkin</code>.\n\nSinulla ei ole lainkaan asennettuja ulkoasuja. (You have no installed skins.)\n\nAlla on lisäohjeita englanniksi:\n\n\n; If you have just installed or upgraded MediaWiki: \n\n: You probably installed from git, or directly from the source code using some other method. This is expected. MediaWiki 1.24 and newer doesn't include any skins in the main repository. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: \n\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n\n:* Downloading individual skin tarballs from [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n\n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code dir=\"ltr\">skins/</code> directory of your MediaWiki installation. \n\n: Doing this should not interfere with your git repository if you're a MediaWiki developer. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable skins and choose the default.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (käytössä)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ei käytössä''')",
"mediastatistics": "Median tilastotiedot",
"SnowedEarth",
"Orikrin1998",
"Automatik",
- "Elodark"
+ "Elodark",
+ "Macofe"
]
},
"tog-underline": "Souligner les liens :",
"tog-shownumberswatching": "Afficher le nombre d'utilisateurs qui suivent la page",
"tog-oldsig": "Signature existante :",
"tog-fancysig": "Traiter la signature comme du wikitexte (sans lien automatique)",
- "tog-uselivepreview": "Utiliser l’aperçu rapide (expérimental)",
+ "tog-uselivepreview": "Utiliser l’aperçu rapide",
"tog-forceeditsummary": "M'avertir lorsque je n'ai pas spécifié de résumé de modification",
"tog-watchlisthideown": "Masquer mes propres modifications dans la liste de suivi",
"tog-watchlisthidebots": "Masquer les modifications faites par des robots dans la liste de suivi",
"anoneditwarning": "<strong>Attention :</strong> Vous n’êtes pas connecté. Votre adresse IP sera visible de tout le monde si vous faites des modifications. Si vous <strong>[$1 vous connectez]</strong> ou <strong>[$2 créez un compte]</strong>, vos modifications seront attribuées à votre nom d’utilisateur, entre autres avantages.",
"anonpreviewwarning": "''Vous n’êtes pas identifié(e). Sauvegarder enregistrera votre adresse IP dans l’historique des modifications de la page.''",
"missingsummary": "'''Rappel :''' vous n'avez pas encore fourni le résumé de votre modification.\nSi vous cliquez de nouveau sur le bouton « {{int:savearticle}} », la publication sera faite sans nouvel avertissement.",
+ "selfredirect": "<strong>Attention :</strong> Vous êtes en train de créer une redirection vers le même article.\nSi vous cliquez de nouveau sur « {{int:savearticle}} », la redirection sera créée.",
"missingcommenttext": "Veuillez entrer un commentaire ci-dessous.",
"missingcommentheader": "'''Rappel :''' vous n'avez pas fourni de sujet ou de titre à ce commentaire.\nSi vous cliquez de nouveau sur « {{int:Savearticle}} », votre modification sera enregistrée sans titre.",
"summary-preview": "Aperçu du résumé :",
"wlheader-enotif": "Tha brathan-naidheachd air a' phost-d an comas.",
"wlheader-showupdated": "Tha clò <strong>trom</strong> air duilleagan a chaidh atharrachadh on turas mu dheireadh a thadhail thu orra.",
"wlnote": "Chì thu gu h-ìosal {{PLURAL:$1|a' $1 mhùthadh|an $1 mhùthadh|na $1 mùthaidhean|am $1 mùthadh}} mu dheireadh san {{PLURAL:$2|$2 uair a thìde|$2 uair a thìde|$2 uairean a thìde|$2 uair a thìde}} mu dheireadh, mar a bha e $3, $4.",
- "wlshowlast": "Seall na $1 uairean a thìde mu dheireadh $2 làithean mu dheireadh",
+ "wlshowlast": "Seall na $1 uairean a thìde mu dheireadh $2 làithean mu dheireadh $3",
"watchlist-options": "Roghainnean mo chlàir-faire",
"watching": "'Ga chur air a' chlàr-fhaire...",
"unwatching": "A' toirt far a' chlàir-fhaire...",
"exif-gpsdifferential": "Ceartachadh diofarail GPS",
"exif-coordinate-format": "$1° $2′ $3″ $4",
"exif-jpegfilecomment": "Beachd faidhle JPEG",
- "exif-keywords": "Facalan-luirg",
+ "exif-keywords": "Faclan-luirg",
"exif-worldregioncreated": "An roinn-dùthcha san deach an dealbh a thogail",
"exif-countrycreated": "An dùthaich san deach an dealbh a thogail",
"exif-countrycodecreated": "Còd na dùthcha san deach an dealbh a thogail",
"tog-shownumberswatching": "Mostrar o número de usuarios que están a vixiar",
"tog-oldsig": "Sinatura actual:",
"tog-fancysig": "Tratar a sinatura como se fose texto wiki (sen ligazón automática)",
- "tog-uselivepreview": "Usar a vista previa en tempo real (experimental)",
+ "tog-uselivepreview": "Usar a vista previa en tempo real",
"tog-forceeditsummary": "Avisádeme cando o campo resumo estea baleiro",
"tog-watchlisthideown": "Agochar as edicións propias na lista de vixilancia",
"tog-watchlisthidebots": "Agochar as edicións dos bots na lista de vixilancia",
"anoneditwarning": "<strong>Aviso:</strong> Non accedeu ao sistema. O seu enderezo IP será rexistado no histórico de edicións desta páxina. Se <strong>[$1 accede ao sistema]</strong> ou <strong>[$2 crea unha conta]</strong>, as súas edicións serán rexistadas co seu nome de usuario, ademais doutros beneficios.",
"anonpreviewwarning": "''Non accedeu ao sistema. Se garda a páxina, o seu enderezo IP quedará rexistrado no historial de edicións.''",
"missingsummary": "'''Aviso:''' Esqueceu incluír o texto do campo resumo.\nSe preme en \"{{int:savearticle}}\" a súa edición gardarase sen ningunha descrición da edición.",
+ "selfredirect": "<strong>Atención:</strong> Está a crear unha redireción cara o mesmo artigo. Se preme \"{{int:savearticle}}\" de novo, crearase a redireción.",
"missingcommenttext": "Por favor, escriba un comentario a continuación.",
"missingcommentheader": "'''Aviso:''' Non escribiu ningún texto no asunto/título deste comentario.\nSe preme sobre \"{{int:savearticle}}\", a súa edición gardarase sen el.",
"summary-preview": "Vista previa do resumo:",
"tog-shownumberswatching": "הצגת מספר המשתמשים העוקבים",
"tog-oldsig": "החתימה הנוכחית:",
"tog-fancysig": "התייחסות לחתימה כקוד ויקי (ללא קישור אוטומטי)",
- "tog-uselivepreview": "שימוש בתצוגה מקדימה מהירה (ניסיוני)",
+ "tog-uselivepreview": "שימוש בתצוגה מקדימה מהירה",
"tog-forceeditsummary": "הצגת אזהרה בעת הכנסת תקציר עריכה ריק",
"tog-watchlisthideown": "הסתרת העריכות שלי ברשימת המעקב",
"tog-watchlisthidebots": "הסתרת עריכות של בוטים ברשימת המעקב",
"passwordreset-capture-help": "אם תסמנו תיבה זו, הדואר האלקטרוני (יחד עם הסיסמה הזמנית) יוצג לכם במקביל לשליחתו למשתמש.",
"passwordreset-email": "כתובת דוא\"ל:",
"passwordreset-emailtitle": "פרטי חשבון ב{{grammar:תחילית|{{SITENAME}}}}",
- "passwordreset-emailtext-ip": "מישהו (ככל הנראה אתם, מכתובת ה־IP מספר $1) ביקש איפוס של\nהסיסמה שלכם ב{{grammar:תחילית|{{SITENAME}}}} ($4). {{PLURAL:$3|חשבון המשתמש הבא|חשבונות המשתמש הבאים}}\nשייכים לכתובת הדואר האלקטרוני הזו:\n\n$2\n\n{{PLURAL:$3|סיסמה זמנית זו|סיסמאות זמניות אלה}} יפקעו תוך {{PLURAL:$5|יום|יומיים|$5 ימים}}.\nעליכם להיכנס ולבחור סיסמה חדשה עכשיו. אם מישהו אחר ביצע בקשה זו, או שנזכרתם בסיסמתכם\nהמקורית ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמה\nהישנה.",
- "passwordreset-emailtext-user": "המשתמש $1 ב{{GRAMMAR:תחילית|{{SITENAME}}}} ביקש איפוס של הסיסמה שלכם ב{{GRAMMAR:תחילית|{{SITENAME}}}}\n($4). {{PLURAL:$3|חשבון המשתמש הבא|חשבונות המשתמש הבאים}} שייכים לכתובת הדואר האלקטרוני הזו:\n\n$2\n\n{{PLURAL:$3|סיסמה זמנית זו|סיסמאות זמניות אלה}} יפקעו תוך {{PLURAL:$5|יום|יומיים|$5 ימים}}.\nעליכם להיכנס ולבחור סיסמה חדשה עכשיו. אם מישהו אחר ביצע בקשה זו, או שנזכרתם בסיסמתכם\nהמקורית ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמה\nהישנה.",
+ "passwordreset-emailtext-ip": "מישהו (ככל הנראה אתם, מכתובת ה־IP מספר $1) ביקש איפוס של\nהסיסמה שלכם ב{{grammar:תחילית|{{SITENAME}}}} ($4). {{PLURAL:$3|חשבון המשתמש הבא|חשבונות המשתמש הבאים}}\nשייכים לכתובת הדואר האלקטרוני הזו:\n\n$2\n\n{{PLURAL:$3|סיסמה זמנית זו תפקע|סיסמאות זמניות אלה יפקעו}} תוך {{PLURAL:$5|יום|יומיים|$5 ימים}}.\nעליכם להיכנס ולבחור סיסמה חדשה עכשיו. אם מישהו אחר ביצע בקשה זו, או שנזכרתם בסיסמתכם\nהמקורית ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמה\nהישנה.",
+ "passwordreset-emailtext-user": "ה{{GENDER:$1|משתמש|משתמשת}} $1 ב{{GRAMMAR:תחילית|{{SITENAME}}}} {{GENDER:$1|ביקש|ביקשה}} איפוס של הסיסמה שלכם ב{{GRAMMAR:תחילית|{{SITENAME}}}}\n($4). {{PLURAL:$3|חשבון המשתמש הבא שייך|חשבונות המשתמש הבאים שייכים}} לכתובת הדואר האלקטרוני הזו:\n\n$2\n\n{{PLURAL:$3|סיסמה זמנית זו תפקע|סיסמאות זמניות אלה יפקעו}} תוך {{PLURAL:$5|יום|יומיים|$5 ימים}}.\nעליכם להיכנס ולבחור סיסמה חדשה עכשיו. אם מישהו אחר ביצע בקשה זו, או שנזכרתם בסיסמתכם\nהמקורית ואינכם רוצים עוד לשנות אותה, באפשרותכם להתעלם מהודעה זו ולהמשיך להשתמש בסיסמה\nהישנה.",
"passwordreset-emailelement": "שם משתמש: $1\nסיסמה זמנית: $2",
"passwordreset-emailsent": "נשלח דואר אלקטרוני לאיפוס הסיסמה.",
"passwordreset-emailsent-capture": "נשלח דואר אלקטרוני לאיפוס הסיסמה, והוא מוצג להלן.",
"anoneditwarning": "<strong>אזהרה:</strong> אינכם מחוברים לחשבון. כתובת ה־IP שלכם תוצג בפומבי אם תבצעו עריכות כלשהן. אם <strong>[$1 תיכנסו לחשבון]</strong> או <strong>[$2 תיצרו חשבון]</strong>, העריכות שלכם תיוחסנה לשם המשתמש שלכם ותקבלו גם יתרונות אחרים.",
"anonpreviewwarning": "''אינכם מחוברים לחשבון. שמירה תגרום לכתובת ה־IP שלכם להירשם בהיסטוריית העריכות של הדף.''",
"missingsummary": "<strong>תזכורת:</strong> לא הזנת תקציר עריכה.\nלחיצה חוזרת על הכפתור \"{{int:savearticle}}\" תגרום לעריכה שלך להישמר בלעדיו.",
+ "selfredirect": "<strong>אזהרה:</strong> ניסית ליצור הפניה מדף זה לעצמו.\nלחיצה חוזרת על הכפתור \"{{int:savearticle}}\" תגרום להפניה להיווצר.",
"missingcommenttext": "יש להקליד את ההודעה למטה.",
"missingcommentheader": "<strong>תזכורת:</strong> לא הזנת נושא/כותרת להודעה זו.\nלחיצה חוזרת על הכפתור \"{{int:savearticle}}\" תגרום לעריכה שלך להישמר ללא נושא/כותרת.",
"summary-preview": "תצוגה מקדימה של התקציר:",
"userinvalidcssjstitle": "'''אזהרה:''' העיצוב \"$1\" אינו קיים.\nדפי .css ו־.js מותאמים אישית משתמשים בכותרת עם אותיות קטנות – למשל, {{ns:user}}:דוגמה/vector.css ולא {{ns:user}}:דוגמה/Vector.css.",
"updated": "(מעודכן)",
"note": "'''הערה:'''",
- "previewnote": "'''זכרו שזו רק תצוגה מקדימה.'''\nהשינויים שלכם טרם נשמרו!",
+ "previewnote": "<strong>זִכרו שזו רק תצוגה מקדימה.</strong>\nהשינויים שלכם טרם נשמרו!",
"continue-editing": "מעבר לאזור העריכה",
"previewconflict": "תצוגה מקדימה זו מציגה כיצד ייראה הטקסט בחלון העריכה העליון, אם תבחרו לשמור אותו.",
"session_fail_preview": "'''לא ניתן לבצע את עריכתכם עקב אובדן מידע הכניסה.'''\nאנא נסו שוב.\nאם זה לא עוזר, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית.",
"protectedpagetext": "Ova stranica je zaključana da bi se onemogućile izmjene.",
"viewsourcetext": "Možete pogledati i kopirati izvorni sadržaj ove stranice:",
"viewyourtext": "Možete vidjeti i kopirati tekst '''vaših uređivanja''' na ovoj stranici:",
- "protectedinterface": "Ova stranica je zaštićena od izmjena jer sadrži tekst MediaWiki softvera.\nAKo želite prevesti neprevedenu poruku ili popraviti prijevod neke druge poruke za sve MediaWiki wikije, posjetite [//translatewiki.net/ translatewiki.net], projekt za lokalizaciju MediaWiki softvera.",
+ "protectedinterface": "Ova stranica je zaštićena od izmjena jer sadrži tekst MediaWiki softvera.\nAko želite prevesti neprevedenu poruku ili popraviti prijevod neke druge poruke za sve MediaWiki wikije, posjetite [//translatewiki.net/ translatewiki.net], projekt za lokalizaciju MediaWiki softvera.",
"editinginterface": "'''Upozorenje:''' Uređujete stranicu koja se rabi za prikaz teksta u sučelju softvera. Promjene učinjene na ovoj stranici će se odraziti na izgled korisničkog sučelja kod drugih suradnika. Za prijevod, razmotrite uporabu [//translatewiki.net/wiki/Main_Page?setlang=hr translatewiki.net], projekta lokalizacije MedijeWiki.",
+ "translateinterface": "Za dodavanje ili promjenu prijevoda za sve wikije koristite [//translatewiki.net/ translatewiki.net], projekt za lokalizaciju MediaWikija.",
"cascadeprotected": "Ova je stranica zaključana za uređivanja jer je uključena u {{PLURAL:$1|slijedeću stranicu|slijedeće stranice}}, koje su zaštićene \"prenosivom zaštitom\":\n$2",
"namespaceprotected": "Ne možete uređivati stranice u imenskom prostoru '''$1'''.",
"customcssprotected": "Ne možete uređivati ovu CSS stranicu zato što ona sadrži osobne postavke drugog suradnika.",
"revdelete-selected-file": "{{PLURAL:$1|Označena inačica|Označene inačice}} datoteke [[:$2]]:",
"logdelete-selected": "{{PLURAL:$1|Odabrani zapis u evidenciji|Odabrani zapisi u evidenciji}}:",
"revdelete-text-text": "Izbrisane izmjene će i dalje biti vidljive u povijesti stranice, ali dijelovi sadržaja neće biti vidljivi javno.",
- "logdelete-text": "Izbrisane izmjene i dalje će biti vidljive u zapisnicima, ali dijelovi njihova sadržaja biti će nedostupni za javnost.",
+ "logdelete-text": "Izbrisane izmjene i dalje će biti vidljive u evidencijama, ali dijelovi njihova sadržaja biti će nedostupni za javnost.",
"revdelete-text-others": "Ostali administratori na projektu {{SITENAME}} će moći vidjeti i vratiti izbrisani sadržaj na isti način, osim ako nisu postavljena dodatna ograničenja.",
"revdelete-confirm": "Molimo potvrdite da namjeravate ovo učiniti, da razumijete posljedice i da to činite u skladu s [[{{MediaWiki:Policy-url}}|pravilima]].",
"revdelete-suppress-text": "Sklanjanje uređivanja treba raditi '''iznimno''' u slijedećih par slučajeva:\n* Privatne informacije neprilične javnom mediju tipa\n*: ''kućna adresa i broj telefona, JMBG ili OIB, itd.''",
"download": "skidanje",
"unwatchedpages": "Nepraćene stranice",
"listredirects": "Popis preusmjeravanja",
+ "listduplicatedfiles": "Popis kopija datoteka",
+ "listduplicatedfiles-summary": "Ovo je popis datoteka kojima je zadnja inačica kopija zadnje inačice druge datoteke. Na popisu su samo lokalno postavljene datoteke.",
"unusedtemplates": "Nekorišteni predlošci",
"unusedtemplatestext": "Slijedi popis svih stranica imenskog prostora {{ns:template}}, koje nisu umetnute na drugim stranicama. Pripazite da prije brisanja provjerite druge poveznice koje vode na te predloške.",
"unusedtemplateswlh": "druge poveznice",
"autoblocker": "Automatski ste blokirani jer je Vašu IP adresu nedavno koristio \"[[User:$1|$1]]\" koji je blokiran zbog: \"$2\".",
"blocklogpage": "Evidencija blokiranja",
"blocklog-showlog": "Ovaj suradnik je ranije blokiran.\nEvidencija blokiranja je prikazan ispod kao napomena:",
- "blocklog-showsuppresslog": "Ovaj suradnik je ranije blokiran i skriven.\nZapisnik skrivanja je prikazan ispod kao napomena:",
+ "blocklog-showsuppresslog": "Ovaj suradnik je ranije blokiran i skriven.\nEvidencija skrivanja je prikazana ispod kao napomena:",
"blocklogentry": "Blokiran je \"[[$1]]\" na rok $2 $3.",
"reblock-logentry": "promijenjene postavke blokiranja za [[$1]] na rok od $2 $3",
"blocklogtext": "Ovo je evidencija blokiranja i deblokiranja.\nNa popisu nema automatski blokiranih IP adresa.\nZa popis trenutačnih zabrana i blokiranja vidi [[Special:BlockList|popis blokiranja]].",
"pageinfo-category-pages": "Broj stranica",
"pageinfo-category-subcats": "Broj podkategorija",
"pageinfo-category-files": "Broj datoteka",
- "markaspatrolleddiff": "Označi za pregledano",
+ "markaspatrolleddiff": "Označi pregledanim",
"markaspatrolledtext": "Označi ovaj članak pregledanim",
"markedaspatrolled": "Pregledano",
"markedaspatrolledtext": "Odabrana promjena [[:$1]] označena je pregledanom.",
"expand_templates_remove_comments": "Ukloni komentare",
"expand_templates_remove_nowiki": "Ukloni <nowiki> tagove u rezultatima.",
"expand_templates_generate_xml": "Prikaži XML stablo",
- "expand_templates_preview": "Vidi kako će izgledati"
+ "expand_templates_preview": "Vidi kako će izgledati",
+ "mediastatistics": "Statistika datoteka",
+ "mediastatistics-summary": "Slijede statistike postavljenih datoteka koje pokazuju zadnju inačicu datoteke. Starije ili izbrisane inačice nisu prikazane."
}
"tog-shownumberswatching": "A lapot figyelő szerkesztők számának megjelenítése",
"tog-oldsig": "A jelenlegi aláírás:",
"tog-fancysig": "Az aláírás wikiszöveg (nem lesz automatikusan hivatkozásba rakva)",
- "tog-uselivepreview": "Élő előnézet használata (kísérleti)",
+ "tog-uselivepreview": "Élő előnézet használata",
"tog-forceeditsummary": "Figyelmeztessen, ha nem adok meg szerkesztési összefoglalót",
"tog-watchlisthideown": "Saját szerkesztések elrejtése",
"tog-watchlisthidebots": "Robotok szerkesztéseinek elrejtése",
"viewsourcetext": "Megtekintheted és másolhatod a lap forrását:",
"viewyourtext": "Megtekintheted és kimásolhatod a '''saját szerkesztéseidet''' az alábbi lapra:",
"protectedinterface": "Ez a lap a szoftver felületéhez szolgáltat szöveget, és a visszaélések elkerülése miatt le van zárva.",
- "editinginterface": "'''Vigyázat:''' egy olyan lapot szerkesztesz, ami a MediaWiki szoftver felületéhez tartozik. A lap megváltoztatása hatással lesz a kinézetre, ahogy más szerkesztők látják a lapot. Fordításra inkább használd a MediaWiki fordítására indított kezdeményezést, a [//translatewiki.net/wiki/Main_Page?setlang=hu translatewiki.net-et].",
+ "editinginterface": "<strong>Vigyázat:</strong> egy olyan lapot szerkesztesz, ami a MediaWiki szoftver felületéhez tartozik. A lap megváltoztatása hatással lesz a kinézetre, ahogy más szerkesztők látják a lapot.",
"cascadeprotected": "Ez a lap szerkesztés elleni védelemmel lett ellátva, mert a következő {{PLURAL:$1|lapon|lapokon}} be van kapcsolva a „kaszkádolt” védelem:\n$2",
"namespaceprotected": "Nincs jogosultságod a(z) '''$1''' névtérben található lapok szerkesztésére.",
"customcssprotected": "Nem szerkesztheted ezt a CSS-lapot, mert egy másik felhasználó személyes beállításait tartalmazza.",
"wlheader-enotif": "Az e-mailen keresztül történő értesítés engedélyezve.",
"wlheader-showupdated": "Azok a lapok, amelyek megváltoztak, mióta utoljára megnézted őket, '''vastagítva''' láthatók.",
"wlnote": "Alább {{PLURAL:$1|az utolsó változás|az utolsó <strong>$1</strong> változás}} látható az elmúlt {{PLURAL:$2|órában|<strong>$2</strong> órában}}, $3 $4-kor.",
- "wlshowlast": "Az elmúlt $1 órában | $2 napon | történt változtatások legyenek láthatóak",
+ "wlshowlast": "Az elmúlt $1 órában | $2 napon történt változtatások legyenek láthatóak",
"watchlist-options": "A figyelőlista beállításai",
"watching": "Figyelés...",
"unwatching": "Figyelés befejezése...",
"exbeforeblank": "az eltávolítás előtti tartalom: „$1”",
"delete-confirm": "$1 törlése",
"delete-legend": "Törlés",
- "historywarning": "'''Figyelem:''' a lapnak, amit törölni készülsz, körülbelül $1 változattal rendelkező laptörténete van:",
+ "historywarning": "<strong>Figyelem:</strong> a lapnak, amit törölni készülsz, $1 változattal rendelkező laptörténete van:",
"confirmdeletetext": "Egy lapot vagy fájlt készülsz törölni a teljes laptörténetével együtt.\nKérjük, erősítsd meg, hogy valóban ezt szeretnéd tenni, átlátod a következményeit, és hogy a műveletet a [[{{MediaWiki:Policy-url}}|törlési irányelvekkel]] összhangban végzed.",
"actioncomplete": "Művelet végrehajtva",
"actionfailed": "A művelet nem sikerült",
"autoblockid": "$1. autoblokk",
"block": "Felhasználó blokkolása",
"unblock": "Felhasználó blokkolásának feloldása",
- "blockip": "Blokkolás",
+ "blockip": "{{GENDER:$1|Felhasználó}} blokkolása",
"blockip-legend": "Felhasználó blokkolása",
"blockiptext": "Az alábbi űrlap segítségével megvonhatod egy szerkesztő vagy IP-cím szerkesztési jogait.\nÜgyelj rá, hogy az intézkedésed mindig legyen tekintettel a vonatkozó [[{{MediaWiki:Policy-url}}|irányelvekre]].\nAdd meg a blokkolás okát is (például idézd a blokkolandó személy által vandalizált lapokat).",
"ipaddressorusername": "IP-cím vagy felhasználói név",
"right-protect": "Agsukat kadagiti agpang ti salaknib ken agurnos kadagiti nasalakniban ti sariap a panid",
"right-editprotected": "Agurnos kadagiti panid a nasalakniban a kas \"{{int:protect-level-sysop}}\"",
"right-editsemiprotected": "Agurnos kadagiti panid a nasalakniban a kas \"{{int:protect-level-autoconfirmed}}\"",
+ "right-editcontentmodel": "Urnosen ti modelo ti linaon iti panid",
"right-editinterface": "Agurnos iti interface ti agar-aramat",
"right-editusercssjs": "Agurnos kadagiti papales ti CSS ken JavaScript dagiti sabali nga agar-aramat",
"right-editusercss": "Agurnos kadagiti papeles ti CSS dagiti sabali nga agar-aramat",
"action-viewmywatchlist": "agkita iti bukodmo a listaan ti bambantayan",
"action-viewmyprivateinfo": "agkita iti bukodmo a pribado a pakaammo",
"action-editmyprivateinfo": "agurnos iti bukodmo a pribado a pakaammo",
+ "action-editcontentmodel": "urnosen ti modelo ti linaon iti panid",
"nchanges": "$1 {{PLURAL:$1|sinukatan|dagiti sinukatan}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|manipud ti naudi a panagsarungkar}}",
"enhancedrc-history": "pakasaritaan",
"specialpages-group-wiki": "Datos ken ramramit",
"specialpages-group-redirects": "Panangibaw-ing kadagiti espesial a panid",
"specialpages-group-spam": "Ramramit ti spam",
+ "specialpages-group-developer": "Ramramit dagiti agraramid",
"blankpage": "Blanko a panid",
"intentionallyblankpage": "Daytoy a panid ket naigagara a blanko.",
"external_image_whitelist": " #Baybayan daytoy a linia a kastoy<pre>\n#Ikabil ti \"regular expression fragments\" (idiay laeng paset nga ikabil ti tengnga ti //) dita baba\n#Dagitoy ipada na ti URLs ti ruar (ti napudot a naikapet) imahen \n#Dagiti agpada ket agparang nga imahen, ket no saan ti panilpo ti imahen ti agparang laeng\n#Dagiti linia nga umuna iti # ket maipabalin a komentario\n#Daytoy ket \"sensetibo ti kadakkel ti letra\"\n\n#Ikabil dagita \"regex fragment\" ti ngato daytoy a linia. Baybay-an a kastoy daytoy a linia</pre>",
"Taxandru",
"C.R.",
"Elitre",
- "Laurentius"
+ "Laurentius",
+ "Macofe"
]
},
"tog-underline": "Sottolinea i collegamenti:",
"tog-shownumberswatching": "Mostra il numero di utenti che hanno la pagina in osservazione",
"tog-oldsig": "Firma attuale:",
"tog-fancysig": "Gestisci la firma come wikitesto (senza collegamento automatico)",
- "tog-uselivepreview": "Abilita la funzione ''Live preview'' (anteprima in diretta - sperimentale)",
+ "tog-uselivepreview": "Abilita la funzione ''Live preview'' (anteprima in diretta)",
"tog-forceeditsummary": "Chiedi conferma se il campo oggetto è vuoto",
"tog-watchlisthideown": "Nascondi le mie modifiche negli osservati speciali",
"tog-watchlisthidebots": "Nascondi le modifiche dei bot negli osservati speciali",
"anoneditwarning": "<strong>Attenzione:</strong> Accesso non effettuato. Se effettuerai delle modifiche il tuo indirizzo IP sarà visibile pubblicamente. Se <strong>[$1 accedi]</strong> o <strong>[$2 crei un'utenza]</strong>, le tue modifiche saranno attribuite al tuo nome utente, insieme ad altri benefici.",
"anonpreviewwarning": "''Non è stato eseguito il login. Salvando la pagina, il proprio indirizzo IP sarà registrato nella cronologia.''",
"missingsummary": "'''Attenzione:''' non è stato specificato l'oggetto di questa modifica. Premendo di nuovo \"{{int:savearticle}}\" la modifica verrà salvata con l'oggetto vuoto.",
+ "selfredirect": "<strong>Attenzione:</strong> stai creando un redirect alla medesima voce.\nSe fai clic nuovamente su \"{{int:savearticle}}\", il redirect sarà creato.",
"missingcommenttext": "Inserire un commento qui sotto.",
"missingcommentheader": "'''Attenzione:''' non è stata specificato l'oggetto/l'intestazione di questo commento. Premendo di nuovo \"{{int:savearticle}}\" la modifica verrà salvata senza intestazione.",
"summary-preview": "Anteprima dell'oggetto:",
"nonunicodebrowser": "<strong>警告: ご使用中のブラウザーは Unicode に未対応です。</strong>\n安全にページを編集する回避策を表示しています: 編集ボックス内の非 ASCII 文字を 16 進数コードで表現しています。",
"editingold": "<strong>警告: このページの古い版を編集しています。</strong>\n保存すると、この版以降になされた変更がすべて失われます。",
"yourdiff": "差分",
- "copyrightwarning": "{{SITENAME}}ã\81¸ã\81®æ\8a\95稿ã\81¯ã\80\81ã\81\99ã\81¹ã\81¦$2 (詳細ã\81¯$1ã\82\92å\8f\82ç\85§) ã\81®ã\82\82ã\81¨ã\81§å\85¬é\96\8bã\81\97ã\81\9fã\81¨è¦\8bã\81ªã\81\95ã\82\8cã\82\8bã\81\93ã\81¨ã\81«ã\81\94注æ\84\8fã\81\8fã\81 ã\81\95ã\81\84ã\80\82\nã\81\82ã\81ªã\81\9fã\81\8cæ\8a\95稿ã\81\97ã\81\9fã\82\82ã\81®ã\82\92ã\80\81ä»\96人ã\81«ã\82\88ã\81£ã\81¦é\81 æ\85®ã\81ªã\81\8fç·¨é\9b\86ã\81\97ã\80\81ã\81\9dã\82\8cã\82\92è\87ªç\94±ã\81«é\85\8då¸\83ã\81\99ã\82\8bã\81®ã\82\92æ\9c\9bã\81¾ã\81ªã\81\84å ´å\90\88ã\81¯ã\80\81ã\81\93ã\81\93ã\81«ã\81¯æ\8a\95稿ã\81\97ã\81ªã\81\84ã\81§ã\81\8fã\81 ã\81\95ã\81\84ã\80\82<br />\nã\81¾ã\81\9fã\80\81æ\8a\95稿ã\81\99ã\82\8bã\81®ã\81¯ã\80\81ã\81\82ã\81ªã\81\9fã\81\8cæ\9b¸ã\81\84ã\81\9fã\82\82ã\81®ã\81\8bã\80\81ã\83\91ã\83\96ã\83ªã\83\83ã\82¯ ã\83\89ã\83¡ã\82¤ã\83³ã\81¾ã\81\9fã\81¯ã\81\9dã\82\8cã\81«é¡\9eã\81\99ã\82\8bã\83\95ã\83ªã\83¼ã\81ªè³\87æ\96\99ã\81\8bã\82\89ã\81®è¤\87製ã\81§ã\81\82ã\82\8bã\81\93ã\81¨ã\82\92ç´\84æ\9d\9fã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82\n<strong>è\91\97ä½\9c権ä¿\9dè·ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bä½\9cå\93\81ã\82\92ã\80\81許諾ã\81ªã\81\97ã\81«æ\8a\95稿ã\81\97ã\81ªã\81\84ã\81§ã\81\8fã\81 ã\81\95ã\81\84!</strong>",
- "copyrightwarning2": "{{SITENAME}}へのすべての投稿は、他の利用者によって編集、変更、除去される場合があります。\nあなたの投稿を、他人が遠慮なく編集するのを望まない場合は、ここには投稿しないでください。<br />\nまた、投稿するのは、あなたが書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください (詳細は$1を参照)。\n<strong>著作権保護されている作品を、許諾なしに投稿してはいけません!</strong>",
+ "copyrightwarning": "{{SITENAME}}ã\81¸ã\81®æ\8a\95稿ã\81¯ã\81\99ã\81¹ã\81¦ã\80\81$2 ï¼\88詳細ã\81¯$1ã\82\92å\8f\82ç\85§ï¼\89ã\81®ã\82\82ã\81¨ã\81§å\85¬é\96\8bã\81\97ã\81\9fã\81¨è¦\8bã\81ªã\81\95ã\82\8cã\82\8bã\81\93ã\81¨ã\81«ã\81\94注æ\84\8fã\81\8fã\81 ã\81\95ã\81\84ã\80\82\nè\87ªå\88\86ã\81\8cæ\9b¸ã\81\84ã\81\9fã\82\82ã\81®ã\81\8cä»\96ã\81®äººã\81«å®¹èµ¦ã\81ªã\81\8fç·¨é\9b\86ã\81\95ã\82\8cã\80\81è\87ªç\94±ã\81«é\85\8då¸\83ã\81\95ã\82\8cã\82\8bã\81®ã\82\92æ\9c\9bã\81¾ã\81ªã\81\84å ´å\90\88ã\81¯ã\80\81ã\81\93ã\81\93ã\81«æ\8a\95稿ã\81\97ã\81ªã\81\84ã\81§ã\81\8fã\81 ã\81\95ã\81\84ã\80\82<br />\nã\81¾ã\81\9fã\80\81æ\8a\95稿ã\81\99ã\82\8bã\81®ã\81¯ã\80\81è\87ªå\88\86ã\81§æ\9b¸ã\81\84ã\81\9fã\82\82ã\81®ã\81\8bã\80\81ã\83\91ã\83\96ã\83ªã\83\83ã\82¯ ã\83\89ã\83¡ã\82¤ã\83³ã\81¾ã\81\9fã\81¯ã\81\9dã\82\8cã\81«é¡\9eã\81\99ã\82\8bã\83\95ã\83ªã\83¼ã\81ªè³\87æ\96\99ã\81\8bã\82\89ã\81®è¤\87製ã\81§ã\81\82ã\82\8bã\81\93ã\81¨ã\82\92ç´\84æ\9d\9fã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82\n<strong>è\91\97ä½\9c権ä¿\9dè·ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bä½\9cå\93\81ã\81¯ã\80\81許諾ã\81ªã\81\97ã\81«æ\8a\95稿ã\81\97ã\81ªã\81\84ã\81§ã\81\8fã\81 ã\81\95ã\81\84ï¼\81</strong>",
+ "copyrightwarning2": "{{SITENAME}}への投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。\n自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。<br />\nまた、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は$1を参照)。\n<strong>著作権保護されている作品は、許諾なしに投稿しないでください!</strong>",
"longpageerror": "<strong>エラー: 投稿された文章は {{PLURAL:$1|$1 KB}} の長さがあります。これは投稿できる最大の長さ {{PLURAL:$2|$2 KB}} を超えています。</strong>\nこの編集内容は保存できません。",
"readonlywarning": "<strong>警告: データベースがメンテナンスのためロックされており、現在は編集内容を保存できません。</strong>\n必要であれば文章をコピー&ペーストしてテキストファイルとして保存し、後ほど保存をやり直してください。\n\nデータベースをロックした管理者による説明は以下の通りです: $1",
"protectedpagewarning": "<strong>警告: このページは保護されているため、管理者権限を持つ利用者のみが編集できます。</strong>\n参考として以下に最後の記録を表示します:",
"specialpages-group-wiki": "データとツール",
"specialpages-group-redirects": "転送される特別ページ",
"specialpages-group-spam": "スパム対策ツール",
+ "specialpages-group-developer": "開発者用ツール",
"blankpage": "白紙ページ",
"intentionallyblankpage": "このページは意図的に白紙にされています。",
"external_image_whitelist": " #この行はこのままにしておいてください<pre>\n#この下に正規表現 (//の間に入る記述) を置いてください\n#外部の (ホットリンクされている) 画像の URL と一致するか検査されます\n#一致する場合は画像として、一致しない場合は画像へのリンクとして表示されます\n#行の頭に # を付けるとコメントとして扱われます\n#大文字と小文字は区別されません\n\n#正規表現はすべてこの行の上に置いてください。この行はこのままにしておいてください</pre>",
"tog-shownumberswatching": "მაკონტროლებელ მომხმარებელთა რიცხვის ჩვენება",
"tog-oldsig": "არსებული ხელმოწერა:",
"tog-fancysig": "საკუთარი ვიკიფორმატიანი ხელმოწერა (ავტომატური ბმულის გარეშე)",
- "tog-uselivepreview": "გამოიყენეთ სწრაფი წინასწარი გადახედვა (ექსპერიმენტული)",
+ "tog-uselivepreview": "გამოიყენეთ სწრაფი წინასწარი გადახედვა",
"tog-forceeditsummary": "გამაფრთხილე ცარიელი რედაქტირების რეზიუმეს შემთხვევაში",
"tog-watchlisthideown": "დამალე ჩემი რედაქტირება კონტროლის სიაში",
"tog-watchlisthidebots": "დამალე რობოტის რედაქტირება კონტროლის სიაში",
"permalink": "მუდმივი ბმული",
"print": "ამობეჭდე",
"view": "იხილე",
+ "view-foreign": "იხილეთ $1-ზე",
"edit": "რედაქტირება",
"edit-local": "ლოკალური აღწერის რედაქტირება",
"create": "შექმნა",
"otherlanguages": "სხვა ენებზე",
"redirectedfrom": "(გადმომისამართდა $1-დან)",
"redirectpagesub": "გადამისამართება გვერდზე",
+ "redirectto": "გადამისამართება:",
"lastmodifiedat": "ეს გვერდი ბოლოს განახლდა $2, $1.",
"viewcount": "ეს გვერდი შემოწმდა {{PLURAL:$1|ერთხელ|$1-ჯერ}}.",
"protectedpage": "დაბლოკილი გვერდი",
"viewsourcetext": "თქვენ შეგიძლიათ ნახოთ ამ გვერდის საწყისი ფაილი და მისი ასლი შექმნათ:",
"viewyourtext": "თქვენ შეგიძლიათ იხილოთ და დააკოპიროთ '''თქვენი რედაქტირებების''' საწყისი ტექსტი ამ გვერდზე:",
"protectedinterface": "ეს გვერდი წარმოადგენს ტექსტურ ინტერფეისს პროგრამული უზრუნველყოფისათვის და დაცულია ვანდალიზმის აღკვეთის მიზნით.",
- "editinginterface": "'''á\83§á\83£á\83 á\83\90á\83\93á\83¦á\83\94á\83\91á\83\90:''' á\83\97á\83¥á\83\95á\83\94á\83\9c á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\9dá\83 á\83\9dá\83\91á\83\97 á\83\92á\83\95á\83\94á\83 á\83\93á\83¡, á\83 á\83\9dá\83\9bá\83\94á\83\9aá\83\98á\83ª á\83\9eá\83 á\83\9dá\83\92á\83 á\83\90á\83\9bá\83\98á\83¡ á\83\98á\83\9cá\83¢á\83\94á\83 á\83¤á\83\94á\83\98á\83¡á\83\98á\83¡ á\83¢á\83\94á\83¥á\83¡á\83¢á\83¡ á\83¨á\83\94á\83\98á\83ªá\83\90á\83\95á\83¡. \ná\83\90á\83\9b á\83\92á\83\95á\83\94á\83 á\83\93á\83\96á\83\94 á\83\92á\83\90á\83\9cá\83®á\83\9dá\83 á\83ªá\83\98á\83\94á\83\9aá\83\94á\83\91á\83£á\83\9aá\83\98 á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\90 á\83\92á\83\90á\83\9bá\83\9dá\83\98á\83¬á\83\95á\83\94á\83\95á\83¡ á\83\90á\83\9b á\83\95á\83\98á\83\99á\83\98á\83¡ á\83¡á\83®á\83\95á\83\90 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¡á\83\90á\83\9bá\83£á\83¨á\83\90á\83\9d á\83\98á\83\9cá\83¢á\83\94á\83 á\83¤á\83\94á\83\98á\83¡á\83\98á\83¡ á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\90á\83¡á\83\90á\83ª. \ná\83\98á\83\9bá\83\98á\83¡á\83\90á\83\97á\83\95á\83\98á\83¡, á\83 á\83\9dá\83\9b á\83\93á\83\90á\83\90á\83\9bá\83\90á\83¢á\83\9dá\83\97 á\83\90á\83\9c á\83¨á\83\94á\83ªá\83\95á\83\90á\83\9aá\83\9dá\83\97 á\83\97á\83\90á\83 á\83\92á\83\9bá\83\90á\83\9cá\83\94á\83\91á\83\98 á\83§á\83\95á\83\94á\83\9aá\83\90 á\83\95á\83\98á\83\99á\83\98á\83¨á\83\98 გთხოვთ, გამოიყენოთ მედიავიკის ლოკალიზაციის პროექტი [//translatewiki.net/ translatewiki.net].",
+ "editinginterface": "'''á\83§á\83£á\83 á\83\90á\83\93á\83¦á\83\94á\83\91á\83\90:''' á\83\97á\83¥á\83\95á\83\94á\83\9c á\83\90á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\97 á\83\92á\83\95á\83\94á\83 á\83\93á\83¡, á\83 á\83\9dá\83\9bá\83\94á\83\9aá\83\98á\83ª á\83\9eá\83 á\83\9dá\83\92á\83 á\83\90á\83\9bá\83\98á\83¡ á\83\98á\83\9cá\83¢á\83\94á\83 á\83¤á\83\94á\83\98á\83¡á\83\98á\83¡ á\83¢á\83\94á\83¥á\83¡á\83¢á\83¡ á\83¨á\83\94á\83\98á\83ªá\83\90á\83\95á\83¡. \ná\83\90á\83\9b á\83\92á\83\95á\83\94á\83 á\83\93á\83\96á\83\94 á\83\92á\83\90á\83\9cá\83®á\83\9dá\83 á\83ªá\83\98á\83\94á\83\9aá\83\94á\83\91á\83£á\83\9aá\83\98 á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\90 á\83\92á\83\90á\83\9bá\83\9dá\83\98á\83¬á\83\95á\83\94á\83\95á\83¡ á\83\90á\83\9b á\83\95á\83\98á\83\99á\83\98á\83¡ á\83¡á\83®á\83\95á\83\90 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¡á\83\90á\83\9bá\83£á\83¨á\83\90á\83\9d á\83\98á\83\9cá\83¢á\83\94á\83 á\83¤á\83\94á\83\98á\83¡á\83\98á\83¡ á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\90á\83¡á\83\90á\83ª. \ná\83\98á\83\9bá\83\98á\83¡á\83\90á\83\97á\83\95á\83\98á\83¡, á\83 á\83\9dá\83\9b á\83\93á\83\90á\83\90á\83\9bá\83\90á\83¢á\83\9dá\83\97 á\83\90á\83\9c á\83¨á\83\94á\83ªá\83\95á\83\90á\83\9aá\83\9dá\83\97 á\83\97á\83\90á\83 á\83\92á\83\9bá\83\90á\83\9cá\83\94á\83\91á\83\98 á\83§á\83\95á\83\94á\83\9aá\83\90 á\83\95á\83\98á\83\99á\83\98á\83¨á\83\98, გთხოვთ, გამოიყენოთ მედიავიკის ლოკალიზაციის პროექტი [//translatewiki.net/ translatewiki.net].",
"cascadeprotected": "ეს გვერდი რედაქტირებისგან დაცულია, რადგან იგი ჩართულია შემდეგ {{PLURAL:$1|გვერდში, რომლის |გვერდებში, რომელთა}} დასაცავადაც ჩართულია პარამეტრი \"იერარქიული\":\n$2",
"namespaceprotected": "თქვენ არ გაქვთ '''$1''' სახელთა სივრცეში გვერდების რედაქტირების უფლება.",
"customcssprotected": "თქვენ არ გაქვთ ამ CSS გვერდის რედაქტირების უფლება, ვინაიდან ის სხვა მომხმარებლის პირად კონფიგურაციას შეიცავს.",
"pageinfo-header-edits": "편집 역사",
"pageinfo-header-restrictions": "문서 보호",
"pageinfo-header-properties": "문서 속성",
- "pageinfo-display-title": "ë³´ì\97¬ì¤\84 ì\9d´ë¦\84",
+ "pageinfo-display-title": "ë³´ì\97¬ì¤\84 ì \9c목",
"pageinfo-default-sort": "기본 정렬 키",
"pageinfo-length": "문서 길이 (바이트)",
"pageinfo-article-id": "문서 ID",
"tog-shownumberswatching": "D'Zuel vun de Benotzer déi dës Säit iwwerwaache weisen",
"tog-oldsig": "Aktuell Ënnerschrëft:",
"tog-fancysig": "Ënnerschrëft als Wiki-Text behandelen (Ouni automatesche Link)",
- "tog-uselivepreview": "Live-Preview benotzen (experimentell)",
+ "tog-uselivepreview": "Live-Preview benotzen",
"tog-forceeditsummary": "Warnen, wa beim Späicheren de Resumé feelt",
"tog-watchlisthideown": "Meng Ännerungen op menger Iwwerwaachungslëscht verstoppen",
"tog-watchlisthidebots": "Ännerunge vu Botten op menger Iwwerwaachungslëscht verstoppen",
"anoneditwarning": "<strong>Opgepasst:</strong> Dir sidd net ageloggt. Dowéinst gëtt amplaz vun engem Benotzernumm Är IP Adress ëffentlech gewise wann Dir Ännerunge maacht. Wann Dir <strong>[$1 Iech aloggt]</strong> oder <strong>[$2 e Bnotzerkont opmaachen]</strong>, Är Ännerunge ginn dann Ärem Benotzerkont zougedeelt, genee wéi aner Avantagen.",
"anonpreviewwarning": "''Dir sidd net ageloggt. Wann Dir ofspäichert gëtt Är IP-Adress an der Lëscht vun de Versioune vun dëser Säit enregistréiert.''",
"missingsummary": "'''Erënnerung:''' Dir hutt kee Resumé aginn.\nWann Dir nacheemol op \"{{int:savearticle}}\" klickt, gëtt Är Ännerung ouni Resumé ofgespäichert.",
+ "selfredirect": "<strong>Opgepasst:</strong> Dir maacht eng Viruleedung op deeselwechten Artikel.\nWann Dir nach eng Kéier op \"{{int:savearticle}}\" klickt, da gëtt d'Viruleedung ugeluecht.",
"missingcommenttext": "Gitt w.e.g. eng Bemierkung an.",
"missingcommentheader": "'''Denkt drun:''' Dir hutt keen Titel/Sujet fir dës Bemierkung aginn.\nWann Dir nach en Kéier op \"{{int:savearticle}}\" klickt da gëtt Är Ännerung ouni Titel gespäichert.",
"summary-preview": "Resumé kucken ouni ofzespäicheren:",
"tog-shownumberswatching": "Прикажи го бројот на корисници кои набљудуваат",
"tog-oldsig": "Постоечки потпис:",
"tog-fancysig": "Сметај го потписот за викитекст (без автоматска врска)",
- "tog-uselivepreview": "Користи преглед во живо (експериментално)",
+ "tog-uselivepreview": "Користи преглед во живо",
"tog-forceeditsummary": "Извести ме кога нема опис на промените",
"tog-watchlisthideown": "Скриј мои уредувања од списокот на набљудувања",
"tog-watchlisthidebots": "Скриј ботовски уредувања од списокот на набљудувања",
"anoneditwarning": "<strong>Предупредување:</strong> Не сте најавени. Вашата IP-адреса ќе биде јавно видлива ако уредувате. Ако <strong>[$1 се најавите]</strong> или <strong>[$2 направите сметка]</strong>, тогаш уредувањата ќе се припишуваат на вашето корисничко име, покрај другите погодности.",
"anonpreviewwarning": "''Не сте најавени. Ако ја зачувате, Вашата IP-адреса ќе биде заведена во историјата на уредување на страницата.''",
"missingsummary": "'''Потсетник:''' Не внесовте опис на измените. Ако притиснете Зачувај повторно, вашите измени ќе се зачуваат без опис.",
+ "selfredirect": "<strong>Предупредување:</strong> Создавате пренасочување кон истата статија.\nАко стиснете на „{{int:savearticle}}“ повторно, тогаш пренасочувањето ќе се создаде.",
"missingcommenttext": "Ве молиме внесете коментар подолу.",
"missingcommentheader": "'''Потсетување:''' Не внесовте наслов за овој коментар.\nАко повторно стиснете на „{{int:savearticle}}“, уредувањето ќе биде зачувано без наслов.",
"summary-preview": "Изглед на описот:",
"pager-older-n": "{{PLURAL:$1|постара 1|постари $1}}",
"suppress": "Скривање",
"querypage-disabled": "Оваа службена страница е оневозможена за да не попречува на делотворноста.",
- "apihelp": "Ð\9fомоÑ\88 Ñ\81о пÑ\80илогот",
+ "apihelp": "Ð\9fомоÑ\88 Ñ\81о извÑ\80Ñ\88никот",
"apihelp-no-such-module": "Модулот „$1“ не е пронајден.",
"booksources": "Печатени извори",
"booksources-search-legend": "Пребарување на извори за книга",
"hijri-calendar-m10": "Шавал",
"hijri-calendar-m11": "Ду ел-Кида",
"hijri-calendar-m12": "Ду ел-Хиџа",
- "hebrew-calendar-m1": "Тишри",
- "hebrew-calendar-m2": "Хешван",
- "hebrew-calendar-m3": "Ð\9aислев",
- "hebrew-calendar-m4": "Тебет",
- "hebrew-calendar-m5": "Шебат",
- "hebrew-calendar-m6": "Ð\90дар",
- "hebrew-calendar-m6a": "Ð\90дар I",
- "hebrew-calendar-m6b": "Ð\90дар II",
- "hebrew-calendar-m7": "Ð\9dисан",
- "hebrew-calendar-m8": "Ð\98јар",
- "hebrew-calendar-m9": "Сиван",
- "hebrew-calendar-m10": "Тамуз",
- "hebrew-calendar-m11": "Ð\90в",
- "hebrew-calendar-m12": "Ð\95лул",
- "hebrew-calendar-m1-gen": "Тишри",
- "hebrew-calendar-m2-gen": "Хешван",
- "hebrew-calendar-m3-gen": "Ð\9aислев",
- "hebrew-calendar-m4-gen": "Тебет",
- "hebrew-calendar-m5-gen": "Шебат",
- "hebrew-calendar-m6-gen": "Ð\90дар",
- "hebrew-calendar-m6a-gen": "Ð\90дар I",
- "hebrew-calendar-m6b-gen": "Ð\90дар II",
- "hebrew-calendar-m7-gen": "Ð\9dисан",
- "hebrew-calendar-m8-gen": "Ð\98јар",
- "hebrew-calendar-m9-gen": "Сиван",
- "hebrew-calendar-m10-gen": "Тамуз",
- "hebrew-calendar-m11-gen": "Ð\90в",
- "hebrew-calendar-m12-gen": "Ð\95лул",
+ "hebrew-calendar-m1": "тишри",
+ "hebrew-calendar-m2": "хешван",
+ "hebrew-calendar-m3": "кислев",
+ "hebrew-calendar-m4": "тевет",
+ "hebrew-calendar-m5": "шват",
+ "hebrew-calendar-m6": "адар",
+ "hebrew-calendar-m6a": "адар I",
+ "hebrew-calendar-m6b": "адар II",
+ "hebrew-calendar-m7": "нисан",
+ "hebrew-calendar-m8": "ијар",
+ "hebrew-calendar-m9": "сиван",
+ "hebrew-calendar-m10": "тамуз",
+ "hebrew-calendar-m11": "ав",
+ "hebrew-calendar-m12": "елул",
+ "hebrew-calendar-m1-gen": "тишри",
+ "hebrew-calendar-m2-gen": "хешван",
+ "hebrew-calendar-m3-gen": "кислев",
+ "hebrew-calendar-m4-gen": "тевет",
+ "hebrew-calendar-m5-gen": "шват",
+ "hebrew-calendar-m6-gen": "адар",
+ "hebrew-calendar-m6a-gen": "адар I",
+ "hebrew-calendar-m6b-gen": "адар II",
+ "hebrew-calendar-m7-gen": "нисан",
+ "hebrew-calendar-m8-gen": "ијар",
+ "hebrew-calendar-m9-gen": "сиван",
+ "hebrew-calendar-m10-gen": "тамуз",
+ "hebrew-calendar-m11-gen": "ав",
+ "hebrew-calendar-m12-gen": "елул",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|разговор]])",
"unknown_extension_tag": "Непозната ознака на додатокот „$1“",
"duplicate-defaultsort": "Предупредување: Основниот клуч за подредување „$2“ го поништува претходниот основен клуч за подредување „$1“.",
"version-parserhooks": "Расчленувачки куки",
"version-variables": "Променливи",
"version-antispam": "Спречување на спам",
- "version-api": "Ð\9fÑ\80илози",
+ "version-api": "Ð\98звÑ\80Ñ\88ниÑ\86и",
"version-other": "Друго",
"version-mediahandlers": "Ракувачи со мултимедијални содржини",
"version-hooks": "Куки",
"feedback-cancel": "Откажи",
"feedback-submit": "Поднеси мислење",
"feedback-adding": "Го додавам искажаното мислење во страницата...",
- "feedback-error1": "Ð\93Ñ\80еÑ\88ка: Ð\9dепÑ\80епознаен Ñ\80езÑ\83лÑ\82аÑ\82 од пÑ\80илогот (API)",
+ "feedback-error1": "Ð\93Ñ\80еÑ\88ка: Ð\9dепÑ\80епознаен Ñ\80езÑ\83лÑ\82аÑ\82 од извÑ\80Ñ\88никот (API)",
"feedback-error2": "Грешка: Уредувањето не успеа",
- "feedback-error3": "Ð\93Ñ\80еÑ\88ка: Ð\9fÑ\80илогоÑ\82 (API) не одговара",
+ "feedback-error3": "Ð\93Ñ\80еÑ\88ка: Ð\98звÑ\80Ñ\88никоÑ\82 не одговара",
"feedback-thanks": "Благодариме! Вашиот одѕив е објавен на страницата „[$2 $1]“.",
"feedback-close": "Готово",
"feedback-bugcheck": "Одлично! Само проверете да не е една од [$1 веќе познатите грешки].",
"tog-shownumberswatching": "ശ്രദ്ധിക്കുന്ന ഉപയോക്താക്കളുടെ എണ്ണം കാണിക്കുക",
"tog-oldsig": "നിലവിലുള്ള ഒപ്പ്:",
"tog-fancysig": "ഒപ്പ് ഒരു വിക്കി എഴുത്തായി പരിഗണിക്കുക (കണ്ണി സ്വയം ചേർക്കേണ്ടതില്ല)",
- "tog-uselivepreview": "തത്സമയ പ്രിവ്യൂ ഉപയോഗപ്പെടുത്തുക (പരീക്ഷണാടിസ്ഥാനം)",
+ "tog-uselivepreview": "തത്സമയ പ്രിവ്യൂ ഉപയോഗപ്പെടുത്തുക",
"tog-forceeditsummary": "തിരുത്തുകളുടെ ചുരുക്കം നൽകിയില്ലെങ്കിൽ എന്നെ ഓർമ്മിപ്പിക്കുക",
"tog-watchlisthideown": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽനിന്ന് എന്റെ തിരുത്തുകൾ മറയ്ക്കുക",
"tog-watchlisthidebots": "ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽനിന്ന് യന്ത്രങ്ങൾ വരുത്തിയ തിരുത്തുകൾ മറയ്ക്കുക",
"anoneditwarning": "<strong>മുന്നറിയിപ്പ്:</strong> താങ്കൾ ലോഗിൻ ചെയ്തിട്ടില്ല. താങ്കൾ തിരുത്തുകളെന്തെങ്കിലും ചെയ്യുകയാണെങ്കിൽ താങ്കളുടെ ഐ.പി. വിലാസം എല്ലാവർക്കും ലഭ്യമായിരിക്കും. താങ്കൾ <strong>[$1 ലോഗിൻ ചെയ്യുകയോ]</strong> <strong>[$2 അംഗത്വമെടുക്കുകയോ]</strong> ചെയ്യുന്നതുവഴി മറ്റ് ഗുണങ്ങളോടൊപ്പം താങ്കളുടെ തിരുത്തുകൾ ഉപയോക്തൃനാമത്തിലാവും അറിയപ്പെടുക.",
"anonpreviewwarning": "''താങ്കൾ ലോഗിൻ ചെയ്തിട്ടില്ല. സേവ് ചെയ്യുമ്പോൾ താളിന്റെ തിരുത്തൽ ചരിത്രത്തിൽ താങ്കളുടെ ഐ.പി. വിലാസം ചേർത്തു സൂക്ഷിക്കപ്പെടും.''",
"missingsummary": "'''ഓർമ്മക്കുറിപ്പ്:''' താങ്കൾ തിരുത്തലിന്റെ ചുരുക്കരൂപം നൽകിയിട്ടില്ല. ''സേവ് ചെയ്യുക'' ബട്ടൺ ഒരുവട്ടം കൂടി അമർത്തിയാൽ താങ്കൾ വരുത്തിയ മാറ്റം കാത്തുസൂക്ഷിക്കുന്നതാണ്.",
+ "selfredirect": "<strong>മുന്നറിയിപ്പ്:</strong> അതേ ലേഖനത്തിലേക്കുള്ള തിരിച്ചുവിടലാണ് താങ്കൾ സൃഷ്ടിക്കുന്നത്.\nവീണ്ടും \"{{int:savearticle}}\" അമർത്തിയാൽ, തിരിച്ചുവിടൽ സൃഷ്ടിക്കപ്പെടുന്നതാണ്.",
"missingcommenttext": "താങ്കളുടെ അഭിപ്രായം ദയവായി താഴെ രേഖപ്പെടുത്തുക.",
"missingcommentheader": "'''ഓർമ്മക്കുറിപ്പ്:''' ഈ കുറിപ്പിന് താങ്കൾ വിഷയം/തലക്കെട്ട് നൽകിയിട്ടില്ല. ''{{int:savearticle}}'' എന്ന ബട്ടൺ ഒരുവട്ടം കൂടി അമർത്തിയാൽ വിഷയം/തലക്കെട്ട് ഇല്ലാതെ തന്നെ കാത്തുസൂക്ഷിക്കുന്നതാവും.",
"summary-preview": "ചുരുക്കരൂപം എങ്ങനെയുണ്ടെന്നു കാണുക:",
"tog-shownumberswatching": "Fa' vedé 'o nummero d'utente che teneno 'a paggena cuntrullata",
"tog-oldsig": "Firma 'e mmo:",
"tog-fancysig": "Piglia 'a firma comme fosse nu wikitesto (senza fà link automatico)",
- "tog-uselivepreview": "Abilita 'o \"Live preview\" (sperimentale)",
+ "tog-uselivepreview": "Abbìa 'o \"Live preview\"",
"tog-forceeditsummary": "Chiere a mme quanno se sta azzeccanno nu campo oggetto abbacante",
"tog-watchlisthideown": "Annascunne 'e cagnamiente d' 'a lista 'e cuntrollo mia",
"tog-watchlisthidebots": "Annasconne 'e cagnamiènte d' 'e bot ncopp'a l'elenco 'e cuntrollo",
"userlogin-createanother": "Cria n'at'account",
"createacct-emailrequired": "Indirizzo email",
"createacct-emailoptional": "Indirizzo 'e posta elettronica (ozzionale)",
- "createacct-email-ph": "Scrive 'o nderizzo mail tuo",
- "createacct-another-email-ph": "Scrive nderizzo mail",
+ "createacct-email-ph": "Scrivite 'o nderizzo mail vuosto",
+ "createacct-another-email-ph": "Scrivite nderizzo mail",
"createaccountmail": "Usa na password qualunque temporanea e manna sta password a l'indirizzo 'e posta e-mail specificato",
"createacct-realname": "Nomme riale (ozzionale)",
"createaccountreason": "Mutivo:",
"createacct-reason": "Mutivo",
"createacct-reason-ph": "Pecché staje crianno n'at'utenza",
"createacct-captcha": "Cuntrollo 'e sicurezza",
- "createacct-imgcaptcha-ph": "Scrive 'o testo ca vire ncoppa",
+ "createacct-imgcaptcha-ph": "Scrivite 'o testo ca vedite ncoppa",
"createacct-submit": "Cria 'a toja utenza",
"createacct-another-submit": "Cria 'n atro account",
"createacct-benefit-heading": "{{SITENAME}} è fatta 'e perzone comme te.",
"emailnotauthenticated": "'O ndirizzo 'e posta elettronica nun è stat'ancora cunfermato.\nNun se mannarranno mmasciate e-mail p' ' funzione ccà abbascio.",
"noemailprefs": "Avite 'a specificà nu ndirizzo e-mail pe ll'attivà sti funzione.",
"emailconfirmlink": "Cunferma 'o nderizzo mail d' 'o tujo.",
- "invalidemailaddress": "'O nderizzo e-mail scritto nun se può accettà pecché nun tene nu furmatto buono.\nScrive n'ata vota nu nderizzo bbuono o abbacanta 'a casella.",
+ "invalidemailaddress": "'O nderizzo e-mail scritto nun se può accettà pecché nun tene nu furmatto buono.\nScrivite n'ata vota nu nderizzo bbuono o abbacantate 'a casciulella.",
"cannotchangeemail": "'E ccunte mail nun se ponno cagnà dint'a sta wiki.",
"emaildisabled": "Chistu sito nun può mannà mmasciate e-mail.",
"accountcreated": "Cunto criato",
"anoneditwarning": "'''Attenzione:''' Nun avite fatto l'acciesso. 'A cronologgia d' 'a vosta sarrà visibbele pubbrecamente si facite cocche cagnamiento. Si <strong>[$1 tràse]</strong> o <strong>[$2 crìe nu cunto]</strong>, 'e cagnamiente vuoste ve sarranno attribbuite a vvuje, nzieme a n'ati migliuramente.",
"anonpreviewwarning": "''Nun avite fatto 'o login. Sarvann' 'a paggena, l'indirizzo IP d' 'o vuosto sarrà riggistrato dint'a cronologgia.''",
"missingsummary": "'''Attenziò:''' nun s'è specificato l'oggetto 'e stu cagnamiento. Clicann' 'a \"{{int:savearticle}}\" n'ata vota 'o cagnamiento sarrà sarvato cu l'oggetto abbacante.",
+ "selfredirect": "<strong>Attenziò:</strong> State crianno nu redirect a 'o stesso articolo.\nSi cliccate \"{{int:savearticle}}\" n'ata vota, si criarrà 'o redirect.",
"missingcommenttext": "Pe' piacere scrivete nu commento ccà abbascio.",
"missingcommentheader": "'''Attenziò:''' nun s'è specificato l'oggetto/titolo 'e stu commento. Clicann' 'a \"{{int:savearticle}}\" n'ata vota 'o cagnamiento sarrà sarvato c' 'o titolo abbacante.",
"summary-preview": "Anteprimma'e l'oggetto:",
"tog-watchdefault": "Spul wa'k bewarke op mien volglieste zetten",
"tog-watchmoves": "Spul wa'k herneume op mien volglieste zetten",
"tog-watchdeletion": "Spul wa'k vortdo op mien volglieste zetten",
+ "tog-watchrollback": "Ziejen waorvan ik bewarkingen weerummedreid hebbe automaties volgen",
"tog-minordefault": "Markeer alle veraanderingen as 'kleine wieziging'",
"tog-previewontop": "De naokiekzied boven t bewarkingsveld zetten",
"tog-previewonfirst": "Naokieken bie eerste wieziging",
"tog-shownumberswatching": "t Antal gebrukers bekieken die disse zied volgt",
"tog-oldsig": "Bestaonde haandtekening:",
"tog-fancysig": "Ondertekening zien as wikitekste (zonder automatiese verwiezing)",
- "tog-uselivepreview": "Gebruuk \"rechtstreeks naokieken\" (experimenteel)",
+ "tog-uselivepreview": "Gebruuk \"rechtstreeks naokieken\"",
"tog-forceeditsummary": "Geef n melding bie n lege samenvatting",
"tog-watchlisthideown": "Verbarg mien eigen bewarkingen",
"tog-watchlisthidebots": "Verbarg botgebrukers",
"view": "Lezen",
"view-foreign": "Bekieken op $1",
"edit": "Bewarken",
+ "edit-local": "Lokale beschrieving bewarken",
"create": "Anmaken",
+ "create-local": "Lokale beschrieving derbie doon",
"editthispage": "Disse zied bewarken",
"create-this-page": "Disse zied anmaken",
"delete": "Vortdoon",
"otherlanguages": "Aandere talen",
"redirectedfrom": "(deurestuurd vanaof \"$1\")",
"redirectpagesub": "Deurverwieszied",
+ "redirectto": "Deurverwiezen naor:",
"lastmodifiedat": "Disse zied is t lest ewiezigd op $1 um $2.",
"viewcount": "Disse zied is $1 {{PLURAL:$1|keer|keer}} bekeken.",
"protectedpage": "Beveiligden zied",
"jumptonavigation": "navigasie",
"jumptosearch": "zeuk",
"view-pool-error": "De servers bin op heden overbelast.\nTe veule gebrukers proberen disse zied te bekieken.\nWacht effen veurda'j opniej toegang proberen te kriegen tot disse zied.\n\n$1",
+ "generic-pool-error": "De servers bin op heden overbelast.\nTe veule gebrukers proberen disse zied te bekieken.\nWacht effen veurda'j opniej toegang proberen te kriegen tot disse zied.",
"pool-timeout": "De maximumwachttied veur databankvergrendeling is verleupen.",
"pool-queuefull": "De wachtrie van de poel is vol",
"pool-errorunknown": "Onbekende fout",
+ "pool-servererror": "De dienst \"pool counter\" is niet beschikbaor ($1).",
"aboutsite": "Over {{SITENAME}}",
"aboutpage": "Project:Info",
"copyright": "De inhoud is beschikbaor onder de $1 as der niks aanders an-egeven is.",
"filerenameerror": "Bestaandsnaamwieziging \"$1\" naor \"$2\" niet meugelik.",
"filedeleteerror": "Kon bestaand \"$1\" niet vortdoon.",
"directorycreateerror": "Map \"$1\" kon niet an-emaakt wörden.",
+ "directoryreadonlyerror": "De map \"$1\" is allinnig-lezen.",
+ "directorynotreadableerror": "De map \"$1\" kan niet elezen wörden.",
"filenotfound": "Kon bestaand \"$1\" niet vienen.",
"unexpected": "Onverwachten weerde: \"$1\"=\"$2\".",
"formerror": "Fout: kon formulier niet versturen",
"viewsourcetext": "Je kunnen de brontekste van disse zied bewarken en bekieken:",
"viewyourtext": "Je kunnen '''joew bewarkingen''' an de brontekste van disse zied bekieken en kopiëren:",
"protectedinterface": "Op disse zied steet tekste die gebruukt wörden veur systeemteksten van disse wiki. Allinnig beheerders kunnen disse zied bewarken.\nUm vertalingen veur alle wiki's derbie te zetten of te wiezigen, gebruuk [//translatewiki.net/ translatewiki.net], t vertaalprojekt veur MediaWiki.",
- "editinginterface": "'''Waorschuwing:''' je bewarken n zied die gebruukt wörden deur de programmatuur. Wa'j hier wiezigen, is van invleud op de hele wiki. Um vertalingen derbie te zetten of te wiezigen veur alle wiki's, gebruuk [//translatewiki.net/wiki/Main_Page?setlang=nds-nl translatewiki.net], t vertalingsprojekt veur MediaWiki.",
+ "editinginterface": "<strong>Waorschuwing:</strong> je bewarken n zied die gebruukt wörden deur de programmatuur. Wa'j hier wiezigen, is van invleud op de hele wiki. Um vertalingen derbie te zetten of te wiezigen veur alle wiki's, gebruuk [//translatewiki.net/wiki/Main_Page?setlang=nds-nl translatewiki.net], t vertalingsprojekt veur MediaWiki.",
"cascadeprotected": "Disse zied is beveiligd umdat t veurkömp in de volgende {{PLURAL:$1|zied|ziejen}}, die beveiligd {{PLURAL:$1|is|bin}} mit de \"kaskade\"-opsie:\n$2",
"namespaceprotected": "Je maggen gien ziejen in de '''$1'''-naamruumte bewarken.",
"customcssprotected": "Je kunnen disse CSS-zied niet bewarken, umdat der persoonlike instellingen van n aandere gebruker in staon.",
"import": "Ziejen invoeren",
"importinterwiki": "Transwiki-invoer",
"import-interwiki-text": "Kies n wiki en ziednaam um in te voeren.\nVersie- en auteursgegevens blieven hierbie beweerd.\nAlle transwiki-invoerhaandelingen wörden op-esleugen in t [[Special:Log/import|invoerlogboek]].",
+ "import-interwiki-sourcewiki": "Bronwiki:",
+ "import-interwiki-sourcepage": "Bronzied:",
"import-interwiki-history": "Kopieer de hele geschiedenisse veur disse zied",
"import-interwiki-templates": "Alle mallen opnemen",
"import-interwiki-submit": "Invoeren",
"version-hook-subscribedby": "In-eschreven deur",
"version-version": "(Versie $1)",
"version-license": "MediaWiki-lisensie",
+ "version-ext-colheader-version": "Versie",
+ "version-ext-colheader-license": "Lisensie",
+ "version-ext-colheader-description": "Beschrieving",
+ "version-ext-colheader-credits": "Auteurs",
"version-poweredby-credits": "Disse wiki wörden an-estuurd deur '''[https://www.mediawiki.org/ MediaWiki]''', auteursrecht © 2001-$1 $2.",
"version-poweredby-others": "aanderen",
"version-poweredby-translators": "vertalers van translatewiki.net",
"fileduplicatesearch-result-n": "Der {{PLURAL:$2|is één bestaand|bin $2 bestaanden}} die liek alleens bin as \"$1\".",
"fileduplicatesearch-noresults": "Der is gien bestaand mit de naam \"$1\" evunnen.",
"specialpages": "Spesiale ziejen",
+ "specialpages-note-top": "Legenda",
"specialpages-note": "* Normale spesiale ziejen.\n* <span class=\"mw-specialpagerestricted\">Beparkt toegankelike spesiale ziejen.</span>",
"specialpages-group-maintenance": "Onderhoudsliesten",
"specialpages-group-other": "Aandere spesiale ziejen",
"expand_templates_remove_comments": "Opmarking vorthaolen",
"expand_templates_remove_nowiki": "Etiketten <nowiki> in resultaot onderdrokken",
"expand_templates_generate_xml": "XML-parserboom bekieken",
- "expand_templates_preview": "Naokieken"
+ "expand_templates_preview": "Naokieken",
+ "pagelang-language": "Taal",
+ "mediastatistics-header-audio": "Audio",
+ "mediastatistics-header-video": "Video's",
+ "mediastatistics-header-multimedia": "Interaktieve media"
}
"Calak",
"Arg",
"NCoppens",
- "Josse.Cottenier"
+ "Josse.Cottenier",
+ "Macofe"
]
},
"tog-underline": "Koppelingen onderstrepen:",
"tog-shownumberswatching": "Het aantal gebruikers weergeven dat deze pagina volgt",
"tog-oldsig": "Bestaande ondertekening:",
"tog-fancysig": "Als wikitekst behandelen (zonder automatische koppeling)",
- "tog-uselivepreview": "\"Live voorvertoning\" gebruiken (experimenteel)",
+ "tog-uselivepreview": "\"Live voorvertoning\" gebruiken",
"tog-forceeditsummary": "Een melding geven bij een lege bewerkingssamenvatting",
"tog-watchlisthideown": "Eigen bewerkingen op mijn volglijst verbergen",
"tog-watchlisthidebots": "Botbewerkingen op mijn volglijst verbergen",
"specialpages-group-wiki": "Gegevens en -hulpmiddelen",
"specialpages-group-redirects": "Doorverwijzende speciale pagina's",
"specialpages-group-spam": "Spamhulpmiddelen",
+ "specialpages-group-developer": "Hulpmiddelen voor ontwikkelaars",
"blankpage": "Lege pagina",
"intentionallyblankpage": "Deze pagina is bewust leeg gelaten en wordt gebruikt voor benchmarks, enzovoort.",
"external_image_whitelist": " #Laat deze regel onveranderd<pre>\n#Zet hieronder reguliere expressiefragmenten (alleen het deel dat tussen de // staat)\n#Deze worden gehouden tegen de URL's van externe (gehotlinkte) afbeeldingen\n#Als de reguliere expressie van toegang is, wordt een afbeelding weergegeven, anders wordt alleen een koppeling weergegeven\n#Regels die beginnen met \"#\" worden als opmerking behandeld\n#Regels in de witte lijst zijn niet hoofdlettergevoelig.\n\n#Zet alle reguliere expressiefragmenten boven deze regel. Laat deze regel onveranderd</pre>",
"Michał Sobkowski",
"Py64",
"Nanaki",
- "Alan ffm"
+ "Alan ffm",
+ "Macofe"
]
},
"tog-underline": "Podkreślenie linków:",
"tog-shownumberswatching": "Pokaż liczbę użytkowników obserwujących stronę",
"tog-oldsig": "Twój obecny podpis:",
"tog-fancysig": "Traktuj podpis jako wikikod (nie linkuj automatycznie całości)",
- "tog-uselivepreview": "Używaj dynamicznego podglądu (eksperymentalny)",
+ "tog-uselivepreview": "Używaj dynamicznego podglądu",
"tog-forceeditsummary": "Informuj o niewypełnieniu opisu zmian",
"tog-watchlisthideown": "Ukryj moje edycje na liście obserwowanych",
"tog-watchlisthidebots": "Ukryj edycje botów na liście obserwowanych",
"tog-shownumberswatching": "Smon-e ël nùmer d'utent che as ten-o la pàgina sot-euj",
"tog-oldsig": "Firma esistenta:",
"tog-fancysig": "Traté la firma com dël test wiki (sensa n'anliura automàtica)",
- "tog-uselivepreview": "Dovré la fonsion ''Preuva dal viv'' (sperimental)",
+ "tog-uselivepreview": "Dovré la fonsion ''Preuva dal viv''",
"tog-forceeditsummary": "Ciamé conferma se ël resumé dla modìfica a l'é veujd",
"tog-watchlisthideown": "Stërmé mie modìfiche ant la ròba che im ten-o sot-euj",
"tog-watchlisthidebots": "Stërmé le modìfiche fàite daj trigomiro ant la lista dle ròbe che im ten-o sot-euj",
"anoneditwarning": "<strong>Atension:<strong> A l'é nen rintrà ant ël sistema. Soa adrëssa IP a së sc-iairërà s'a fà dle modìfiche. Si chiel a <strong>[$1 rintra ant ël sistema]</strong> o <strong>[$2 a crea an cont]</strong>, soe modìfiche a saran atribuìe a sò stranòm, ansema a d'àutri vantagg.",
"anonpreviewwarning": "''A l'é nen rintrà ant ël sistema. An salvand a sarà memorisà soa adrëssa IP ant la stòria dle modìfiche ëd sa pàgina.''",
"missingsummary": "'''Nòta:''' a l'ha butà gnun resumé dla modìfica. Se a sgnaca «{{int:savearticle}}» n'àutra vira, soa modìfica a resterà salvà sensa resumé.",
+ "selfredirect": "<strong>Atension:</strong> A l'é an camin ch'a crea na ridiriression a l'istess artìcol.\nS'a sgnaca torna ansima a «{{int:savearticle}}», la ridiression a sarà creà.",
"missingcommenttext": "Për piasì, che a buta un coment sì-sota.",
"missingcommentheader": "'''Ch'a arcòrda:''' A l'ha pa dàit ëd soget o d'intestassion për cost coment.\nSe a sgnaca torna «{{int:savearticle}}», soa modìfica a sarà salvà sensa gnun-a intestassion.",
"summary-preview": "Preuva dël resumé:",
"tog-shownumberswatching": "Mostrar o número de utilizadores a vigiar",
"tog-oldsig": "Assinatura atual:",
"tog-fancysig": "Tratar assinatura como texto wiki (sem hiperligações automáticas)",
- "tog-uselivepreview": "Usar a antevisão ao vivo (experimental)",
+ "tog-uselivepreview": "Usar a antevisão ao vivo",
"tog-forceeditsummary": "Avisar-me se deixar o resumo da edição vazio",
"tog-watchlisthideown": "Esconder as minhas edições ao listar mudanças às páginas vigiadas",
"tog-watchlisthidebots": "Esconder edições de robôs ao listar mudanças às páginas vigiadas",
"specialpages-group-wiki": "Dados e ferramentas",
"specialpages-group-redirects": "Redirecionar páginas especiais",
"specialpages-group-spam": "Ferramentas anti-spam",
+ "specialpages-group-developer": "Ferramentas de desenvolvimento",
"blankpage": "Página em branco",
"intentionallyblankpage": "Esta página foi intencionalmente deixada em branco",
"external_image_whitelist": " # Deixe esta linha exatamente como ela está<pre>\n# Coloque fragmentos de expressões regulares (apenas a parte entre //) abaixo\n# Estas serão comparadas com as URL das imagens externas (com ligação direta)\n# As que corresponderem serão apresentadas como imagens, caso contrário apenas será apresentado um link para a imagem\n# As linhas que começam com um símbolo de cardinal (#) são tratadas como comentários\n# Esta lista não distingue maiúsculas de minúsculas\n\n# Coloque todos os fragmentos de expressões regulares (regex) acima desta linha. Deixe esta linha exatamente como ela está</pre>",
"tog-shownumberswatching": "Toggle option used in [[Special:Preferences]], in the section for recent changes. When this option is activated, the entries in recent changes includes the number of users who watch pages. {{Gender}}",
"tog-oldsig": "Used in [[Special:Preferences]], tab User profile. {{Gender}}",
"tog-fancysig": "In user preferences under the signature box. {{Gender}}",
- "tog-uselivepreview": "{{Gender}}\nToggle option used in [[Special:Preferences]].\n\nLive preview is an experimental feature (unavailable by default) to use edit preview without loading the page again.",
+ "tog-uselivepreview": "{{Gender}}\nToggle option used in [[Special:Preferences]].\n\nLive preview is a feature to use edit preview without loading the page again.",
"tog-forceeditsummary": "Toggle option used in [[Special:Preferences]] to force an edit ''{{msg-mw|summary}}''. {{Gender}}",
"tog-watchlisthideown": "[[Special:Preferences]], tab 'Watchlist'. Offers user to hide own edits from watchlist. {{Gender}}",
"tog-watchlisthidebots": "[[Special:Preferences]], tab 'Watchlist'. Offers user to hide bot edits from watchlist. {{Gender}}",
"anoneditwarning": "Shown when editing a page anonymously.\n\nParameters:\n* $1 – A link to log in, <nowiki>{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}</nowiki>\n* $2 – A link to sign up, <nowiki>{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}</nowiki>\n\nSee also:\n* {{msg-mw|mobile-frontend-editor-anoneditwarning}}",
"anonpreviewwarning": "See also:\n* {{msg-mw|Anoneditwarning}}",
"missingsummary": "The text \"edit summary\" is in {{msg-mw|Summary}}.\n\nSee also:\n* {{msg-mw|Missingcommentheader}}\n* {{msg-mw|Savearticle}}",
+ "selfredirect": "Notice displayed once after the user tries to create a redirect to the same article.",
"missingcommenttext": "This message is shown, when the textbox by a new-section is empty.",
"missingcommentheader": "Edit summary that is shown if you enable \"Prompt me when entering a blank summary\" and add a new section without headline to a talk page.\n\nSee also:\n* {{msg-mw|Missingsummary}}\n* {{msg-mw|Savearticle}}",
"summary-preview": "Preview of the edit summary, shown under the edit summary itself.\nShould match: {{msg-mw|summary}}.",
"tog-shownumberswatching": "Arată numărul utilizatorilor care urmăresc",
"tog-oldsig": "Semnătură actuală:",
"tog-fancysig": "Tratează semnătura ca wikitext (fără o legătură automată)",
- "tog-uselivepreview": "Folosește previzualizarea în timp real (experimental)",
+ "tog-uselivepreview": "Folosește previzualizarea în timp real",
"tog-forceeditsummary": "Avertizează-mă când uit să descriu modificările",
"tog-watchlisthideown": "Ascunde modificările mele la lista mea de urmărire",
"tog-watchlisthidebots": "Ascunde modificările boților la lista mea de urmărire",
"anoneditwarning": "<strong>Atenție:</strong> Nu v-ați autentificat. Adresa dumneavoastră IP va fi vizibilă în mod public dacă efectuați modificări. Dacă vă <strong>[$1 autentificați]</strong> sau vă <strong>[$2 creați un cont]</strong>, modificările dumneavoastră vor fi asociate numelui de utilizator, pe lângă alte beneficii.",
"anonpreviewwarning": "''Nu v-ați autentificat. Dacă salvați pagina adresa dumneavoastră IP va fi înregistrată în istoric.''",
"missingsummary": "'''Atenție:''' Nu ați completat caseta „descriere modificări”. Dacă apăsați din nou butonul „salvează pagina” modificările vor fi salvate fără descriere.",
+ "selfredirect": "<strong>Atenție:</strong> Sunteți pe cale să creați o redirecționare către același articol.\nDacă apăsați din nou pe „{{int:savearticle}}”, redirecționarea va fi creată.",
"missingcommenttext": "Vă rugăm să introduceți un comentariu.",
"missingcommentheader": "'''Atenție,''' nu ați pus titlu sau subiect la acest comentariu.\nDacă dați din nou clic pe „{{int:savearticle}}” modificarea va fi salvată fără titlu.",
"summary-preview": "Previzualizare descriere:",
"tog-shownumberswatching": "Показывать число участников, включивших страницу в свой список наблюдения",
"tog-oldsig": "Текущая подпись:",
"tog-fancysig": "Собственная вики-разметка подписи (без автоматической ссылки)",
- "tog-uselivepreview": "Использовать быстрый предварительный просмотр (экспериментально)",
+ "tog-uselivepreview": "Использовать быстрый предварительный просмотр",
"tog-forceeditsummary": "Предупреждать, когда не заполнено поле описания правки",
"tog-watchlisthideown": "Скрывать мои правки из списка наблюдения",
"tog-watchlisthidebots": "Скрывать правки ботов из списка наблюдения",
"tog-watchdefault": "Eik pages n files that Ah eedit til ma watchleet",
"tog-watchmoves": "Eik pages n files that Ah muiv til ma watchleet",
"tog-watchdeletion": "Eik pages n files that Ah get rid o til ma watchleet",
+ "tog-watchrollback": "Eik pages whaur Ah'v performed ae rowback tae ma watchleet",
"tog-minordefault": "Mairk aa eedits \"smaa\" bi defaut",
"tog-previewontop": "Shaw luikower afore eedit kist n naw efter it",
"tog-previewonfirst": "Shaw luikower oan firstwhile eidit",
"underline-default": "Skin or brouser defaut",
"editfont-style": "Eidit area font style:",
"editfont-default": "Brouser defaut",
+ "editfont-monospace": "Monospaced font",
"editfont-sansserif": "Sans-serif font",
"editfont-serif": "Serif font",
"sunday": "Sunday",
"permalink": "Permanent airtin",
"print": "Prent",
"view": "See",
+ "view-foreign": "See oan $1",
"edit": "Eedit",
"edit-local": "Eedit local description",
"create": "Ceaut",
+ "create-local": "Eik local descreeption",
"editthispage": "Eedit this page",
"create-this-page": "Creaut this page",
"delete": "Delyte",
"otherlanguages": "In ither leids",
"redirectedfrom": "(Reguidit fae $1)",
"redirectpagesub": "Reguidal page",
+ "redirectto": "Reguidit tae:",
"lastmodifiedat": "This page wis hintmaist chynged oan $2, $1.",
"viewcount": "This page haes been accesst $1 {{PLURAL:$1|yince|$1 times}}.",
"protectedpage": "Protectit page",
"hidetoc": "skauk",
"collapsible-collapse": "Collapse.",
"collapsible-expand": "Mak mair muckle",
+ "confirmable-confirm": "Ar {{GENDER:$1|ye}} sair?",
+ "confirmable-yes": "Ay",
+ "confirmable-no": "Na",
"thisisdeleted": "See or restore $1?",
"viewdeleted": "See $1?",
"restorelink": "{{PLURAL:$1|yin delytit eidit|$1 delytit eidits}}",
"filerenameerror": "Cuidna rename file \"$1\" til \"$2\".",
"filedeleteerror": "Cuidna delyte file \"$1\".",
"directorycreateerror": "Couldna creat directerie \"$1\".",
+ "directoryreadonlyerror": "Directerie \"$1\" is read-yinlie.",
+ "directorynotreadableerror": "Directerie \"$1\" is no readable.",
"filenotfound": "Coudna fynd file \"$1\".",
"unexpected": "Vailyie isnae expectit: \"$1\"=\"$2\".",
"formerror": "Mistak: cuidna haun in form",
"viewsourcetext": "Ye can leuk at n copie the soorce o this page:",
"viewyourtext": "Ye can see n copie the soorce o <strong>yer eedits</strong> til this page:",
"protectedinterface": "This page provides interface tex fer the saffware oan this wiki, n is protected fer tae hinder abuise.\nTae eik or chynge owersets fer aw wikis, please uise [//translatewiki.net/ translatewiki.net], the MediaWiki localisation waurk.",
- "editinginterface": "<strong>Warnishment:</strong> Ye'r eeditin ae page that is uised tae provide interface tex fer the saffware.\nChynges til this page will affect the kithin o the uiser interface fer ither uisers oan this wiki.\nTae eik or chynge owersets fer aw wikis, please uise [//translatewiki.net/ translatewiki.net], the MediaWiki localisation waurk.",
+ "editinginterface": "<strong>Warnishment:</strong> Ye'r eeditin ae page that is uised tae provide interface tex fer the saffware.\nChynges til this page will affect the kithin o the uiser interface fer ither uisers oan this wiki.",
+ "translateinterface": "Tae eik or chynge owersets fer aw wikis, please uise [//translatewiki.net/ translatewiki.net], the MediaWiki localisation wairk.",
"cascadeprotected": "This page haes been protectit fae eiditin, cause it is inclædit in the follaein {{PLURAL:$1|page|pages}}, that ar protectit wi the \"cascadin\" optie turnit oan:\n$2",
"namespaceprotected": "Ye dinna hae permeession tae edit pages in the '''$1''' namespace.",
"customcssprotected": "Ye dinna hae permeession tae eidit this CSS page cause it contains anither uiser's personal settings.",
"createaccount-text": "Somebodie cræftit aen accoont fer yer wab-mail address oan {{SITENAME}} ($4) named \"$2\", wi passwaird \"$3\".\nYe shid log in n chynge yer passwaird nou.\n\nYe can ignore this message, gif this accoont wis cræftit bi mistak.",
"login-throttled": "Ye'v makit ower monie recynt login attempts.\nPlease wait $1 afore giein it anither gae.",
"login-abort-generic": "Yer login wisna successful - Aborted",
+ "login-migrated-generic": "Yer accoont's been migratit, n yer uisername nae langer exeests oan this wiki.",
"loginlanguagelabel": "Leid: $1",
"suspicious-userlogout": "Yer request tae log oot wis denied cause it luiks like it wis sent bi ae broken brouser or caching proxy.",
"createacct-another-realname-tip": "Real name is aen optie.\nGif ye chuise tae provide it, this will be uised fer giein the uiser attreebution fer their wark.",
"passwordreset-disabled": "Passwaird resets hae been disabled oan this wiki.",
"passwordreset-emaildisabled": "Wab-mail features hae been disabled oan this wiki.",
"passwordreset-username": "Uisername:",
+ "passwordreset-domain": "Domain:",
"passwordreset-capture": "See the ootcomin e-mail?",
"passwordreset-capture-help": "Gif ye check this kist, the e-mail (wi the temperie passwaird) will be shawn til ye n be sent til the uiser ava.",
"passwordreset-email": "Wab-mail address:",
"preview": "Luikower",
"showpreview": "Shaw luikower",
"showdiff": "Shaw chynges",
+ "blankarticle": "<strong>Wairnishment:</strong> The page that ye'r creautin is blank.\nGif ye clap \"{{int:savearticle}}\" again, the page will be creautit wioot oniething oan it.",
"anoneditwarning": "<strong>Warnishment:</strong> Ye'r no loggit in. Yer IP address will be publeeclie veesible gif ye mak onie eedits. Gif ye <strong>[$1 log in]</strong> or <strong>[$2 creaute aen accoont]</strong>, yer eedits will be attreebutit tae yer uisername, aes weel aes ither benefits.",
"anonpreviewwarning": "<em>Ye'r no loggit in. Hainin will record yer IP address in this page's eedit histerie.</em>",
"missingsummary": "<strong>Mynd:</strong> Ye'v naw gien aen eedit owerview. Gif ye clap oan \"{{int:savearticle}}\" again, yer eedit will be haint wioot ane.",
"edit-gone-missing": "Coudna update the page.\nIt appears tae hae been delytit.",
"edit-conflict": "Eedit confleect.",
"edit-no-change": "Yer eedit wis ignored cause nae chynge wis makit til the tex.",
+ "postedit-confirmation-created": "The page haes been creautit.",
+ "postedit-confirmation-restored": "The page haes been restored.",
"postedit-confirmation-saved": "Yer eedit wis hained.",
"edit-already-exists": "Coudna mak ae new page.\nIt awreadie exists.",
"defaultmessagetext": "Defaut message tex",
"editpage-notsupportedcontentformat-text": "The content format $1 isna supported bi the content model $2.",
"content-model-wikitext": "wikitex",
"content-model-text": "plain tex",
+ "content-model-javascript": "JavaScript",
+ "content-model-css": "CSS",
+ "duplicate-args-category": "Pages uisin dupleecate arguments in template caws",
+ "duplicate-args-category-desc": "The page contains template caws that uise dupleecates o arguments, lik <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
"expensive-parserfunction-warning": "<strong>Warnishment:</strong> This page contains ower moni expensive parser function caws.\n\nIt shid hae less than $2 {{PLURAL:$2|caw|caws}}, thaur {{PLURAL:$1|is nou $1 caw|ar noo $1 caws}}.",
"expensive-parserfunction-category": "Pages wi ower moni expensive parser function caws",
"post-expand-template-inclusion-warning": "<strong>Warnishment Template incluid size is owermuckle. \nSome templates will na be incluidit.",
"parser-template-recursion-depth-warning": "Template recursion depth limit owershote ($1)",
"language-converter-depth-warning": "Leid converter depth limit owershote ($1)",
"node-count-exceeded-category": "Pages whaur node-coont is owershote",
+ "node-count-exceeded-category-desc": "The page exceeds the mucklest node coont.",
"node-count-exceeded-warning": "Page owershot the node coont",
"expansion-depth-exceeded-category": "Pages whaur expansion depth is owershote",
+ "expansion-depth-exceeded-category-desc": "The page exceeds the mucklest expansion depth.",
"expansion-depth-exceeded-warning": "Page owershote the expansion depth",
"parser-unstrip-loop-warning": "Unstrip luip detected",
"parser-unstrip-recursion-limit": "Unstrip recursion limit owershote ($1)",
"rev-deleted-event": "(log action remuived)",
"rev-deleted-user-contribs": "[uisername or IP address remuived - eidit skauk't fae contreebutions]",
"rev-deleted-text-permission": "This page reveesion haes been <strong>delytit</strong>.\nDetails can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} delytion log].",
+ "rev-suppressed-text-permission": "This page reveesion haes been <strong>suppressed</strong>.\nTae fynd oot why the [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].",
"rev-deleted-text-unhide": "This page luikower haes been <strong>delytit</strong>.\nDetails can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} delytion log].\nYe can still [$1 see this luikower] gif ye wish tae proceed.",
"rev-suppressed-text-unhide": "This page luikower haes been <strong>suppressed</strong>.\nDetails can be foond in the [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].\nYe can still [$1 see this luikower] gif ye wish tae proceed.",
"rev-deleted-text-view": "This page luikower haes been <strong>delytit</strong>.\nYe can see it; the details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} delytion log].",
"search-result-category-size": "{{PLURAL:$1|1 memmer|$1 memmers}} ({{PLURAL:$2|1 subcategerie|$2 subcategeries}}, {{PLURAL:$3|1 file|$3 files}})",
"search-redirect": "(reguide $1)",
"search-section": "(section $1)",
+ "search-category": "(categerie $1)",
"search-file-match": "(matches file content.)",
"search-suggest": "Did ye mean: $1",
"search-interwiki-caption": "Sister projec's",
"searchall": "aw",
"showingresults": "Shawin ablo up tae {{PLURAL:$1|'''1''' ootcome|'''$1''' ootcomes}} stertin wi #'''$2'''.",
"showingresultsinrange": "Shawin ablo up til {{PLURAL:$1|<strong>1</strong> ootcome|<strong>$1</strong> ootcome}} in range #<strong>$2</strong> til #<strong>$3</strong>.",
+ "search-showingresults": "{{PLURAL:$4|Ootcome <strong>$1</strong> o <strong>$3</strong>|Ootcomes <strong>$1 - $2</strong> o <strong>$3</strong>}}",
"search-nonefound": "Thaur were naw ootcomes matchin the speiring.",
"powersearch-legend": "Advanced rake",
"powersearch-ns": "Rake in namespaces:",
"restoreprefs": "Restore aw defaut settins (in aw sections)",
"prefs-editing": "Eeditin",
"rows": "Raws:",
+ "columns": "Columns:",
"searchresultshead": "Rake ootcome settins",
"stub-threshold": "Threeshaud fer <a href=\"#\" class=\"stub\">stub airtin</a> formattin (bytes):",
"stub-threshold-disabled": "Disablt",
"prefs-help-recentchangescount": "This includes recent chynges, page histories, n logs.",
"prefs-help-watchlist-token2": "This is the hidlins key til the wab feed o yer watchleet. Onibodie wha kens this can read yer watchleet, sae dinna shair it. Gif ye need to, [[Special:ResetTokens|Ye can reset it]].",
"savedprefs": "Yer preferences haes been hained.",
+ "timezonelegend": "Time zone:",
+ "localtime": "Local time:",
"timezoneuseserverdefault": "Uise wiki defaut ($1)",
"timezoneuseoffset": "Ither (speceefie affset)",
"servertime": "Server time the nou",
"timezoneregion-atlantic": "Atlaunteec Ocean",
"timezoneregion-australia": "Australie",
"timezoneregion-europe": "Europ",
+ "timezoneregion-indian": "Indian Ocean",
"timezoneregion-pacific": "Paceefic Ocean",
"allowemail": "Allou email fae ither uisers",
"prefs-searchoptions": "Rake",
+ "prefs-namespaces": "Namespaces",
"default": "defaut",
"prefs-files": "Files",
"prefs-custom-css": "Custom CSS",
"gender-female": "She eedits wiki pages",
"prefs-help-gender": "Settin this preference is aen optie.\nThe saffware uises its value tae address ye n tae mention ye til ithers uisin the appropriate grammatical gender.\nThis information will be publeec.",
"email": "E-mail",
- "prefs-help-realname": "Real name is aen optie.\nGif ye chuise tae provide it, this will be uised fer giein ye attreebution fer yer wark.",
+ "prefs-help-realname": "Real name is aen optie.\nGif ye chuise tae provide it, this will be uised fer giein ye attreebution fer yer wirk.",
"prefs-help-email": "Wab-mail is optional, bit is needed fer passwaird resets, shid ye ferget yer passwaird.",
"prefs-help-email-others": "Ye can chuise tae let ithers contact ye bi wab-mail through ae link oan yer uiser or tauk page.\nYer wab-mail address isna revealed whan ither uisers contact ye.",
"prefs-help-email-required": "Yer e-mail address is needit.",
+ "prefs-info": "Baseec information",
"prefs-i18n": "Internaitionalisation",
"prefs-signature": "Signatur",
+ "prefs-dateformat": "Date format",
"prefs-timeoffset": "Time affset",
"prefs-advancedediting": "General opties",
"prefs-editor": "Eediter",
"prefs-advancedwatchlist": "Advanced opties",
"prefs-displayrc": "Displey opties",
"prefs-displaywatchlist": "Displey opties",
+ "prefs-tokenwatchlist": "Token",
"prefs-diffs": "Diffs",
"prefs-help-prefershttps": "This preeferance will tak effect oan yer nex login.",
+ "prefswarning-warning": "Ye'v makit chynges tae yer preferances that'v no been hained yet.\nGif ye leave this page wioot clapin \"$1\" than yer preferances 'll no be updatit.",
"prefs-tabs-navigation-hint": "Tip: Ye can uise the cair n richt arrae keys tae naveegate atween the tabs in the tabs leet.",
"email-address-validity-valid": "Wab-mail address appears tae be valid",
"email-address-validity-invalid": "Enter ae valid wab-mail address",
"group-autoconfirmed": "Autæconfirmed uisers",
"group-bot": "Bots",
"group-sysop": "Admeenistraters",
+ "group-bureaucrat": "Bureaucrats",
"group-suppress": "Owersichts",
"group-all": "(aw)",
"group-user-member": "{{GENDER:$1|uiser}}",
"group-autoconfirmed-member": "{{GENDER:$1|autæconfirmed uiser}}",
"group-bot-member": "{{GENDER:$1|bot}}",
"group-sysop-member": "{{GENDER:$1|admeenistrater}}",
+ "group-bureaucrat-member": "{{GENDER:$1|bureaucrat}}",
"group-suppress-member": "{{GENDER:$1|owersicht}}",
"grouppage-user": "{{ns:project}}:Uisers",
"grouppage-autoconfirmed": "{{ns:project}}:Autæconfirmed uisers",
+ "grouppage-bot": "{{ns:project}}:Bots",
"grouppage-sysop": "{{ns:project}}:Admeenistraters",
+ "grouppage-bureaucrat": "{{ns:project}}:Bureaucrats",
"grouppage-suppress": "{{ns:project}}:Owersicht",
+ "right-read": "Read pages",
"right-edit": "Eedit pages",
"right-createpage": "Cræft pages (that arna tauk pages)",
"right-createtalk": "Cræft discussion pages",
"right-move": "Muiv pages",
"right-move-subpages": "Muiv pages wi thair subpages",
"right-move-rootuserpages": "Muiv ruit uiser pages",
+ "right-move-categorypages": "Muiv categerie pages",
"right-movefile": "Muiv files",
"right-suppressredirect": "Na cræft reguidals fae soorce pages whan muivin pages",
"right-upload": "Uplaid files",
"right-browsearchive": "Rake delytit pages",
"right-undelete": "Ondelyte ae page",
"right-suppressrevision": "See, skauk n onskauk speceefic reveesions o pages fae onie uiser",
+ "right-viewsuppressed": "See owerluiks that'r skaukt fae onie uiser",
"right-suppressionlog": "see preevate logs",
"right-block": "Block ither uisers fae eeditin",
"right-blockemail": "Block ae uiser fae sendin wab-mail",
"right-protect": "Chynge protection levels n eedit cascade-protected pages",
"right-editprotected": "Eedit pages protected aes \"{{int:protect-level-sysop}}\"",
"right-editsemiprotected": "Eedit pages protected aes \"{{int:protect-level-autoconfirmed}}\"",
+ "right-editcontentmodel": "Eedit the content model o ae page",
"right-editinterface": "Eedit the uiser interface",
"right-editusercssjs": "Eedit ither uisers' CSS n JavaScript files",
"right-editusercss": "Eedit ither uisers' CSS files",
"newuserlogpagetext": "This is ae log o uiser cræftins.",
"rightslog": "Uiser richts log",
"rightslogtext": "This is a log o chynges tae uiser richts.",
+ "action-read": "read this page",
"action-edit": "eedit this page",
"action-createpage": "cræft pages",
"action-createtalk": "cræft discussion pages",
"action-createaccount": "cræft this uiser accoont",
+ "action-history": "see the histerie o this page",
"action-minoredit": "maurk this eedit aes smaa",
"action-move": "muiv this page",
"action-move-subpages": "mui this page, n its subpages",
"action-move-rootuserpages": "muiv ruit uiser pages",
+ "action-move-categorypages": "muiv categerie pages",
"action-movefile": "muiv this file",
"action-upload": "uplaid this file",
"action-reupload": "owerwrite this exeestin file",
"action-viewmywatchlist": "see yer watchleet",
"action-viewmyprivateinfo": "see yer preevate information",
"action-editmyprivateinfo": "eedit yer preevate information",
+ "action-editcontentmodel": "eedit the content model o ae page",
"nchanges": "$1 {{PLURAL:$1|chynge|chynges}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sin laist veesit}}",
"enhancedrc-history": "histeri",
"recentchanges-label-bot": "This eedit wis performed bi ae bot",
"recentchanges-label-unpatrolled": "This eedit haes no bin patrolled yet",
"recentchanges-label-plusminus": "The page size chynged bi this nummer o bytes",
+ "recentchanges-legend-heading": "'''Legend:'''",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (see [[Special:NewPages|leet o new pages]] n aw)",
"rcnotefrom": "Ablo {{PLURAL:$5|is the chynge|ar the chynges}} sin <strong>$3, $4</strong> (up tae <strong>$1</strong> shawn).",
"rclistfrom": "Shaw new chynges stertin fae $3 $2",
"rc_categories": "Limit til categeries (separate wi \"|\")",
"rc_categories_any": "Onie",
"rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} efter chynge",
+ "newsectionsummary": "/* $1 */ new section",
"rc-enhanced-expand": "Shaw details",
"rc-enhanced-hide": "Skauk details",
"rc-old-title": "oreeginlie cræftit aes \"$1\"",
"upload-recreate-warning": "'''Warnishment: Ae file bi that name haes been delytit or muived.'''\n\nThe delytion n muiv log fer this page ar gien here fer conveeneeance:",
"uploadtext": "Uise the form ablo tae uplaid files.\nTae see or rake aforegaun uplaided files gang til the [[Special:FileList|leet o uplaided files]], (re)uplaids ar loggit in the [[Special:Log/upload|uplaid log]] aes weel, n delytions in the [[Special:Log/delete|delytion log]].\n\nTae incluid ae file in ae page, uise aen airtin in yin o the follaein forms:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong> tae uise the ful version o the file\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt tex]]</nowiki></code></strong> tae uise ae 200 pixel wide rendeetion in ae kist in the cair margin wi \"alt tex\" aes descreeption\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> fer linkin directlie til the file wioot displeyin the file.",
"upload-permitted": "Permitit file types: $1.",
+ "upload-preferred": "Preferred file types: $1.",
"upload-prohibited": "Proheebited file types: $1.",
"uploadlogpage": "Uplaid log",
"uploadlogpagetext": "Ablo is ae leet o the maist recynt file uplaids.\nSee the [[Special:NewFiles|gallerie o new files]] fer ae mair veesual luikower.",
+ "filename": "Filename",
"filedesc": "Ootline",
"fileuploadsummary": "Ootline:",
"filereuploadsummary": "File chynges:",
"license-nopreview": "(Luikower naw available)",
"upload_source_url": "(yer chosen file fae ae valid, publeeclie accessible URL)",
"upload_source_file": "(yer chosen file fae yer computer)",
+ "listfiles-delete": "delyte",
"listfiles-summary": "This speecial page shaws aw uplaided files.",
"listfiles_search_for": "Rake fer media name:",
"imgfile": "file",
"listfiles": "The file leet",
"listfiles_thumb": "Thummnail",
+ "listfiles_date": "The Date",
"listfiles_name": "Name",
"listfiles_user": "Uiser",
"listfiles_size": "Size",
"listfiles_description": "Descreeption",
+ "listfiles_count": "Versions",
"listfiles-show-all": "Incluide auld versions o eemages",
"listfiles-latestversion": "The Nou version",
"listfiles-latestversion-yes": "Ay",
"filehist-nothumb": "Naw thummnail",
"filehist-user": "Uiser",
"filehist-dimensions": "Dimensions",
+ "filehist-filesize": "The File size",
"filehist-comment": "Comment",
"imagelinks": "File uisage",
"linkstoimage": "The follaein {{PLURAL:$1|page airts|$1 pages airt}} tae this file:",
"randomincategory": "Random page in categerie",
"randomincategory-invalidcategory": "\"$1\" isna ae valid categerie name.",
"randomincategory-nopages": "Thaur's naw pages in the [[:Category:$1|$1]] categerie.",
+ "randomincategory-category": "Categerie:",
+ "randomincategory-legend": "Random page in categerie",
"randomredirect": "Random reguidal",
"randomredirect-nopages": "Thaur's naw reguidals in the namespace \"$1\".",
"statistics": "Stateestics",
"statistics-header-edits": "Eidit stateestics",
"statistics-header-users": "Uiser stateestics",
"statistics-header-hooks": "Ither stateestics",
+ "statistics-articles": "Content pages",
"statistics-pages": "Pages",
"statistics-pages-desc": "Aw pages in the wiki, incluidin tauk pages, reguidals, etc.",
"statistics-files": "Uplaided files",
"fewestrevisions": "Pages wi the fewest reeveesions",
"nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
"ncategories": "$1 {{PLURAL:$1|categerie|categeries}}",
+ "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwikis}}",
"nlinks": "$1 {{PLURAL:$1|airtin|airtins}}",
"nmembers": "$1 {{PLURAL:$1|memmer|memmers}}",
"nmemberschanged": "$1 → $2 {{PLURAL:$2|memmer|memmers}}",
"wantedpages-badtitle": "Onvalid title in ootcome set: $1",
"wantedfiles": "Wantit files",
"wantedfiletext-cat": "The follaein files ar uised but dinna exeest. Files fae foreign repositeries micht be leetit despite exeestin. Onie sic false poseeteeves will be <del>struck oot</del>. Addeetionallie, pages that embed files that dinna exeest ar leetit in [[:$1]].",
+ "wantedfiletext-cat-noforeign": "The follaein files ar uised but dinna exeest. Mair than that, pages that embed files that dinna exeest ar leetit in [[:$1]].",
"wantedfiletext-nocat": "The follaein files ar uised but dinna exeest. Files fae foreign repositeries micht be leetit despite exeestin. Onie sic false poseeteeves will be <del>struck oot</del>.",
+ "wantedfiletext-nocat-noforeign": "The folleain files ar uised but dinna exeest.",
"wantedtemplates": "Wantit templates",
"mostlinked": "Maist airtit-tae pages",
"mostlinkedcategories": "Maist airtit-tae categeries",
"prefixindex": "Aw pages wi prefix",
"prefixindex-namespace": "Aw pages wi preefix ($1 namespace)",
"prefixindex-strip": "Strip preefix in leet",
+ "shortpages": "Short pages",
"longpages": "Lang pages",
"deadendpages": "Deid-end pages",
"deadendpagestext": "The follaein pages dinna link til ither pages in {{SITENAME}}.",
"pager-older-n": "{{PLURAL:$1|aulder 1|aulder $1}}",
"suppress": "Owersicht",
"querypage-disabled": "This speecial page is disablit fer performance raisons.",
+ "apihelp": "API help",
+ "apihelp-no-such-module": "Module \"$1\" wis no foond.",
"booksources": "Buik soorces",
"booksources-search-legend": "Rake fer buik soorces",
+ "booksources-search": "Rake",
"booksources-text": "Ablo is ae leet o airtins til ither steids that sell new n uised buiks, n micht hae further information aneat buiks that ye'r seekin ava:",
"booksources-invalid-isbn": "The gien ISBN disna seem tae be valid; check fer mistaks copiein fae the oreeginal soorce.",
"specialloguserlabel": "Performer:",
"listgrouprights-removegroup-self": "Remuiv {{PLURAL:$2|groop|groops}} fae yer accoont: $1",
"listgrouprights-addgroup-self-all": "Eik aw groops til yer accoont",
"listgrouprights-removegroup-self-all": "Remuiv aw groops fae yer accoont",
+ "listgrouprights-namespaceprotection-header": "Namespace restreections",
+ "listgrouprights-namespaceprotection-namespace": "Namespace",
+ "listgrouprights-namespaceprotection-restrictedto": "Richt(s) allooing ae uiser tae eedit",
"trackingcategories": "Keepin track o categeries",
"trackingcategories-summary": "This page leets the trackin categeries that ar autæmateecallie populatit bi the MediaWiki saffware. Thair names can be chynged bi alterin the reelavant system messages in the {{ns:8}} namespace.",
"trackingcategories-msg": "The Trackin Categerie",
"emailto": "Til:",
"emailsubject": "Aneat:",
"emailmessage": "Message:",
+ "emailsend": "Send",
"emailccme": "Wab-mail me ae copie o ma message.",
"emailccsubject": "Copie o yer message til $1: $2",
"emailsent": "Wab-mail sent",
"watchnologin": "Nae loggit in",
"addwatch": "Eik til watchleet",
"addedwatchtext": "The page \"[[:$1]]\" haes been added til yer [[Special:Watchlist|watchleet]].\nFutur chynges til this page n its associated tauk page will be leeted thaur.",
+ "addedwatchtext-short": "The page \"$1\" haes been eikit tae yer watchleet.",
"removewatch": "Remuiv fae watchleet",
"removedwatchtext": "The page \"[[:$1]]\" haes been remuied fae [[Special:Watchlist|yer watchleet]].",
+ "removedwatchtext-short": "The page \"$1\" haes been remuived fae yer watchleet.",
"watch": "Watch",
"watchthispage": "Watch this page",
"unwatch": "Onwatch",
"wlheader-enotif": "Wab-mail annooncemant is enabled.",
"wlheader-showupdated": "Pages that hae been chynged sin ye last veesitit thaim ar shawn in '''baud'''.",
"wlnote": "Ablo {{PLURAL:$1|is the laist chynge|ae the laist <strong>$1</strong> chynges}} in the laist {{PLURAL:$2|hoor|<strong>$2</strong> hoors}}, aes o $3, $4.",
- "wlshowlast": "Shaw hainmaist $1 hoors $2 days",
+ "wlshowlast": "Shaw the hainmaist $1 hoors $2 days",
"watchlist-options": "Watchleet opties",
"watching": "Watchin...",
"unwatching": "Onwatchin...",
"created": "cræftit",
"changed": "chynged",
"deletepage": "Delyte page",
+ "confirm": "Confirm",
"excontent": "content wis: '$1'",
"excontentauthor": "content wis: '$1' (n the ae contreebuter wis '[[Special:Contributions/$2|$2]]')",
"exbeforeblank": "content afore blankin wis: '$1'",
"delete-edit-reasonlist": "Eedit delytion raisons",
"delete-toobig": "This page haes ae muckle eedit histerie, ower $1 {{PLURAL:$1|reveesion|reveesions}}.\nDelytion o sic pages haes been restrictit tae stap accidental disruption o {{SITENAME}}.",
"delete-warning-toobig": "This page haes ae muckle eedit histerie, ower $1 {{PLURAL:$1|reveesion|reveesions}}.\nDelytin it micht disrupt database operations o {{SITENAME}};\nproceed wi caution.",
+ "deleteprotected": "Ye canna delyte this page cause it's been fended.",
"deleting-backlinks-warning": "'''Warnishment:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Ither pages]] airt til or transcluide the page ye'r aboot tae delyte.",
"rollback": "Row back eedits",
"rollback_short": "Rowback",
"revertpage": "Reverted eidits bi [[Special:Contributions/$2|$2]] ([[User talk:$2|tauk]]) til laist reveesion bi [[User:$1|$1]]",
"revertpage-nouser": "Reverted eedits bi ae skaukt uiser til laist revesion bi {{GENDER:$1|[[User:$1|$1]]}}",
"rollback-success": "Reverted eedits b $1;\nchynged back til the laist reveesion bi $2.",
+ "sessionfailure-title": "Session failure",
"sessionfailure": "Thaur seems tae be ae proablem wi yer login session;\nthis action haes been canceled aes ae precaution again session hijackin.\nGang back til the preeveeoos page, relaid that page n than gie it anither gae.",
"protectlogpage": "Fend log",
"protectlogtext": "Ablow is ae leet o chynges til page protections.\nSee the [[Special:ProtectedPages|protected pages leet]] fer the leet o currently operational page protections.",
"protect-title": "Chynge protection level fer \"$1\"",
"protect-title-notallowed": "See protection level o \"$1\"",
"prot_1movedto2": "[[$1]] muivit tae [[$2]]",
+ "protect-badnamespace-title": "No-fendable namespace",
"protect-badnamespace-text": "Pages in this namespace canna be protected.",
"protect-norestrictiontypes-text": "This page canna be protected aes thaur's naw restreection types available.",
+ "protect-norestrictiontypes-title": "No-fendable page",
+ "protect-legend": "Confirm fendin",
"protectcomment": "Raison:",
"protectexpiry": "Expires:",
"protect_expiry_invalid": "Expirie time is onvalit.",
"protect-othertime": "Ither time:",
"protect-othertime-op": "ither time",
"protect-existing-expiry": "Exeestin expirie time: $3, $2",
+ "protect-existing-expiry-infinity": "Exeestin expirie time: infeenit",
"protect-otherreason": "Ither/addeetional raison:",
"protect-otherreason-op": "Ither raison",
"protect-dropdown": "*Commyn protection raisons\n** Excesseeve vandaleesm\n** Excesseeve spammin\n** Coonter-producteeve eedit warrin\n** Hei traffeec page",
"restriction-level": "Restreection level:",
"minimum-size": "Smaaest size",
"maximum-size": "Mucklest size:",
+ "pagesize": "(bytes)",
"restriction-edit": "Eidit",
"restriction-move": "Muiv",
"restriction-create": "Creaut",
"undelete-revision": "Deleted reveesion o $1 (aes o $4, at $5) bi $3:",
"undeleterevision-missing": "Onvalid or missin reveesion.\nYe micht hae ae bad link, or the reveesion micht hae been restored or remuived fae the archive.",
"undelete-nodiff": "Naw preeveeoos reveesion foond.",
+ "undeletebtn": "Restore",
"undeletelink": "see/restore",
"undeleteviewlink": "see",
+ "undeleteinvert": "Invert the selection",
"undeletecomment": "Raison:",
"undeletedrevisions": "{{PLURAL:$1|1 reveesion|$1 reveesions}} restored",
"undeletedrevisions-files": "{{PLURAL:$1|1 reveesion|$1 reveesions}} n {{PLURAL:$2|1 file|$2 files}} restored",
+ "undeletedfiles": "{{PLURAL:$1|1 file|$1 files}} restored",
"cannotundelete": "Ondelyte failed:\n$1",
"undeletedpage": "<strong>$1 haes been restored</strong>\n\nConsult the [[Special:Log/delete|delytion log]] fer ae record o recynt delytions n restorations.",
"undelete-header": "See [[Special:Log/delete|the delytion log]] fer the recentlie delytit pages.",
"namespace": "Namespace:",
"invert": "Invert selection",
"tooltip-invert": "Check this kist tae skauk chynges til pages wiin the selectit namespace (n the associatit namespace gif checked)",
+ "namespace_association": "Associatit namespace",
"tooltip-namespace_association": "Check this kist foreby tae incluid the tauk or subject namespace associatit wi the selectit namespace",
"blanknamespace": "(Main)",
"contributions": "{{GENDER:$1|Uiser}} contributions",
"contributions-title": "Uiser contreebutions fer $1",
"mycontris": "Ma contreebutions",
"contribsub2": "Fer {{GENDER:$3|$1}} ($2)",
+ "contributions-userdoesnotexist": "Uiser accoont \"$1\" is no registerit.",
"nocontribs": "Nae chynges wis funnd matchin thir criteria.",
"uctop": "(current)",
"month": "Fae month (n afore):",
"ipbwatchuser": "Watch this uiser's uiser n tauk pages",
"ipb-disableusertalk": "Stap this uiser fae eeditin thair ain tauk page while blockit",
"ipb-change-block": "Re-block the uiser wi thir settins",
+ "ipb-confirm": "Confirm the block",
"badipaddress": "That IP address is nae guid",
"blockipsuccesssub": "Block succeedit",
"blockipsuccesstext": "[[Special:Contributions/$1|$1]] haes been blockit.\n<br />See [[Special:BlockList|block leet]] tae review blocks.",
"unblocked": "[[User:$1|$1]] haes been onblockit.",
"unblocked-range": "$1 haes been onblockit.",
"unblocked-id": "Block $1 haes been remuived.",
+ "unblocked-ip": "[[Special:Contributions/$1|$1]] haes been onblockt.",
"blocklist": "Blockit uisers",
"ipblocklist": "Blockit uisers",
"ipblocklist-legend": "Fynd ae blockit uiser",
"blocklist-tempblocks": "Skauk temparie blocks",
"blocklist-addressblocks": "Skauk single IP blocks",
"blocklist-rangeblocks": "Skauk range blocks",
+ "blocklist-timestamp": "Timestamp",
"blocklist-target": "Tairget",
"blocklist-expiry": "Dies",
"blocklist-by": "Blockin admeen",
"blocklist-params": "Block boonds",
"blocklist-reason": "Raison",
"ipblocklist-submit": "Rake",
+ "ipblocklist-localblock": "Local block",
"ipblocklist-otherblocks": "Ither {{PLURAL:$1|block|blocks}}",
"infiniteblock": "infeenite",
"expiringblock": "dies oan $1 at $2",
"cant-see-hidden-user": "The uiser that ye'r attemptin tae block haes awreadie been blockit n skaukt.\nAes ye dinna hae the skaukuiser richt, ye canna see or eedit the uiser's block.",
"ipbblocked": "Ye canna block or onblock ither uisers cause ye yersel is blockit.",
"ipbnounblockself": "Yer na permitit tae onblock yersel.",
+ "lockdb": "Lock database",
"unlockdb": "Lowse database",
"lockdbtext": "Lockin the database will suspend the abeelitie o aw uisers tae eedit pages, chynge thair preeferences, eedit thair watchleets, n ither things needin chynges in the database. Please confirm that this is whit ye'r etlin tae dae, n that ye'll lowse the database whan yer maintenance is dun.",
"unlockdbtext": "Lowsin the database will gie back the abeelitie fer aa uisers tae eidit pages, chynge their preeferences, eidit their watchleets, an ither things needin chynges in the database. Please confirm that this is whit ye ettle tae dae.",
"lockconfirm": "Ai, Ah reellie want tae lock the database.",
"unlockconfirm": "Ai, Ah reellie want tae lowse the database.",
+ "lockbtn": "Lock database",
"unlockbtn": "Lowse database",
"locknoconfirm": "Ye didna tick the confirmation kist.",
"lockdbsuccesssub": "Database lock fine",
"movepagetalktext": "The associated tauk page will be autaematiclie muived alang wi it <strong>onless:</strong>\n*A no-tuim tauk page awreadie exeests unner the new name, or\n*Ye oncheck the kist ablo.\n\nIn thae cases, ye will hae tae muiv or merge the page manuallie gif ye sae desire.",
"movearticle": "Muiv page:",
"moveuserpage-warning": "<strong>Warnishment:</strong> Ye'r aboot tae muiv ae uiser page. Please tak tent that yinlie the page will be muivd n the uiser will <em>naw</em> be renamed.",
+ "movecategorypage-warning": "<strong>Wairnishment:</strong> Ye'r aboot tae muiv ae categerie page. Please mynd that yinlie the page'll be muived n onie pages in the auld categerie will <em>no</em> be recategerised intae the new categerie.",
"movenologintext": "Ye maun be a registert uiser n [[Special:UserLogin|loggit in]] tae muiv ae page.",
"movenotallowed": "Ye dinna hae permeession tae muiv pages.",
"movenotallowedfile": "Ye dinna hae permeession tae muiv files.",
"cant-move-user-page": "Ye dinna hae permeession tae muiv uiser pages (aside fae subpages).",
"cant-move-to-user-page": "Ye dinna hae permeession tae muiv ae page til ae uiser page (except til ae uiser subpage).",
+ "cant-move-category-page": "Ye dinna hae permeession tae muiv categerie pages.",
+ "cant-move-to-category-page": "Ye dinna hae permeession tae muiv ae page tae ae categerie page.",
"newtitle": "Til new teitle",
"move-watch": "Watch soorce page n tairget page",
"movepagebtn": "Muiv page",
"movepage-max-pages": "The mmucklest o $1 {{PLURAL:$1|page|pages}} haes been muived n naw mair will be muived autæmateeclie.",
"movelogpage": "Muiv log",
"movelogpagetext": "Ae leet o aw page muives is ablo.",
+ "movesubpage": "{{PLURAL:$1|Subpage|Subpages}}",
"movesubpagetext": "This page haes $1 {{PLURAL:$1|subpage|subpages}} shawn ablo.",
"movenosubpage": "This page haes naw subpages.",
"movereason": "Raison:",
"exportcuronly": "Inclæde juist the nou reveesion, naw the ful histerie",
"exportnohistory": "----\n<strong>Mynd:</strong> Exportin the ful histerie o pages throogh this form haes been disabled cause o performance raisons.",
"exportlistauthors": "Incluid ae ful leet o contreebuters fer ilka page",
+ "export-submit": "Export",
"export-addcattext": "Eik pages fae categerie:",
+ "export-addcat": "Eik",
"export-addnstext": "Eik pages fae namespace:",
+ "export-addns": "Eik",
"export-download": "Hain aes file",
"export-templates": "Incluid templates",
"export-pagelinks": "Incluid linkt pages til ae depth o:",
"allmessagescurrent": "Message tex the nou",
"allmessagestext": "This is ae leet o seestem messages available in the MediaWiki namespace.\nPlease veesit [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] n [//translatewiki.net translatewiki.net] gif ye wish tae contreebute tae the generic MediaWiki localisation.",
"allmessagesnotsupportedDB": "This page canna be uised cause <strong>$wgUseDatabaseMessages</strong> haes been disablt.",
+ "allmessages-filter-legend": "Filter",
"allmessages-filter": "Filter b custymization state:",
"allmessages-filter-unmodified": "Onmodified",
"allmessages-filter-all": "Aw",
"thumbnail_gd-library": "Oncompleate GD librie confeeguration: Missin function $1",
"thumbnail_image-missing": "File seems tae be missin: $1",
"thumbnail_image-failure-limit": "Thaur hae been ower monie recynt failed attempts ($1 or mair) tae render this thummnail. Please ettle again later.",
+ "import": "Import pages",
+ "importinterwiki": "Transwiki import",
"import-interwiki-text": "Select ae wiki n page title tae import.\nReveesion dates n eediters' names will be preserved.\nAw transwiki import actions ar loggit at the [[Special:Log/import|import log]].",
+ "import-interwiki-sourcewiki": "The Soorce wiki:",
+ "import-interwiki-sourcepage": "The Soorce page:",
"import-interwiki-history": "Copie aw histerie reveesions fer this page",
"import-interwiki-templates": "Incluid aw templates",
+ "import-interwiki-submit": "Import",
"import-interwiki-namespace": "Desteenation namespace:",
"import-interwiki-rootpage": "Desteenation ruit page (aen optie):",
+ "import-upload-filename": "Filename:",
+ "import-comment": "Comment:",
"importtext": "Please export the file fae the soorce wiki uising the [[Special:Export|export utilitie]].\nHain it til yer computer n uplaid it here.",
"importstart": "Importin pages...",
"import-revision-count": "$1 {{PLURAL:$1|reveesion|reveesions}}",
"importnopages": "Naw pages tae import.",
"imported-log-entries": "Imported $1 {{PLURAL:$1|log entrie|log entries}}.",
+ "importfailed": "The Import failed: <nowiki>$1</nowiki>",
"importunknownsource": "Onkent import soorce type",
"importcantopen": "Coudna apen import file",
+ "importbadinterwiki": "Bad interwiki airtin",
"importsuccess": "Importit fine!",
"importnosources": "Nae transwiki import soorces haes been defined n direct histerie uplaids is disabled.",
"importnofile": "Naw import file wis uplaided.",
"importuploaderrorsize": "Uplaid o import file failed.\nThe file is muckler than the permitit uplaid size.",
"importuploaderrorpartial": "Uplaid o import file failed.\nThe file wis yinlie pairtlie uplaided.",
"importuploaderrortemp": "Uplaid o import file failed.\nAe temparie fauder is missin.",
+ "import-parse-failure": "XML import parse failure",
"import-noarticle": "Naw page tae import!",
"import-nonewrevisions": "Nae reveesions imported (aw were either awreadie present, or skipt cause o mistaks).",
+ "xml-error-string": "$1 oan line $2, col $3 (byte $4): $5",
"import-upload": "Uplaid XML data",
"import-token-mismatch": "Loss o session data.\nPlease gie it anither gae.",
"import-invalid-interwiki": "Canna import fae the speceefied wiki.",
"import-options-wrong": "Wrang {{PLURAL:$2|optie|opties}}: <nowiki>$1</nowiki>",
"import-rootpage-invalid": "Gien ruit page is aen onvalit title.",
"import-rootpage-nosubpage": "Namespace \"$1\" o the ruit page disna permit subpages.",
+ "importlogpage": "The Import log",
"importlogpagetext": "Admeenistrateeve imports o pages wi eedit histerie fae ither wikis.",
"import-logentry-upload": "imported [[$1]] bi file uplaid",
"import-logentry-upload-detail": "$1 {{PLURAL:$1|reveesion|reveesions}} importit",
+ "import-logentry-interwiki": "transwikied $1",
"import-logentry-interwiki-detail": "$1 {{PLURAL:$1|reveesion|reveesions}} importit fae $2",
"javascripttest": "JavaScript testin",
"javascripttest-title": "Rinnin $1 tests",
"javascripttest-pagetext-frameworks": "Please chuise yin o the follaein testin framewairks: $1",
"javascripttest-pagetext-skins": "Chuise ae skin tae rin the tests wi:",
"javascripttest-qunit-intro": "See [$1 testin documentation] oan mediawiki.org.",
+ "javascripttest-qunit-heading": "MediaWiki JavaScript QUnit test suite",
"tooltip-pt-userpage": "Yer uiser page",
"tooltip-pt-anonuserpage": "The uiser page fer the IP address that ye'r eeditin aes",
"tooltip-pt-mytalk": "Yer tauk page",
"tooltip-pt-mycontris": "Leet o yer contreebutions",
"tooltip-pt-login": "It's ae guid idea tae log in, but ye dinna hae tae.",
"tooltip-pt-logout": "Log oot",
+ "tooltip-pt-createaccount": "We encoorage ye tae creaute aen accoont n log in; houever, it's no strictllie nesisair",
"tooltip-ca-talk": "Discussion aneat the content page",
"tooltip-ca-edit": "Ye can eedit this page. Please uise the luikower button afore hainin",
"tooltip-ca-addsection": "Stairt ae new section",
"tooltip-feed-atom": "Atom feed fer this page",
"tooltip-t-contributions": "See ae leet o this uiser's contreebutions",
"tooltip-t-emailuser": "Send ae wab-mail til this uiser",
+ "tooltip-t-info": "Mair information aneat this page",
"tooltip-t-upload": "Uplaid files",
"tooltip-t-specialpages": "Ae leet o aw byordinar pages",
"tooltip-t-print": "Prentable version o this page",
"anonusers": "{{SITENAME}} anonymoos {{PLURAL:$2|uiser|uisers}} $1",
"creditspage": "Page creeedits",
"nocredits": "Thaur's nae creedit info available fer this page.",
+ "spamprotectiontitle": "Spam protection filter",
"spamprotectiontext": "The tex ye wished tae save wis blockit bi the spam filter.\nThis is maistlikly caused bi aen airtin til ae blaickleeted external site.",
"spamprotectionmatch": "The follaein tex is whit triggered wir spam filter: $1",
+ "spambot_username": "MediaWiki spam cleanup",
"spam_reverting": "Revertin til the laist reveesion na containin links til $1",
"spam_blanking": "Aw reveesions contained links til $1, blankin",
"spam_deleting": "Aw reveesions contained links til $1, delytin",
"simpleantispam-label": "Anti-spam check.\nDiv <strong>NAW</strong> ful this in!",
"pageinfo-title": "Information fer \"$1\"",
"pageinfo-not-current": "Sairrie, it's na possible tae provide this information fer auld reveesions.",
+ "pageinfo-header-basic": "Baseec information",
"pageinfo-header-edits": "Eedit histerie",
+ "pageinfo-header-restrictions": "Page fendin",
+ "pageinfo-header-properties": "Page properties",
"pageinfo-display-title": "Displey title",
"pageinfo-default-sort": "Defaut sort key",
+ "pageinfo-length": "Page langth (in bytes)",
+ "pageinfo-article-id": "The Page ID",
"pageinfo-language": "Page content leid",
+ "pageinfo-content-model": "The Page content model",
"pageinfo-robot-policy": "Indexin bi robots",
"pageinfo-robot-index": "Permitit",
"pageinfo-robot-noindex": "Na permitit",
"pageinfo-hidden-categories": "Skaukt {{PLURAL:$1|categerie|categeries}} ($1)",
"pageinfo-templates": "Transcluided {{PLURAL:$1|template|templates}} ($1)",
"pageinfo-transclusions": "{{PLURAL:$1|Page|Pages}} transcluided oan ($1)",
+ "pageinfo-toolboxlink": "Page information",
"pageinfo-redirectsto": "Reguidals til",
+ "pageinfo-redirectsto-info": "info",
"pageinfo-contentpage": "Coonted aes ae content page",
"pageinfo-contentpage-yes": "Ay",
"pageinfo-protect-cascading": "Protections ar cascadin fae here",
"mediawarning": "<strong>Warnishment:</strong> This file type micht contain maleecious code.\nBi executin it, yer system micht be compromised.",
"imagemaxsize": "Eemage size leemit:<br /><em>(fer file descreeption pages)</em>",
"thumbsize": "Thummnail size:",
+ "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|page|pages}}",
+ "file-info": "file size: $1, MIME type: $2",
"file-info-size": "$1 × $2 pixels, file size: $3, MIME type: $4",
+ "file-info-size-pages": "$1 × $2 pixels, file size: $3, MIME type: $4, $5 {{PLURAL:$5|page|pages}}",
"file-nohires": "Nae heier resolution available.",
"svg-long-desc": "SVG file, nominallie $1 × $2 pixels, file size: $3",
"svg-long-desc-animated": "Animated SVG file, nominallie $1 × $2 pixels, file size: $3",
"show-big-image": "Oreeginal file",
"show-big-image-preview": "Size o this luikower: $1.",
"show-big-image-other": "Ither {{PLURAL:$2|resolution|resolutions}}: $1.",
+ "show-big-image-size": "$1 × $2 pixels",
"file-info-gif-looped": "luip't",
+ "file-info-gif-frames": "$1 {{PLURAL:$1|frame|frames}}",
"file-info-png-looped": "luip't",
"file-info-png-repeat": "pleyed $1 {{PLURAL:$1|time|times}}",
+ "file-info-png-frames": "$1 {{PLURAL:$1|frame|frames}}",
"file-no-thumb-animation": "<strong>Mynd: Due til techneecal limitations, thummnails o this file will na be animated.</strong>",
"file-no-thumb-animation-gif": "<strong>Mynd: Due til techneecal limitations, thummnails o hei resolution GIF eemages sic aes this will na be animated.</strong>",
"newimages": "Gallerie o new files",
"imagelisttext": "Ablo is a leet o $1 {{PLURAL:$1|eemage|eemages}} sortit $2.",
"newimages-summary": "This byordinair page shaws the last uplaidit files.",
+ "newimages-legend": "Filter",
"newimages-label": "Filename (or ae pairt o it):",
+ "newimages-showbots": "Shaw uplaids bi bots",
"noimages": "Nawthing tae see.",
"ilsubmit": "Rake",
"bydate": "bi date",
"sp-newimages-showfrom": "Shaw new files stairtin fae $2, $1",
"seconds": "{{PLURAL:$1|$1 seicont|$1 seiconts}}",
+ "minutes": "{{PLURAL:$1|$1 minute|$1 minutes}}",
"hours": "{{PLURAL:$1|$1 hoor|$1 hoors}}",
+ "days": "{{PLURAL:$1|$1 day|$1 days}}",
+ "weeks": "{{PLURAL:$1|$1 week|$1 weeks}}",
+ "months": "{{PLURAL:$1|$1 month|$1 months}}",
+ "years": "{{PLURAL:$1|$1 year|$1 years}}",
"ago": "$1 sin",
"just-now": "richt nou",
"hours-ago": "$1 {{PLURAL:$1|hoor|hoors}} sin",
"minutes-ago": "$1 {{PLURAL:$1|minute|minutes}} sin",
"seconds-ago": "$1 {{PLURAL:$1|seicont|seiconts}} sin",
"monday-at": "Monenday at $1",
+ "tuesday-at": "Tuesday at $1",
"wednesday-at": "Wedensday at $1",
+ "thursday-at": "Thursday at $1",
"friday-at": "Frisday at $1",
+ "saturday-at": "Saturday at $1",
+ "sunday-at": "Sunday at $1",
+ "yesterday-at": "Yesterday at $1",
"bad_image_list": "The format is aes follaes:\n\nAinlie leet eetems (lines stairtin wi *) ar considered. The foremaist airtin oan ae line maun be aen airtin til aen ill file. Onie subsequent airtins oan the same line ar considered tae be exceptions, i,e., pages whaur the eemage can occur inline.",
"metadata": "Metadata",
"metadata-help": "This file contains addeetional information, likelie eikit fae the deegital camera or scanner uised tae cræft or deegitise it. \nGif the file haes bin modeefied fae its oreeginal state, some details micht na fullie reflect the modeefied file.",
"metadata-expand": "Shaw extendit details",
"metadata-collapse": "Skauk extendit details",
"metadata-fields": "Eemage metadata fields leetit in this message will be incluidit oan eemage page displey whan the metadata buird is collaps't. Ithers will be skaukt bi defaut. \n* mak\n* model\n* datetimeoreeginal\n* exposuretime\n* fnummer\n* isospeedratins\n* focallength\n* airtist\n* copiericht\n* eemagedescreeption\n* gpslateetuid\n* gpslangeetuid\n* gpsalteetuid",
+ "exif-imagewidth": "Width",
"exif-imagelength": "Heicht",
+ "exif-bitspersample": "Bits per component",
+ "exif-compression": "Compression scheme",
"exif-photometricinterpretation": "Pixel composeetion",
+ "exif-orientation": "Orientation",
"exif-samplesperpixel": "Nummer o components",
+ "exif-planarconfiguration": "Data arrangement",
"exif-ycbcrsubsampling": "Subsamplin ratio o Y til C",
"exif-ycbcrpositioning": "Y n C poseetionin",
+ "exif-xresolution": "Horizontal resolution",
"exif-yresolution": "Verteecal resolution",
"exif-stripoffsets": "Eemage data location",
"exif-rowsperstrip": "Nummer o raws per streep",
"exif-referenceblackwhite": "Pair o blaick n white referance values",
"exif-datetime": "File chynge date n time",
"exif-imagedescription": "Eemage title",
+ "exif-make": "Camera manufacturer",
+ "exif-model": "The Camera model",
"exif-software": "Saffware uised",
"exif-artist": "Writer",
"exif-copyright": "Copiericht hauder",
+ "exif-exifversion": "Exif version",
"exif-flashpixversion": "Supportit Flashpix version",
"exif-colorspace": "Colour space",
"exif-componentsconfiguration": "Meanin o ilka component",
"exif-subsectime": "DateTime subseiconts",
"exif-subsectimeoriginal": "DateTimeOreeginal subseiconts",
"exif-subsectimedigitized": "DateTimeDeegeetized subseiconts",
+ "exif-exposuretime": "Exposure time",
+ "exif-exposuretime-format": "$1 sec ($2)",
"exif-fnumber": "F Nummer",
+ "exif-exposureprogram": "Exposure Program",
"exif-spectralsensitivity": "Spectral sensiteevitie",
"exif-isospeedratings": "ISO speed ratin",
+ "exif-shutterspeedvalue": "APEX shutter speed",
+ "exif-aperturevalue": "APEX aperture",
"exif-brightnessvalue": "APEX brichtness",
+ "exif-exposurebiasvalue": "APEX exposure bias",
"exif-maxaperturevalue": "Mucklest launn aperture",
+ "exif-subjectdistance": "Subject distance",
"exif-meteringmode": "Meterin mode",
"exif-lightsource": "Licht soorce",
+ "exif-flash": "Flash",
+ "exif-focallength": "Lens focal langth",
"exif-subjectarea": "Subject airt",
"exif-flashenergy": "Flash energie",
+ "exif-focalplanexresolution": "Focal plane X resolution",
+ "exif-focalplaneyresolution": "Focal plane Y resolution",
+ "exif-focalplaneresolutionunit": "Focal plane resolution unit",
+ "exif-subjectlocation": "Subject location",
+ "exif-exposureindex": "Exposure index",
"exif-sensingmethod": "Sensin methyd",
"exif-filesource": "File soorce",
+ "exif-scenetype": "Scene type",
"exif-customrendered": "Custym eemage processin",
+ "exif-exposuremode": "Exposure mode",
+ "exif-whitebalance": "White balance",
"exif-digitalzoomratio": "Deegeetal zuim ratio",
+ "exif-focallengthin35mmfilm": "Focal length in 35 mm film",
+ "exif-scenecapturetype": "Scene captur type",
+ "exif-gaincontrol": "Scene control",
+ "exif-contrast": "Contrast",
+ "exif-saturation": "Saturation",
"exif-sharpness": "Shairpness",
"exif-devicesettingdescription": "Device settins descreeption",
"exif-subjectdistancerange": "Subject deestance range",
"exif-imageuniqueid": "Uníque eemage ID",
+ "exif-gpsversionid": "GPS tag version",
"exif-gpslatituderef": "Nort or sooth lateetude",
"exif-gpslatitude": "Lateetude",
"exif-gpslongituderef": "Aest or west langeetude",
"exif-gpstimestamp": "GPS time (atomeec clock)",
"exif-gpssatellites": "Satellites uised fer measurement",
"exif-gpsstatus": "Receever status",
+ "exif-gpsmeasuremode": "Measurement mode",
"exif-gpsdop": "Measurement preeceesion",
+ "exif-gpsspeedref": "Speed unit",
"exif-gpsspeed": "Speed o GPS receever",
"exif-gpstrackref": "Referance fer direction o muivement",
"exif-gpstrack": "Direction o muivement",
"exif-gpsdestdistance": "Distance til destination",
"exif-gpsprocessingmethod": "Name o GPS processin methyd",
"exif-gpsareainformation": "Name o GPS airt",
+ "exif-gpsdatestamp": "GPS date",
"exif-gpsdifferential": "GPS differantial correction",
+ "exif-jpegfilecomment": "JPEG file comment",
"exif-keywords": "Keywairds",
"exif-worldregioncreated": "Region o the Yird that the picture wis taen in",
"exif-countrycreated": "Kintra that the picture wis taen in",
"exif-provinceorstatedest": "Provínce or state shawn",
"exif-citydest": "Ceetie shawn",
"exif-sublocationdest": "Sublocation o ceetie shawn",
+ "exif-objectname": "Short title",
"exif-specialinstructions": "Byordiair insructions",
"exif-headline": "Heidline",
"exif-credit": "Creedit/Provider",
"exif-locationdest": "Location depeected",
"exif-locationdestcode": "Code o location depeected",
"exif-objectcycle": "Time o day that media is intended fer",
+ "exif-contact": "Contact information",
+ "exif-writer": "Writer",
"exif-languagecode": "Leid",
+ "exif-iimversion": "IIM version",
"exif-iimcategory": "Categerie",
"exif-iimsupplementalcategory": "Supplemental categeries",
"exif-datetimeexpires": "Dinna uise efter",
"exif-lens": "Lens uised",
"exif-serialnumber": "Serial nummer o camera",
"exif-cameraownername": "Ainer o camera",
+ "exif-label": "Label",
"exif-datetimemetadata": "Date metadata wis laist modeefied",
"exif-nickname": "Informal name o eemage",
"exif-rating": "Ratin (oot o 5)",
"exif-morepermissionsurl": "Alternative licensin information",
"exif-attributionurl": "Whan re-uisin this wairk, please link til",
"exif-preferredattributionname": "Whan re-uisin this wairk, please creedit",
+ "exif-pngfilecomment": "PNG file comment",
+ "exif-disclaimer": "Disclaimer",
"exif-contentwarning": "Content warnishment",
+ "exif-giffilecomment": "GIF file comment",
"exif-intellectualgenre": "Type o eetem",
+ "exif-subjectnewscode": "Subject code",
+ "exif-scenecode": "IPTC scene code",
"exif-event": "Event depected",
"exif-organisationinimage": "Organization depected",
"exif-personinimage": "Person depected",
"exif-copyrighted-true": "Copierichted",
"exif-copyrighted-false": "Copiericht status na set",
"exif-unknowndate": "Onkent date",
+ "exif-orientation-1": "Ordinair",
"exif-orientation-2": "Flipt horizontallie",
"exif-orientation-3": "Rotatit 180°",
"exif-orientation-4": "Flipt verticlie",
"exif-orientation-7": "Rotatit 90° CW n flipt verticlie",
"exif-orientation-8": "Rotatit 90° CW",
"exif-planarconfiguration-1": "chunkie format",
+ "exif-planarconfiguration-2": "planar format",
"exif-colorspace-65535": "Oncalibratit",
"exif-componentsconfiguration-0": "disna exeest",
"exif-exposureprogram-0": "Na defined",
+ "exif-exposureprogram-1": "Manual",
+ "exif-exposureprogram-2": "Ordinair program",
"exif-exposureprogram-3": "Apertur prioritie",
"exif-exposureprogram-4": "Shutter prioritie",
"exif-exposureprogram-5": "Cræftie program (biased thewaird the depth o field)",
"exif-exposureprogram-6": "Action program (biased thewaird fast shutter speed)",
"exif-exposureprogram-7": "Portrait mode (fer closeup photæs wi the backgroond oot o focus)",
"exif-exposureprogram-8": "Launnscape mode (fer launnscape photæs wi the backgroonn in focus)",
+ "exif-subjectdistance-value": "$1 meters",
"exif-meteringmode-0": "Onkent",
+ "exif-meteringmode-1": "Average",
"exif-meteringmode-2": "Center weichtit average",
+ "exif-meteringmode-3": "Spot",
"exif-meteringmode-4": "Multí-Spot",
+ "exif-meteringmode-5": "Pattern",
"exif-meteringmode-6": "Pairtial",
"exif-meteringmode-255": "Ither",
"exif-lightsource-0": "Onkent",
"exif-lightsource-1": "Daylicht",
"exif-lightsource-2": "Fluorescant",
"exif-lightsource-3": "Tungsten (incandescant licht)",
+ "exif-lightsource-4": "Flash",
+ "exif-lightsource-9": "Fine weather",
"exif-lightsource-10": "Cloodie weather",
+ "exif-lightsource-11": "Gloam",
"exif-lightsource-12": "Daylicht fluorescant (D 5700 – 7100K)",
"exif-lightsource-13": "Day white fluorescant (N 4600 – 5400K)",
"exif-lightsource-14": "Cuil white fluorescant (W 3900 – 4500K)",
"exif-lightsource-17": "Staunart licht A",
"exif-lightsource-18": "Staunart licht B",
"exif-lightsource-19": "Staunart licht C",
+ "exif-lightsource-24": "ISO studio tungsten",
"exif-lightsource-255": "Ither licht soorce",
"exif-flash-fired-0": "Flash didna fire",
+ "exif-flash-fired-1": "Flash fired",
"exif-flash-return-0": "naw flash return detection function",
"exif-flash-return-2": "flash return licht na detectit",
"exif-flash-return-3": "flash return licht detectit",
"exif-flash-mode-3": "autæ mode",
"exif-flash-function-1": "Naw flash function",
"exif-flash-redeye-1": "reid-ee reduction mode",
+ "exif-focalplaneresolutionunit-2": "inches",
"exif-sensingmethod-1": "Ondefined",
"exif-sensingmethod-2": "Yin-chip colour airt senser",
"exif-sensingmethod-3": "Twa-chip colour airt senser",
"exif-sensingmethod-8": "Colour sequential linear senser",
"exif-filesource-3": "Deegeetal still camera",
"exif-scenetype-1": "Ae directlie photægraphed eemage",
+ "exif-customrendered-0": "Ordinair process",
"exif-customrendered-1": "Custym process",
"exif-exposuremode-0": "Autæ exposure",
+ "exif-exposuremode-1": "Manual exposure",
"exif-exposuremode-2": "Autæ bracket",
"exif-whitebalance-0": "Autæ white balance",
+ "exif-whitebalance-1": "Manual white balance",
"exif-scenecapturetype-0": "Staunart",
"exif-scenecapturetype-1": "Launscape",
+ "exif-scenecapturetype-2": "Portrait",
"exif-scenecapturetype-3": "Nicht scene",
"exif-gaincontrol-0": "Nane",
"exif-gaincontrol-1": "Law gain up",
"exif-gaincontrol-2": "Hei gain up",
"exif-gaincontrol-3": "Law gain doon",
"exif-gaincontrol-4": "Hei gain doon",
+ "exif-contrast-0": "Ordinair",
"exif-contrast-1": "Saft",
"exif-contrast-2": "Haurd",
+ "exif-saturation-0": "Ordinair",
"exif-saturation-1": "Law saturation",
"exif-saturation-2": "Hei saturation",
+ "exif-sharpness-0": "Ordinair",
"exif-sharpness-1": "Saff",
"exif-sharpness-2": "Haurd",
"exif-subjectdistancerange-0": "Onkent",
+ "exif-subjectdistancerange-1": "Macro",
"exif-subjectdistancerange-2": "Claise luik at",
"exif-subjectdistancerange-3": "Distance sechtline",
"exif-gpslatitude-n": "Nort lateetude",
"exif-gpslongitude-w": "West langeetude",
"exif-gpsaltitude-above-sealevel": "$1 {{PLURAL:$1|meter|meters}} abuin sea level",
"exif-gpsaltitude-below-sealevel": "$1 {{PLURAL:$1|meter|meters}} ablo sea level",
+ "exif-gpsstatus-a": "Measurement in progress",
"exif-gpsstatus-v": "Measurement interoperabeelitie",
+ "exif-gpsmeasuremode-2": "2-dimensional measurement",
+ "exif-gpsmeasuremode-3": "3-dimensional measurement",
"exif-gpsspeed-k": "Kilometers aen hoor",
"exif-gpsspeed-m": "Miles aen hoor",
+ "exif-gpsspeed-n": "Knots",
+ "exif-gpsdestdistance-k": "Kilometers",
+ "exif-gpsdestdistance-m": "Miles",
"exif-gpsdestdistance-n": "Nauteecal miles",
"exif-gpsdop-excellent": "Excellant ($1)",
"exif-gpsdop-good": "Guid ($1)",
+ "exif-gpsdop-moderate": "Moderate ($1)",
+ "exif-gpsdop-fair": "Fair ($1)",
"exif-gpsdop-poor": "Puir ($1)",
"exif-objectcycle-a": "Mornin yinlie",
"exif-objectcycle-p": "Evenin yinlie",
"exif-objectcycle-b": "Baith mornin n evenin",
+ "exif-gpsdirection-t": "True direction",
"exif-gpsdirection-m": "Magneteec direction",
+ "exif-ycbcrpositioning-1": "Centerit",
+ "exif-ycbcrpositioning-2": "Co-steidit",
"exif-dc-contributor": "Contreebuters:",
"exif-dc-coverage": "Spatial or tempral scope o media",
+ "exif-dc-date": "Date(s)",
+ "exif-dc-publisher": "Publisher",
"exif-dc-relation": "Relatit media",
"exif-dc-rights": "Richts",
"exif-dc-source": "Soorce media",
"exif-iimcategory-clj": "Crime n law",
"exif-iimcategory-dis": "Disasters n accidants",
"exif-iimcategory-fin": "Economie n business",
+ "exif-iimcategory-edu": "Education",
+ "exif-iimcategory-evn": "Environment",
"exif-iimcategory-hth": "The Heal",
"exif-iimcategory-hum": "Fawk interest",
"exif-iimcategory-lab": "Laber",
"exif-iimcategory-rel": "Releegion n truent",
"exif-iimcategory-sci": "Sciance n technologie",
"exif-iimcategory-soi": "Social eessues",
+ "exif-iimcategory-spo": "Sports",
"exif-iimcategory-war": "War, conflict n onrest",
+ "exif-iimcategory-wea": "Weather",
+ "exif-urgency-normal": "Ordinair ($1)",
"exif-urgency-low": "Law ($1)",
"exif-urgency-high": "Hei ($1)",
"exif-urgency-other": "Uiser-defined prioritie ($1)",
"confirm_purge_button": "OK",
"confirm-purge-top": "Clair the cache o this page?",
"confirm-purge-bottom": "Purgin ae page clears the cache n forces the maist recynt reveesion tae appear.",
+ "confirm-watch-button": "OK",
"confirm-watch-top": "Eik this page til yer watchleet?",
+ "confirm-unwatch-button": "OK",
"confirm-unwatch-top": "Remuiv this page fae yer watchleet?",
+ "quotation-marks": "\"$1\"",
"imgmultipageprev": "← preeveeoos page",
"imgmultipagenext": "nex page →",
"imgmultigo": "Gang!",
"img-lang-default": "(defaut leid)",
"img-lang-info": "Render this eemage in $1. $2",
"img-lang-go": "Gang",
+ "ascending_abbrev": "asc",
+ "descending_abbrev": "desc",
"table_pager_next": "Page aifter",
"table_pager_prev": "Page afore",
+ "table_pager_first": "First page",
"table_pager_last": "Laist page",
"table_pager_limit": "Shaw $1 eetems per page",
"table_pager_limit_label": "Eetems per page:",
"autosumm-replace": "Replacin page wi '$1'",
"autoredircomment": "Reguidin til [[$1]]",
"autosumm-new": "Cræftit page wi \"$1\"",
+ "autosumm-newblank": "Creautit blank page",
"lag-warn-normal": "Chynges newer than $1 {{PLURAL:$1|seicont|seiconts}} micht na be shawn in this leet.",
"lag-warn-high": "Cause o hei database server lag, chynges newer than $1 {{PLURAL:$1|seicont|seiconts}} micht na be shawn in this leet.",
"watchlistedit-normal-title": "Eedit watchleet",
"watchlistedit-raw-title": "Eedit raw watchleet",
"watchlistedit-raw-legend": "Eedit raw watchleet",
"watchlistedit-raw-explain": "Titles oan yer watchleet ar shawn ablo, n can be eeditit bi eikin til n remuivin fae the leet;\nyin title per line.\nWhan dun, clap \"{{int:Watchlistedit-raw-submit}}\".\nYe can [[Special:EditWatchlist|uise the staundairt eediter]] n aw.",
+ "watchlistedit-raw-titles": "Titles:",
"watchlistedit-raw-submit": "Update watchleet",
"watchlistedit-raw-done": "Yer watchleet haes been updated.",
"watchlistedit-raw-added": "{{PLURAL:$1|1 title wis|$1 titles were}} added:",
"watchlistedit-raw-removed": "{{PLURAL:$1|1 title wis|$1 titles were}} remuived:",
+ "watchlistedit-clear-title": "Cleared watchleet",
+ "watchlistedit-clear-legend": "Clear watchleet",
+ "watchlistedit-clear-explain": "Aw o the titles will be remuived fae yer watchleet",
+ "watchlistedit-clear-titles": "Titles:",
+ "watchlistedit-clear-submit": "Clear the watchleet (This is fer aye!)",
+ "watchlistedit-clear-done": "Yer watchleet's been cleared.",
+ "watchlistedit-clear-removed": "{{PLURAL:$1|1 title wis|$1 titles were}} remuived:",
+ "watchlistedit-too-many": "Thaur's ower monie pages tae displey here.",
+ "watchlisttools-clear": "Clear the watchleet",
"watchlisttools-view": "See reelavant chynges",
"watchlisttools-edit": "See n eedit watchleet",
"watchlisttools-raw": "Eedit raw watchleet",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|tauk]])",
"unknown_extension_tag": "Onkent extension tag \"$1\"",
"duplicate-defaultsort": "<strong>Warnishment:</strong> Defaut sort key \"$2\" owerrides earlier defaut sort key \"$1\".",
+ "duplicate-displaytitle": "<strong>Warnishment:</strong> Displey title \"$2\" owerrides the earlier displey title \"$1\".",
+ "invalid-indicator-name": "<strong>Mistak:</strong> Page status indicaters' <code>name</code> attreebute maunna be tuim.",
+ "version": "Version",
"version-extensions": "Instawed extensions",
+ "version-skins": "Instawed skins",
"version-specialpages": "Byordinar pages",
"version-parserhooks": "Parser huiks",
"version-variables": "Vareeables",
+ "version-antispam": "Spam hinderance",
"version-other": "Ither",
"version-mediahandlers": "Media haunnlers",
"version-hooks": "Huiks",
+ "version-parser-extensiontags": "Parser extension tags",
"version-parser-function-hooks": "Parser function huiks",
"version-hook-name": "Huik name",
"version-hook-subscribedby": "Subscribed bi",
"version-no-ext-name": "[no name]",
+ "version-license": "MediaWiki License",
+ "version-ext-license": "License",
+ "version-ext-colheader-name": "Extension",
+ "version-skin-colheader-name": "Skin",
+ "version-ext-colheader-version": "Version",
+ "version-ext-colheader-license": "License",
"version-ext-colheader-description": "Descreeption",
"version-ext-colheader-credits": "Writers",
"version-license-title": "License fer $1",
"version-credits-summary": "We'd like tae recognize the follaein fawk fer thair contreebution til [[Special:Version|MediaWiki]].",
"version-license-info": "MediaWiki is free saffware; ye can reedistreebute it n/or modifie it unner the terms o the GNU General Public License aes publeesht bi the Free Software Foundation; either version 2 o the License, or (bi yer optie) onie later version.\n\nMediaWiki is distreebuted in the hope that it will be uissfu, bit WIOOT ONIE WARRANTIE; wioot even the implied warrantie o MERCHANTABILITIE or FITNESS FER AE PARTEECULAR PURPYSS. See the GNU General Public License fer mair details.\n\nYe shid hae receeved [{{SERVER}}{{SCRIPTPATH}}/COPIEIN ae copie o the GNU General Public License] alang wi this program; gif na, write til the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA or [//www.gnu.org/licenses/old-licenses/gpl-2.0.html read it online].",
"version-software": "Instawed saffware",
+ "version-software-product": "Product",
+ "version-software-version": "Version",
"version-entrypoints": "Entrie point URLs",
"version-entrypoints-header-entrypoint": "Entrie point",
+ "version-entrypoints-header-url": "URL",
"redirect": "Reguidal bi file, uiser, page or reveesion ID",
"redirect-legend": "Reguidal til ae file or page",
"redirect-summary": "This byordiair page reguides til ae file (gien the file name), ae page (gien ae reveesion ID or page ID), or ae uiser page (gien ae numereec uiser ID). Uissage: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/reveesion/328429]], or [[{{#Special:Redirect}}/uiser/101]].",
"redirect-submit": "Gang",
"redirect-lookup": "Luikup:",
+ "redirect-value": "Value:",
"redirect-user": "Uiser ID",
+ "redirect-page": "Page ID",
"redirect-revision": "Page reveesion",
+ "redirect-file": "File name",
"redirect-not-exists": "Value na foond",
"fileduplicatesearch": "Rake fer dupleecate files",
"fileduplicatesearch-summary": "Rake fer dupleecate files based oan hash values.",
"fileduplicatesearch-legend": "Rake fer ae dupleecate",
"fileduplicatesearch-filename": "Filename:",
"fileduplicatesearch-submit": "Rake",
+ "fileduplicatesearch-info": "$1 × $2 pixel<br />File size: $3<br />MIME type: $4",
"fileduplicatesearch-result-1": "The file \"$1\" haes naw identeecal dupleecation.",
"fileduplicatesearch-result-n": "The file \"$1\" haes {{PLURAL:$2|1 identeecal dupleecation|$2 identeecal dupleecations}}.",
"fileduplicatesearch-noresults": "Naw file named \"$1\" foond.",
"specialpages": "Byordinar pages",
+ "specialpages-note-top": "The Legend",
"specialpages-note": "* Normal byordinair pages.\n* <span class=\"mw-specialpagerestricted\">Restreected byordinair pages.</span>",
+ "specialpages-group-maintenance": "Maintenance reports",
"specialpages-group-other": "Ither byordinair pages",
"specialpages-group-login": "Login / cræft accoont",
"specialpages-group-changes": "Recynt chynges n logs",
"specialpages-group-wiki": "Data n tuils",
"specialpages-group-redirects": "Reguidin byordinair pages",
"specialpages-group-spam": "Spam tuils",
+ "specialpages-group-developer": "Deveeloper tuils",
+ "blankpage": "Blank page",
"intentionallyblankpage": "This page is intentionlie left blank.",
"external_image_whitelist": " #Lea this line exactlie aes it is<pre>\n#Put regulair expression fragments (jist the pairt that gaes atween the //) ablo\n#Thir will be matched wi the URLs o ootby (hotairtit) eemages\n#Thae that match will be displeyed aes eemages, itherwise yinlie aen airtin til the eemage will be shawn\n#Lines beginnin wi # ar treated aes comments\n#This is case-onsensiteeve\n\n#Put aw regex fragments abuin this line. Lea this line exactlie aes it is</pre>",
"tags": "Valit chynge tags",
"tag-filter": "[[Special:Tags|Tag]] filter:",
"tag-filter-submit": "Filter",
+ "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+ "tags-title": "Tags",
"tags-intro": "This page leets the tags that the saffware can maurk aen eedit wi, n thair meanin.",
+ "tags-tag": "Tag name",
"tags-display-header": "Appearance oan chynge leets",
"tags-description-header": "Ful descreeption o meanin",
"tags-active-header": "Acteeve?",
"tags-active-no": "Naw",
"tags-edit": "eedit",
"tags-hitcount": "$1 {{PLURAL:$1|chynge|chynges}}",
+ "comparepages": "Compare pages",
+ "compare-page1": "Page 1",
+ "compare-page2": "Page 2",
"compare-rev1": "Reveesion 1",
"compare-rev2": "Reveesion 2",
+ "compare-submit": "Compare",
"compare-invalid-title": "The title that ye speceefied is onvalit.",
"compare-title-not-exists": "The title that ye speceefied disna exeest.",
"compare-revision-not-exists": "The reveesion that ye speceefied disna exeest.",
"htmlform-no": "Naw",
"htmlform-yes": "Ay",
"htmlform-chosen-placeholder": "Select aen optie",
+ "htmlform-cloner-create": "Eik mair",
+ "htmlform-cloner-delete": "Remuiv",
+ "htmlform-cloner-required": "At least the ae value is needit.",
"sqlite-has-fts": "$1 wi ful-tex rake support",
"sqlite-no-fts": "$1 wioot ful-tex rake support",
"logentry-delete-delete": "$1 {{GENDER:$2|delytit}} page $3",
+ "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
"logentry-delete-event": "$1 {{GENDER:$2|chynged}} veesibeelitie o {{PLURAL:$5|ae log event|$5 log events}} oan $3: $4",
"logentry-delete-revision": "$1 {{GENDER:$2|chynged}} veesibeelitie o {{PLURAL:$5|ae reveesion|$5 reveesions}} oan page $3: $4",
"logentry-delete-event-legacy": "$1 {{GENDER:$2|chynged}} veesibeelitie o log events oan $3",
"logentry-delete-revision-legacy": "$1 {{GENDER:$2|chynged}} veesibeelitie o reveesions oan page $3",
+ "logentry-suppress-delete": "$1 {{GENDER:$2|suppressed}} page $3",
"logentry-suppress-event": "$1 hidlinswise {{GENDER:$2|chynged}} veesibeelitie o {{PLURAL:$5|ae log event|$5 log events}} oan $3: $4",
"logentry-suppress-revision": "$1 hidlinswise {{GENDER:$2|chynged}} veesibeelity o {{PLURAL:$5|ae reveesion|$5 reveesions}} oan page $3: $4",
"logentry-suppress-event-legacy": "$1 hidlinswise {{GENDER:$2|chynged}} veesibeelitie o log events oan $3",
"revdelete-uname-unhid": "uisername onskaukt",
"revdelete-restricted": "applied restreections til admeenistraters",
"revdelete-unrestricted": "remuived restreections fer admeenistraters",
+ "logentry-merge-merge": "$1 {{GENDER:$2|merged}} $3 intae $4 (reveesions up tae $5)",
"logentry-move-move": "$1 {{GENDER:$2|muived}} page $3 til $4",
"logentry-move-move-noredirect": "$1 {{GENDER:$2|muived}} page $3 til $4 wioot leain ae reguidal",
"logentry-move-move_redir": "$1 {{GENDER:$2|muived}} page $3 til $4 ower reguidal",
"logentry-rights-rights": "$1 {{GENDER:$2|chynged}} groop memmership fer $3 fae $4 til $5",
"logentry-rights-rights-legacy": "$1 {{GENDER:$2|chynged}} groop memmership fer $3",
"logentry-rights-autopromote": "$1 wis autæmateeclie {{GENDER:$2|promoted}} fae $4 til $5",
+ "logentry-upload-upload": "$1 {{GENDER:$2|uplaidit}} $3",
+ "logentry-upload-overwrite": "$1 {{GENDER:$2|uplaidit}} ae new version o $3",
+ "logentry-upload-revert": "$1 {{GENDER:$2|uplaidit}} $3",
"rightsnone": "(nane)",
+ "revdelete-summary": "eedit the ootline",
"feedback-bugornote": "Gif yer readie tae describe ae techneecal proablem in detail please [$1 report ae bug].\nItherwise, ye can uiss the easie form ablo. Yer comment will be eikit til the page \"[$3 $2]\", alang wi yer uisername.",
+ "feedback-subject": "Aneat:",
+ "feedback-message": "Message:",
+ "feedback-cancel": "Cancel",
+ "feedback-submit": "Haund Feedback In",
"feedback-adding": "Eikin feedback til page...",
"feedback-error1": "Mistak: Onrecognised ootcome fae API",
"feedback-error2": "Mistak: Eedit failed",
"searchsuggest-search": "Rake",
"searchsuggest-containing": "containin...",
"api-error-badaccess-groups": "Ye'r na permittit tae uplaid files til this wiki.",
+ "api-error-badtoken": "Inby mistak: Bad token.",
"api-error-copyuploaddisabled": "Uplaidin bi URL is disabled oan this server.",
"api-error-duplicate": "Thaur {{PLURAL:$1|is [$2 anither file]|ar [$2 some ither files]}} awreadie oan the site wi the same content.",
"api-error-duplicate-archive": "Thaur {{PLURAL:$1|wis [$2 anither file]|were [$2 some ither files]}} awreadie oan the site wi the same content, but {{PLURAL:$1|it wis|thay were}} delytit.",
"api-error-stashfailed": "Internal mistak: Server failed tae store temparie file.",
"api-error-publishfailed": "Internal mistak: Server failed tae publeesh temparie file.",
"api-error-stasherror": "Thaur wis ae mistak while uplaidin the file tae stash.",
+ "api-error-stashedfilenotfound": "The stashed file wis no foond whan attemptin tae uplaid it fae the stash.",
+ "api-error-stashpathinvalid": "The path that the stashed file shid hae been foond at wis no valid.",
+ "api-error-stashfilestorage": "Thaur wis ae mistak in storin the file in the stash.",
+ "api-error-stashzerolength": "The server coudna stash the file, cause it haed zero langth.",
+ "api-error-stashnotloggedin": "Ye maun be loggit in tae hain files in the uplaid stash.",
+ "api-error-stashwrongowner": "The file that ye were attemptin tae access in the stash disna belang tae ye.",
+ "api-error-stashnosuchfilekey": "The file key that ye were attemptin tae access in the stash disna exeest.",
"api-error-timeout": "The server didna respond wiin the expectit time.",
"api-error-unclassified": "Aen onkent mistake occurred.",
+ "api-error-unknown-code": "Onknawn mistak: \"$1\".",
"api-error-unknown-error": "Internal mistak: Sommit went wrang whan uplaidin yer file.",
+ "api-error-unknown-warning": "Onknawn warnishment: \"$1\".",
+ "api-error-unknownerror": "Onknawn mistak: \"$1\".",
"api-error-uploaddisabled": "Uplaidin is disabled oan this wiki.",
"api-error-verification-error": "This file micht be rotten, or hae the wrang extension.",
"duration-seconds": "$1 {{PLURAL:$1|seicont|seiconts}}",
+ "duration-minutes": "$1 {{PLURAL:$1|minute|minutes}}",
"duration-hours": "$1 {{PLURAL:$1|hoor|hoors}}",
+ "duration-days": "$1 {{PLURAL:$1|day|days}}",
+ "duration-weeks": "$1 {{PLURAL:$1|week|weeks}}",
+ "duration-years": "$1 {{PLURAL:$1|year|years}}",
+ "duration-decades": "$1 {{PLURAL:$1|decade|decades}}",
"duration-centuries": "$1 {{PLURAL:$1|centuair|centuairs}}",
+ "duration-millennia": "$1 {{PLURAL:$1|millennium|millennia}}",
"rotate-comment": "Eemage rotated bi $1 {{PLURAL:$1|degree|degrees}} clockwise",
"limitreport-title": "Parser profilin data:",
"limitreport-cputime": "CPU time uissage",
"limitreport-ppvisitednodes": "Preprocessor veesitit node coont",
"limitreport-ppgeneratednodes": "Preprocessor generated node coont",
"limitreport-postexpandincludesize": "Post-expand incluid size",
+ "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
+ "limitreport-templateargumentsize": "Template argument size",
+ "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
"limitreport-expansiondepth": "Heiest expansion depth",
"limitreport-expensivefunctioncount": "Expensive parser function coont",
+ "expandtemplates": "Mak templates muckler",
"expand_templates_intro": "This byordiair page taks tex n expauns aw templates in it recurseevelie.\nIt foreby expaunds supported parser functions like\n<code><nowiki>{{</nowiki>#language:…}}</code> n vareeables like\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nIn fact, it expauns just aboot awthings in dooble-braces.",
"expand_templates_title": "Contex title, fer {{FULLPAGENAME}}, etc.:",
+ "expand_templates_input": "The Input tex:",
"expand_templates_output": "Ootcome",
"expand_templates_xml_output": "XML ootpit",
"expand_templates_html_output": "Raw HTML ootpit",
+ "expand_templates_ok": "OK",
+ "expand_templates_remove_comments": "Remuiv comments",
"expand_templates_remove_nowiki": "Suppress <nowiki> tags in ootcome",
"expand_templates_generate_xml": "Shaw XML parse tree",
"expand_templates_generate_rawhtml": "Shaw raw HTML",
- "expand_templates_preview": "Luikower"
+ "expand_templates_preview": "Luikower",
+ "expand_templates_preview_fail_html": "<em>Cause {{SITENAME}} haes raw HTML enabled n thaur wis ae loss o session data, the luikower haes been skaukt tae help defend again JavaScript attacks.</em>\n\n<strong>Gif this is a legeetimate luikower attempt, please gie it anither shot.</strong>\nGif ye still haae nae joy, than gie [[Special:UserLogout|loggin oot]] n loggin back in ae shot.",
+ "expand_templates_preview_fail_html_anon": "<em>Cause {{SITENAME}} haes raw HTML enabled n ye'r no loggit in, the luikower haes been skaukt tae fend again JavaScript attacks.</em>\n\n<strong>Gif this is ae legeetimate luikower attempt, than please [[Special:UserLogin|log in]] n gie it anither shot.</strong>",
+ "pagelanguage": "Page leid selecter",
+ "pagelang-name": "Page",
+ "pagelang-language": "Leid",
+ "pagelang-use-default": "Uise the defaut leid",
+ "pagelang-select-lang": "Pick yer leid",
+ "right-pagelang": "Chynge page leid",
+ "action-pagelang": "chynge the page leid",
+ "log-name-pagelang": "Chynge leid log",
+ "log-description-pagelang": "This is ae log o chynges in page leids.",
+ "logentry-pagelang-pagelang": "$1 {{GENDER:$2|chynged}} page leid fer $3 fae $4 tae $5.",
+ "default-skin-not-found": "Whoops! The defaut skin fer yer wiki, defined in <code dir=\"ltr\">$wgDefaultSkin</code> aes <code>$1</code>, is no available.\n\nYer instawation seems tae incluid the follaein skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] fer information oan hou tae enable thaim n chuise the defaut.\n\n$2\n\n; Gif ye'v juist instawed MediaWiki:\n: Ye proabablie instawed it fae git, or directlie fae the soorce code uisin some ither method. This is expectie. Gie instawin some skins fae [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] ae shot, bi:\n:* Dounlaidin the [https://www.mediawiki.org/wiki/Download tarball installer], this comes wi several skins n extensions. Ye can than capie n paste the <code>skins/</code> directerie fae this.\n:* Dounlaidin indiveedual skin tarballs frae [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Clonin one of the <code>mediawiki/skins/*</code> repositries bi wa o git intae the <code dir=\"ltr\">skins/</code> directerie o yer MediaWiki instawation.\n: Daein this shoudna interfere wi yer git repositrie gif ye'r ae MediaWiki deveeloper.\n\n; Gif ye,v juist upgradit MediaWiki:\n: MediaWiki 1.24 n newer nae langer enables instawed skins autæmateeclie (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). Ye can paste the follaein lines intae <code>LocalSettings.php</code> tae enable aw nou installed skins:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Gif ye'v juist modified <code>LocalSettings.php</code>:\n: Double-check the skin names fer typos.",
+ "default-skin-not-found-no-skins": "Whoops! The defaut skin fer yer wiki, defined in <code>$wgDefaultSkin</code> aes <code>$1</code>, is no available.\n\nYe'v nae instawed skins.\n\n; Gif ye'v juist instawed or upgradit MediaWiki:\n: Ye probably instawed fae git, or directlie fae the soorce code uisin some ither method. This is expectit. MediaWiki 1.24 n newer disna incluid onie skins in the main repositrie. Gie instawin some skins fae [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] ae shot, bi:\n:* Dounlaidin the [https://www.mediawiki.org/wiki/Download tarball installer], this comes wi several skins n extensions. Ye can than capie n paste the <code>skins/</code> directerie fae it.\n:* Dounlaidin individual skin tarballs fae [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Cloning yin o the <code>mediawiki/skins/*</code> repositries bi wa o git intae the <code dir=\"ltr\">skins/</code> directerie o yer MediaWiki instawation.\n: Daein this shoudna interfere wi yer git repositrie gif ye'r ae MediaWiki deveeloper. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] fer information oan hou tae enable skins n chuise the defaut.",
+ "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (enabled)",
+ "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disablt''')",
+ "mediastatistics": "Media stateestics",
+ "mediastatistics-summary": "Stateestics aneat uplaided file types. This yinlie incluids the maist recent version o ae file. Auld or delytit versions o files ar excluidit.",
+ "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
+ "mediastatistics-table-mimetype": "MIME type",
+ "mediastatistics-table-extensions": "Possible extensions",
+ "mediastatistics-table-count": "Nummer o files",
+ "mediastatistics-table-totalbytes": "Combined size",
+ "mediastatistics-header-unknown": "Onknawn",
+ "mediastatistics-header-bitmap": "Bitmap eemages",
+ "mediastatistics-header-drawing": "Drawins (vecter eemages)",
+ "mediastatistics-header-audio": "Audio",
+ "mediastatistics-header-video": "Videos",
+ "mediastatistics-header-multimedia": "Rich media",
+ "mediastatistics-header-office": "Affice",
+ "mediastatistics-header-text": "Texual",
+ "mediastatistics-header-executable": "Executables",
+ "mediastatistics-header-archive": "Compressed formats",
+ "json-warn-trailing-comma": "$1 trailin {{PLURAL:$1|comma wis|commas were}} remuived fae JSON",
+ "json-error-unknown": "Thaur wis ae proablem wi the JSON. Mistak: $1",
+ "json-error-depth": "The mucklest stack depth haes been exceedit",
+ "json-error-state-mismatch": "Onvalit or malformed JSON",
+ "json-error-ctrl-char": "Control chairacter mistak, possiblie wranglie encoded",
+ "json-error-syntax": "Syntax mistak",
+ "json-error-utf8": "Malformed UTF-8 chairacters, possiblie wranglie encoded",
+ "json-error-recursion": "Yin or mair recurseeve references in the value tae be encoded",
+ "json-error-inf-or-nan": "Yin or mair NAN or INF values in the value tae be encoded",
+ "json-error-unsupported-type": "Ae value o ae type that canna be encoded wis gien"
}
"tog-shownumberswatching": "Prikaži število uporabnikov, ki spremljajo temo",
"tog-oldsig": "Trenutni podpis:",
"tog-fancysig": "Obravnavaj podpis kot wikibesedilo (brez samodejne povezave)",
- "tog-uselivepreview": "Uporabi hitri predogled (preizkusno)",
+ "tog-uselivepreview": "Uporabi hitri predogled",
"tog-forceeditsummary": "Ob vpisu praznega povzetka urejanja me opozori",
"tog-watchlisthideown": "Na spisku nadzorov skrij moja urejanja",
"tog-watchlisthidebots": "Na spisku nadzorov skrij urejanja botov",
"anoneditwarning": "<strong>Opozorilo:</strong> Niste prijavljeni. Vaš IP-naslov bo javno viden, če naredite kakršno koli urejanje. Če se <strong>[$1 prijavite]</strong> ali <strong>[$2 ustvarite račun]</strong>, bodo vaša urejanja pripisana vašemu uporabniškemu imenu skupaj z drugimi prednostmi.",
"anonpreviewwarning": "Niste prijavljeni. Ob spremembi strani se bo vaš IP-naslov zapisal v zgodovini urejanja te strani.",
"missingsummary": "'''Opozorilo:''' Niste napisali povzetka urejanja. Ob ponovnem kliku gumba ''Shrani'' se bo vaše urejanje shranilo brez njega.",
+ "selfredirect": "<strong>Opozorilo:</strong> Ustvarjate preusmeritev na isti članek.\nČe ponovno kliknete »{{int:savearticle}}«, bomo preusmeritev ustvarili.",
"missingcommenttext": "Prosimo, vpišite v spodnje polje komentar.",
"missingcommentheader": "'''Opozorilo:''' Niste vnesli zadeve/naslova za ta komentar.\nČe boste ponovno kliknili »{{int:savearticle}}«, bo vaše urejanje shranjeno brez le-tega.",
"summary-preview": "Predogled povzetka",
"tog-shownumberswatching": "Visa antalet användare som bevakar",
"tog-oldsig": "Nuvarande signatur:",
"tog-fancysig": "Behandla signatur som wikitext (utan en automatisk länk)",
- "tog-uselivepreview": "Använd direktuppdaterad förhandsgranskning (experimentell)",
+ "tog-uselivepreview": "Använd direktuppdaterad förhandsgranskning",
"tog-forceeditsummary": "Påminn mig om jag inte fyller i en redigeringskommentar",
"tog-watchlisthideown": "Dölj mina redigeringar i bevakningslistan",
"tog-watchlisthidebots": "Visa inte robotredigeringar i bevakningslistan",
"anoneditwarning": "<strong>Varning:</strong> Du är inte inloggad. Din IP-adress kommer att vara publikt synlig om du gör några redigeringar. Om du <strong>[$1 loggar in]</strong> eller <strong>[$2 skapar ett konto]</strong> kommer dina redigeringar att tillskrivas ditt användarnamn, tillsammans med andra fördelar.",
"anonpreviewwarning": "''Du är inte inloggad. Om du sparar kommer din IP-adress registreras på denna sidas redigeringshistorik.''",
"missingsummary": "<strong>Påminnelse:</strong> Du har inte skrivit någon redigeringskommentar.\nOm du klickar på \"{{int:savearticle}}\" igen kommer din redigering att sparas utan en sådan.",
+ "selfredirect": "<strong>Varning:</strong> Du omdirigerar till samma artikel.\nOm du klickar på \"{{int:savearticle}}\" igen kommer omdirigeringen att skapas.",
"missingcommenttext": "Var god och skriv in en kommentar nedan.",
"missingcommentheader": "<strong>Påminnelse:</strong> Du har inte skrivit något ämne/rubrik för den här kommentaren.\nOm du trycker på \"{{int:savearticle}}\" igen kommer din redigering sparas utan rubrik.",
"summary-preview": "Förhandsgranskning av sammanfattning:",
"right-protect": "Ändra skyddsnivåer och redigera kaskadskyddade sidor",
"right-editprotected": "Redigera skyddade sidor som \"{{int:protect-level-sysop}}\"",
"right-editsemiprotected": "Redigera skyddade sidor som \"{{int:protect-level-autoconfirmed}}\"",
+ "right-editcontentmodel": "Ändra innehållsmodellen för en sida",
"right-editinterface": "Redigera användargränssnittet",
"right-editusercssjs": "Redigera andra användares CSS- och JS-filer",
"right-editusercss": "Redigera andra användares CSS-filer",
"action-viewmywatchlist": "visa din bevakningslista",
"action-viewmyprivateinfo": "visa din privata information",
"action-editmyprivateinfo": "redigera din privata information",
+ "action-editcontentmodel": "ändra innehållsmodellen för en sida",
"nchanges": "$1 {{PLURAL:$1|ändring|ändringar}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sedan senaste besöket}}",
"enhancedrc-history": "historik",
"expand_templates_generate_xml": "Visa parseträd som XML",
"expand_templates_generate_rawhtml": "Visa rå HTML",
"expand_templates_preview": "Förhandsvisning",
+ "expand_templates_preview_fail_html": "<em>Eftersom {{SITENAME}} har rå HTML aktiverat och det uppstod en förlust av sessionsdata har förhandsgranskningen dolts som en försiktighetsåtgärd för att skydda mot JavaScript-attacker.</em>\n\n<strong>Om detta är ett äkta försök att förhandsgranska sidan, vänligen försök igen.</strong>\nOm det fortfarande inte fungerar, försök att [[Special:UserLogout|logga ut]] och sedan logga in igen.",
+ "expand_templates_preview_fail_html_anon": "<em>Eftersom {{SITENAME}} har rå HTML aktiverat och du inte är inloggad har förhandsgranskningen dolts som en försiktighetsåtgärd för att skydda mot JavaScript-attacker.</em>\n\n<strong>Om detta är ett äkta försök att förhandsgranska sidan, vänligen [[Special:UserLogin|logga in]] och försök igen.</strong>",
"pagelanguage": "Sidspråksväljare",
"pagelang-name": "Sida",
"pagelang-language": "Språk",
"log-description-pagelang": "Detta är en logg över ändringar i sidspråken.",
"logentry-pagelang-pagelang": "$1 {{GENDER:$2|ändrade}} sidspråket för $3 från $4 till $5.",
"default-skin-not-found": "Ojsan! Standardutseendet för din wiki, definierad i <code dir=\"ltr\">$wgDefaultSkin</code> som <code>$1</code>, är inte tillgängligt.\n\nDin installation verkar innehålla följande utseenden. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur du aktiverar dem och hur standard väljs.\n\n$2\n\n; Om du precis installerat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är normalt. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klippa och klistra in <code>skins/</code>-katalogen från den.\n:* Ladda ner individuella tarballs med utseenden från [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code dir=\"ltr\">skins/</code>-arkiven i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare. \n\n; Om du precis har uppgraderat MediaWiki:\n: MediaWiki 1.24 och nyare aktiverar ej längre automatiskt installerade utseenden (se [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Automatisk identifiering av utseenden]). Du kan klistra in följande rader i <code>LocalSettings.php</code> för att aktivera alla för närvarande installerade utseenden:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Om du precis har modifierat <code>LocalSettings.php</code>:\n: Dubbelkolla namnen för utseendena för att identifiera stavfel.",
- "default-skin-not-found-no-skins": "Ojsan! Standardutseendet för din wiki, definierad i <code>$wgDefaultSkin</code> som <code>$1</code>, är inte tillgängligt.\n\nDu har inga installerade utseenden.\n\n; Om du precis installerat eller uppdaterat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är att förvänta. MediaWiki 1.24 och nyare inkluderar inte några utseenden i det huvudsakliga centralförvaret. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klipp-och-klistra in <code dir=\"ltr\">skins/</code>-katalogen från den.\n* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code>skins/</code>-katalogen i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur utseenden aktiveras och hur standardutseendet väljs.",
+ "default-skin-not-found-no-skins": "Ojsan! Standardutseendet för din wiki, definierad i <code>$wgDefaultSkin</code> som <code>$1</code>, är inte tillgängligt.\n\nDu har inga installerade utseenden.\n\n; Om du precis installerat eller uppdaterat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är att förvänta. MediaWiki 1.24 och nyare inkluderar inte några utseenden i det huvudsakliga centralförvaret. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klipp-och-klistra in <code dir=\"ltr\">skins/</code>-katalogen från den.\n:* Ladda ner individuella tarballs med utseende från [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code>skins/</code>-katalogen i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur utseenden aktiveras och hur standardutseendet väljs.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (aktiverad)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''inaktiverad''')",
"mediastatistics": "Mediastatistik",
"tog-shownumberswatching": "వీక్షకుల సంఖ్యను చూపు",
"tog-oldsig": "ప్రస్తుత సంతకం:",
"tog-fancysig": "సంతకాన్ని వికీపాఠ్యంగా తీసుకో (ఆటోమెటిక్ లింకు లేకుండా)",
- "tog-uselivepreview": "à°µà±\86à°¨à±\81à°µà±\86à°\82à°\9f à°®à±\81à°¨à±\81à°\9cà±\82à°ªà±\81à°¨à±\81 వాడà±\81 (à°ªà±\8dà°°à°¯à±\8bà°\97ాతà±\8dà°®à°\95à°\82)",
+ "tog-uselivepreview": "తాà°\9cà°¾ à°®à±\81à°¨à±\81à°\9cà±\82à°ªà±\81à°¨à±\81 వాడà±\81",
"tog-forceeditsummary": "దిద్దుబాటు సారాంశం ఖాళీగా ఉంటే ఆ విషయాన్ని నాకు సూచించు",
"tog-watchlisthideown": "నా మార్పులను వీక్షణా జాబితాలో చూపించొద్దు",
"tog-watchlisthidebots": "బాట్లు చేసిన మార్పులను నా వీక్షణా జాబితాలో చూపించొద్దు",
"hidetoc": "దాచు",
"collapsible-collapse": "కుదించు",
"collapsible-expand": "విస్తరించు",
+ "confirmable-yes": "అవును",
+ "confirmable-no": "కాదు",
"thisisdeleted": "$1ను చూస్తారా, పునఃస్థాపిస్తారా?",
"viewdeleted": "$1 చూస్తారా?",
"restorelink": "{{PLURAL:$1|ఒక తొలగించిన మార్పు|$1 తొలగించిన మార్పులు}}",
"search-result-category-size": "{{PLURAL:$1|1 సభ్యుడు|$1 సభ్యులు}} ({{PLURAL:$2|1 ఉవవర్గం|$2 ఉపవర్గాలు}}, {{PLURAL:$3|1 దస్త్రం|$3 దస్త్రాలు}})",
"search-redirect": "(దారిమార్పు $1)",
"search-section": "(విభాగం $1)",
+ "search-category": "(వర్గం $1)",
"search-file-match": "(ఫైలు విషయంతో సరిపోలుతోంది)",
"search-suggest": "మీరు అంటున్నది ఇదా: $1",
"search-interwiki-caption": "సోదర ప్రాజెక్టులు",
"license-nopreview": "(మునుజూపు అందుబాటులో లేదు)",
"upload_source_url": " (సార్వజనికంగా అందుబాటులో ఉన్న, సరైన URL)",
"upload_source_file": " (మీ కంప్యూటర్లో ఒక ఫైలు)",
+ "listfiles-delete": "తొలగించు",
"listfiles-summary": "ఈ ప్రత్యేక పేజీ, ఎక్కించిన ఫైళ్ళన్నిటినీ చూపిస్తుంది.",
"listfiles_search_for": "మీడియా పేరుకై వెతుకు:",
"imgfile": "దస్త్రం",
"randomincategory": "వర్గంలోని యాదృచ్చిక పేజీ",
"randomincategory-invalidcategory": "\"$1\" అనేది సరైన పర్గం పేరు కాదు.",
"randomincategory-nopages": "[[:Category:$1|$1]] వర్గంలో పేజీలేమీ లేవు.",
+ "randomincategory-category": "వర్గం:",
"randomredirect": "యాదృచ్చిక దారిమార్పు",
"randomredirect-nopages": "\"$1\" పేరుబరిలో దారిమార్పులేమీ లేవు.",
"statistics": "గణాంకాలు",
"querypage-disabled": "పనితీరు కారణాల వలన, ఈ ప్రత్యేకపేజీని అశక్తం చేసాం.",
"booksources": "పుస్తక మూలాలు",
"booksources-search-legend": "పుస్తక మూలాల కోసం వెతుకు",
+ "booksources-search": "వెతుకు",
"booksources-text": "కొత్త, పాత పుస్తకాలు అమ్మే ఇతర సైట్లకు లింకులు కింద ఇచ్చాం. మీరు వెతికే పుస్తకాలకు సంబంధించిన మరింత సమాచారం కూడా అక్కడ దొరకొచ్చు:",
"booksources-invalid-isbn": "మీరిచ్చిన ISBN సరైనదిగా అనిపించుటలేదు; అసలు మూలాన్నుండి కాపీ చేయడంలో పొరపాట్లున్నాయేమో చూసుకోండి.",
"specialloguserlabel": "కర్త:",
"confirm-watch-top": "ఈ పుటను మీ వీక్షణ జాబితాలో చేర్చాలా?",
"confirm-unwatch-button": "సరే",
"confirm-unwatch-top": "ఈ పుటను మీ వీక్షణ జాబితా నుండి తొలగించాలా?",
+ "quotation-marks": "“$1”",
"imgmultipageprev": "← మునుపటి పేజీ",
"imgmultipagenext": "తరువాతి పేజీ →",
"imgmultigo": "వెళ్ళు!",
"autosumm-replace": "పేజీని '$1' తో మారుస్తున్నాం",
"autoredircomment": "[[$1]]కు దారిమళ్ళించారు",
"autosumm-new": "'$1' తో కొత్త పేజీని సృష్టించారు",
+ "autosumm-newblank": "ఖాళీ పేజీని సృష్టించారు",
"lag-warn-normal": "$1 {{PLURAL:$1|క్షణం|క్షణాల}} లోపు జరిగిన మార్పులు ఈ జాబితాలో కనిపించకపోవచ్చు.",
"lag-warn-high": "అధిక వత్తిడి వలన డేటాబేసు సర్వరు వెనుకబడింది, $1 {{PLURAL:$1|క్షణం|క్షణాల}} కంటే కొత్తవైన మార్పులు ఈ జాబితాలో కనిపించకపోవచ్చు.",
"watchlistedit-normal-title": "వీక్షణ జాబితాను మార్చు",
"duplicate-defaultsort": "హెచ్చరిక: డిఫాల్టు పేర్చు కీ \"$2\", గత డిఫాల్టు పేర్చు కీ \"$1\" ని అతిక్రమిస్తుంది.",
"version": "సంచిక",
"version-extensions": "స్థాపించిన పొడగింతలు",
- "version-skins": "అలంకారాలు",
+ "version-skins": "à°¸à±\8dథాపిà°\82à°\9aà°¿à°¨ à°\85à°²à°\82à°\95ారాలà±\81",
"version-specialpages": "ప్రత్యేక పేజీలు",
"version-parserhooks": "పార్సరు కొక్కాలు",
"version-variables": "చరరాశులు",
"version-hook-name": "కొక్కెం పేరు",
"version-hook-subscribedby": "ఉపయోగిస్తున్నవి",
"version-version": "(కూర్పు $1)",
+ "version-no-ext-name": "[పేరు లేదు]",
"version-license": "MediaWiki లైసెన్సు",
"version-ext-license": "లైసెన్సు",
"version-ext-colheader-name": "పొడిగింత",
+ "version-skin-colheader-name": "అలంకారం",
"version-ext-colheader-version": "కూర్పు",
"version-ext-colheader-license": "లైసెన్సు",
"version-ext-colheader-description": "వివరణ",
"specialpages-group-wiki": "డాటా మరియు పనిముట్లు",
"specialpages-group-redirects": "ప్రత్యేక పేజీల దారిమార్పులు",
"specialpages-group-spam": "స్పామ్ పనిముట్లు",
+ "specialpages-group-developer": "వికాసకుల పనిముట్లు",
"blankpage": "ఖాళీ పేజీ",
"intentionallyblankpage": "బెంచిమార్కింగు, మొదలగు వాటికై ఈ పేజీని కావాలనే ఖాళీగా వదిలాము.",
"external_image_whitelist": " #ఈ లైనును ఎలా ఉన్నదో అలాగే వదిలెయ్యండి<pre>\n#regular expression తునకలను (// ల మధ్య ఉండే భాగం)కింద పెట్టండి\n#వీటిని బయటి బొమ్మల URLలతో సరిపోల్చుతాము\n#సరిపోలిన బొమ్మలను చూపిస్తాము, మిగిలినవాటి లింకులను మాత్రమే చూపిస్తాము\n##తో మొదలయ్యే లైనులు వ్యాఖ్యానాలుగా భావించబడతాయి\n#ఇది కేస్-సెన్సిటివ్\n\n#అన్ని తునకలను ఈ లైనుకు పైన ఉంచండి. ఈ లైనును ఎలా ఉన్నదో అలాగే వదిలెయ్యండి</pre>",
"expand_templates_remove_nowiki": "ఫలితంలో <nowiki> ట్యాగులను అణచిపెట్టు",
"expand_templates_generate_xml": "XML పార్స్ ట్రీని చూపించు",
"expand_templates_generate_rawhtml": "ముడి HTML ను చూపించు",
- "expand_templates_preview": "మునుజూపు"
+ "expand_templates_preview": "మునుజూపు",
+ "pagelang-name": "పేజీ",
+ "pagelang-language": "భాష",
+ "pagelang-use-default": "అప్రమేయ భాషను వాడు"
}
"tog-shownumberswatching": "แสดงจำนวนผู้ใช้ที่เฝ้าดู",
"tog-oldsig": "ลายเซ็นที่ใช้อยู่:",
"tog-fancysig": "ถือลายเซ็นเป็นข้อความวิกิ (โดยไม่มีลิงก์อัตโนมัติ)",
- "tog-uselivepreview": "à¹\83à¸\8aà¹\89à¸\95ัวà¸à¸¢à¹\88าà¸\87à¸\97ัà¸\99à¸\97ี (à¸\97à¸\94ลà¸à¸\87)",
+ "tog-uselivepreview": "à¹\83à¸\8aà¹\89à¸\81ารà¹\81สà¸\94à¸\87à¸\95ัวà¸à¸¢à¹\88าà¸\87à¹\81à¸\9aà¸\9aสà¸\94",
"tog-forceeditsummary": "เตือนเมื่อช่องคำอธิบายอย่างย่อว่าง",
"tog-watchlisthideown": "ซ่อนการแก้ไขของฉันจากรายการเฝ้าดู",
"tog-watchlisthidebots": "ซ่อนการแก้ไขของบอตจากรายการเฝ้าดู",
"anoneditwarning": "<strong>คำเตือน:</strong> คุณมิได้ล็อกอิน สาธารณะจะเห็นเลขที่อยู่ไอพีของคุณหากคุณแก้ไข หากคุณ<strong>[$1 ล็อกอิน]</strong>หรือ<strong>[$2 สร้างบัญชี]</strong> การแก้ไขของคุณจะถือว่าเป็นของชื่อผู้ใช้ของคุณ ร่วมกับประโยชน์อื่น",
"anonpreviewwarning": "<em>คุณมิได้ล็อกอิน การบันทึกจะเก็บเลขที่อยู่ไอพีของคุณในประวัติการแก้ไขของหน้านี้</em>",
"missingsummary": "<strong>อย่าลืม:</strong> คุณยังไม่ได้ให้คำอธิบายการแก้ไข \nถ้าคุณคลิก \"{{int:savearticle}}\" อีก จะบันทึกการแก้ไขของคุณโดยไม่มีคำอธิบายการแก้ไข",
+ "selfredirect": "<strong>คำเตือน:</strong> คุณกำลังสร้างการเปลี่ยนทางไปบทความเดียวกัน หากคุณคลิก \"{{int:savearticle}}\" อีกครั้ง จะสร้างการเปลี่ยนทาง",
"missingcommenttext": "กรุณากรอกความเห็นด้านล่าง",
"missingcommentheader": "<strong>อย่าลืม:</strong> คุณยังไม่ได้ใส่หัวข้อ/พาดหัวสำหรับความเห็นนี้ \nถ้าคุณคลิก \"{{int:savearticle}}\" อีก จะบันทึกการแก้ไขของคุณโดยไม่มีหัวข้อ/พาดหัว",
"summary-preview": "ตัวอย่างคำอธิบาย:",
"tog-shownumberswatching": "Показувати число користувачів, які додали сторінку до свого списку спостереження",
"tog-oldsig": "Існуючий підпис:",
"tog-fancysig": "Сприймати підпис як вікі-текст (без автоматичного посилання)",
- "tog-uselivepreview": "Використовувати швидкий попередній перегляд (експериментально)",
+ "tog-uselivepreview": "Використовувати швидкий попередній перегляд",
"tog-forceeditsummary": "Попереджати, коли не зазначений короткий опис редагування",
"tog-watchlisthideown": "Приховати мої редагування у списку спостереження",
"tog-watchlisthidebots": "Приховати редагування ботів у списку спостереження",
"anoneditwarning": "<strong>Увага!</strong> Ви не авторизувалися на сайті. Ваша IP-адреса буде публічно видима, якщо ви будете вносити будь-які правки. Якщо ви <strong>[$1 увійдете]</strong> або <strong>[$2 створите обліковий запис]</strong>, правки замість цього будуть пов'язані з вашим ім'ям користувача, а також у вас з'являться інші переваги.",
"anonpreviewwarning": "''Ви не увійшли в систему. Якщо ви виконаєте збереження, то в історію сторінки буде записана ваша IP-адреса.''",
"missingsummary": "'''Нагадування''': Ви не дали короткого опису змін.\nНатиснувши кнопку «Зберегти» ще раз, ви збережете зміни без коментаря.",
+ "selfredirect": "<strong>Попередження:</strong> Ви створюєте перенаправлення на цю ж сторінку.\nЯкщо Ви натиснете \"{{int:savearticle}}\" ще раз, перенаправлення буде створено.",
"missingcommenttext": "Будь ласка, введіть нижче ваше повідомлення.",
"missingcommentheader": "'''Нагадування''': ви не вказали тему/заголовок для цього коментаря.\nНатиснувши кнопку «{{int:savearticle}}» ще раз, ви збережете редагування без заголовка.",
"summary-preview": "Опис буде:",
"exif-iimcategory-wea": "Ob-havo",
"namespacesall": "Barchasi",
"monthsall": "barchasi",
+ "confirmrecreate": "Ushbu sahifa siz tahrir qilayotganingizda foydalanuvchi [[User:$1|$1]] ([[User talk:$1|munozara]]) tomonidan quyidagi sababga binoan yoʻqotilgan:\n: <em>$2</em>\nIltimos, sahifani qaytadan yaratmoqchi ekanligingizni tasdiqlang.",
+ "confirmrecreate-noreason": "Ushbu sahifa siz tahrir qilayotganingizda foydalanuvchi [[User:$1|$1]] ([[User talk:$1|munozara]]) tomonidan yoʻqotilgan. Iltimos, sahifani qaytadan yaratmoqchi ekanligingizni tasdiqlang.",
"unit-pixel": " piksel",
"imgmultipageprev": "← oldingi sahifa",
"imgmultipagenext": "keyingi sahifa →",
"tog-newpageshidepatrolled": "באַהאַלטן פאַטראלירטע בלעטער פון דער ליסטע פון נײַע בלעטער",
"tog-extendwatchlist": "פארברייטערן די אויפפאסן ליסטע צו צייגן אלע פאסנדע ענדערונגען (אנדערשט: בלויז די לעצטע ענדערונג פון יעדן בלאט)",
"tog-usenewrc": "גרופירן ענדערונגען לויטן בלאט אין \"לעצטע ענדערונגען\" און אויפֿפאסן ליסטע",
- "tog-numberheadings": "נומערירן קעפלעך אויטאמאטיש",
+ "tog-numberheadings": "נומערירן קעפּלעך אויטאָמאַטיש",
"tog-showtoolbar": "ווײַזן רעדאקטירן געצייג-שטאנג",
- "tog-editondblclick": "רעדאקטירן בלעטער דורך טאפל קליק",
+ "tog-editondblclick": "רעדאַקטירן בלעטער דורך טאָפּל־קליק",
"tog-editsectiononrightclick": "באמעגלעכן אפטייל רעדאקטירן דורכן רעכטס־קליקן אויף אפטייל קעפלעך",
"tog-watchcreations": "צולייגן בלעטער וואס איך באשאף און טעקעס וואס איך לאד ארויף צו מיין אכטונג ליסטע",
"tog-watchdefault": "צולייגן בלעטער וואס איך רעדאקטיר צו מיין אכטונג ליסטע",
"tog-shownumberswatching": "显示监视用户数",
"tog-oldsig": "当前签名:",
"tog-fancysig": "将签名视为维基文本(不自动生成链接)",
- "tog-uselivepreview": "使用实时预览(试验中)",
+ "tog-uselivepreview": "使用实时预览",
"tog-forceeditsummary": "未输入编辑摘要时提醒我",
"tog-watchlisthideown": "隐藏监视列表中的我的编辑",
"tog-watchlisthidebots": "隐藏监视列表中的机器人编辑",
"anoneditwarning": "<strong>警告:</strong>您没有登录。您做出任何编辑后您的IP地址会公开可见。如果您<strong>[$1 登陆]</strong>或<strong>[$2 注册]</strong>一个账户,您的编辑将归属于您的用户名,以及有其他好处。",
"anonpreviewwarning": "<em>你没有登录。保存会记录你的IP地址于该页面的编辑历史中。</em>",
"missingsummary": "'''提示:'''你没有提供编辑摘要。如果你再次点击“{{int:savearticle}}”,你的编辑将不带编辑摘要保存。",
+ "selfredirect": "<strong>警告:</strong>您正在创建重定向到同一条目的重定向。\n如果您再次点击“{{int:savearticle}}”,重定向将被创建。",
"missingcommenttext": "请在下面输入评论。",
"missingcommentheader": "'''提示:''' 您还没有为此评论提供一个标题。如果您再次点击“{{int:savearticle}}”,您的编辑将不带标题保存。",
"summary-preview": "摘要预览:",
"protectlogtext": "下面是页面保护更改的列表。请见[[Special:ProtectedPages|受保护页面列表]]查看目前正在进行的页面保护的列表。",
"protectedarticle": "保护“[[$1]]”",
"modifiedarticleprotection": "更改“[[$1]]”的保护等级",
- "unprotectedarticle": "移除保护自“[[$1]]”",
+ "unprotectedarticle": "移除页面“[[$1]]”的保护",
"movedarticleprotection": "移动保护设置自“[[$2]]”至“[[$1]]”",
"protect-title": "更改“$1”的保护等级",
"protect-title-notallowed": "查看“$1”的保护等级",
"file-no-thumb-animation": "'''注意:由于技术限制,该文件的缩略图无法进行动画处理。'''",
"file-no-thumb-animation-gif": "'''注意:由于技术限制,高分辨率GIF图像的缩略图无法进行动画处理。'''",
"newimages": "新文件图库",
- "imagelisttext": "以下是按$2排列的'''$1'''个文件列表。",
+ "imagelisttext": "以下是按$2排列的<strong>$1</strong>个文件列表。",
"newimages-summary": "本特殊页面展示最后上传的文件。",
"newimages-legend": "过滤",
"newimages-label": "文件名(或它的一部份):",
"confirm-purge-top": "要清除此页面的缓存吗?",
"confirm-purge-bottom": "清除页面数据会清除缓存并强制显示最近的版本。",
"confirm-watch-button": "确定",
- "confirm-watch-top": "将此页添加到您的监视吗?",
+ "confirm-watch-top": "å°\86æ¤é¡µæ·»å\8a å\88°æ\82¨ç\9a\84ç\9b\91è§\86å\88\97表å\90\97ï¼\9f",
"confirm-unwatch-button": "确定",
"confirm-unwatch-top": "从监视列表中删除此页吗?",
"semicolon-separator": ";",
"api-error-stashnosuchfilekey": "您试图在藏匿处访问的文件密钥不存在。",
"api-error-timeout": "服务器没有在预期内响应。",
"api-error-unclassified": "出现未知错误。",
- "api-error-unknown-code": "未知错误:$1",
+ "api-error-unknown-code": "未知错误:“$1”。",
"api-error-unknown-error": "内部错误:尝试上传文件时出错。",
"api-error-unknown-warning": "未知的警告:“$1”。",
"api-error-unknownerror": "未知错误:$1。",
"tog-shownumberswatching": "顯示正在監視的使用者數",
"tog-oldsig": "現有簽名:",
"tog-fancysig": "將簽名視為 Wikitext 語言 (不自動產生連結)",
- "tog-uselivepreview": "使用即時預覽 (實驗中)",
+ "tog-uselivepreview": "使用即時預覽",
"tog-forceeditsummary": "未填寫編輯摘要時提示我",
"tog-watchlisthideown": "隱藏監視清單中我的編輯",
"tog-watchlisthidebots": "隱藏監視清單中機器人的編輯",
"generic-pool-error": "抱歉,太多使用者正嘗試檢視此資源,伺服器超出負荷。\n請稍候片刻再嘗試。",
"pool-timeout": "正在等待取消鎖定",
"pool-queuefull": "程序序列已滿",
- "pool-errorunknown": "未知錯誤",
+ "pool-errorunknown": "不明錯誤",
"pool-servererror": "無法使用程序計數服務 ($1)。",
"aboutsite": "關於 {{SITENAME}}",
"aboutpage": "Project:About",
"anoneditwarning": "<strong>警告:</strong>您尚未登入。 若您進行任何的編輯您的 IP 位置將會被公開。 若您 <strong>[$1 登入]</strong> 或 <strong>[$2 建立帳號]</strong>,您的編輯將會以您的使用者名稱標示,擁有其他優點。",
"anonpreviewwarning": "<em>您尚未登入。儲存頁面會將您的 IP 位址記錄在此頁面的編輯歷史中。</em>",
"missingsummary": "<strong>提醒:</strong>您未填寫編輯摘要。\n若您再點選 \"{{int:savearticle}}\" 一次,將略過摘要直接儲存您的編輯。",
+ "selfredirect": "<strong>警告:</strong> 您正建立連結至自己的重新導向。\n若您再點選 \"{{int:savearticle}}\" 一次,將會繼續建立重新導向。",
"missingcommenttext": "請在下方輸入評論。",
"missingcommentheader": "<strong>提醒:</strong>您未填寫此評論的主旨/標題。\n若您再點選 \"{{int:savearticle}}\" 一次,將略過主旨/標題直接儲存您的評論。",
"summary-preview": "摘要預覽:",
"semiprotectedpagewarning": "<strong>注意:</strong>本頁已經被保護,只有已註冊的使用者才可編輯。\n以下提供最近的日誌以便參考:",
"cascadeprotectedwarning": "<strong>警告:</strong>本頁已經被保護,只有擁有管理員權限的使用者才可編輯,此頁面被下列頁面引用因此連鎖保護:",
"titleprotectedwarning": "<strong>警告:本頁面已被保護,需要 [[Special:ListGroupRights|特殊權限]] 方可建立。</strong>\n以下提供最近的日誌以便參考:",
- "templatesused": "此頁面使用了以下{{PLURAL:$1|樣版}}:",
+ "templatesused": "此頁面使用了以下{{PLURAL:$1|樣板}}:",
"templatesusedpreview": "此預覽使用了以下{{PLURAL:$1|樣板}}:",
- "templatesusedsection": "此頁面使用了以下{{PLURAL:$1|樣版}}:",
+ "templatesusedsection": "此頁面使用了以下{{PLURAL:$1|樣板}}:",
"template-protected": "(受保護)",
"template-semiprotected": "(受半保護)",
"hiddencategories": "此頁面屬於 {{PLURAL:$1|1 個隱藏分類|$1 個隱藏分類}}的成員:",
"content-model-text": "純文字",
"content-model-javascript": "JavaScript",
"content-model-css": "CSS",
- "duplicate-args-category": "樣版呼叫時使用重複的參數的頁面",
- "duplicate-args-category-desc": "該頁面包含重複使用參數的樣版呼叫,如 <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> 或 <code><nowiki>{{foo|bar|1=baz}}</nowiki>。",
+ "duplicate-args-category": "樣板呼叫時使用重複的參數的頁面",
+ "duplicate-args-category-desc": "該頁面包含重複使用參數的樣板呼叫,如 <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> 或 <code><nowiki>{{foo|bar|1=baz}}</nowiki>。",
"expensive-parserfunction-warning": "<strong>警告:</strong>此頁面使用了太多消耗系統資源的解析函數。\n\n使用次數應小於 $2 次,但目前使用了 $1 次。",
"expensive-parserfunction-category": "使用了太多消耗系統資源的分析函數的頁面",
"post-expand-template-inclusion-warning": "<strong>警告:</strong>引用樣板後大小超出限制。\n部份樣板內容將不會被使用。",
"post-expand-template-inclusion-category": "引用樣板後大小超出限制的頁面",
- "post-expand-template-argument-warning": "<strong>警告:</strong>此頁面有一個以上的樣版參數過長。\n過長的參數會被直接忽略。",
+ "post-expand-template-argument-warning": "<strong>警告:</strong>此頁面有一個以上的樣板參數過長。\n過長的參數會被直接忽略。",
"post-expand-template-argument-category": "樣板參數有部份被忽略的頁面",
"parser-template-loop-warning": "偵測到樣板遞迴:[[$1]]",
- "parser-template-recursion-depth-warning": "超出樣版遞迴深度限制 ($1)",
+ "parser-template-recursion-depth-warning": "超出樣板遞迴深度限制 ($1)",
"language-converter-depth-warning": "已超出語言轉換器深度限制 ($1)",
"node-count-exceeded-category": "節點數量超出限制的頁面",
"node-count-exceeded-category-desc": "超出節點數量限制的頁面。",
"history-feed-empty": "請求的頁面不存在,\n可能已被刪除或重新命名。\n請嘗試 [[Special:Search|搜尋本站]] 取得其他相關的新頁面。",
"rev-deleted-comment": "(已移除編輯摘要)",
"rev-deleted-user": " (已移除使用者名稱)",
- "rev-deleted-event": "(已移除日誌)",
+ "rev-deleted-event": "(已移除日誌操作)",
"rev-deleted-user-contribs": "[使用者名稱或 IP 位址已移除 - 已隱藏貢獻清單中的編輯]",
"rev-deleted-text-permission": "此頁面修訂已被 <strong>刪除</strong>。\n可至 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 刪除日誌] 取得詳細資訊。",
"rev-suppressed-text-permission": "此頁面修訂已被 <strong>禁止顯示</strong>。\n可至 [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 禁止顯示日誌] 取得詳細資訊。",
"searchprofile-advanced-tooltip": "搜尋自訂命名空間",
"search-result-size": "$1 ($2 個字)",
"search-result-category-size": "$1 位成員 ($2 個子分類,$3 個檔案)",
- "search-redirect": "(重新導向自 $1 )",
+ "search-redirect": "(重新導向自 $1)",
"search-section": "(章節 $1)",
"search-category": "(分類 $1)",
"search-file-match": "(符合檔案內容)",
"right-protect": "更改保護層級及編輯被連鎖保護的頁面",
"right-editprotected": "編輯保護層級為 \"{{int:protect-level-sysop}}\" 的頁面",
"right-editsemiprotected": "編輯保護層級為 \"{{int:protect-level-autoconfirmed}}\" 的頁面",
+ "right-editcontentmodel": "編輯頁面的內容模型",
"right-editinterface": "編輯使用者介面",
"right-editusercssjs": "編輯其他使用者的 CSS 和 JavaScript 檔案",
"right-editusercss": "編輯其他使用者的 CSS 檔案",
"action-viewmywatchlist": "檢視您的監視清單",
"action-viewmyprivateinfo": "檢視您的個人資訊",
"action-editmyprivateinfo": "編輯您的個人資訊",
+ "action-editcontentmodel": "編輯頁面的內容模型",
"nchanges": "$1 次變更",
"enhancedrc-since-last-visit": "自上次訪問已有 $1",
"enhancedrc-history": "歷史",
"listduplicatedfiles-summary": "此清單中包含最新版本的檔案與其他檔案重複的清單,本清單只顯示本地檔案。",
"listduplicatedfiles-entry": "[[:File:$1|$1]] 有[[$3|其他 $2 個重複檔案]]。",
"unusedtemplates": "未使用的樣板",
- "unusedtemplatestext": "此頁面列出所有於 {{ns:template}} 命名空間下未被其他頁面引用的樣版。\n在刪除前,仍需檢查是否有連結這些樣版的其他頁面。",
+ "unusedtemplatestext": "此頁面列出所有於 {{ns:template}} 命名空間下未被其他頁面引用的樣板。\n在刪除前,仍需檢查是否有連結這些樣板的其他頁面。",
"unusedtemplateswlh": "其他連結",
"randompage": "隨機頁面",
"randompage-nopages": "在{{PLURAL:$2|命名空間}}中沒有任何頁面:$1。",
"uncategorizedpages": "未分類的頁面",
"uncategorizedcategories": "未分類的分類",
"uncategorizedimages": "未分類的檔案",
- "uncategorizedtemplates": "待分類樣版",
+ "uncategorizedtemplates": "待分類樣板",
"unusedcategories": "未使用的分類",
"unusedimages": "未使用的檔案",
"wantedcategories": "需要的分類",
"wantedfiletext-cat-noforeign": "下列檔案已被使用但不存在。 除此之外,頁面已內嵌但不存在的檔案列於 [[:$1]]。",
"wantedfiletext-nocat": "下列檔案被時用,但檔案不存在。 外部儲存庫的檔案儘管存在,但此清單仍會列出。 這類誤報的項目會以 <del>刪除線</del> 標示。",
"wantedfiletext-nocat-noforeign": "下列檔案已被使用但不存在。",
- "wantedtemplates": "需要的樣版",
+ "wantedtemplates": "需要的樣板",
"mostlinked": "被連結最多的頁面",
"mostlinkedcategories": "被連結最多的分類",
"mostlinkedtemplates": "被引用最多的頁面",
"trackingcategories-desc": "分類收錄標準",
"noindex-category-desc": "命名空間允許,且含有魔術字 <code><nowiki>__NOINDEX__</nowiki></code> 未被機器人列入索引的頁面。",
"index-category-desc": "命名空間允許,且含有魔術字 <code><nowiki>__INDEX__</nowiki></code> 被機器人列入索引的頁面。",
- "post-expand-template-inclusion-category-desc": "展開樣版後大小超過 <code>$wgMaxArticleSize</code> 導致部份樣版未正常展開的頁面。",
- "post-expand-template-argument-category-desc": "展開樣版參數後大小超過 <code>$wgMaxArticleSize</code> 的頁面 (有些於三括號中,如 <code>{{{Foo}}}</code>)。",
+ "post-expand-template-inclusion-category-desc": "展開樣板後大小超過 <code>$wgMaxArticleSize</code> 導致部份樣板未正常展開的頁面。",
+ "post-expand-template-argument-category-desc": "展開樣板參數後大小超過 <code>$wgMaxArticleSize</code> 的頁面 (有些於三括號中,如 <code>{{{Foo}}}</code>)。",
"expensive-parserfunction-category-desc": "頁面使用太多消耗系統資源的解析器函數 (如 <code>#ifexist</code>)。\n請參考 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit]。",
"broken-file-category-desc": "含有損壞檔案連結的頁面 (內嵌檔案連結的檔案不存在)。",
"hidden-category-category-desc": "內容中使用 <code><nowiki>__HIDDENCAT__</nowiki></code> 的分類,可隱藏預設在頁面上顯示的分類連結方塊。",
"whatlinkshere-prev": "前 $1 筆",
"whatlinkshere-next": "後 $1 筆",
"whatlinkshere-links": "← 連結",
- "whatlinkshere-hideredirs": "$1重新導向頁面",
+ "whatlinkshere-hideredirs": "$1 重新導向頁面",
"whatlinkshere-hidetrans": "$1 引用",
"whatlinkshere-hidelinks": "$1 連結",
"whatlinkshere-hideimages": "$1 檔案連結",
"tooltip-search": "搜尋 {{SITENAME}}",
"tooltip-search-go": "若與此名稱相符的頁面存在,前往該頁面",
"tooltip-search-fulltext": "搜尋使用此文字的頁面",
- "tooltip-p-logo": "前往主頁面",
- "tooltip-n-mainpage": "前往主頁面",
- "tooltip-n-mainpage-description": "前往主頁面",
- "tooltip-n-portal": "關於本專案,您可以做什麼、哪裡可以找到事情",
- "tooltip-n-currentevents": "尋找新聞中最新動態的背景資訊",
+ "tooltip-p-logo": "前往主頁",
+ "tooltip-n-mainpage": "前往主頁",
+ "tooltip-n-mainpage-description": "前往主頁",
+ "tooltip-n-portal": "關於本專案、您可以做什麼、哪裡可以找到您需要的事物",
+ "tooltip-n-currentevents": "於最新動態中尋找背景資訊",
"tooltip-n-recentchanges": "列出此 Wiki 中的近期變更清單",
"tooltip-n-randompage": "隨機進入一個頁面",
"tooltip-n-help": "尋求協助的地方",
"pageinfo-recent-authors": "最近作者數",
"pageinfo-magic-words": "魔術{{PLURAL:$1|字}} ($1)",
"pageinfo-hidden-categories": "隱藏分類 ($1)",
- "pageinfo-templates": "引用樣版 ($1)",
+ "pageinfo-templates": "引用樣板 ($1)",
"pageinfo-transclusions": "頁面被引用於 ($1)",
"pageinfo-toolboxlink": "頁面資訊",
"pageinfo-redirectsto": "重新導向至",
"exif-datetimemetadata": "資料定義最後修改日期",
"exif-nickname": "非正式的影像名稱",
"exif-rating": "評分 (共 5 分)",
- "exif-rightscertificate": "版權管理證書",
+ "exif-rightscertificate": "版權管理憑證",
"exif-copyrighted": "版權狀態",
"exif-copyrightowner": "版權所有人",
"exif-usageterms": "使用條款",
"tag-filter-submit": "搜尋",
"tag-list-wrapper": "([[Special:Tags|標籤]]:$2)",
"tags-title": "標籤",
- "tags-intro": "此頁面列出所有可用來標示編輯的標籤,以及這些標籤的含意。",
+ "tags-intro": "此頁面列出所有可用來標示編輯內容的標籤以及這些標籤所代表的意思。",
"tags-tag": "標籤名稱",
- "tags-display-header": "在更改清單中的出現方式",
- "tags-description-header": "完整含意說明",
+ "tags-display-header": "在變更日誌中顯示的方式",
+ "tags-description-header": "意義完整的說明",
"tags-active-header": "開啟?",
- "tags-hitcount-header": "已加上標籤的更改",
+ "tags-hitcount-header": "已標記的變更",
"tags-active-yes": "是",
"tags-active-no": "否",
"tags-edit": "編輯",
"api-error-overwrite": "不允許覆蓋已存在的檔案。",
"api-error-stashfailed": "內部錯誤:伺服器儲存暫存檔案失敗。",
"api-error-publishfailed": "內部錯誤:伺服器發佈暫存檔案失敗。",
- "api-error-stasherror": "上傳檔案至儲存庫時發生錯誤。",
- "api-error-stashedfilenotfound": "嘗試從藏匿處上傳時找不到藏匿的檔案。",
- "api-error-stashpathinvalid": "æ\89¾å\88°ç\9a\84è\97\8få\8c¿æª\94æ¡\88ç\9a\84è·¯å¾\91æ\98¯ç\84¡æ\95\88ç\9a\84。",
- "api-error-stashfilestorage": "儲存檔案至藏匿處時出錯。",
- "api-error-stashzerolength": "伺服器不能藏匿檔案,因爲它已經沒有藏匿空間了。",
- "api-error-stashnotloggedin": "您必須登入以儲存檔案至上傳藏匿處。",
- "api-error-stashwrongowner": "您嘗試在藏匿處存取的檔案不屬於您。",
- "api-error-stashnosuchfilekey": "您嘗試在藏匿處存取的檔案金鑰不存在。",
+ "api-error-stasherror": "上傳檔案至儲藏庫時發生錯誤。",
+ "api-error-stashedfilenotfound": "嘗試從儲藏庫上傳檔案時查無該檔案。",
+ "api-error-stashpathinvalid": "æ\87\89該å\98å\9c¨å\84²è\97\8fæª\94æ¡\88ç\9a\84è·¯å¾\91ç\84¡æ\95\88。",
+ "api-error-stashfilestorage": "儲存檔案至儲藏庫時發生錯誤。",
+ "api-error-stashzerolength": "伺服器無法儲藏該檔案,因為該檔案大小為 0。",
+ "api-error-stashnotloggedin": "您必須登入以儲存檔案於上傳儲藏庫。",
+ "api-error-stashwrongowner": "您嘗試在儲藏庫存取的檔案不屬於您的。",
+ "api-error-stashnosuchfilekey": "您嘗試在儲藏庫存取的檔案金鑰不存在。",
"api-error-timeout": "伺服器沒有在預期的時間內回應。",
"api-error-unclassified": "發生不明錯誤。",
"api-error-unknown-code": "不明錯誤:\"$1\"。",
"limitreport-expansiondepth": "最高展開深度",
"limitreport-expensivefunctioncount": "高消耗解析器函數次數",
"expandtemplates": "展開樣板",
- "expand_templates_intro": "本特殊頁面會將文字中的樣版展開,可以包含支援的解析器語法,如 <code><nowiki>{{</nowiki>#language:…}}</code> 與變數如 <code><nowiki>{{</nowiki>CURRENTDAY}}</code>。\n實際上,絕大部分在雙括號中的內容都會被展開。",
+ "expand_templates_intro": "本特殊頁面會將文字中的樣板展開,可以包含支援的解析器語法,如 <code><nowiki>{{</nowiki>#language:…}}</code> 與變數如 <code><nowiki>{{</nowiki>CURRENTDAY}}</code>。\n實際上,絕大部分在雙括號中的內容都會被展開。",
"expand_templates_title": "上下文標題,用於 {{FULLPAGENAME}} 等:",
"expand_templates_input": "輸入文字:",
"expand_templates_output": "結果",
"expand_templates_generate_xml": "顯示 XML 解析樹",
"expand_templates_generate_rawhtml": "顯示原始 HTML",
"expand_templates_preview": "預覽",
+ "expand_templates_preview_fail_html": "<em>因連線階段的資料遺失且 {{SITENAME}} 已開啟顯示原始 HTML 功能,為預防 JavaScript 攻擊已隱藏預覽內容。</em>\n\n<strong>若您目前的預覽動作並無非法,請再試一次。</strong>\n若仍然無效,請嘗試[[Special:UserLogout|登出]]並再登入一次。",
+ "expand_templates_preview_fail_html_anon": "<em>因您尚未登入且 {{SITENAME}} 已開啟顯示原始 HTML 功能,為預防 JavaScript 攻擊已隱藏預覽內容。</em>\n\n<strong>若您目前的預覽動作並無非法,請[[Special:UserLogin|登入]]後再試一次。</strong>",
"pagelanguage": "頁面語言選擇器",
"pagelang-name": "頁面",
"pagelang-language": "語言",
"log-name-pagelang": "更改語言日誌",
"log-description-pagelang": "此頁為頁面語言的變更日誌。",
"logentry-pagelang-pagelang": "$1 {{GENDER:$2|已更改}}頁面 $3 的語言從 $4 到 $5。",
- "default-skin-not-found": "哎呀!您於 <code dir=\"ltr\">$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您的安裝程序應包含以下外觀。 請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。\n\n$2\n\n; 若您才剛安裝完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code dir=\"ltr\">skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。\n\n; 若您才剛升級 MediaWiki:\n: MediaWiki 1.24 與較新的版本不再自動開啟已安裝的外觀 (請參考 [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 操作手冊:外觀自動搜尋])。 您可以將下列行貼上至 <code>LocalSettings.php</code> 來開啟所有目前已經安裝的外觀:\n\n<pre dir=\"ltr\">$3</pre>\n\n; 若您才剛修改 <code>LocalSettings.php</code>:\n: 請再次確認您輸入的外觀名稱是否有誤。",
- "default-skin-not-found-no-skins": "哎呀!您於 <code>$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您未安裝任何的外觀。\n\n; 若您才剛安裝完或升級完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。 MediaWiki 1.24 或較新的版本在主要儲存庫中不再包含任何的外觀。 請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code dir=\"ltr\">skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。 請參考 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。",
+ "default-skin-not-found": "哎呀!您於 <code dir=\"ltr\">$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您的安裝程序應包含以下外觀。 請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。\n\n$2\n\n; 若您才剛安裝完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 自 [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org] 下載個別外觀 tarball。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code dir=\"ltr\">skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。\n\n; 若您才剛升級 MediaWiki:\n: MediaWiki 1.24 與較新的版本不再自動開啟已安裝的外觀 (請參考 [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 操作手冊:外觀自動搜尋])。 您可以將下列行貼上至 <code>LocalSettings.php</code> 來開啟所有目前已經安裝的外觀:\n\n<pre dir=\"ltr\">$3</pre>\n\n; 若您才剛修改 <code>LocalSettings.php</code>:\n: 請再次確認您輸入的外觀名稱是否有誤。",
+ "default-skin-not-found-no-skins": "哎呀!您於 <code>$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您未安裝任何的外觀。\n\n; 若您才剛安裝完或升級完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。 MediaWiki 1.24 或較新的版本在主要儲存庫中不再包含任何的外觀。 請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 自 [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org] 下載個別外觀 tarball。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code dir=\"ltr\">skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。 請參考 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (已開啟)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''已停用''')",
"mediastatistics": "媒體統計資訊",
'Listgrouprights' => array( 'רשימת_הרשאות_לקבוצה' ),
'Listredirects' => array( 'רשימת_הפניות', 'הפניות' ),
'Listusers' => array( 'רשימת_משתמשים', 'משתמשים' ),
+ 'ListDuplicatedFiles' => array( 'רשימת_קבצים_כפולים' ),
'Lockdb' => array( 'נעילת_בסיס_הנתונים' ),
'Log' => array( 'יומנים' ),
'Lonelypages' => array( 'דפים_יתומים' ),
'Specialpages' => array( 'דפים_מיוחדים' ),
'Statistics' => array( 'סטטיסטיקות' ),
'Tags' => array( 'תגיות' ),
+ 'TrackingCategories' => array( 'קטגוריות_מעקב' ),
'Unblock' => array( 'שחרור_חסימה' ),
'Uncategorizedcategories' => array( 'קטגוריות_חסרות_קטגוריה' ),
'Uncategorizedimages' => array( 'קבצים_חסרי_קטגוריה', 'תמונות_חסרות_קטגוריה' ),
private $mDependantParameters = array();
/**
- * Used by getDD() / setDB()
+ * Used by getDB() / setDB()
* @var DatabaseBase
*/
private $mDb = null;
$wgShowSQLErrors = true;
- // @codingStandardsIgnoreStart Allow error supppression. wfSuppressWarnings()
- // is not avaiable.
+ // @codingStandardsIgnoreStart Allow error suppression. wfSuppressWarnings()
+ // is not available.
@set_time_limit( 0 );
// @codingStandardsIgnoreStart
* We default as considering stdin a tty (for nice readline methods)
* but treating stout as not a tty to avoid color codes
*
- * @param int $fd File descriptor
+ * @param mixed $fd File descriptor
* @return bool
*/
public static function posix_isatty( $fd ) {
$this->thisPage .= $data;
}
}
- elseif ( $this->lastName == "model" ) {
+ elseif ( $this->lastName == "model" ) {
$this->thisRevModel .= $data;
}
- elseif ( $this->lastName == "format" ) {
+ elseif ( $this->lastName == "format" ) {
$this->thisRevFormat .= $data;
}
*/
require_once __DIR__ . '/Maintenance.php';
-require_once 'PHPUnit/Autoload.php';
/**
* @ingroup Maintenance
// require it here.
require_once __DIR__ . '/../tests/TestsAutoLoader.php';
+ // If phpunit isn't available by autoloader try pulling it in
+ if ( !class_exists( 'PHPUnit_Framework_TestCase' ) ) {
+ require_once 'PHPUnit/Autoload.php';
+ }
+
+ // RequestContext::resetMain() will print warnings unless this
+ // is defined.
+ if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
+ define( 'MW_PHPUNIT_TEST', true );
+ }
+
$textUICommand = new PHPUnit_TextUI_Command();
$argv = array(
"$IP/tests/phpunit/phpunit.php",
whatlinkshere
whatwg
wheely
-wheter
+whether
whitelist
whitelisted
whitelistedittext
$IP . '/includes/jobqueue/',
$IP . '/includes/json/',
$IP . '/includes/logging/',
+ $IP . '/includes/mail/',
$IP . '/includes/media/',
$IP . '/includes/page/',
$IP . '/includes/parser/',
* @author Antoine Musso <hashar at free dot fr>
*/
-/** A general output object. Need to be overriden */
+/** A general output object. Need to be overridden */
class StatsOutput {
function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
wfSuppressWarnings();
* Parse some wikitext.
*
* Wikitext can be given by stdin or using a file. The wikitext will be parsed
- * using 'CLIParser' as a title. This can be overriden with --title option.
+ * using 'CLIParser' as a title. This can be overridden with --title option.
*
* Example1:
* @code
/**
* Title object to use for CLI parsing.
- * Default title is 'CLIParser', it can be overriden with the option
+ * Default title is 'CLIParser', it can be overridden with the option
* --title <Your:Title>
*
* @return Title
* @param int $pageId
*/
function doPage( $pageId ) {
- $title = Title::newFromId( $pageId );
+ $title = Title::newFromID( $pageId );
if ( $title ) {
$titleText = $title->getPrefixedText();
} else {
parent::__construct();
$this->mDescription = "Count of the number of articles and update the site statistics table";
$this->addOption( 'update', 'Update the site_stats table with the new count' );
+ $this->addOption( 'use-master', 'Count using the master database' );
}
public function execute() {
$this->output( "Counting articles..." );
- $counter = new SiteStatsInit( false );
+ if ( $this->hasOption( 'use-master' ) ) {
+ $dbr = wfGetDB( DB_MASTER );
+ } else {
+ $dbr = wfGetDB( DB_SLAVE, 'vslow' );
+ }
+ $counter = new SiteStatsInit( $dbr );
$result = $counter->articles();
$this->output( "found {$result}.\n" );
'user.cssprefs' => array( 'class' => 'ResourceLoaderUserCSSPrefsModule' ),
// Populate mediawiki.user placeholders with information about the current user
+ 'user.defaults' => array( 'class' => 'ResourceLoaderUserDefaultsModule' ),
'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ),
'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ),
'zh-cn' => 'resources/lib/moment/locale/zh-cn.js',
'zh-tw' => 'resources/lib/moment/locale/zh-tw.js',
),
+ 'targets' => array( 'desktop', 'mobile' ),
),
/* MediaWiki */
'dependencies' => array(
'jquery.form',
'jquery.spinner',
+ 'mediawiki.api',
'mediawiki.action.history.diff',
+ 'mediawiki.util',
+ 'mediawiki.jqueryMsg',
+ ),
+ 'messages' => array(
+ 'otherlanguages',
+ 'tooltip-p-lang',
+ 'summary-preview',
+ 'parentheses',
),
),
'mediawiki.action.edit.stash' => array(
'resources/lib/oojs-ui/oojs-ui.js',
),
'skinScripts' => array(
- 'default' => 'resources/lib/oojs-ui/oojs-ui-apex.js',
- 'minerva' => 'resources/lib/oojs-ui/oojs-ui-mediawiki.js',
+ 'default' => 'resources/lib/oojs-ui/oojs-ui-mediawiki.js',
),
- 'skinStyles' => array(
- 'default' => 'resources/lib/oojs-ui/oojs-ui-apex.svg.css',
- 'minerva' => 'resources/lib/oojs-ui/oojs-ui-mediawiki.svg.css',
+ 'dependencies' => array(
+ 'es5-shim',
+ 'oojs',
+ 'oojs-ui.styles',
),
'messages' => array(
'ooui-dialog-message-accept',
'ooui-toolgroup-collapse',
'ooui-toolgroup-expand',
),
- 'dependencies' => array(
- 'es5-shim',
- 'oojs',
+ 'targets' => array( 'desktop', 'mobile' ),
+ ),
+
+ 'oojs-ui.styles' => array(
+ 'position' => 'top',
+ 'skinStyles' => array(
+ 'default' => 'resources/lib/oojs-ui/oojs-ui-mediawiki.svg.css',
),
'targets' => array( 'desktop', 'mobile' ),
),
"SMP",
"Vriullop",
"Toniher",
- "Edustus"
+ "Edustus",
+ "Davidpar"
]
},
- "ooui-outline-control-move-down": "Baixa element",
- "ooui-outline-control-move-up": "Puja element",
+ "ooui-outline-control-move-down": "Baixa l'element",
+ "ooui-outline-control-move-up": "Puja l'element",
+ "ooui-outline-control-remove": "Esborra l'ítem",
"ooui-toolbar-more": "Més",
"ooui-toolgroup-expand": "Més",
"ooui-toolgroup-collapse": "Menys",
+ "ooui-dialog-message-accept": "D'acord",
+ "ooui-dialog-message-reject": "Cancel·la",
+ "ooui-dialog-process-error": "Alguna cosa no ha funcionat",
"ooui-dialog-process-dismiss": "Descarta",
- "ooui-dialog-process-retry": "Torneu-ho a provar"
+ "ooui-dialog-process-retry": "Torneu-ho a provar",
+ "ooui-dialog-process-continue": "Continua"
}
"SteveR",
"Tel'et",
"Tifinaghes",
- "Ата"
+ "Ата",
+ "Piramidion"
]
},
"ooui-outline-control-move-down": "Перемістити елемент униз",
"ooui-outline-control-move-up": "Перемістити елемент вгору",
"ooui-outline-control-remove": "Видалити елемент",
"ooui-toolbar-more": "Більше",
+ "ooui-toolgroup-expand": "Більше",
+ "ooui-toolgroup-collapse": "Менше",
"ooui-dialog-message-accept": "Готово",
"ooui-dialog-message-reject": "Скасувати",
"ooui-dialog-process-error": "Щось пішло не так",
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:30Z
+ * Date: 2014-12-12T20:13:21Z
*/
.oo-ui-progressBarWidget-slide-frames from {
margin-left: -40%;
.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
margin-left: 0.25em;
}
-.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #087ecc;
}
.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
outline: none;
}
.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
line-height: 1.9em;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
margin-left: -0.5em;
margin-right: 0.3em;
}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
border: solid 1px #a6cee1;
background: #cde7f4;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
background-image: -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
background-image: linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
border-color: #9dc2d4;
}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
border: solid 1px #a6cee1;
background: #cde7f4;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-draggableElement {
+ cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
+ /*
+ * HACK: In order to style horizontally, we must override
+ * OO.ui.OptionWidget's display rule that is currently set
+ * to be 'block'
+ */
+}
+.oo-ui-draggableElement-dragging {
+ cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
+ background: rgba(0, 0, 0, 0.2);
+ opacity: 0.4;
+}
+.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
+ display: inline-block;
+}
+.oo-ui-draggableGroupElement-placeholder {
+ position: absolute;
+ display: block;
+ background: rgba(0, 0, 0, 0.4);
+}
.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
overflow-y: hidden;
}
.oo-ui-fieldLayout:after {
clear: both;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
- display: block;
- float: left;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
display: block;
float: left;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
text-align: right;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- display: inline-block;
- vertical-align: middle;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+ display: table;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
- display: inline-block;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+ display: table-cell;
vertical-align: middle;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
display: inline-block;
}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
- z-index: 1;
-}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
float: right;
}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help-content {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+ z-index: 1;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
padding: 0.5em 0.75em;
line-height: 1.5em;
}
.oo-ui-fieldLayout:last-child {
margin-bottom: 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding-top: 0.5em;
margin-right: 5%;
width: 35%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
width: 60%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- padding: 0.75em 0.5em 0.5em 0.5em;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+ padding: 0.5em;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
padding: 0.5em 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding: 0.5em 0;
}
.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
.oo-ui-popupWidget-head .oo-ui-labelElement-label {
margin: 0.75em 1em;
}
-.oo-ui-popupWidget-body {
- box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
-}
.oo-ui-popupWidget-body-padded {
padding: 0 1em;
}
}
.oo-ui-textInputWidget {
position: relative;
+ vertical-align: middle;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
.oo-ui-outlineControlsWidget-items,
.oo-ui-outlineControlsWidget-movers {
height: 2em;
- margin: 0.5em;
+ margin: 0.5em 0.5em 0.5em 0;
padding: 0;
}
.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
margin: 0.5em 0 0.5em 0.5em;
opacity: 0.2;
}
-.oo-ui-outlineControlsWidget-items {
- margin-left: 0;
-}
.oo-ui-comboBoxWidget {
display: inline-block;
position: relative;
.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
background-color: rgba(0, 0, 0, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
/* Adjust for border so text aligns with title */
margin: -1px;
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:19Z
+ * Date: 2014-12-12T20:13:09Z
*/
/* Instantiation */
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:30Z
+ * Date: 2014-12-12T20:13:21Z
*/
.oo-ui-progressBarWidget-slide-frames from {
margin-left: -40%;
.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
margin-left: 0.25em;
}
-.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #087ecc;
}
.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
outline: none;
}
.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
line-height: 1.9em;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
margin-left: -0.5em;
margin-right: 0.3em;
}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
border: solid 1px #a6cee1;
background: #cde7f4;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
background-image: -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
background-image: linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
border-color: #9dc2d4;
}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
border: solid 1px #a6cee1;
background: #cde7f4;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-draggableElement {
+ cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
+ /*
+ * HACK: In order to style horizontally, we must override
+ * OO.ui.OptionWidget's display rule that is currently set
+ * to be 'block'
+ */
+}
+.oo-ui-draggableElement-dragging {
+ cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
+ background: rgba(0, 0, 0, 0.2);
+ opacity: 0.4;
+}
+.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
+ display: inline-block;
+}
+.oo-ui-draggableGroupElement-placeholder {
+ position: absolute;
+ display: block;
+ background: rgba(0, 0, 0, 0.4);
+}
.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
overflow-y: hidden;
}
.oo-ui-fieldLayout:after {
clear: both;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
- display: block;
- float: left;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
display: block;
float: left;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
text-align: right;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- display: inline-block;
- vertical-align: middle;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+ display: table;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
- display: inline-block;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+ display: table-cell;
vertical-align: middle;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
display: inline-block;
}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
- z-index: 1;
-}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
float: right;
}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help-content {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+ z-index: 1;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
padding: 0.5em 0.75em;
line-height: 1.5em;
}
.oo-ui-fieldLayout:last-child {
margin-bottom: 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding-top: 0.5em;
margin-right: 5%;
width: 35%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
width: 60%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- padding: 0.75em 0.5em 0.5em 0.5em;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+ padding: 0.5em;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
padding: 0.5em 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding: 0.5em 0;
}
.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
.oo-ui-popupWidget-head .oo-ui-labelElement-label {
margin: 0.75em 1em;
}
-.oo-ui-popupWidget-body {
- box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
-}
.oo-ui-popupWidget-body-padded {
padding: 0 1em;
}
}
.oo-ui-textInputWidget {
position: relative;
+ vertical-align: middle;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
.oo-ui-outlineControlsWidget-items,
.oo-ui-outlineControlsWidget-movers {
height: 2em;
- margin: 0.5em;
+ margin: 0.5em 0.5em 0.5em 0;
padding: 0;
}
.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
margin: 0.5em 0 0.5em 0.5em;
opacity: 0.2;
}
-.oo-ui-outlineControlsWidget-items {
- margin-left: 0;
-}
.oo-ui-comboBoxWidget {
display: inline-block;
position: relative;
.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
background-color: rgba(0, 0, 0, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
/* Adjust for border so text aligns with title */
margin: -1px;
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:30Z
+ * Date: 2014-12-12T20:13:21Z
*/
.oo-ui-progressBarWidget-slide-frames from {
margin-left: -40%;
}
.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
- width: 2.2em;
- height: 2.2em;
+ width: 1.9em;
+ height: 1.9em;
}
.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #444444;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
color: #598ad1;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #777777;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #015ccc;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
}
.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
margin: 0.1em 0;
- padding: 0.3em 1.2em;
- border-radius: 0.3em;
+ padding: 0.2em 0.8em;
+ border-radius: 2px;
-webkit-transition: background 0.1s ease-in-out, color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
-moz-transition: background 0.1s ease-in-out, color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
-ms-transition: background 0.1s ease-in-out, color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
outline: none;
}
.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- line-height: 2.2em;
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+ line-height: 1.9em;
}
.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
margin-left: -0.5em;
background-color: #d0d0d0;
border-color: #d0d0d0;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
+ color: #0274ff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 -0.2em 0 0 #015ccc, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
+ border-bottom-color: #015ccc;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+ color: #00af89;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 -0.2em 0 0 #008c6d, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
+ border-bottom-color: #008c6d;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+ color: #d11d13;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 -0.2em 0 0 #a7170f, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
+ border-bottom-color: #a7170f;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #0274ff;
border-color: #0274ff;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
box-shadow: inset 0 -0.2em 0 0 #015ccc, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
border-bottom-color: #015ccc;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #015ccc;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #00af89;
border-color: #00af89;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
box-shadow: inset 0 -0.2em 0 0 #008c6d, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
border-bottom-color: #008c6d;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #008c6d;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #d11d13;
border-color: #d11d13;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
box-shadow: inset 0 -0.2em 0 0 #a7170f, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
border-bottom-color: #a7170f;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #a7170f;
}
.oo-ui-clippableElement-clippable {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-draggableElement {
+ cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
+ /*
+ * HACK: In order to style horizontally, we must override
+ * OO.ui.OptionWidget's display rule that is currently set
+ * to be 'block'
+ */
+}
+.oo-ui-draggableElement-dragging {
+ cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
+ background: rgba(0, 0, 0, 0.2);
+ opacity: 0.4;
+}
+.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
+ display: inline-block;
+}
+.oo-ui-draggableGroupElement-placeholder {
+ position: absolute;
+ display: block;
+ background: rgba(0, 0, 0, 0.4);
+}
.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
overflow-y: hidden;
}
.oo-ui-fieldLayout:after {
clear: both;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
display: block;
float: left;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
- display: block;
- float: left;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
text-align: right;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- display: inline-block;
- vertical-align: middle;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+ display: table;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
- display: inline-block;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+ display: table-cell;
vertical-align: middle;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
display: inline-block;
}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
- z-index: 1;
-}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
float: right;
}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help-content {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+ z-index: 1;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
padding: 0.5em 0.75em;
line-height: 1.5em;
}
.oo-ui-fieldLayout:last-child {
margin-bottom: 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding-top: 0.5em;
margin-right: 5%;
width: 35%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
width: 60%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- padding: 0.75em 0.5em 0.5em 0.5em;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+ padding: 0.5em;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
padding: 0.5em 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding: 0.5em 0;
}
.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
.oo-ui-listToolGroup .oo-ui-tool-link {
padding-right: 0.5em;
}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
background-color: #eeeeee;
}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled,
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
+ background-color: #d0d0d0;
+}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
color: #cccccc;
}
background-image: /* @embed */ url(themes/mediawiki/images/icons/check.svg);
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
- background-color: #e1f3ff;
+ background-color: #eeeeee;
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
color: #cccccc;
pointer-events: none;
}
.oo-ui-toolbar-bar {
- border-bottom: solid 1px #cccccc;
+ border-bottom: solid 4px rgba(0, 0, 0, 0.15);
background: #ffffff;
}
.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
display: none;
}
.oo-ui-selectWidget {
- border-radius: 0.3em;
+ border-radius: 2px;
}
.oo-ui-selectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
border-radius: 0;
margin-left: -1px;
}
.oo-ui-selectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
- border-bottom-left-radius: 0.3em;
- border-top-left-radius: 0.3em;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
margin-left: 0;
}
.oo-ui-selectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
- border-bottom-right-radius: 0.3em;
- border-top-right-radius: 0.3em;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
}
.oo-ui-optionWidget {
position: relative;
}
.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected,
.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed {
- background-color: #a7dcff;
+ background-color: #d0d0d0;
}
.oo-ui-optionWidget.oo-ui-widget-disabled {
color: #cccccc;
.oo-ui-buttonSelectWidget {
display: inline-block;
white-space: nowrap;
- border-radius: 0.3em;
+ border-radius: 2px;
}
.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
border-radius: 0;
margin-left: -1px;
}
.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
- border-bottom-left-radius: 0.3em;
- border-top-left-radius: 0.3em;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
margin-left: 0;
}
.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
- border-bottom-right-radius: 0.3em;
- border-top-right-radius: 0.3em;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
}
.oo-ui-radioSelectWidget {
padding: 0.75em 0 0.5em 0;
vertical-align: middle;
}
.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
- height: 2.2em;
+ height: 1.9em;
}
.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
- height: 2.2em;
+ height: 1.9em;
margin-top: 0;
}
.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
background-position: center center;
background-repeat: no-repeat;
line-height: 2.5em;
- height: 2.2em;
- width: 2.2em;
+ height: 1.9em;
+ width: 1.9em;
}
.oo-ui-iconWidget.oo-ui-widget-disabled {
opacity: 0.2;
background-position: center center;
background-repeat: no-repeat;
line-height: 2.5em;
- height: 2.2em;
- width: 2.2em;
+ height: 1.9em;
+ width: 1.9em;
}
.oo-ui-indicatorWidget.oo-ui-widget-disabled {
opacity: 0.2;
.oo-ui-buttonGroupWidget {
display: inline-block;
white-space: nowrap;
- border-radius: 0.3em;
+ border-radius: 2px;
}
.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
border-radius: 0;
margin-left: -1px;
}
.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
- border-bottom-left-radius: 0.3em;
- border-top-left-radius: 0.3em;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
margin-left: 0;
}
.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
- border-bottom-right-radius: 0.3em;
- border-top-right-radius: 0.3em;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
}
.oo-ui-toggleSwitchWidget {
position: relative;
.oo-ui-popupWidget-head .oo-ui-labelElement-label {
margin: 0.75em 1em;
}
-.oo-ui-popupWidget-body {
- box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
-}
.oo-ui-popupWidget-body-padded {
padding: 0 1em;
}
}
.oo-ui-checkboxInputWidget {
position: relative;
- line-height: 1.6em;
+ line-height: 2em;
+ white-space: nowrap;
}
.oo-ui-checkboxInputWidget * {
+ font: inherit;
vertical-align: middle;
}
.oo-ui-checkboxInputWidget input[type="checkbox"] {
opacity: 0;
- width: 1.6em;
- height: 1.6em;
+ margin: 0;
+ width: 2em;
+ height: 2em;
max-width: none;
}
.oo-ui-checkboxInputWidget input[type="checkbox"] + span {
}
.oo-ui-checkboxInputWidget input[type="checkbox"] + span::before {
content: "";
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
position: absolute;
left: 0;
- border-radius: 0.3em;
- width: 1.6em;
- height: 1.6em;
- background-color: #ffffff;
- border: 1px solid grey;
+ border-radius: 2px;
+ width: 2em;
+ height: 2em;
+ background-color: white;
+ border: 1px solid #777777;
}
.oo-ui-checkboxInputWidget input[type="checkbox"]:checked + span::before {
background-image: /* @embed */ url(themes/mediawiki/images/icons/check-constructive.svg);
- background-size: 1.6em, 1.6em;
+ background-size: 2em, 2em;
background-repeat: no-repeat;
- background-position: center top;
+ background-position: center center;
+ background-origin: border-box;
}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:active + span::after,
-.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span::after {
+.oo-ui-checkboxInputWidget input[type="checkbox"]:active + span::before {
+ background-color: #dddddd;
+ border-color: #dddddd;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span::before {
+ border-width: 2px;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:focus:hover + span::before,
+.oo-ui-checkboxInputWidget input[type="checkbox"]:hover + span::before {
+ border-bottom-width: 3px;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span::before {
+ cursor: default;
+ background-color: #eeeeee;
+ border-color: #eeeeee;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled:checked + span::before {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/check-invert.svg);
+}
+.oo-ui-radioInputWidget {
+ position: relative;
+ line-height: 2em;
+}
+.oo-ui-radioInputWidget * {
+ font: inherit;
+ vertical-align: middle;
+}
+.oo-ui-radioInputWidget input[type="radio"] {
+ opacity: 0;
+ margin: 0;
+ width: 2em;
+ height: 2em;
+ max-width: none;
+}
+.oo-ui-radioInputWidget input[type="radio"] + span {
+ cursor: pointer;
+ margin: 0 0.4em;
+}
+.oo-ui-radioInputWidget input[type="radio"] + span::before {
+ transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -moz-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -ms-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -o-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -webkit-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
content: "";
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
position: absolute;
- width: 1.6em;
- height: 1.5em;
- left: 1px;
- border-bottom: solid 0.2em #d3d3d3;
+ left: 0;
+ border-radius: 100%;
+ width: 2em;
+ height: 2em;
+ background: white;
+ border: 1px solid #777777;
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-constructive.svg);
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-origin: border-box;
+ background-size: 0 0;
+}
+.oo-ui-radioInputWidget input[type="radio"]:checked + span::before {
+ background-size: 100% 100%;
}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span {
+.oo-ui-radioInputWidget input[type="radio"]:active + span::before {
+ background-color: #dddddd;
+ border-color: #dddddd;
+}
+.oo-ui-radioInputWidget input[type="radio"]:focus + span::before {
+ border-width: 2px;
+}
+.oo-ui-radioInputWidget input[type="radio"]:focus:hover + span::before,
+.oo-ui-radioInputWidget input[type="radio"]:hover + span::before {
+ border-bottom-width: 3px;
+}
+.oo-ui-radioInputWidget input[type="radio"]:disabled + span::before {
cursor: default;
+ background-color: #eeeeee;
+ border-color: #eeeeee;
}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span::before {
- background-color: lightgrey;
+.oo-ui-radioInputWidget input[type="radio"]:disabled:checked + span::before {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-invert.svg);
}
.oo-ui-textInputWidget {
position: relative;
+ vertical-align: middle;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.oo-ui-textInputWidget.oo-ui-indicatorElement input,
.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
- padding-right: 2.2em;
+ padding-right: 1.9em;
}
.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
width: 1.6em;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
+ font-size: 1.1em;
+ padding: 0.75em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+ padding-right: 1.5em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+ opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget-level-0 {
+ padding-left: 3.5em;
+}
+.oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
+ left: 1em;
+}
+.oo-ui-outlineOptionWidget-level-1 {
+ padding-left: 5em;
+}
+.oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
+ left: 2.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 {
+ padding-left: 6.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
+ left: 4em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
+ background-color: #d0d0d0;
+ text-shadow: 0 1px 1px #ffffff;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
+ font-weight: bold;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
+ font-style: italic;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
+ opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
+ color: #777777;
+}
+.oo-ui-outlineControlsWidget {
+ height: 3em;
+ background-color: #ffffff;
}
.oo-ui-outlineControlsWidget-items,
.oo-ui-outlineControlsWidget-movers {
.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
float: right;
}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+ height: 2em;
+ margin: 0.5em 0.5em 0.5em 0;
+ padding: 0;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+ width: 1.5em;
+ height: 2em;
+ margin: 0.5em 0 0.5em 0.5em;
+ opacity: 0.2;
+}
.oo-ui-comboBoxWidget {
display: inline-block;
position: relative;
height: 2.35em;
}
.oo-ui-comboBoxWidget .oo-ui-textInputWidget.oo-ui-indicatorElement {
- padding-right: 2.2em;
+ padding-right: 1.9em;
}
.oo-ui-comboBoxWidget .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
- width: 2.2em;
+ width: 1.9em;
background-position: center center;
border: solid 1px #cccccc;
border-left: none;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-searchWidget {
+ border: solid 1px #cccccc;
+}
.oo-ui-searchWidget-query {
position: absolute;
top: 0;
overflow-y: auto;
}
.oo-ui-searchWidget-query {
- height: 2.4em;
- top: 1px;
+ height: 4em;
+ padding: 0 1em;
+ border-bottom: solid 1px #cccccc;
}
-.oo-ui-searchWidget-query .oo-ui-textInputWidget input {
- border-width: 1px 0;
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+ margin: 0.75em 0;
}
.oo-ui-searchWidget-results {
- top: 2.2em;
- bottom: 0.2em;
+ top: 4em;
+ padding: 1em;
line-height: 0;
}
.oo-ui-window {
.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
background-color: rgba(0, 0, 0, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
/* Adjust for border so text aligns with title */
margin: -1px;
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
.oo-ui-image-invert.oo-ui-icon-previous {
background-image: /* @embed */ url(themes/mediawiki/images/icons/move-rtl-invert.png);
}
+.oo-ui-icon-circle {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle.png);
+}
+.oo-ui-image-constructive .oo-ui-icon-circle,
+.oo-ui-image-constructive.oo-ui-icon-circle {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-constructive.png);
+}
+.oo-ui-image-invert .oo-ui-icon-circle,
+.oo-ui-image-invert.oo-ui-icon-circle {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-invert.png);
+}
.oo-ui-icon-redo {
background-image: /* @embed */ url(themes/mediawiki/images/icons/arched-arrow-ltr.png);
}
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:19Z
+ * Date: 2014-12-12T20:13:09Z
*/
/**
* @class
var variant,
variants = {
invert: false,
- primary: false,
+ progressive: false,
constructive: false,
destructive: false
},
classes = OO.ui.MediaWikiTheme.super.prototype.getElementClasses.call( this, element );
if ( element.supports( [ 'isFramed', 'isDisabled', 'hasFlag' ] ) ) {
- if ( element.isFramed() && !element.isDisabled() ) {
- if (
- element.hasFlag( 'primary' ) ||
- element.hasFlag( 'constructive' ) ||
- element.hasFlag( 'destructive' )
- ) {
- variants.invert = true;
- }
+ if ( !element.isDisabled() && element.isFramed() && element.hasFlag( 'primary' ) ) {
+ variants.invert = true;
} else {
- variants.primary = element.hasFlag( 'primary' );
+ variants.progressive = element.hasFlag( 'progressive' );
variants.constructive = element.hasFlag( 'constructive' );
variants.destructive = element.hasFlag( 'destructive' );
}
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:30Z
+ * Date: 2014-12-12T20:13:21Z
*/
.oo-ui-progressBarWidget-slide-frames from {
margin-left: -40%;
}
.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
- width: 2.2em;
- height: 2.2em;
+ width: 1.9em;
+ height: 1.9em;
}
.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #444444;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
color: #598ad1;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #777777;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #015ccc;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
}
.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
margin: 0.1em 0;
- padding: 0.3em 1.2em;
- border-radius: 0.3em;
+ padding: 0.2em 0.8em;
+ border-radius: 2px;
-webkit-transition: background 0.1s ease-in-out, color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
-moz-transition: background 0.1s ease-in-out, color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
-ms-transition: background 0.1s ease-in-out, color 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
outline: none;
}
.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- line-height: 2.2em;
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+ line-height: 1.9em;
}
.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
margin-left: -0.5em;
background-color: #d0d0d0;
border-color: #d0d0d0;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
+ color: #0274ff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 -0.2em 0 0 #015ccc, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
+ border-bottom-color: #015ccc;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+ color: #00af89;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 -0.2em 0 0 #008c6d, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
+ border-bottom-color: #008c6d;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+ color: #d11d13;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 -0.2em 0 0 #a7170f, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
+ border-bottom-color: #a7170f;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #0274ff;
border-color: #0274ff;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
box-shadow: inset 0 -0.2em 0 0 #015ccc, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
border-bottom-color: #015ccc;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #015ccc;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #00af89;
border-color: #00af89;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
box-shadow: inset 0 -0.2em 0 0 #008c6d, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
border-bottom-color: #008c6d;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #008c6d;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #d11d13;
border-color: #d11d13;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
box-shadow: inset 0 -0.2em 0 0 #a7170f, 0 0.1em 0 0 rgba(0, 0, 0, 0.1);
border-bottom-color: #a7170f;
}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #a7170f;
}
.oo-ui-clippableElement-clippable {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-draggableElement {
+ cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
+ /*
+ * HACK: In order to style horizontally, we must override
+ * OO.ui.OptionWidget's display rule that is currently set
+ * to be 'block'
+ */
+}
+.oo-ui-draggableElement-dragging {
+ cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
+ background: rgba(0, 0, 0, 0.2);
+ opacity: 0.4;
+}
+.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
+ display: inline-block;
+}
+.oo-ui-draggableGroupElement-placeholder {
+ position: absolute;
+ display: block;
+ background: rgba(0, 0, 0, 0.4);
+}
.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
overflow-y: hidden;
}
.oo-ui-fieldLayout:after {
clear: both;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
display: block;
float: left;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
- display: block;
- float: left;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
text-align: right;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- display: inline-block;
- vertical-align: middle;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+ display: table;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
- display: inline-block;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+ display: table-cell;
vertical-align: middle;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
display: inline-block;
}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
- z-index: 1;
-}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
float: right;
}
-.oo-ui-fieldLayout .oo-ui-fieldLayout-help-content {
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+ z-index: 1;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
padding: 0.5em 0.75em;
line-height: 1.5em;
}
.oo-ui-fieldLayout:last-child {
margin-bottom: 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding-top: 0.5em;
margin-right: 5%;
width: 35%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
width: 60%;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
- padding: 0.75em 0.5em 0.5em 0.5em;
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+ padding: 0.5em;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
padding: 0.5em 0;
}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
padding: 0.5em 0;
}
.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
.oo-ui-listToolGroup .oo-ui-tool-link {
padding-right: 0.5em;
}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
background-color: #eeeeee;
}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled,
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
+ background-color: #d0d0d0;
+}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
color: #cccccc;
}
background-image: /* @embed */ url(themes/mediawiki/images/icons/check.svg);
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
- background-color: #e1f3ff;
+ background-color: #eeeeee;
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
color: #cccccc;
pointer-events: none;
}
.oo-ui-toolbar-bar {
- border-bottom: solid 1px #cccccc;
+ border-bottom: solid 4px rgba(0, 0, 0, 0.15);
background: #ffffff;
}
.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
display: none;
}
.oo-ui-selectWidget {
- border-radius: 0.3em;
+ border-radius: 2px;
}
.oo-ui-selectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
border-radius: 0;
margin-left: -1px;
}
.oo-ui-selectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
- border-bottom-left-radius: 0.3em;
- border-top-left-radius: 0.3em;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
margin-left: 0;
}
.oo-ui-selectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
- border-bottom-right-radius: 0.3em;
- border-top-right-radius: 0.3em;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
}
.oo-ui-optionWidget {
position: relative;
}
.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected,
.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed {
- background-color: #a7dcff;
+ background-color: #d0d0d0;
}
.oo-ui-optionWidget.oo-ui-widget-disabled {
color: #cccccc;
.oo-ui-buttonSelectWidget {
display: inline-block;
white-space: nowrap;
- border-radius: 0.3em;
+ border-radius: 2px;
}
.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
border-radius: 0;
margin-left: -1px;
}
.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
- border-bottom-left-radius: 0.3em;
- border-top-left-radius: 0.3em;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
margin-left: 0;
}
.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
- border-bottom-right-radius: 0.3em;
- border-top-right-radius: 0.3em;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
}
.oo-ui-radioSelectWidget {
padding: 0.75em 0 0.5em 0;
vertical-align: middle;
}
.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
- height: 2.2em;
+ height: 1.9em;
}
.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
- height: 2.2em;
+ height: 1.9em;
margin-top: 0;
}
.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
background-position: center center;
background-repeat: no-repeat;
line-height: 2.5em;
- height: 2.2em;
- width: 2.2em;
+ height: 1.9em;
+ width: 1.9em;
}
.oo-ui-iconWidget.oo-ui-widget-disabled {
opacity: 0.2;
background-position: center center;
background-repeat: no-repeat;
line-height: 2.5em;
- height: 2.2em;
- width: 2.2em;
+ height: 1.9em;
+ width: 1.9em;
}
.oo-ui-indicatorWidget.oo-ui-widget-disabled {
opacity: 0.2;
.oo-ui-buttonGroupWidget {
display: inline-block;
white-space: nowrap;
- border-radius: 0.3em;
+ border-radius: 2px;
}
.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
border-radius: 0;
margin-left: -1px;
}
.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
- border-bottom-left-radius: 0.3em;
- border-top-left-radius: 0.3em;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
margin-left: 0;
}
.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
- border-bottom-right-radius: 0.3em;
- border-top-right-radius: 0.3em;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
}
.oo-ui-toggleSwitchWidget {
position: relative;
.oo-ui-popupWidget-head .oo-ui-labelElement-label {
margin: 0.75em 1em;
}
-.oo-ui-popupWidget-body {
- box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
-}
.oo-ui-popupWidget-body-padded {
padding: 0 1em;
}
}
.oo-ui-checkboxInputWidget {
position: relative;
- line-height: 1.6em;
+ line-height: 2em;
+ white-space: nowrap;
}
.oo-ui-checkboxInputWidget * {
+ font: inherit;
vertical-align: middle;
}
.oo-ui-checkboxInputWidget input[type="checkbox"] {
opacity: 0;
- width: 1.6em;
- height: 1.6em;
+ margin: 0;
+ width: 2em;
+ height: 2em;
max-width: none;
}
.oo-ui-checkboxInputWidget input[type="checkbox"] + span {
}
.oo-ui-checkboxInputWidget input[type="checkbox"] + span::before {
content: "";
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
position: absolute;
left: 0;
- border-radius: 0.3em;
- width: 1.6em;
- height: 1.6em;
- background-color: #ffffff;
- border: 1px solid grey;
+ border-radius: 2px;
+ width: 2em;
+ height: 2em;
+ background-color: white;
+ border: 1px solid #777777;
}
.oo-ui-checkboxInputWidget input[type="checkbox"]:checked + span::before {
background-image: /* @embed */ url(themes/mediawiki/images/icons/check-constructive.svg);
- background-size: 1.6em, 1.6em;
+ background-size: 2em, 2em;
background-repeat: no-repeat;
- background-position: center top;
+ background-position: center center;
+ background-origin: border-box;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:active + span::before {
+ background-color: #dddddd;
+ border-color: #dddddd;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span::before {
+ border-width: 2px;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:focus:hover + span::before,
+.oo-ui-checkboxInputWidget input[type="checkbox"]:hover + span::before {
+ border-bottom-width: 3px;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span::before {
+ cursor: default;
+ background-color: #eeeeee;
+ border-color: #eeeeee;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled:checked + span::before {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/check-invert.svg);
+}
+.oo-ui-radioInputWidget {
+ position: relative;
+ line-height: 2em;
+}
+.oo-ui-radioInputWidget * {
+ font: inherit;
+ vertical-align: middle;
}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:active + span::after,
-.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span::after {
+.oo-ui-radioInputWidget input[type="radio"] {
+ opacity: 0;
+ margin: 0;
+ width: 2em;
+ height: 2em;
+ max-width: none;
+}
+.oo-ui-radioInputWidget input[type="radio"] + span {
+ cursor: pointer;
+ margin: 0 0.4em;
+}
+.oo-ui-radioInputWidget input[type="radio"] + span::before {
+ transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -moz-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -ms-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -o-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ -webkit-transition: background-size 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
content: "";
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
position: absolute;
- width: 1.6em;
- height: 1.5em;
- left: 1px;
- border-bottom: solid 0.2em #d3d3d3;
+ left: 0;
+ border-radius: 100%;
+ width: 2em;
+ height: 2em;
+ background: white;
+ border: 1px solid #777777;
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-constructive.svg);
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-origin: border-box;
+ background-size: 0 0;
+}
+.oo-ui-radioInputWidget input[type="radio"]:checked + span::before {
+ background-size: 100% 100%;
}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span {
+.oo-ui-radioInputWidget input[type="radio"]:active + span::before {
+ background-color: #dddddd;
+ border-color: #dddddd;
+}
+.oo-ui-radioInputWidget input[type="radio"]:focus + span::before {
+ border-width: 2px;
+}
+.oo-ui-radioInputWidget input[type="radio"]:focus:hover + span::before,
+.oo-ui-radioInputWidget input[type="radio"]:hover + span::before {
+ border-bottom-width: 3px;
+}
+.oo-ui-radioInputWidget input[type="radio"]:disabled + span::before {
cursor: default;
+ background-color: #eeeeee;
+ border-color: #eeeeee;
}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span::before {
- background-color: lightgrey;
+.oo-ui-radioInputWidget input[type="radio"]:disabled:checked + span::before {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-invert.svg);
}
.oo-ui-textInputWidget {
position: relative;
+ vertical-align: middle;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.oo-ui-textInputWidget.oo-ui-indicatorElement input,
.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
- padding-right: 2.2em;
+ padding-right: 1.9em;
}
.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
width: 1.6em;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
+ font-size: 1.1em;
+ padding: 0.75em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+ padding-right: 1.5em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+ opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget-level-0 {
+ padding-left: 3.5em;
+}
+.oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
+ left: 1em;
+}
+.oo-ui-outlineOptionWidget-level-1 {
+ padding-left: 5em;
+}
+.oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
+ left: 2.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 {
+ padding-left: 6.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
+ left: 4em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
+ background-color: #d0d0d0;
+ text-shadow: 0 1px 1px #ffffff;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
+ font-weight: bold;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
+ font-style: italic;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
+ opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
+ color: #777777;
+}
+.oo-ui-outlineControlsWidget {
+ height: 3em;
+ background-color: #ffffff;
}
.oo-ui-outlineControlsWidget-items,
.oo-ui-outlineControlsWidget-movers {
.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
float: right;
}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+ height: 2em;
+ margin: 0.5em 0.5em 0.5em 0;
+ padding: 0;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+ width: 1.5em;
+ height: 2em;
+ margin: 0.5em 0 0.5em 0.5em;
+ opacity: 0.2;
+}
.oo-ui-comboBoxWidget {
display: inline-block;
position: relative;
height: 2.35em;
}
.oo-ui-comboBoxWidget .oo-ui-textInputWidget.oo-ui-indicatorElement {
- padding-right: 2.2em;
+ padding-right: 1.9em;
}
.oo-ui-comboBoxWidget .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
- width: 2.2em;
+ width: 1.9em;
background-position: center center;
border: solid 1px #cccccc;
border-left: none;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-searchWidget {
+ border: solid 1px #cccccc;
+}
.oo-ui-searchWidget-query {
position: absolute;
top: 0;
overflow-y: auto;
}
.oo-ui-searchWidget-query {
- height: 2.4em;
- top: 1px;
+ height: 4em;
+ padding: 0 1em;
+ border-bottom: solid 1px #cccccc;
}
-.oo-ui-searchWidget-query .oo-ui-textInputWidget input {
- border-width: 1px 0;
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+ margin: 0.75em 0;
}
.oo-ui-searchWidget-results {
- top: 2.2em;
- bottom: 0.2em;
+ top: 4em;
+ padding: 1em;
line-height: 0;
}
.oo-ui-window {
.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
background-color: rgba(0, 0, 0, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
/* Adjust for border so text aligns with title */
margin: -1px;
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
background-color: rgba(8, 126, 204, 0.05);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
background-color: rgba(8, 126, 204, 0.1);
}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
font-weight: bold;
}
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
.oo-ui-image-invert.oo-ui-icon-previous {
background-image: /* @embed */ url(themes/mediawiki/images/icons/move-rtl-invert.svg);
}
+.oo-ui-icon-circle {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle.svg);
+}
+.oo-ui-image-constructive .oo-ui-icon-circle,
+.oo-ui-image-constructive.oo-ui-icon-circle {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-constructive.svg);
+}
+.oo-ui-image-invert .oo-ui-icon-circle,
+.oo-ui-image-invert.oo-ui-icon-circle {
+ background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-invert.svg);
+}
.oo-ui-icon-redo {
background-image: /* @embed */ url(themes/mediawiki/images/icons/arched-arrow-ltr.svg);
}
/*!
- * OOjs UI v0.2.4
+ * OOjs UI v0.5.0
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-12-02T18:45:19Z
+ * Date: 2014-12-12T20:13:09Z
*/
( function ( OO ) {
config = config || {};
// Properties
- this.$ = config.$ || OO.ui.Element.getJQuery( document );
+ this.$ = config.$ || OO.ui.Element.static.getJQuery( document );
this.data = config.data;
this.$element = this.$( this.$.context.createElement( this.getTagName() ) );
this.elementGroup = null;
* not in an iframe
* @return {Function} Bound jQuery function
*/
-OO.ui.Element.getJQuery = function ( context, $iframe ) {
+OO.ui.Element.static.getJQuery = function ( context, $iframe ) {
function wrapper( selector ) {
return $( selector, wrapper.context );
}
* @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for
* @return {HTMLDocument|null} Document object
*/
-OO.ui.Element.getDocument = function ( obj ) {
+OO.ui.Element.static.getDocument = function ( obj ) {
// jQuery - selections created "offscreen" won't have a context, so .context isn't reliable
return ( obj[0] && obj[0].ownerDocument ) ||
// Empty jQuery selections might have a context
* @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for
* @return {Window} Window object
*/
-OO.ui.Element.getWindow = function ( obj ) {
+OO.ui.Element.static.getWindow = function ( obj ) {
var doc = this.getDocument( obj );
return doc.parentWindow || doc.defaultView;
};
* @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for
* @return {string} Text direction, either 'ltr' or 'rtl'
*/
-OO.ui.Element.getDir = function ( obj ) {
+OO.ui.Element.static.getDir = function ( obj ) {
var isDoc, isWin;
if ( obj instanceof jQuery ) {
* @param {Object} [offset] Offset to start with, used internally
* @return {Object} Offset object, containing left and top properties
*/
-OO.ui.Element.getFrameOffset = function ( from, to, offset ) {
+OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) {
var i, len, frames, frame, rect;
if ( !to ) {
* @param {jQuery} $anchor Element to get $element's position relative to
* @return {Object} Translated position coordinates, containing top and left properties
*/
-OO.ui.Element.getRelativePosition = function ( $element, $anchor ) {
+OO.ui.Element.static.getRelativePosition = function ( $element, $anchor ) {
var iframe, iframePos,
pos = $element.offset(),
anchorPos = $anchor.offset(),
* @param {HTMLElement} el Element to measure
* @return {Object} Dimensions object with `top`, `left`, `bottom` and `right` properties
*/
-OO.ui.Element.getBorders = function ( el ) {
+OO.ui.Element.static.getBorders = function ( el ) {
var doc = el.ownerDocument,
win = doc.parentWindow || doc.defaultView,
style = win && win.getComputedStyle ?
* @param {HTMLElement|Window} el Element to measure
* @return {Object} Dimensions object with `borders`, `scroll`, `scrollbar` and `rect` properties
*/
-OO.ui.Element.getDimensions = function ( el ) {
+OO.ui.Element.static.getDimensions = function ( el ) {
var $el, $win,
doc = el.ownerDocument || el.document,
win = doc.parentWindow || doc.defaultView;
}
};
+/**
+ * Get scrollable object parent
+ *
+ * documentElement can't be used to get or set the scrollTop
+ * property on Blink. Changing and testing its value lets us
+ * use 'body' or 'documentElement' based on what is working.
+ *
+ * https://code.google.com/p/chromium/issues/detail?id=303131
+ *
+ * @static
+ * @param {HTMLElement} el Element to find scrollable parent for
+ * @return {HTMLElement} Scrollable parent
+ */
+OO.ui.Element.static.getRootScrollableElement = function ( el ) {
+ var scrollTop, body;
+
+ if ( OO.ui.scrollableElement === undefined ) {
+ body = el.ownerDocument.body;
+ scrollTop = body.scrollTop;
+ body.scrollTop = 1;
+
+ if ( body.scrollTop === 1 ) {
+ body.scrollTop = scrollTop;
+ OO.ui.scrollableElement = 'body';
+ } else {
+ OO.ui.scrollableElement = 'documentElement';
+ }
+ }
+
+ return el.ownerDocument[ OO.ui.scrollableElement ];
+};
+
/**
* Get closest scrollable container.
*
* @param {string} [dimension] Dimension of scrolling to look for; `x`, `y` or omit for either
* @return {HTMLElement} Closest scrollable container
*/
-OO.ui.Element.getClosestScrollableContainer = function ( el, dimension ) {
+OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) {
var i, val,
props = [ 'overflow' ],
$parent = $( el ).parent();
}
while ( $parent.length ) {
- if ( $parent[0] === el.ownerDocument.body ) {
+ if ( $parent[0] === this.getRootScrollableElement( el ) ) {
return $parent[0];
}
i = props.length;
* to scroll in both directions
* @param {Function} [config.complete] Function to call when scrolling completes
*/
-OO.ui.Element.scrollIntoView = function ( el, config ) {
+OO.ui.Element.static.scrollIntoView = function ( el, config ) {
// Configuration initialization
config = config || {};
$win = $( this.getWindow( el ) );
// Compute the distances between the edges of el and the edges of the scroll viewport
- if ( $sc.is( 'body' ) ) {
- // If the scrollable container is the <body> this is easy
+ if ( $sc.is( 'html, body' ) ) {
+ // If the scrollable container is the root, this is easy
rel = {
top: eld.rect.top,
bottom: $win.innerHeight() - eld.rect.bottom,
}
};
-/**
- * Bind a handler for an event on a DOM element.
- *
- * Used to be for working around a jQuery bug (jqbug.com/14180),
- * but obsolete as of jQuery 1.11.0.
- *
- * @static
- * @deprecated Use jQuery#on instead.
- * @param {HTMLElement|jQuery} el DOM element
- * @param {string} event Event to bind
- * @param {Function} callback Callback to call when the event fires
- */
-OO.ui.Element.onDOMEvent = function ( el, event, callback ) {
- $( el ).on( event, callback );
-};
-
-/**
- * Unbind a handler bound with #static-method-onDOMEvent.
- *
- * @deprecated Use jQuery#off instead.
- * @static
- * @param {HTMLElement|jQuery} el DOM element
- * @param {string} event Event to unbind
- * @param {Function} [callback] Callback to unbind
- */
-OO.ui.Element.offDOMEvent = function ( el, event, callback ) {
- $( el ).off( event, callback );
-};
-
/* Methods */
/**
* @return {HTMLDocument} Document object
*/
OO.ui.Element.prototype.getElementDocument = function () {
- return OO.ui.Element.getDocument( this.$element );
+ // Don't use this.$.context because subclasses can rebind this.$
+ // Don't cache this in other ways either because subclasses could can change this.$element
+ return OO.ui.Element.static.getDocument( this.$element );
};
/**
* @return {Window} Window object
*/
OO.ui.Element.prototype.getElementWindow = function () {
- return OO.ui.Element.getWindow( this.$element );
+ return OO.ui.Element.static.getWindow( this.$element );
};
/**
* Get closest scrollable container.
*/
OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
- return OO.ui.Element.getClosestScrollableContainer( this.$element[0] );
+ return OO.ui.Element.static.getClosestScrollableContainer( this.$element[0] );
};
/**
* @param {Object} [config] Configuration options
*/
OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
- return OO.ui.Element.scrollIntoView( this.$element[0], config );
-};
-
-/**
- * Bind a handler for an event on this.$element
- *
- * @deprecated Use jQuery#on instead.
- * @param {string} event
- * @param {Function} callback
- */
-OO.ui.Element.prototype.onDOMEvent = function ( event, callback ) {
- OO.ui.Element.onDOMEvent( this.$element, event, callback );
-};
-
-/**
- * Unbind a handler bound with #offDOMEvent
- *
- * @deprecated Use jQuery#off instead.
- * @param {string} event
- * @param {Function} callback
- */
-OO.ui.Element.prototype.offDOMEvent = function ( event, callback ) {
- OO.ui.Element.offDOMEvent( this.$element, event, callback );
+ return OO.ui.Element.static.scrollIntoView( this.$element[0], config );
};
/**
OO.ui.Window.prototype.getContentHeight = function () {
var bodyHeight,
win = this,
- styleObj = this.$frame[0].style;
+ bodyStyleObj = this.$body[0].style,
+ frameStyleObj = this.$frame[0].style;
// Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.
// Disable transitions first, otherwise we'll get values from when the window was animating.
this.withoutSizeTransitions( function () {
- var oldHeight = styleObj.height;
- styleObj.height = '1px';
+ var oldHeight = frameStyleObj.height, oldPosition = bodyStyleObj.position;
+ frameStyleObj.height = '1px';
+ // Force body to resize to new width
+ bodyStyleObj.position = 'relative';
bodyHeight = win.getBodyHeight();
- styleObj.height = oldHeight;
+ frameStyleObj.height = oldHeight;
+ bodyStyleObj.position = oldPosition;
} );
return Math.round(
} else {
this.$content = this.$( '<div>' );
this.$document = $( this.getElementDocument() );
- this.$content.addClass( 'oo-ui-window-content' );
+ this.$content.addClass( 'oo-ui-window-content' ).attr( 'tabIndex', 0 );
this.$frame.append( this.$content );
}
this.toggle( false );
// Figure out directionality:
- this.dir = OO.ui.Element.getDir( this.$iframe || this.$content ) || 'ltr';
+ this.dir = OO.ui.Element.static.getDir( this.$iframe || this.$content ) || 'ltr';
return this;
};
this.getHoldProcess( data ).execute().done( function () {
// Get the focused element within the window's content
- var $focus = win.$content.find( OO.ui.Element.getDocument( win.$content ).activeElement );
+ var $focus = win.$content.find( OO.ui.Element.static.getDocument( win.$content ).activeElement );
// Blur the focused element
if ( $focus.length ) {
doc.close();
// Properties
- this.$ = OO.ui.Element.getJQuery( doc, this.$iframe );
+ this.$ = OO.ui.Element.static.getJQuery( doc, this.$iframe );
this.$content = this.$( '.oo-ui-window-content' ).attr( 'tabIndex', 0 );
this.$document = this.$( doc );
OO.ui.Dialog.prototype.onDocumentKeyDown = function ( e ) {
if ( e.which === OO.ui.Keys.ESCAPE ) {
this.close();
- return false;
+ e.preventDefault();
+ e.stopPropagation();
}
};
* @throws {Error} If windows being removed are not being managed
*/
OO.ui.WindowManager.prototype.removeWindows = function ( names ) {
- var i, len, win, name,
+ var i, len, win, name, cleanupWindow,
manager = this,
promises = [],
cleanup = function ( name, win ) {
if ( !win ) {
throw new Error( 'Cannot remove window' );
}
- promises.push( this.closeWindow( name ).then( cleanup.bind( null, name, win ) ) );
+ cleanupWindow = cleanup.bind( null, name, win );
+ promises.push( this.closeWindow( name ).then( cleanupWindow, cleanupWindow ) );
}
return $.when.apply( $, promises );
return;
}
- var viewport = OO.ui.Element.getDimensions( win.getElementWindow() ),
+ var viewport = OO.ui.Element.static.getDimensions( win.getElementWindow() ),
sizes = this.constructor.static.sizes,
size = win.getSize();
this.$button
.removeClass( 'oo-ui-buttonElement-button' )
.removeAttr( 'role accesskey tabindex' )
- .off( this.onMouseDownHandler );
+ .off( 'mousedown', this.onMouseDownHandler );
}
this.$button = $button
return this;
};
+/**
+ * A mixin for an element that can be dragged and dropped.
+ * Use in conjunction with DragGroupWidget
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ */
+OO.ui.DraggableElement = function OoUiDraggableElement() {
+ // Properties
+ this.index = null;
+
+ // Initialize and events
+ this.$element
+ .attr( 'draggable', true )
+ .addClass( 'oo-ui-draggableElement' )
+ .on( {
+ dragstart: this.onDragStart.bind( this ),
+ dragover: this.onDragOver.bind( this ),
+ dragend: this.onDragEnd.bind( this ),
+ drop: this.onDrop.bind( this )
+ } );
+};
+
+/* Events */
+
+/**
+ * @event dragstart
+ * @param {OO.ui.DraggableElement} item Dragging item
+ */
+
+/**
+ * @event dragend
+ */
+
+/**
+ * @event drop
+ */
+
+/* Methods */
+
+/**
+ * Respond to dragstart event.
+ * @param {jQuery.Event} event jQuery event
+ * @fires dragstart
+ */
+OO.ui.DraggableElement.prototype.onDragStart = function ( e ) {
+ var dataTransfer = e.originalEvent.dataTransfer;
+ // Define drop effect
+ dataTransfer.dropEffect = 'none';
+ dataTransfer.effectAllowed = 'move';
+ // We must set up a dataTransfer data property or Firefox seems to
+ // ignore the fact the element is draggable.
+ try {
+ dataTransfer.setData( 'application-x/OOjs-UI-draggable', this.getIndex() );
+ } catch ( err ) {
+ // The above is only for firefox. No need to set a catch clause
+ // if it fails, move on.
+ }
+ // Add dragging class
+ this.$element.addClass( 'oo-ui-draggableElement-dragging' );
+ // Emit event
+ this.emit( 'dragstart', this );
+ return true;
+};
+
+/**
+ * Respond to dragend event.
+ * @fires dragend
+ */
+OO.ui.DraggableElement.prototype.onDragEnd = function () {
+ this.$element.removeClass( 'oo-ui-draggableElement-dragging' );
+ this.emit( 'dragend' );
+};
+
+/**
+ * Handle drop event.
+ * @param {jQuery.Event} event jQuery event
+ * @fires drop
+ */
+OO.ui.DraggableElement.prototype.onDrop = function ( e ) {
+ e.preventDefault();
+ this.emit( 'drop', e );
+};
+
+/**
+ * In order for drag/drop to work, the dragover event must
+ * return false and stop propogation.
+ */
+OO.ui.DraggableElement.prototype.onDragOver = function ( e ) {
+ e.preventDefault();
+};
+
+/**
+ * Set item index.
+ * Store it in the DOM so we can access from the widget drag event
+ * @param {number} Item index
+ */
+OO.ui.DraggableElement.prototype.setIndex = function ( index ) {
+ if ( this.index !== index ) {
+ this.index = index;
+ this.$element.data( 'index', index );
+ }
+};
+
+/**
+ * Get item index
+ * @return {number} Item index
+ */
+OO.ui.DraggableElement.prototype.getIndex = function () {
+ return this.index;
+};
+
+/**
+ * Element containing a sequence of child elements that can be dragged
+ * and dropped.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$group] Container node, assigned to #$group, omit to use a generated `<div>`
+ * @cfg {string} [orientation] Item orientation, 'horizontal' or 'vertical'. Defaults to 'vertical'
+ */
+OO.ui.DraggableGroupElement = function OoUiDraggableGroupElement( config ) {
+ // Configuration initialization
+ config = config || {};
+
+ // Parent constructor
+ OO.ui.GroupElement.call( this, config );
+
+ // Properties
+ this.orientation = config.orientation || 'vertical';
+ this.dragItem = null;
+ this.itemDragOver = null;
+ this.itemKeys = {};
+ this.sideInsertion = '';
+
+ // Events
+ this.aggregate( {
+ dragstart: 'itemDragStart',
+ dragend: 'itemDragEnd',
+ drop: 'itemDrop'
+ } );
+ this.connect( this, {
+ itemDragStart: 'onItemDragStart',
+ itemDrop: 'onItemDrop',
+ itemDragEnd: 'onItemDragEnd'
+ } );
+ this.$element.on( {
+ dragover: $.proxy( this.onDragOver, this ),
+ dragleave: $.proxy( this.onDragLeave, this )
+ } );
+
+ // Initialize
+ if ( $.isArray( config.items ) ) {
+ this.addItems( config.items );
+ }
+ this.$placeholder = $( '<div>' )
+ .addClass( 'oo-ui-draggableGroupElement-placeholder' );
+ this.$element
+ .addClass( 'oo-ui-draggableGroupElement' )
+ .append( this.$status )
+ .toggleClass( 'oo-ui-draggableGroupElement-horizontal', this.orientation === 'horizontal' )
+ .prepend( this.$placeholder );
+};
+
+/* Setup */
+OO.mixinClass( OO.ui.DraggableGroupElement, OO.ui.GroupElement );
+
+/* Events */
+
+/**
+ * @event reorder
+ * @param {OO.ui.DraggableElement} item Reordered item
+ * @param {number} [newIndex] New index for the item
+ */
+
+/* Methods */
+
+/**
+ * Respond to item drag start event
+ * @param {OO.ui.DraggableElement} item Dragged item
+ */
+OO.ui.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {
+ var i, len;
+
+ // Map the index of each object
+ for ( i = 0, len = this.items.length; i < len; i++ ) {
+ this.items[i].setIndex( i );
+ }
+
+ if ( this.orientation === 'horizontal' ) {
+ // Set the height of the indicator
+ this.$placeholder.css( {
+ height: item.$element.outerHeight(),
+ width: 2
+ } );
+ } else {
+ // Set the width of the indicator
+ this.$placeholder.css( {
+ height: 2,
+ width: item.$element.outerWidth()
+ } );
+ }
+ this.setDragItem( item );
+};
+
+/**
+ * Respond to item drag end event
+ */
+OO.ui.DraggableGroupElement.prototype.onItemDragEnd = function () {
+ this.unsetDragItem();
+ return false;
+};
+
+/**
+ * Handle drop event and switch the order of the items accordingly
+ * @param {OO.ui.DraggableElement} item Dropped item
+ * @fires reorder
+ */
+OO.ui.DraggableGroupElement.prototype.onItemDrop = function ( item ) {
+ var toIndex = item.getIndex();
+ // Check if the dropped item is from the current group
+ // TODO: Figure out a way to configure a list of legally droppable
+ // elements even if they are not yet in the list
+ if ( this.getDragItem() ) {
+ // If the insertion point is 'after', the insertion index
+ // is shifted to the right (or to the left in RTL, hence 'after')
+ if ( this.sideInsertion === 'after' ) {
+ toIndex++;
+ }
+ // Emit change event
+ this.emit( 'reorder', this.getDragItem(), toIndex );
+ }
+ // Return false to prevent propogation
+ return false;
+};
+
+/**
+ * Handle dragleave event.
+ */
+OO.ui.DraggableGroupElement.prototype.onDragLeave = function () {
+ // This means the item was dragged outside the widget
+ this.$placeholder
+ .css( 'left', 0 )
+ .hide();
+};
+
+/**
+ * Respond to dragover event
+ * @param {jQuery.Event} event Event details
+ */
+OO.ui.DraggableGroupElement.prototype.onDragOver = function ( e ) {
+ var dragOverObj, $optionWidget, itemOffset, itemMidpoint, itemBoundingRect,
+ itemSize, cssOutput, dragPosition, itemIndex, itemPosition,
+ clientX = e.originalEvent.clientX,
+ clientY = e.originalEvent.clientY;
+
+ // Get the OptionWidget item we are dragging over
+ dragOverObj = this.getElementDocument().elementFromPoint( clientX, clientY );
+ $optionWidget = $( dragOverObj ).closest( '.oo-ui-draggableElement' );
+ if ( $optionWidget[0] ) {
+ itemOffset = $optionWidget.offset();
+ itemBoundingRect = $optionWidget[0].getBoundingClientRect();
+ itemPosition = $optionWidget.position();
+ itemIndex = $optionWidget.data( 'index' );
+ }
+
+ if (
+ itemOffset &&
+ this.isDragging() &&
+ itemIndex !== this.getDragItem().getIndex()
+ ) {
+ if ( this.orientation === 'horizontal' ) {
+ // Calculate where the mouse is relative to the item width
+ itemSize = itemBoundingRect.width;
+ itemMidpoint = itemBoundingRect.left + itemSize / 2;
+ dragPosition = clientX;
+ // Which side of the item we hover over will dictate
+ // where the placeholder will appear, on the left or
+ // on the right
+ cssOutput = {
+ left: dragPosition < itemMidpoint ? itemPosition.left : itemPosition.left + itemSize,
+ top: itemPosition.top
+ };
+ } else {
+ // Calculate where the mouse is relative to the item height
+ itemSize = itemBoundingRect.height;
+ itemMidpoint = itemBoundingRect.top + itemSize / 2;
+ dragPosition = clientY;
+ // Which side of the item we hover over will dictate
+ // where the placeholder will appear, on the top or
+ // on the bottom
+ cssOutput = {
+ top: dragPosition < itemMidpoint ? itemPosition.top : itemPosition.top + itemSize,
+ left: itemPosition.left
+ };
+ }
+ // Store whether we are before or after an item to rearrange
+ // For horizontal layout, we need to account for RTL, as this is flipped
+ if ( this.orientation === 'horizontal' && this.$element.css( 'direction' ) === 'rtl' ) {
+ this.sideInsertion = dragPosition < itemMidpoint ? 'after' : 'before';
+ } else {
+ this.sideInsertion = dragPosition < itemMidpoint ? 'before' : 'after';
+ }
+ // Add drop indicator between objects
+ if ( this.sideInsertion ) {
+ this.$placeholder
+ .css( cssOutput )
+ .show();
+ } else {
+ this.$placeholder
+ .css( {
+ left: 0,
+ top: 0
+ } )
+ .hide();
+ }
+ } else {
+ // This means the item was dragged outside the widget
+ this.$placeholder
+ .css( 'left', 0 )
+ .hide();
+ }
+ // Prevent default
+ e.preventDefault();
+};
+
+/**
+ * Set a dragged item
+ * @param {OO.ui.DraggableElement} item Dragged item
+ */
+OO.ui.DraggableGroupElement.prototype.setDragItem = function ( item ) {
+ this.dragItem = item;
+};
+
+/**
+ * Unset the current dragged item
+ */
+OO.ui.DraggableGroupElement.prototype.unsetDragItem = function () {
+ this.dragItem = null;
+ this.itemDragOver = null;
+ this.$placeholder.hide();
+ this.sideInsertion = '';
+};
+
+/**
+ * Get the current dragged item
+ * @return {OO.ui.DraggableElement|null} item Dragged item or null if no item is dragged
+ */
+OO.ui.DraggableGroupElement.prototype.getDragItem = function () {
+ return this.dragItem;
+};
+
+/**
+ * Check if there's an item being dragged.
+ * @return {Boolean} Item is being dragged
+ */
+OO.ui.DraggableGroupElement.prototype.isDragging = function () {
+ return this.getDragItem() !== null;
+};
+
/**
* Element containing an icon.
*
return this.icon;
};
+/**
+ * Get icon title.
+ *
+ * @return {string} Icon title text
+ */
+OO.ui.IconElement.prototype.getIconTitle = function () {
+ return this.iconTitle;
+};
+
/**
* Element containing an indicator.
*
*
* @constructor
* @param {Object} [config] Configuration options
- * @cfg {string|string[]} [flags] Styling flags, e.g. 'primary', 'destructive' or 'constructive'
+ * @cfg {string|string[]} [flags] Flags describing importance and functionality, e.g. 'primary',
+ * 'safe', 'progressive', 'destructive' or 'constructive'
* @cfg {jQuery} [$flagged] Flagged node, assigned to #$flagged, omit to use #$element
*/
OO.ui.FlaggedElement = function OoUiFlaggedElement( config ) {
this.clipping = clipping;
if ( clipping ) {
this.$clippableContainer = this.$( this.getClosestScrollableElementContainer() );
- // If the clippable container is the body, we have to listen to scroll events and check
+ // If the clippable container is the root, we have to listen to scroll events and check
// jQuery.scrollTop on the window because of browser inconsistencies
- this.$clippableScroller = this.$clippableContainer.is( 'body' ) ?
- this.$( OO.ui.Element.getWindow( this.$clippableContainer ) ) :
+ this.$clippableScroller = this.$clippableContainer.is( 'html, body' ) ?
+ this.$( OO.ui.Element.static.getWindow( this.$clippableContainer ) ) :
this.$clippableContainer;
this.$clippableScroller.on( 'scroll', this.onClippableContainerScrollHandler );
this.$clippableWindow = this.$( this.getElementWindow() )
return this;
}
- var buffer = 10,
+ var buffer = 7, // Chosen by fair dice roll
cOffset = this.$clippable.offset(),
- $container = this.$clippableContainer.is( 'body' ) ?
+ $container = this.$clippableContainer.is( 'html, body' ) ?
this.$clippableWindow : this.$clippableContainer,
ccOffset = $container.offset() || { top: 0, left: 0 },
ccHeight = $container.innerHeight() - buffer,
}
if ( this.autoFocus ) {
// Event 'focus' does not bubble, but 'focusin' does
- this.stackLayout.onDOMEvent( 'focusin', this.onStackLayoutFocus.bind( this ) );
+ this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
}
// Initialization
*
* @return {string|null} Current page name
*/
-OO.ui.BookletLayout.prototype.getPageName = function () {
+OO.ui.BookletLayout.prototype.getCurrentPageName = function () {
return this.currentPageName;
};
* @cfg {string} [help] Explanatory text shown as a '?' icon.
*/
OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
+ var hasInputWidget = fieldWidget instanceof OO.ui.InputWidget;
+
// Configuration initialization
config = $.extend( { align: 'left' }, config );
// Properties
this.$field = this.$( '<div>' );
+ this.$body = this.$( '<' + ( hasInputWidget ? 'label' : 'div' ) + '>' );
this.align = null;
if ( config.help ) {
this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
}
// Events
- if ( this.fieldWidget instanceof OO.ui.InputWidget ) {
+ if ( hasInputWidget ) {
this.$label.on( 'click', this.onLabelClick.bind( this ) );
}
this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
// Initialization
- this.$element.addClass( 'oo-ui-fieldLayout' );
+ this.$element
+ .addClass( 'oo-ui-fieldLayout' )
+ .append( this.$help, this.$body );
+ this.$body.addClass( 'oo-ui-fieldLayout-body' );
this.$field
.addClass( 'oo-ui-fieldLayout-field' )
.toggleClass( 'oo-ui-fieldLayout-disable', this.fieldWidget.isDisabled() )
.append( this.fieldWidget.$element );
+
this.setAlignment( config.align );
};
/* Methods */
-/**
- * @inheritdoc
- */
-OO.ui.FieldLayout.prototype.getTagName = function () {
- if ( this.fieldWidget instanceof OO.ui.InputWidget ) {
- return 'label';
- } else {
- return 'div';
- }
-};
-
/**
* Handle field disable events.
*
}
// Reorder elements
if ( value === 'inline' ) {
- this.$element.append( this.$field, this.$label, this.$help );
+ this.$body.append( this.$field, this.$label );
} else {
- this.$element.append( this.$help, this.$label, this.$field );
+ this.$body.append( this.$label, this.$field );
}
// Set classes. The following classes can be used here:
// * oo-ui-fieldLayout-align-left
width = this.widths[x];
panel = this.panels[i];
dimensions = {
- width: Math.round( width * 100 ) + '%',
- height: Math.round( height * 100 ) + '%',
- top: Math.round( top * 100 ) + '%'
+ width: ( width * 100 ) + '%',
+ height: ( height * 100 ) + '%',
+ top: ( top * 100 ) + '%'
};
// If RTL, reverse:
- if ( OO.ui.Element.getDir( this.$.context ) === 'rtl' ) {
- dimensions.right = Math.round( left * 100 ) + '%';
+ if ( OO.ui.Element.static.getDir( this.$.context ) === 'rtl' ) {
+ dimensions.right = ( left * 100 ) + '%';
} else {
- dimensions.left = Math.round( left * 100 ) + '%';
+ dimensions.left = ( left * 100 ) + '%';
}
// HACK: Work around IE bug by setting visibility: hidden; if width or height is zero
if ( width === 0 || height === 0 ) {
* @constructor
* @param {string} name Unique symbolic name of page
* @param {Object} [config] Configuration options
- * @param {string} [outlineItem] Outline item widget
*/
OO.ui.PageLayout = function OoUiPageLayout( name, config ) {
// Configuration initialization
// Properties
this.name = name;
- this.outlineItem = config.outlineItem || null;
+ this.outlineItem = null;
this.active = false;
// Initialization
* @constructor
* @param {Object} [config] Configuration options
* @cfg {boolean} [continuous=false] Show all pages, one after another
- * @cfg {string} [icon=''] Symbolic icon name
* @cfg {OO.ui.Layout[]} [items] Layouts to add
*/
OO.ui.StackLayout = function OoUiStackLayout( config ) {
this.lookupInput = input;
this.$overlay = config.$overlay || this.$element;
this.lookupMenu = new OO.ui.TextInputMenuSelectWidget( this, {
- $: OO.ui.Element.getJQuery( this.$overlay ),
+ $: OO.ui.Element.static.getJQuery( this.$overlay ),
input: this.lookupInput,
$container: config.$container
} );
*/
OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
// Configuration initialization
- config = $.extend( { target: '_blank' }, config );
+ config = config || {};
// Parent constructor
OO.ui.ButtonWidget.super.call( this, config );
*/
OO.ui.InputWidget.prototype.setValue = function ( value ) {
value = this.cleanUpValue( value );
+ // Update the DOM if it has changed. Note that with cleanUpValue, it
+ // is possible for the DOM value to change without this.value changing.
+ if ( this.$input.val() !== value ) {
+ this.$input.val( value );
+ }
if ( this.value !== value ) {
this.value = value;
this.emit( 'change', this.value );
}
- // Update the DOM if it has changed. Note that with cleanUpValue, it
- // is possible for the DOM value to change without this.value changing.
- if ( this.$input.val() !== this.value ) {
- this.$input.val( this.value );
- }
return this;
};
*
* @constructor
* @param {Object} [config] Configuration options
+ * @cfg {boolean} [selected=false] Whether the checkbox is initially selected
*/
OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
// Parent constructor
// Initialization
this.$element.addClass( 'oo-ui-checkboxInputWidget' );
+ this.setSelected( config.selected !== undefined ? config.selected : false );
};
/* Setup */
};
/**
- * Get checked state of the checkbox
- *
- * @return {boolean} If the checkbox is checked
+ * @inheritdoc
*/
-OO.ui.CheckboxInputWidget.prototype.getValue = function () {
- return this.value;
+OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
+ var widget = this;
+ if ( !this.isDisabled() ) {
+ // Allow the stack to clear so the value will be updated
+ setTimeout( function () {
+ widget.setSelected( widget.$input.prop( 'checked' ) );
+ } );
+ }
};
/**
- * Set checked state of the checkbox
+ * Set selection state of this checkbox.
*
- * @param {boolean} value New value
+ * @param {boolean} state Whether the checkbox is selected
+ * @chainable
*/
-OO.ui.CheckboxInputWidget.prototype.setValue = function ( value ) {
- value = !!value;
- if ( this.value !== value ) {
- this.value = value;
- this.$input.prop( 'checked', this.value );
- this.emit( 'change', this.value );
+OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state ) {
+ state = !!state;
+ if ( this.selected !== state ) {
+ this.selected = state;
+ this.$input.prop( 'checked', this.selected );
+ this.emit( 'change', this.selected );
}
+ return this;
};
/**
- * @inheritdoc
+ * Check if this checkbox is selected.
+ *
+ * @return {boolean} Checkbox is selected
*/
-OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
- var widget = this;
- if ( !this.isDisabled() ) {
- // Allow the stack to clear so the value will be updated
- setTimeout( function () {
- widget.setValue( widget.$input.prop( 'checked' ) );
- } );
- }
+OO.ui.CheckboxInputWidget.prototype.isSelected = function () {
+ return this.selected;
};
/**
* Radio buttons only make sense as a set, and you probably want to use the OO.ui.RadioSelectWidget
* class instead of using this class directly.
*
- * This class doesn't make it possible to learn whether the radio button is selected ("pressed").
- *
* @class
* @extends OO.ui.InputWidget
*
* @constructor
* @param {Object} [config] Configuration options
- * @param {boolean} [config.selected=false] Whether the radio button is initially selected
+ * @cfg {boolean} [selected=false] Whether the radio button is initially selected
*/
OO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {
// Parent constructor
this.maxRows = config.maxRows !== undefined ? config.maxRows : 10;
this.validate = null;
+ // Clone for resizing
+ if ( this.autosize ) {
+ this.$clone = this.$input
+ .clone()
+ .insertAfter( this.$input )
+ .hide();
+ }
+
this.setValidation( config.validate );
// Events
* @chainable
*/
OO.ui.TextInputWidget.prototype.adjustSize = function () {
- var $clone, scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError, idealHeight;
+ var scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError, idealHeight;
if ( this.multiline && this.autosize && this.$input.val() !== this.valCache ) {
- $clone = this.$input.clone()
+ this.$clone
.val( this.$input.val() )
+ .attr( 'rows', '' )
// Set inline height property to 0 to measure scroll height
- .css( 'height', 0 )
- .insertAfter( this.$input );
+ .css( 'height', 0 );
+
+ this.$clone[0].style.display = 'block';
+
this.valCache = this.$input.val();
- scrollHeight = $clone[0].scrollHeight;
+
+ scrollHeight = this.$clone[0].scrollHeight;
+
// Remove inline height property to measure natural heights
- $clone.css( 'height', '' );
- innerHeight = $clone.innerHeight();
- outerHeight = $clone.outerHeight();
+ this.$clone.css( 'height', '' );
+ innerHeight = this.$clone.innerHeight();
+ outerHeight = this.$clone.outerHeight();
+
// Measure max rows height
- $clone.attr( 'rows', this.maxRows ).css( 'height', 'auto' ).val( '' );
- maxInnerHeight = $clone.innerHeight();
+ this.$clone
+ .attr( 'rows', this.maxRows )
+ .css( 'height', 'auto' )
+ .val( '' );
+ maxInnerHeight = this.$clone.innerHeight();
+
// Difference between reported innerHeight and scrollHeight with no scrollbars present
// Equals 1 on Blink-based browsers and 0 everywhere else
- measurementError = maxInnerHeight - $clone[0].scrollHeight;
- $clone.remove();
+ measurementError = maxInnerHeight - this.$clone[0].scrollHeight;
idealHeight = Math.min( maxInnerHeight, scrollHeight + measurementError );
+
+ this.$clone[0].style.display = 'none';
+
// Only apply inline height when expansion beyond natural height is needed
if ( idealHeight > innerHeight ) {
// Use the difference between the inner and outer height as a buffer
) );
this.menu = new OO.ui.TextInputMenuSelectWidget( this.input, $.extend(
{
- $: OO.ui.Element.getJQuery( this.$overlay ),
+ $: OO.ui.Element.static.getJQuery( this.$overlay ),
widget: this,
input: this.input,
disabled: this.isDisabled()
/**
* Get an item relative to another one.
*
- * @param {OO.ui.OptionWidget} item Item to start at
- * @param {number} direction Direction to move in, -1 to look backward, 1 to move forward
+ * @param {OO.ui.OptionWidget|null} item Item to start at, null to get relative to list start
+ * @param {number} direction Direction to move in, -1 to move backward, 1 to move forward
* @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the menu
*/
OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direction ) {
- var inc = direction > 0 ? 1 : -1,
- len = this.items.length,
- index = item instanceof OO.ui.OptionWidget ?
- $.inArray( item, this.items ) : ( inc > 0 ? -1 : 0 ),
- stopAt = Math.max( Math.min( index, len - 1 ), 0 ),
- i = inc > 0 ?
- // Default to 0 instead of -1, if nothing is selected let's start at the beginning
- Math.max( index, -1 ) :
- // Default to n-1 instead of -1, if nothing is selected let's start at the end
- Math.min( index, len );
-
- while ( len !== 0 ) {
- i = ( i + inc + len ) % len;
- item = this.items[i];
+ var currentIndex, nextIndex, i,
+ increase = direction > 0 ? 1 : -1,
+ len = this.items.length;
+
+ if ( item instanceof OO.ui.OptionWidget ) {
+ currentIndex = $.inArray( item, this.items );
+ nextIndex = ( currentIndex + increase + len ) % len;
+ } else {
+ // If no item is selected and moving forward, start at the beginning.
+ // If moving backward, start at the end.
+ nextIndex = direction > 0 ? 0 : len - 1;
+ }
+
+ for ( i = 0; i < len; i++ ) {
+ item = this.items[nextIndex];
if ( item instanceof OO.ui.OptionWidget && item.isSelectable() ) {
return item;
}
- // Stop iterating when we've looped all the way around
- if ( i === stopAt ) {
- break;
- }
+ nextIndex = ( nextIndex + increase + len ) % len;
}
return null;
};
*/
OO.ui.TextInputMenuSelectWidget.prototype.position = function () {
var $container = this.$container,
- pos = OO.ui.Element.getRelativePosition( $container, this.$element.offsetParent() );
+ pos = OO.ui.Element.static.getRelativePosition( $container, this.$element.offsetParent() );
// Position under input
pos.top += $container.height();
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00C697 }</style><circle cx="12" cy="12" r="6"></circle></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style><circle cx="12" cy="12" r="6"></circle></svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="6"></circle></svg>
// Cached access key prefix for used browser
var cachedAccessKeyPrefix,
- // Wether to use 'test-' instead of correct prefix (used for testing)
+ // Whether to use 'test-' instead of correct prefix (used for testing)
useTestPrefix = false,
// tag names which can have a label tag
// Tanslations for conforming browser names
nameTranslations = [],
// Names of known layout engines
- layouts = ['gecko', 'konqueror', 'msie', 'trident', 'opera', 'webkit'],
+ layouts = ['gecko', 'konqueror', 'msie', 'trident', 'edge', 'opera', 'webkit'],
// Translations for conforming layout names
layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ],
// Names of supported layout engines for version number
- layoutVersions = ['applewebkit', 'gecko', 'trident'],
+ layoutVersions = ['applewebkit', 'gecko', 'trident', 'edge'],
// Names of known operating systems
platforms = ['win', 'wow64', 'mac', 'linux', 'sunos', 'solaris', 'iphone'],
// Translations for conforming operating system names
version = match[1];
}
}
+ // And IE 12's different lies about not being IE
+ if ( name === 'chrome' && ( match = ua.match( /\bedge\/([0-9\.]*)/ ) ) ) {
+ name = 'msie';
+ version = match[1];
+ layout = 'edge';
+ layoutversion = parseInt( match[1], 10 );
+ }
// And Amazon Silk's lies about being Android on mobile or Safari on desktop
if ( match = ua.match( /\bsilk\/([0-9.\-_]*)/ ) ) {
if ( match[1] ) {
* Enable collapsible-functionality on all elements in the collection.
*
* - Will prevent binding twice to the same element.
- * - Initial state is expanded by default, this can be overriden by adding class
+ * - Initial state is expanded by default, this can be overridden by adding class
* "mw-collapsed" to the "mw-collapsible" element.
* - Elements made collapsible have jQuery data "mw-made-collapsible" set to true.
* - The inner content is wrapped in a "div.mw-collapsible-content" (except for tables and lists).
selText = selText.replace( /\r?\n/g, '\r\n' );
post = post.replace( /\r?\n/g, '\r\n' );
}
- if ( isSample && options.selectPeri && !options.splitlines ) {
+ if ( isSample && options.selectPeri && ( !options.splitlines || ( options.splitlines && selText.indexOf( '\n' ) === -1 ) ) ) {
this.selectionStart = startPos + pre.length;
this.selectionEnd = startPos + pre.length + selText.length;
} else {
* @param {jQuery.Event} e
*/
function doLivePreview( e ) {
- var $wikiPreview, $editform, copySelectors, $copyElements, $spinner,
- targetUrl, postData, $previewDataHolder;
+ var isDiff, api, request, postData, copySelectors, section,
+ $wikiPreview, $wikiDiff, $editform, $copyElements, $spinner;
e.preventDefault();
- // Deprecated: Use mw.hook instead
- $( mw ).trigger( 'LivePreviewPrepare' );
-
+ isDiff = ( e.target.name === 'wpDiff' );
$wikiPreview = $( '#wikiPreview' );
+ $wikiDiff = $( '#wikiDiff' );
$editform = $( '#editform' );
+ section = $editform.find( '[name="wpSection"]' ).val();
// Show #wikiPreview if it's hidden to be able to scroll to it
// (if it is hidden, it's also empty, so nothing changes in the rendering)
// Jump to where the preview will appear
$wikiPreview[0].scrollIntoView();
- // List of selectors matching elements that we will
- // update from from the ajax-loaded preview page.
copySelectors = [
// Main
'#firstHeading',
'#wikiPreview',
'#wikiDiff',
'#catlinks',
- '.hiddencats',
'#p-lang',
// Editing-related
'.templatesUsed',
// (e.g. empty #catlinks)
$copyElements.animate( { opacity: 0.4 }, 'fast' );
- $previewDataHolder = $( '<div>' );
- targetUrl = $editform.attr( 'action' );
- targetUrl += targetUrl.indexOf( '?' ) !== -1 ? '&' : '?';
- targetUrl += $.param( {
- debug: mw.config.get( 'debug' ),
+ api = new mw.Api();
+ postData = {
+ action: 'parse',
uselang: mw.config.get( 'wgUserLanguage' ),
- useskin: mw.config.get( 'skin' )
- } );
+ title: mw.config.get( 'wgPageName' ),
+ text: $editform.find( '#wpTextbox1' ).val(),
+ summary: $editform.find( '#wpSummary' ).val()
+ };
- // Gather all the data from the form
- postData = $editform.formToArray();
- postData.push( {
- name: e.target.name,
- value: ''
- } );
+ if ( isDiff ) {
+ $wikiPreview.hide();
- // Load new preview data.
- // TODO: This should use the action=parse API instead of loading the entire page,
- // although that requires figuring out how to convert that raw data into proper HTML.
- $previewDataHolder.load( targetUrl + ' ' + copySelectors.join( ',' ), postData, function () {
- var i, $from, $next, $parent;
+ // First PST the input, then diff it
+ postData.onlypst = '';
+ request = api.post( postData );
+ request.done( function ( response ) {
+ var postData;
+ postData = {
+ action: 'query',
+ indexpageids: '',
+ prop: 'revisions',
+ titles: mw.config.get( 'wgPageName' ),
+ rvdifftotext: response.parse.text['*'],
+ rvprop: ''
+ };
+ if ( section !== '' ) {
+ postData.rvsection = section;
+ }
+ return api.post( postData ).done( function ( result2 ) {
+ try {
+ var diffHtml = result2.query.pages[result2.query.pageids[0]]
+ .revisions[0].diff['*'];
+ $wikiDiff.find( 'table.diff tbody' ).html( diffHtml );
+ } catch ( e ) {
+ // "result.blah is undefined" error, ignore
+ mw.log.warn( e );
+ }
+ $wikiDiff.show();
+ } );
+ } );
+ } else {
+ $wikiDiff.hide();
+ $.extend( postData, {
+ pst: '',
+ preview: '',
+ prop: 'text|displaytitle|modules|categorieshtml|templates|langlinks|limitreporthtml'
+ } );
+ if ( section !== '' ) {
+ postData.sectionpreview = '';
+ }
+ request = api.post( postData );
+ request.done( function ( response ) {
+ var li, newList, $next, $parent, $list;
+ if ( response.parse.modules ) {
+ mw.loader.load( response.parse.modules.concat(
+ response.parse.modulescripts,
+ response.parse.modulestyles,
+ response.parse.modulemessages ) );
+ }
+ if ( response.parse.displaytitle ) {
+ $( '#firstHeading' ).html( '<span dir="auto">' + response.parse.displaytitle + '</span>' );
+ }
+ if ( response.parse.categorieshtml ) {
+ $( '#catlinks' ).replaceWith( response.parse.categorieshtml['*'] );
+ }
+ if ( response.parse.templates ) {
+ newList = [];
+ $.each( response.parse.templates, function ( i, template ) {
+ li = $( '<li>' )
+ .append( $('<a>')
+ .attr( {
+ 'href': mw.util.getUrl( template['*'] ),
+ 'class': ( template.exists !== undefined ? '' : 'new' )
+ } )
+ .text( template['*'] )
+ );
+ newList.push( li );
+ } );
- // Copy the contents of the specified elements from the loaded page to the real page.
- // Also copy their class attributes.
- for ( i = 0; i < copySelectors.length; i++ ) {
- $from = $previewDataHolder.find( copySelectors[i] );
+ $editform.find( '.mw-editfooter-list' ).detach().empty().append( newList ).appendTo( '.templatesUsed' );
+ }
+ if ( response.parse.limitreporthtml ) {
+ $( '.limitreport' ).html( response.parse.limitreporthtml['*'] );
+ }
+ if ( response.parse.langlinks && mw.config.get( 'skin' ) === 'vector' ) {
+ newList = [];
+ $.each( response.parse.langlinks, function ( i, langlink ) {
+ li = $( '<li>' )
+ .addClass( 'interlanguage-link interwiki-' + langlink.lang )
+ .append( $( '<a>' )
+ .attr( {
+ 'href': langlink.url,
+ 'title': langlink['*'] + ' - ' + langlink.langname,
+ 'lang': langlink.lang,
+ 'hreflang': langlink.lang
+ } )
+ .text( langlink.autonym )
+ );
+ newList.push( li );
+ } );
+ $list = $( '#p-lang ul' );
+ $parent = $list.parent();
+ $list.detach().empty().append( newList ).prependTo( $parent );
+ }
- if ( copySelectors[i] === '#wikiPreview' ) {
+ if ( response.parse.text['*'] ) {
$next = $wikiPreview.next();
// If there is no next node, use parent instead.
// Only query parent if needed, false otherwise.
$wikiPreview
.detach()
- .empty()
- .append( $from.contents() )
- .attr( 'class', $from.attr( 'class' ) );
+ .html( response.parse.text['*'] );
mw.hook( 'wikipage.content' ).fire( $wikiPreview );
} else {
$next.before( $wikiPreview );
}
+ $wikiPreview.show();
- } else {
- $( copySelectors[i] )
- .empty()
- .append( $from.contents() )
- .attr( 'class', $from.attr( 'class' ) );
}
+ } );
+ }
+ request.done( function ( response ) {
+ if ( response.parse.parsedsummary ) {
+ // TODO implement special behavior for section === 'new'
+ $editform.find( '.mw-summary-preview' )
+ .empty()
+ .append(
+ mw.message( 'summary-preview' ).parse(),
+ ' ',
+ $( '<span>' ).addClass( 'comment' ).html(
+ // There is no equivalent to rawParams
+ mw.message( 'parentheses' ).escaped()
+ .replace( '$1', response.parse.parsedsummary['*'] )
+ )
+ );
}
-
- // Deprecated: Use mw.hook instead
- $( mw ).trigger( 'LivePreviewDone', [copySelectors] );
-
+ } );
+ request.always( function () {
$spinner.remove();
$copyElements.animate( {
opacity: 1
// have to fish and (hopefully) put them in the right place (since skins
// can change where they are output).
- if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) ) {
- $( '#p-tb' ).after(
- $( '<div>' ).attr( 'id', 'p-lang' )
+ if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) && mw.config.get( 'skin' ) === 'vector' ) {
+ $( '.portal:last' ).after(
+ $( '<div>' ).attr( {
+ 'class': 'portal',
+ 'id': 'p-lang',
+ 'role': 'navigation',
+ 'title': mw.msg( 'tooltip-p-lang' ),
+ 'aria-labelledby': 'p-lang-label'
+ } )
+ .append( $( '<h3>' ).attr( 'id', 'p-lang-label' ).text( mw.msg( 'otherlanguages' ) ) )
+ .append( $( '<div>' ).addClass( 'body' ).append( '<ul>' ) )
);
}
if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
$( '#wikiPreview' ).after(
- $( '<div>' ).attr( 'id', 'wikiDiff' )
+ $( '<div>' )
+ .attr( 'id', 'wikiDiff' )
+ .html( '<table class="diff"><col class="diff-marker"/><col class="diff-content"/>' +
+ '<col class="diff-marker"/><col class="diff-content"/><tbody/></table>' )
);
}
*/
( function ( mw, $ ) {
$( function () {
- var api = new mw.Api(), pending = null, $form = $( '#editform' );
+ var idleTimeout = 5000,
+ api = new mw.Api(),
+ pending = null,
+ $form = $( '#editform' ),
+ $text = $form.find( '#wpTextbox1' ),
+ data = {},
+ timer = null;
function stashEdit( token ) {
- var data = $form.serializeObject();
+ data = $form.serializeObject();
pending = api.post( {
action: 'stashedit',
} );
}
+ /* Has the edit body text changed since the last stashEdit() call? */
+ function isChanged() {
+ // Normalize line endings to CRLF, like $.fn.serializeObject does.
+ var newText = $text.val().replace( /\r?\n/g, '\r\n' );
+ return newText !== data.wpTextbox1;
+ }
+
function onEditChanged() {
- // If a stash request is already in flight, abort it, since its
- // payload has just been invalidated by this change.
+ if ( !isChanged() ) {
+ return;
+ }
+
+ // If a request is in progress, abort it; its payload is stale.
if ( pending ) {
pending.abort();
}
+
api.getToken( 'edit' ).then( stashEdit );
}
+ function onKeyPress( e ) {
+ // Ignore keystrokes that don't modify text, like cursor movements.
+ // See <http://stackoverflow.com/q/2284844>.
+ if ( e.which === 0 ) {
+ return;
+ }
+
+ clearTimeout( timer );
+
+ if ( pending ) {
+ pending.abort();
+ }
+
+ timer = setTimeout( onEditChanged, idleTimeout );
+ }
+
// We don't attempt to stash new section edits because in such cases
// the parser output varies on the edit summary (since it determines
// the new section's name).
return;
}
- $form.find( '#wpTextbox1' ).on( 'change', onEditChanged );
+ $text.on( { change: onEditChanged, keypress: onKeyPress } );
+
} );
}( mediaWiki, jQuery ) );
* Usage in message text: `{{gender:[gender|user object]|masculine|feminine|neutral}}`.
* If second or third parameter are not specified, masculine is used.
*
- * These details may be overriden per language.
+ * These details may be overridden per language.
*
* @param {string} gender 'male', 'female', or anything else for neutral.
* @param {Array} forms List of gender forms
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 15" width="15" height="11">
+ <g id="magnify-clip" fill="#fff" stroke="#000">
+ <path id="bigbox" d="M1.509 1.865h10.99v7.919h-10.99z"/>
+ <path id="smallbox" d="M-1.499 6.868h5.943v4.904h-5.943z"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 15" width="15" height="11">
+ <g id="magnify-clip" fill="#fff" stroke="#000">
+ <path id="bigbox" d="M9.491 1.865h-10.99v7.919h10.99z"/>
+ <path id="smallbox" d="M12.499 6.868h-5.943v4.904h5.943z"/>
+ </g>
+</svg>
/* …and replace it with the image */
width: 15px;
height: 11px;
- /* @embed */
+ /* Use same SVG support hack as mediawiki.legacy's shared.css */
background: url(images/magnify-clip-ltr.png) center center no-repeat;
+ /* @embed */
+ background-image: -webkit-linear-gradient(transparent, transparent), url(images/magnify-clip-ltr.svg);
+ /* @embed */
+ background-image: linear-gradient(transparent, transparent), url(images/magnify-clip-ltr.svg);
/* Don't annoy people who copy-paste everything too much */
-moz-user-select: none;
-webkit-user-select: none;
/**
* @class mw.Title
*
- * Parse titles into an object struture. Note that when using the constructor
+ * 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
* logic directly and get null for invalid titles which is easier to work with.
*
*/
/**
- * A factory method to create a variation of mw.Uri with a different default location (for
- * relative URLs, including protocol-relative URLs). Used so the library is still testable &
- * purely functional.
+ * A factory method to create a Uri class with a default location to resolve relative URLs
+ * against (including protocol-relative URLs).
*
* @method
+ * @param {string|Function} documentLocation A full url, or function returning one.
+ * If passed a function, the return value may change over time and this will be honoured. (T74334)
* @member mw
*/
mw.UriRelative = function ( documentLocation ) {
- var defaultUri;
+ var getDefaultUri = ( function () {
+ // Cache
+ var href, uri;
+
+ return function () {
+ var hrefCur = typeof documentLocation === 'string' ? documentLocation : documentLocation();
+ if ( href === hrefCur ) {
+ return uri;
+ }
+ href = hrefCur;
+ uri = new Uri( href );
+ return uri;
+ };
+ }() );
/**
* @class mw.Uri
* override each other (`true`) or automagically convert them to an array (`false`).
*/
function Uri( uri, options ) {
+ var prop,
+ defaultUri = getDefaultUri();
+
options = typeof options === 'object' ? options : { strictMode: !!options };
options = $.extend( {
strictMode: false,
this.parse( uri, options );
} else if ( typeof uri === 'object' ) {
// Copy data over from existing URI object
- for ( var prop in uri ) {
+ for ( prop in uri ) {
// Only copy direct properties, not inherited ones
if ( uri.hasOwnProperty( prop ) ) {
// Deep copy object properties
}
};
- defaultUri = new Uri( documentLocation );
-
return Uri;
};
// Default to the current browsing location (for relative URLs).
- mw.Uri = mw.UriRelative( location.href );
+ mw.Uri = mw.UriRelative( function () {
+ return location.href;
+ } );
}( mediaWiki, jQuery ) );
{ redirect: true }
)
.done( function ( result ) {
- if ( result.edit !== undefined ) {
- if ( result.edit.result === 'Success' ) {
- fb.displayThanks();
- } else {
- // unknown API result
- fb.displayError( 'feedback-error1' );
- }
+ if ( result.edit.result === 'Success' ) {
+ fb.displayThanks();
} else {
- // edit failed
- fb.displayError( 'feedback-error2' );
+ // unknown API result
+ fb.displayError( 'feedback-error1' );
}
} )
- .fail( function () {
- // ajax request failed
- fb.displayError( 'feedback-error3' );
+ .fail( function ( code, result ) {
+ if ( code === 'http' ) {
+ // ajax request failed
+ fb.displayError( 'feedback-error3' );
+ mw.log.warn( 'Feedback report failed with HTTP error: ' + result.textStatus );
+ } else {
+ fb.displayError( 'feedback-error2' );
+ mw.log.warn( 'Feedback report failed with API error: ' + code );
+ }
} );
},
/**
* Base library for MediaWiki.
*
- * Exposed as globally as `mediaWiki` with `mw` as shortcut.
+ * Exposed globally as `mediaWiki` with `mw` as shortcut.
*
* @class mw
* @alternateClassName mediaWiki
Map.prototype = {
/**
- * Get the value of one or multiple a keys.
+ * Get the value of one or multiple keys.
*
* If called with no arguments, all values will be returned.
*
* If selection was an array, returns an object of key/values (value is null if not found),
* If selection was not passed or invalid, will return the 'values' object member (be careful as
* objects are always passed by reference in JavaScript!).
- * @return {string|Object|null} Values as a string or object, null if invalid/inexistant.
+ * @return {string|Object|null} Values as a string or object, null if invalid/inexistent.
*/
get: function ( selection, fallback ) {
var results, i;
}
/**
- * Generates an ISO8601 "basic" string from a UNIX timestamp
+ * Convert UNIX timestamp to ISO8601 format
+ * @param {number} timestamp UNIX timestamp
* @private
*/
function formatVersionNumber( timestamp ) {
function sortDependencies( module, resolved, unresolved ) {
var n, deps, len, skip;
- if ( registry[module] === undefined ) {
+ if ( !hasOwn.call( registry, module ) ) {
throw new Error( 'Unknown dependency: ' + module );
}
// Build a list of modules which are in one of the specified states
for ( s = 0; s < states.length; s += 1 ) {
for ( m = 0; m < modules.length; m += 1 ) {
- if ( registry[modules[m]] === undefined ) {
+ if ( !hasOwn.call( registry, modules[m] ) ) {
// Module does not exist
if ( states[s] === 'unregistered' ) {
// OK, undefined
var key, value, media, i, urls, cssHandle, checkCssHandles,
cssHandlesRegistered = false;
- if ( registry[module] === undefined ) {
+ if ( !hasOwn.call( registry, module ) ) {
throw new Error( 'Module has not been registered yet: ' + module );
} else if ( registry[module].state === 'registered' ) {
throw new Error( 'Module has not been requested from the server yet: ' + module );
addScript( sourceLoadScript + '?' + $.param( request ) + '&*', null, async );
}
+ /**
+ * Resolve indexed dependencies.
+ *
+ * ResourceLoader uses an optimization to save space which replaces module names in
+ * dependency lists with the index of that module within the array of module
+ * registration data if it exists. The benefit is a significant reduction in the data
+ * size of the startup module. This function changes those dependency lists back to
+ * arrays of strings.
+ *
+ * @param {Array} modules Modules array
+ */
+ function resolveIndexedDependencies( modules ) {
+ var i, iLen, j, jLen, module, dependency;
+
+ // Expand indexed dependency names
+ for ( i = 0, iLen = modules.length; i < iLen; i++ ) {
+ module = modules[i];
+ if ( module[2] ) {
+ for ( j = 0, jLen = module[2].length; j < jLen; j++ ) {
+ dependency = module[2][j];
+ if ( typeof dependency === 'number' ) {
+ module[2][j] = modules[dependency][0];
+ }
+ }
+ }
+ }
+ }
+
/* Public Members */
return {
/**
// Appends a list of modules from the queue to the batch
for ( q = 0; q < queue.length; q += 1 ) {
// Only request modules which are registered
- if ( registry[queue[q]] !== undefined && registry[queue[q]].state === 'registered' ) {
+ if ( hasOwn.call( registry, queue[q] ) && registry[queue[q]].state === 'registered' ) {
// Prevent duplicate entries
if ( $.inArray( queue[q], batch ) === -1 ) {
batch[batch.length] = queue[q];
for ( b = 0; b < batch.length; b += 1 ) {
bSource = registry[batch[b]].source;
bGroup = registry[batch[b]].group;
- if ( splits[bSource] === undefined ) {
+ if ( !hasOwn.call( splits, bSource ) ) {
splits[bSource] = {};
}
- if ( splits[bSource][bGroup] === undefined ) {
+ if ( !hasOwn.call( splits[bSource], bGroup ) ) {
splits[bSource][bGroup] = [];
}
bSourceGroup = splits[bSource][bGroup];
prefix = modules[i].substr( 0, lastDotIndex );
suffix = modules[i].slice( lastDotIndex + 1 );
- bytesAdded = moduleMap[prefix] !== undefined
+ bytesAdded = hasOwn.call( moduleMap, prefix )
? suffix.length + 3 // '%2C'.length == 3
: modules[i].length + 3; // '%7C'.length == 3
async = true;
l = currReqBaseLength + 9;
}
- if ( moduleMap[prefix] === undefined ) {
+ if ( !hasOwn.call( moduleMap, prefix ) ) {
moduleMap[prefix] = [];
}
moduleMap[prefix].push( suffix );
return true;
}
- if ( sources[id] !== undefined ) {
+ if ( hasOwn.call( sources, id ) ) {
throw new Error( 'source already registered: ' + id );
}
* Register a module, letting the system know about it and its
* properties. Startup modules contain calls to this function.
*
- * @param {string} module Module name
+ * When using multiple module registration by passing an array, dependencies that
+ * are specified as references to modules within the array will be resolved before
+ * the modules are registered.
+ *
+ * @param {string|Array} module Module name or array of arrays, each containing
+ * a list of arguments compatible with this method
* @param {number} version Module version number as a timestamp (falls backs to 0)
* @param {string|Array|Function} dependencies One string or array of strings of module
* names on which this module depends, or a function that returns that array.
* @param {string} [skip=null] Script body of the skip function
*/
register: function ( module, version, dependencies, group, source, skip ) {
- var m;
+ var i, len;
// Allow multiple registration
if ( typeof module === 'object' ) {
- for ( m = 0; m < module.length; m += 1 ) {
+ resolveIndexedDependencies( module );
+ for ( i = 0, len = module.length; i < len; i++ ) {
// module is an array of module names
- if ( typeof module[m] === 'string' ) {
- mw.loader.register( module[m] );
+ if ( typeof module[i] === 'string' ) {
+ mw.loader.register( module[i] );
// module is an array of arrays
- } else if ( typeof module[m] === 'object' ) {
- mw.loader.register.apply( mw.loader, module[m] );
+ } else if ( typeof module[i] === 'object' ) {
+ mw.loader.register.apply( mw.loader, module[i] );
}
}
return;
if ( typeof module !== 'string' ) {
throw new Error( 'module must be a string, not a ' + typeof module );
}
- if ( registry[module] !== undefined ) {
+ if ( hasOwn.call( registry, module ) ) {
throw new Error( 'module already registered: ' + module );
}
// List the module as registered
throw new Error( 'templates must be an object, not a ' + typeof templates );
}
// Automatically register module
- if ( registry[module] === undefined ) {
+ if ( !hasOwn.call( registry, module ) ) {
mw.loader.register( module );
}
// Check for duplicate implementation
- if ( registry[module] !== undefined && registry[module].script !== undefined ) {
+ if ( hasOwn.call( registry, module ) && registry[module].script !== undefined ) {
throw new Error( 'module already implemented: ' + module );
}
// Attach components
// an array of unrelated modules, whereas the modules passed to
// using() are related and must all be loaded.
for ( filtered = [], m = 0; m < modules.length; m += 1 ) {
- module = registry[modules[m]];
- if ( module !== undefined ) {
+ if ( hasOwn.call( registry, modules[m] ) ) {
+ module = registry[modules[m]];
if ( $.inArray( module.state, ['error', 'missing'] ) === -1 ) {
filtered[filtered.length] = modules[m];
}
}
return;
}
- if ( registry[module] === undefined ) {
+ if ( !hasOwn.call( registry, module ) ) {
mw.loader.register( module );
}
if ( $.inArray( state, ['ready', 'error', 'missing'] ) !== -1
/**
* Get the version of a module.
*
- * @param {string} module Name of module to get version for
+ * @param {string} module Name of module
* @return {string|null} The version, or null if the module (or its version) is not
* in the registry.
*/
getVersion: function ( module ) {
- if ( registry[module] !== undefined && registry[module].version !== undefined ) {
- return formatVersionNumber( registry[module].version );
+ if ( !hasOwn.call( registry, module ) || registry[module].version === undefined ) {
+ return null;
}
- return null;
+ return formatVersionNumber( registry[module].version );
},
/**
* Get the state of a module.
*
- * @param {string} module Name of module to get state for
+ * @param {string} module Name of module
+ * @return {string|null} The state, or null if the module (or its version) is not
+ * in the registry.
*/
getState: function ( module ) {
- if ( registry[module] !== undefined && registry[module].state !== undefined ) {
- return registry[module].state;
+ if ( !hasOwn.call( registry, module ) || registry[module].state === undefined ) {
+ return null;
}
- return null;
+ return registry[module].state;
},
/**
* @return {string|null} Module key or null if module does not exist
*/
getModuleKey: function ( module ) {
- return typeof registry[module] === 'object' ?
+ return hasOwn.call( registry, module ) ?
( module + '@' + registry[module].version ) : null;
},
* p-cactions (Content actions), p-personal (Personal tools),
* p-navigation (Navigation), p-tb (Toolbox)
*
- * The first three paramters are required, the others are optional and
+ * The first three parameters are required, the others are optional and
* may be null. Though providing an id and tooltip is recommended.
*
* By default the new link will be added to the end of the list. To
/*
-!/common/
!/.gitignore
+!/README
'TestUser' => "$testDir/phpunit/includes/TestUser.php",
'LessFileCompilationTest' => "$testDir/phpunit/LessFileCompilationTest.php",
- # tests/phpunit/includes
- 'BlockTest' => "$testDir/phpunit/includes/BlockTest.php",
- 'RevisionStorageTest' => "$testDir/phpunit/includes/RevisionStorageTest.php",
- 'WikiPageTest' => "$testDir/phpunit/includes/WikiPageTest.php",
-
# tests/phpunit/includes/api
'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php",
'ApiQueryTestBase' => "$testDir/phpunit/includes/api/query/ApiQueryTestBase.php",
$parser->setTransparentTagHook( $tag, $callback );
}
- wfRunHooks( 'ParserTestParser', array( &$parser ) );
+ Hooks::run( 'ParserTestParser', array( &$parser ) );
return $parser;
}
$this->savedGlobals = array();
/** @since 1.20 */
- wfRunHooks( 'ParserTestGlobals', array( &$settings ) );
+ Hooks::run( 'ParserTestGlobals', array( &$settings ) );
foreach ( $settings as $var => $val ) {
if ( array_key_exists( $var, $GLOBALS ) ) {
// Allow extensions to add to the list of tables to duplicate;
// may be necessary if they hook into page save or other code
// which will require them while running tests.
- wfRunHooks( 'ParserTestTables', array( &$tables ) );
+ Hooks::run( 'ParserTestTables', array( &$tables ) );
return $tables;
}
# cat add category links
# ill add inter-language links
# subpage enable subpages (disabled by default)
-# noxml don't check for XML well formdness
+# noxml don't check for XML well-formedness
# title=[[XXX]] run test using article title XXX
# language=XXX set content language to XXX for this test
# variant=XXX set the variant of language for this test (eg zh-tw)
</p>
!!end
-
!! test
Italics and bold: 2-quote opening sequence: (2,3)
!! options
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 2-quote opening sequence: (2,3) w/ nowiki
!! wikitext
-''<nowiki>foo'</nowiki>''
+''foo'<nowiki/>''
!! html
<p><i>foo'</i>
</p>
!! end
-
!! test
Italics and bold: 2-quote opening sequence: (2,4)
!! options
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 2-quote opening sequence: (2,4) w/ nowiki
!! wikitext
-''<nowiki>foo''</nowiki>''
+''foo<nowiki>''</nowiki>''
!! html
<p><i>foo''</i>
</p>
!! end
-
# The PHP parser strips the empty tags out for giggles; parsoid doesn't.
!! test
Italics and bold: 2-quote opening sequence: (2,5)
!! test
Italics and bold: 3-quote opening sequence: (3,2)
+!! options
+parsoid=wt2html
!! wikitext
'''foo''
-!! html
+!! html/*
<p>'<i>foo</i>
</p>
!!end
+# same html as previous, but wikitext adjusted to match parsoid html2wt
+!! test
+Italics and bold: 3-quote opening sequence: (3,2) w/ nowiki
+!! wikitext
+'<nowiki/>''foo''
+!! html
+<p>'<i>foo</i>
+</p>
+!!end
!! test
Italics and bold: 3-quote opening sequence: (3,3)
</p>
!!end
-
!! test
Italics and bold: 3-quote opening sequence: (3,4)
!! options
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 3-quote opening sequence: (3,4) w/ nowiki
!! wikitext
-'''<nowiki>foo'</nowiki>'''
+'''foo'<nowiki/>'''
!! html
<p><b>foo'</b>
</p>
!! end
-
# The PHP parser strips the empty tags out for giggles; parsoid doesn't.
!! test
Italics and bold: 3-quote opening sequence: (3,5)
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 4-quote opening sequence: (4,2) w/ nowiki
</p>
!! end
-
!! test
Italics and bold: 4-quote opening sequence: (4,3)
+!! options
+parsoid=wt2html
!! wikitext
''''foo'''
-!! html
+!! html/*
<p>'<b>foo</b>
</p>
!!end
+# same html as previous, but wikitext adjusted to match parsoid html2wt
+!! test
+Italics and bold: 4-quote opening sequence: (4,3) w/ nowiki
+!! wikitext
+'<nowiki/>'''foo'''
+!! html
+<p>'<b>foo</b>
+</p>
+!!end
!! test
Italics and bold: 4-quote opening sequence: (4,4)
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 4-quote opening sequence: (4,4) w/ nowiki
!! wikitext
-''''<nowiki>foo'</nowiki>'''
+'<nowiki/>'''foo'<nowiki/>'''
!! html
<p>'<b>foo'</b>
</p>
!! end
-
# The PHP parser strips the empty tags out for giggles; parsoid doesn't.
!! test
Italics and bold: 4-quote opening sequence: (4,5)
!! test
Italics and bold: 4-quote opening sequence: (4,5+2) w/ nowiki
!! wikitext
-''''foo'''''<nowiki/>''
+'<nowiki/>'''foo'''''<nowiki/>''
!! html/php
<p>'<b>foo</b>
</p>
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
# skipping wt2html and html2html because it wants to put <i> before <b>
!! test
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 5-quote opening sequence: (5,3+2)
</p>
!! end
-
!! test
Italics and bold: 5-quote opening sequence: (5,4)
!! options
</p>
!!end
-
# same html as previous, but wikitext adjusted to match parsoid html2wt
!! test
Italics and bold: 5-quote opening sequence: (5,4+2) w/ nowiki
!! wikitext
-'''''<nowiki>foo'</nowiki>'''''
+'''''foo'<nowiki/>'''''
!! html
<p><i><b>foo'</b></i>
</p>
!! end
-
!! test
Italics and bold: 5-quote opening sequence: (5,5)
!! wikitext
!! test
Italics and bold: multiple quote sequences: (2,4,2+3) w/ nowiki
!! wikitext
-''<nowiki>foo'</nowiki>'''bar'''''
+''foo'<nowiki/>'''bar'''''
!! html
<p><i>foo'<b>bar</b></i>
</p>
!! test
Italics and bold: multiple quote sequences: (2,4,3+2) w/ nowiki
!! wikitext
-''<nowiki>foo'</nowiki>'''bar'''''
+''foo'<nowiki/>'''bar'''''
!! html
<p><i>foo'<b>bar</b></i>
</p>
!! test
Italics and bold: multiple quote sequences: (2,4,4+2) w/ nowiki
!! wikitext
-''<nowiki>foo'</nowiki>'''<nowiki>bar'</nowiki>'''''
+''foo'<nowiki/>'''bar'<nowiki/>'''''
!! html
<p><i>foo'<b>bar'</b></i>
</p>
# same html as previous, but wikitext adjusted to match parsoid html2wt
-# add 'parsoid' option to use 'parsoid' normalization of the placeholder
!! test
Italics and bold: other quote tests: (3,2,3+2+2,2)
-!! options
-parsoid
!! wikitext
'''this is about ''foo'''''<nowiki/>''s family''
-!! html/*
+!! html
<p><b>this is about <i>foo</i></b><i>s family</i>
</p>
!! end
!! test
Italics and bold: other quote tests: (3,2,3,3)
!! options
+parsoid=wt2html
!! wikitext
'''this is about ''foo'''s family'''
+!! html/*
+<p>'<i>this is about </i>foo<b>s family</b>
+</p>
+!!end
+
+
+# same html as previous, but wikitext adjusted to match parsoid html2wt
+!! test
+Italics and bold: other quote tests: (3,2,3,3) w/ nowiki
+!! wikitext
+'<nowiki/>''this is about ''foo'''s family'''
!! html
<p>'<i>this is about </i>foo<b>s family</b>
</p>
## of eager output of buffered tokens in the p-wrapper. But, I'm going to ignore
## them for now.
!! test
-P-wrapping should leave sol-transparent tags outside p-tags where possible
+1. P-wrapping should leave sol-transparent tags outside p-tags where possible
!! options
parsoid=wt2html
!! wikitext
<link href="Category:A1"/> <link href="Category:A2"/> <link href="Category:A3"/> <link href="Category:A4"/>
!! end
+!! test
+2. P-wrapping should leave sol-transparent tags outside p-tags where possible
+!! options
+parsoid=wt2html
+!! wikitext
+[[Category:A1]]a
+!! html/parsoid
+<link href="Category:A1"/><p>a</p>
+!! end
+
###
### Preformatted text
###
<table><pre></pre></table>
!! html/parsoid
-<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<pre <pre>x</pre>"}},"i":0}}]}'><pre </p><pre>x</pre>
+<pre about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"a":{"<pre":null},"sa":{"<pre":""},"stx":"html","pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<pre <pre>x</pre>"}},"i":0}}]}'>x</pre>
+
<p><pre </p>
<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}}]}'>foo</p>
!!end
+!! test
+Templates: Handle comments in parameter names (bug 67657)
+!! wikitext
+{{echo|1
+<!-- should be ignored -->
+=foo}}
+
+{{echo|
+<!-- should be ignored -->
+1 = foo}}
+
+{{echo|1<!-- should be ignored --> = foo}}
+
+{{echo|<!-- should be ignored -->1 = foo}}
+!!html/parsoid
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo","key":{"wt":"1\n<!-- should be ignored -->"}}},"i":0}}]}'>foo</p>
+
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo","key":{"wt":"<!-- should be ignored -->\n1"}}},"i":0}}]}'>foo</p>
+
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo","key":{"wt":"1<!-- should be ignored -->"}}},"i":0}}]}'>foo</p>
+
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo","key":{"wt":"<!-- should be ignored -->1"}}},"i":0}}]}'>foo</p>
+!!end
+
+!! test
+Templates: Other wikitext in parameter names (bug 67657)
+!! wikitext
+{{echo|''1''=foo}}
+!!html/parsoid
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"''1''":{"wt":"foo"}},"i":0}}]}'>{{{1}}}</p>
+!!html/php
+<p>{{{1}}}
+</p>
+!!end
+
#--------------------------------------------------------------------
# Transclusion parameter escaping tests
#--------------------------------------------------------------------
<p><a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo" title="wikipedia:Foo"><span>Bar</span></a></p>
!! end
+!! test
+External links: Free with trailing punctuation
+!! wikitext
+http://example.com,
+http://example.com;
+http://example.com\
+http://example.com.
+http://example.com:
+http://example.com!
+http://example.com?
+http://example.com)
+http://example.com/url_with_(brackets)
+!! html
+<p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>,
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>;
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>\
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>.
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>:
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>!
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>?
+<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>)
+<a rel="nofollow" class="external free" href="http://example.com/url_with_(brackets)">http://example.com/url_with_(brackets)</a>
+</p>
+!! end
+
+!! test
+External links: No preceding word characters allowed (bug 65278)
+!! wikitext
+NOPEhttp://example.com
+N0http://example.com
+ok:http://example.com
+ok-http://example.com
+!! html
+<p>NOPEhttp://example.com
+N0http://example.com
+ok:<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>
+ok-<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>
+</p>
+!! end
+
!! test
External image
!! wikitext
{|
|{{table_attribs}}
| {{table_attribs}}
+| <!--foo--> <!--bar--> <!--baz--> {{table_attribs}}
+|align=center {{table_attribs}}
+| <!--foo--> align=center <!--bar--> {{table_attribs}}
|}
!! html
<table>
<td style="color: red"> Foo
</td>
<td style="color: red"> Foo
-</td></tr></table>
-
-!! end
-
-!! test
-Template-generated table cell attributes and cell content (2)
-!! wikitext
-{|
-|align=center {{table_attribs}}
-|}
-!! html
-<table>
-<tr>
+</td>
+<td style="color: red"> Foo
+</td>
+<td align="center" style="color: red"> Foo
+</td>
<td align="center" style="color: red"> Foo
</td></tr></table>
!! end
!! test
-Template-generated table cell attributes and cell content (3)
+Template-generated table cell attributes and cell content (2)
!! wikitext
{|
|align=center {{table_cells}}
!! end
+!! test
+Build table with pipe as data
+!! wikitext
+{| class="wikitable"
+! header
+! second header
+|- style="color:red;"
+| data || style="color:red;" | second data
+|-
+| style="color:red;" | data with | || style="color:red;" | second data with |
+|-
+|| data with | ||| second data with |
+|}
+!! html
+<table class="wikitable">
+<tr>
+<th> header
+</th>
+<th> second header
+</th></tr>
+<tr style="color:red;">
+<td> data </td>
+<td style="color:red;"> second data
+</td></tr>
+<tr>
+<td style="color:red;"> data with | </td>
+<td style="color:red;"> second data with |
+</td></tr>
+<tr>
+<td> data with | </td>
+<td> second data with |
+</td></tr></table>
+
+!! end
+
+!! test
+Build table with wikilink
+!! wikitext
+{| class="wikitable"
+! header || second header
+|- style="color:red;"
+| data [[Main Page|linktext]] || second data [[Main Page|linktext]]
+|-
+| data || second data [[Main Page|link|text with pipe]]
+|}
+!! html
+<table class="wikitable">
+<tr>
+<th> header </th>
+<th> second header
+</th></tr>
+<tr style="color:red;">
+<td> data <a href="/wiki/Main_Page" title="Main Page">linktext</a> </td>
+<td> second data <a href="/wiki/Main_Page" title="Main Page">linktext</a>
+</td></tr>
+<tr>
+<td> data </td>
+<td> second data <a href="/wiki/Main_Page" title="Main Page">link|text with pipe</a>
+</td></tr></table>
+
+!! end
+
# The expected HTML structure in this test is debatable. The PHP parser does
# not parse this kind of table at all. The main focus for Parsoid is on
# round-tripping, so this output is ok for now. TODO: revisit!
!! test
Link with double quotes in title part (literal) and alternate part (interpreted)
!! wikitext
-[[File:Denys Savchenko ''Pentecoste''.jpg]]
+[[File:Denys_Savchenko_''Pentecoste''.jpg]]
[[''Pentecoste'']]
</p><p><a href="/index.php?title=%27%27Pentecoste%27%27&action=edit&redlink=1" class="new" title="''Pentecoste'' (page does not exist)"><i>Pentecoste</i></a>
</p>
!! html/parsoid
-<meta typeof="mw:Placeholder"/>
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="./File:Denys_Savchenko_''Pentecoste''.jpg"><img resource="./File:Denys_Savchenko_''Pentecoste''.jpg" src="./Special:FilePath/Denys_Savchenko_''Pentecoste''.jpg" height="220" width="220"/></a></span></p>
<p><a rel="mw:WikiLink" href="''Pentecoste''" title="''Pentecoste''">''Pentecoste''</a></p>
<p><a rel="mw:WikiLink" href="''Pentecoste''" title="''Pentecoste''">Pentecoste</a></p>
<p><a rel="mw:WikiLink" href="''Pentecoste''" title="''Pentecoste''"><i>Pentecoste</i></a></p>
Broken image links with HTML captions (bug 39700)
!! wikitext
[[File:Nonexistent|<script></script>]]
-[[File:Nonexistent|100px|<script></script>]]
+[[File:Nonexistent|100x100px|<script></script>]]
[[File:Nonexistent|<]]
[[File:Nonexistent|a<i>b</i>c]]
-!! html
+!! html/php
<p><a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent"><script></script></a>
<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent"><script></script></a>
<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent"><</a>
<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent">abc</a>
</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"<script></script>"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span>
+<span typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"<script></script>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="100" width="100"/></a></span>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"&lt;"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"a<i>b</i>c"}'><a href="./File:Nonexistent"><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220"/></a></span></p>
!! end
!! test
!! test
Interlanguage link
+!! options
+parsoid=wt2html,wt2wt,html2html
!! wikitext
Blah blah blah
[[zh:Chinese]]
!! test
Double interlanguage link
+!! options
+parsoid=wt2html,wt2wt,html2html
!! wikitext
Blah blah blah
[[es:Spanish]]
!! test
Interlanguage link variations
+!! options
+parsoid=wt2html,wt2wt,html2html
!! wikitext
Blah blah blah
[[ es :Spanish]]
[[ ZH :Chinese]]
+[[es:Foo_bar]]
+[[es:Foo bar]]
!! html/php
<p>Blah blah blah
</p>
!! html/parsoid
<p>Blah blah blah</p>
-<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Spanish" data-parsoid='{"stx":"simple","a":{"href":"http://es.wikipedia.org/wiki/Spanish"},"sa":{"href":" es :Spanish"}}'/>
-<link rel="mw:PageProp/Language" href="http://zh.wikipedia.org/wiki/Chinese" data-parsoid='{"stx":"simple","a":{"href":"http://zh.wikipedia.org/wiki/Chinese"},"sa":{"href":" ZH :Chinese"}}'/>
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Spanish" />
+<link rel="mw:PageProp/Language" href="http://zh.wikipedia.org/wiki/Chinese" />
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar" />
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar" />
!! end
!! test
</p>
!!end
+## FIXME: Is Parsoid's acceptance of self-closing html-tags
+## a feature or a bug? See https://phabricator.wikimedia.org/T76962
!! test
Handling html with a div self-closing tag
!! wikitext
<div title=bar />
<div title=bar/>
<div title=bar/ >
-!! html
+!! html/php
<p><div title />
<div title/>
</p>
<div title="bar/"></div>
</div>
+!! html/parsoid
+<div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
+<div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
+<div title="" data-parsoid='{"stx":"html","selfClose":true,"brokenHTMLTag":true}'></div>
+<div title="bar" data-parsoid='{"stx":"html","selfClose":true}'></div>
+<div title="bar" data-parsoid='{"stx":"html","selfClose":true}'></div>
+<div title="bar/" data-parsoid='{"stx":"html","autoInsertedEnd":true}'></div>
!! end
!! test
!! html/parsoid
<p><br title="" />
<br title="" />
-<br />
+<br title="" />
<br title="bar" />
<br title="bar" />
<br title="bar/" />
</p>
!! end
+!! test
+Magic links: RFC (bug 65278)
+!! wikitext
+This is RFC 822 but thisRFC 822 is not RFC 822linked.
+!! html
+<p>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc822">RFC 822</a> but thisRFC 822 is not RFC 822linked.
+</p>
+!! end
+
!! test
Magic links: ISBN (bug 1937)
!! wikitext
</p>
!! end
+!! test
+Magic links: ISBN (bug 65278)
+!! wikitext
+This is ISBN 978-0-316-09811-3 but thisISBN 978-0-316-09811-3 is not ISBN 978-0-316-09811-3linked.
+!! html
+<p>This is <a href="/wiki/Special:BookSources/9780316098113" class="internal mw-magiclink-isbn">ISBN 978-0-316-09811-3</a> but thisISBN 978-0-316-09811-3 is not ISBN 978-0-316-09811-3linked.
+</p>
+!! end
+
!! test
Magic links: PMID incorrectly converts space to underscore
!! wikitext
</p>
!! end
+!! test
+Magic links: PMID (bug 65278)
+!! wikitext
+This is PMID 1234 but thisPMID 1234 is not PMID 1234linked.
+!! html
+<p>This is <a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.
+</p>
+!! end
+
###
### Templates
####
!! test
Template with thumb image (with link in description)
!! wikitext
-{{paramtest|
- param =[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}}
+{{paramtest|param =[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}}
!! html/php
This is a test template with parameter <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a> <div class="thumbcaption"><a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">caption</a></div></div></div>
<div class="thumbcaption"><a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">caption</a></div>
</div>
</div>
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"paramtest","href":"./Template:Paramtest"},"params":{"param":{"wt":"[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]"}},"i":0}}]}'>This is a test template with parameter </p><figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" about="#mwt1" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="./File:Noimage.png" ><img resource="./File:Noimage.png" src="./Special:FilePath/Noimage.png" height="220" width="220"/></a><figcaption><a rel="mw:WikiLink" href="./No_link" title="No link">link</a> <a rel="mw:WikiLink" href="./No_link" title="No link">caption</a></figcaption></figure>
!! end
!! article
</figcaption></figure>
!! end
+!! test
+Titles in unlinked images (T23454)
+!! wikitext
+[[File:Foobar.jpg|link=|stuff]]
+!! html/php
+<p><img alt="stuff" src="http://example.com/images/3/3a/Foobar.jpg" title="stuff" width="1941" height="220" />
+</p>
+!! end
+
!! test
Link with empty target
!! wikitext
#REDIRECT [[File:Barfoo.jpg]]
!! endarticle
+# FIXME: Parsoid should run this test -- but we'd need to teach the
+# mockAPI about the redirected Barfoo.jpg image.
!! test
Redirected image
!! wikitext
[[Image:Barfoo.jpg]]
-!! html
+!! html/php
<p><a href="/wiki/File:Barfoo.jpg" title="File:Barfoo.jpg">File:Barfoo.jpg</a>
</p>
!! end
!! options
wgEnableUploads=0
!! wikitext
-[[Image:Foobaz.jpg]]
-!! html
+[[File:Foobaz.jpg]]
+!! html/php
<p><a href="/wiki/File:Foobaz.jpg" title="File:Foobaz.jpg">File:Foobaz.jpg</a>
</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="File:Foobaz.jpg"><img resource="./File:Foobaz.jpg" src="./Special:FilePath/Foobaz.jpg" height="220" width="220"/></a></span></p>
!! end
# Parsoid-specific testing for images
</p>
!! end
-# TODO: make this PHP-parser compatible!
+!! article
+Subpage test/1/2/subpage
+!! text
+blah
+!! endarticle
+
!! test
Relative subpage noslash link
!! options
[[../../subpage/]]
[[../../subpage]]
-!! html
-<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage/" title="Subpage test/1/2/subpage/">subpage</a></p>
+!! html/php
+<p><a href="/wiki/Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">subpage</a>
+</p><p><a href="/wiki/Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">Subpage test/1/2/subpage</a>
+</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">subpage</a></p>
<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">Subpage_test/1/2/subpage</a></p>
!! end
!! test
Image link to nonexistent file (bug 1850 - good)
!! wikitext
-[[Image:No such.jpg]]
-!! html
+[[File:No_such.jpg]]
+!! html/php
<p><a href="/index.php?title=Special:Upload&wpDestFile=No_such.jpg" class="new" title="File:No such.jpg">File:No such.jpg</a>
</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="File:No_such.jpg"><img resource="./File:No_such.jpg" src="./Special:FilePath/No_such.jpg" height="220" width="220"/></a></span></p>
!! end
!! test
:Image link to nonexistent file (bug 1850 - bad)
!! wikitext
[[:Image:No such.jpg]]
-!! html
+!! html/php
<p><a href="/index.php?title=File:No_such.jpg&action=edit&redlink=1" class="new" title="File:No such.jpg (page does not exist)">Image:No such.jpg</a>
</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./File:No_such.jpg" title="File:No such.jpg">Image:No such.jpg</a></p>
!! end
<div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div>
!! html/parsoid
-<meta typeof="mw:Placeholder" data-parsoid='{"src":"[[Image:foobar.jpg|thumbnail= ]]","optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}'/>
+<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}],"dsr":[0,32,2,2]}' data-mw='{"errors":[{"key":"missing-thumbnail","message":"This thumbnail does not exist.","params":{"name":""}}],"thumb":""}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{},"dsr":[2,30,null,null]}'><img resource="./File:Foobar.jpg" src="./Special:FilePath/" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"220"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
!!end
!! test
Gallery (with options)
!! wikitext
<gallery widths='70px' heights='40px' perrow='2' caption='Foo [[Main Page]]' >
-File:Nonexistant.jpg|caption
-File:Nonexistant.jpg
+File:Nonexistent.jpg|caption
+File:Nonexistent.jpg
image:foobar.jpg|some '''caption''' [[Main Page]]
image:foobar.jpg
image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.
<ul class="gallery mw-gallery-traditional" style="max-width: 226px;_width: 226px;">
<li class='gallerycaption'>Foo <a href="/wiki/Main_Page" title="Main Page">Main Page</a></li>
<li class="gallerybox" style="width: 105px"><div style="width: 105px">
- <div class="thumb" style="height: 70px;">Nonexistant.jpg</div>
+ <div class="thumb" style="height: 70px;">Nonexistent.jpg</div>
<div class="gallerytext">
<p>caption
</p>
</div>
</div></li>
<li class="gallerybox" style="width: 105px"><div style="width: 105px">
- <div class="thumb" style="height: 70px;">Nonexistant.jpg</div>
+ <div class="thumb" style="height: 70px;">Nonexistent.jpg</div>
<div class="gallerytext">
</div>
</div></li>
gallery (with showfilename option)
!! wikitext
<gallery showfilename>
-File:Nonexistant.jpg|caption
-File:Nonexistant.jpg
+File:Nonexistent.jpg|caption
+File:Nonexistent.jpg
image:foobar.jpg|some '''caption''' [[Main Page]]
File:Foobar.jpg
</gallery>
!! html
<ul class="gallery mw-gallery-traditional">
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
- <div class="thumb" style="height: 150px;">Nonexistant.jpg</div>
+ <div class="thumb" style="height: 150px;">Nonexistent.jpg</div>
<div class="gallerytext">
-<p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br />
+<p><a href="/wiki/File:Nonexistent.jpg" title="File:Nonexistent.jpg">Nonexistent.jpg</a><br />
caption
</p>
</div>
</div></li>
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
- <div class="thumb" style="height: 150px;">Nonexistant.jpg</div>
+ <div class="thumb" style="height: 150px;">Nonexistent.jpg</div>
<div class="gallerytext">
-<p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br />
+<p><a href="/wiki/File:Nonexistent.jpg" title="File:Nonexistent.jpg">Nonexistent.jpg</a><br />
</p>
</div>
</div></li>
Gallery (with namespace-less filenames)
!! wikitext
<gallery>
-File:Nonexistant.jpg
-Nonexistant.jpg
+File:Nonexistent.jpg
+Nonexistent.jpg
image:foobar.jpg
foobar.jpg
</gallery>
!! html
<ul class="gallery mw-gallery-traditional">
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
- <div class="thumb" style="height: 150px;">Nonexistant.jpg</div>
+ <div class="thumb" style="height: 150px;">Nonexistent.jpg</div>
<div class="gallerytext">
</div>
</div></li>
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
- <div class="thumb" style="height: 150px;">Nonexistant.jpg</div>
+ <div class="thumb" style="height: 150px;">Nonexistent.jpg</div>
<div class="gallerytext">
</div>
</div></li>
djvu
!! wikitext
[[File:LoremIpsum.djvu|page=2]]
-!! html
+!! html/php
<p><a href="/index.php?title=File:LoremIpsum.djvu&page=2" class="image"><img alt="LoremIpsum.djvu" src="http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-2480px-LoremIpsum.djvu.jpg" width="2480" height="3508" srcset="http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-3720px-LoremIpsum.djvu.jpg 1.5x, http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-4960px-LoremIpsum.djvu.jpg 2x" /></a>
</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"page","ak":"page=2"}]}'><a href="./File:LoremIpsum.djvu" data-parsoid='{"a":{"href":"./File:LoremIpsum.djvu"},"sa":{}}'><img resource="./File:LoremIpsum.djvu" src="//example.com/images/5/5f/LoremIpsum.djvu" height="3508" width="2480" data-parsoid='{"a":{"resource":"./File:LoremIpsum.djvu","height":"3508","width":"2480"},"sa":{"resource":"File:LoremIpsum.djvu"}}'/></a></span></p>
!! end
!! test
<a href="/index.php?title=ABC3D%25_%2B%2B&action=edit&redlink=1" class="new" title="ABC3D% ++ (page does not exist)">ABC3D% ++</a> <a href="/index.php?title=ABC3D%25_%2B%2B&action=edit&redlink=1" class="new" title="ABC3D% ++ (page does not exist)">+%20</a>
!! end
-# FIXME: Omitting the php sections here because of differences in the local and
-# jenkins output. But, more importantly, the Bad.jpg isn't being stripped,
-# which seems to be a problem with the testing infrastructure.
+# Parsoid doesn't support this yet: see bug 73581
+# but it *should* omit the 'src' attribute if the image is bad.
+# PHP side of tests was disabled in
+# mediawiki/core:6bd31e7d95161a6e88fa86df60871051da997c3c
+# because of issues in the PHP parserTests infrastructure
+# (but the output below is indeed what the PHP side emits)
!! test
Bad images - basic functionality
!! wikitext
[[File:Bad.jpg]]
+!! DISABLED/html/php
!! html/parsoid
-<meta typeof="mw:Placeholder" data-parsoid='{"src":"[[File:Bad.jpg]]","optList":[]}'/>
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span></p>
!! end
-# FIXME: Same reasoning as above. The expected php is:
-# <p>Foo bar
-# </p><p>Bar foo
-# </p>
!! test
Bad images - bug 16039: text after bad image disappears
!! wikitext
Foo bar
[[File:Bad.jpg]]
Bar foo
+!! DISABLED/html/php
+<p>Foo bar
+</p><p>Bar foo
+</p>
!! html/parsoid
<p>Foo bar
-<meta typeof="mw:Placeholder" data-parsoid='{"src":"[[File:Bad.jpg]]","optList":[]}'/>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span>
Bar foo</p>
!! end
!! wikitext
[[User:+%]] [[Page+title%]]
[[%+]] [[%+|%20]] [[%+ ]] [[%+r]]
-[[%]] [[+]] [[image:%+abc%39|foo|[[bar]]]]
+[[%]] [[+]] [[File:%+abc%39|foo|[[bar]]]]
[[%33%45]] [[%33%45+]]
-!! html
+!! html/php
<p><a href="/index.php?title=User:%2B%25&action=edit&redlink=1" class="new" title="User:+% (page does not exist)">User:+%</a> <a href="/index.php?title=Page%2Btitle%25&action=edit&redlink=1" class="new" title="Page+title% (page does not exist)">Page+title%</a>
<a href="/index.php?title=%25%2B&action=edit&redlink=1" class="new" title="%+ (page does not exist)">%+</a> <a href="/index.php?title=%25%2B&action=edit&redlink=1" class="new" title="%+ (page does not exist)">%20</a> <a href="/index.php?title=%25%2B&action=edit&redlink=1" class="new" title="%+ (page does not exist)">%+ </a> <a href="/index.php?title=%25%2Br&action=edit&redlink=1" class="new" title="%+r (page does not exist)">%+r</a>
<a href="/index.php?title=%25&action=edit&redlink=1" class="new" title="% (page does not exist)">%</a> <a href="/index.php?title=%2B&action=edit&redlink=1" class="new" title="+ (page does not exist)">+</a> <a href="/index.php?title=Special:Upload&wpDestFile=%25%2Babc9" class="new" title="File:%+abc9">bar</a>
<a href="/index.php?title=3E&action=edit&redlink=1" class="new" title="3E (page does not exist)">3E</a> <a href="/index.php?title=3E%2B&action=edit&redlink=1" class="new" title="3E+ (page does not exist)">3E+</a>
</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="User:+%" title="User:+%">User:+%</a> <a rel="mw:WikiLink" href="Page+title%" title="Page+title%">Page+title%</a> <a rel="mw:WikiLink" href="%+" title="%+">%+</a> <a rel="mw:WikiLink" href="%+" title="%+">%20</a> <a rel="mw:WikiLink" href="%+" title="%+">%+ </a> <a rel="mw:WikiLink" href="%+r" title="%+r">%+r</a> <a rel="mw:WikiLink" href="%" title="%">%</a> <a rel="mw:WikiLink" href="+" title="+">+</a> <span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"[[bar]]"}'><a href="File:%+abc9"><img resource="./File:%25+abc9" src="./Special:FilePath/%+abc9" height="220" width="220"/></a></span> <a rel="mw:WikiLink" href="3E" title="3E">3E</a> <a rel="mw:WikiLink" href="3E+" title="3E+">3E+</a></p>
!! end
!! test
!! wikitext
[[File:Contains & ampersand.jpg]]
[[File:Does not exist.jpg|Title with & ampersand]]
-!! html
+!! html/php
<p><a href="/index.php?title=Special:Upload&wpDestFile=Contains_%26_ampersand.jpg" class="new" title="File:Contains & ampersand.jpg">File:Contains & ampersand.jpg</a>
<a href="/index.php?title=Special:Upload&wpDestFile=Does_not_exist.jpg" class="new" title="File:Does not exist.jpg">Title with & ampersand</a>
</p>
+!! html/parsoid
+<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="File:Contains_&_ampersand.jpg"><img resource="./File:Contains_&_ampersand.jpg" src="./Special:FilePath/Contains_&_ampersand.jpg" height="220" width="220"/></a></span>
+<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}],"caption":"Title with & ampersand"}'><a href="File:Does_not_exist.jpg"><img resource="./File:Does_not_exist.jpg" src="./Special:FilePath/Does_not_exist.jpg" height="220" width="220"/></a></span></p>
!! end
-
!! test
Confirm that 'apos' named character reference doesn't make it to output (not legal in HTML 4)
!! wikitext
<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li></ol>
!!end
+!!test
+Ref: 17. Generate valid HTML5 id/about attributes
+!!options
+parsoid
+!!wikitext
+<ref name="a b">foo</ref>
+
+<references />
+!!html
+<p><span class="reference" id="cite_ref-a_b-1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"a b"}}'><a href="#cite_note-a_b-1">[1]</a></span>
+</p>
+
+<ol class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'>
+<li id="cite_note-a_b-1"><span rel="mw:referencedBy"><a href="#cite_ref-a_b-1-0">↑</a></span> foo</li>
+!!end
+
!!test
References: 1. references tag without any refs should be handled properly
!!options
!! wikitext
<ref name="test & me">hi</ref>
!! html
-<p><span about="#mwt2" class="reference" id="cite_ref-test & me-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"<ref name=\"test &amp; me\">hi</ref>"}' data-mw='{"name":"ref","body":{"html":"hi"},"attrs":{"name":"test & me"}}'><a href="#cite_note-test & me-1">[1]</a></span></p>
+<p><span about="#mwt2" class="reference" id="cite_ref-test_&_me-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"<ref name=\"test &amp; me\">hi</ref>"}' data-mw='{"name":"ref","body":{"html":"hi"},"attrs":{"name":"test & me"}}'><a href="#cite_note-test_&_me-1">[1]</a></span></p>
!! end
# This test is wt2html only because we're permitting the serializer to produce
!! options
parsoid=html2wt,wt2wt
!! wikitext
-''<nowiki>'foo'</nowiki>''
+''<nowiki/>'foo'<nowiki/>''
''<nowiki>''foo''</nowiki>''
''<nowiki>'''foo'''</nowiki>''
''foo''<nowiki/>'s
-'''<nowiki>'foo'</nowiki>'''
+'''<nowiki/>'foo'<nowiki/>'''
'''<nowiki>''foo''</nowiki>'''
'''<nowiki>'''foo'''</nowiki>'''
-'''<nowiki>foo'</nowiki>''<nowiki>bar'</nowiki>''baz'''
+'''foo'<nowiki/>''bar'<nowiki/>''baz'''
'''foo'''<nowiki/>'s
-'''foo''
+'<nowiki/>''foo''
''foo''<nowiki/>'
'<nowiki/>''foo''<nowiki/>'
-''''foo'''
+'<nowiki/>'''foo'''
'''foo'''<nowiki/>'
'<nowiki/>'''foo'''<nowiki/>'
''fools'<span> errand</span>''
''<span>fool</span>'s errand''
-!! html
+!! html/*
<p><i>'foo'</i>
<i>''foo''</i>
<i>'''foo'''</i>
'<i>foo</i>'
'<b>foo</b>
<b>foo</b>'
-'<b>foo</b>'</p>
+'<b>foo</b>'
<i>fools'<span> errand</span></i>
<i><span>fool</span>'s errand</i>
+</p>
!! end
!! test
!!test
Multi-line image caption generated by templates with/without trailing newlines
-!!options
-parsoid
!! wikitext
-[[File:foo.jpg|thumb|300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}]]
-[[File:foo.jpg|thumb|300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}\n\n]]
-!! html
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Foo.jpg" class="new" title="File:Foo.jpg">File:Foo.jpg</a> <div class="thumbcaption">foo\nA\nB\nC</div></div></div>
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Foo.jpg" class="new" title="File:Foo.jpg">File:Foo.jpg</a> <div class="thumbcaption">foo\nA\nB\nC\n\n</div></div></div>
-
+[[File:Foobar.jpg|thumb|300x300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}]]
+[[File:Foobar.jpg|thumb|300x300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}\n\n]]
+!! html/parsoid
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" height="34" width="300"/></a><figcaption>foo\n<span about="#mwt9" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"A"}},"i":0}}]}'>A</span>\n<span about="#mwt10" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"B"}},"i":0}}]}'>B</span>\n<span about="#mwt11" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"C"}},"i":0}}]}'>C</span></figcaption></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" height="34" width="300"/></a><figcaption>foo\n<span about="#mwt12" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"A"}},"i":0}}]}'>A</span>\n<span about="#mwt13" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"B"}},"i":0}}]}'>B</span>\n<span about="#mwt14" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"C"}},"i":0}}]}'>C</span>\n\n</figcaption></figure>
!!end
!! test
<object data="test.swf"></object>
!!end
+!! test
+Don't block XML namespace declaration
+!! wikitext
+<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">MediaWiki</span>
+!! html/php
+<p><span>MediaWiki</span>
+</p>
+!! html/parsoid
+<p><span xmlns:dct="http://purl.org/dc/terms/" data-x-property="dct:title" data-parsoid='{"stx":"html"}'>MediaWiki</span></p>
+!! end
+
# -----------------------------------------------------------------
# The following section of tests are primarily to spec requirements
# around serialization of new/edited content.
<p><a rel="mw:ExtLink" href="http://mi.wikipedia.org/wiki/Foo">Foo</a></p>
!! end
+!! test
+New wiki links (href variations)
+!! options
+parsoid=html2wt
+!! html
+<a rel="mw:WikiLink" href="./Foo_bar">Foo_bar</a>
+<a rel="mw:WikiLink" href="Foo_bar">Foo_bar</a>
+<a rel="mw:WikiLink" href="Foo bar">Foo_bar</a>
+<a rel="mw:WikiLink" href="./Toxine_bact%C3%A9rienne">Toxine bactérienne</a>
+!! wikitext
+[[Foo_bar]]
+[[Foo_bar]]
+[[Foo_bar]]
+[[Toxine bactérienne]]
+!! end
+
+!! test
+New wiki links (content string variations)
+!! options
+parsoid=html2wt
+!! html
+<a rel="mw:WikiLink" href="./Foo_bar">Foo_bar</a>
+<a rel="mw:WikiLink" href="./Foo_bar">Foo bar</a>
+<a rel="mw:WikiLink" href="./Foo_bar">./Foo_bar</a>
+!! wikitext
+[[Foo_bar]]
+[[Foo bar]]
+[[Foo_bar|./Foo_bar]]
+!! end
+
+!! test
+New category links (href variations)
+!! options
+parsoid=html2wt
+!! html
+<link rel="mw:PageProp/Category" href="./Category:Toxine_bactérienne" />
+<link rel="mw:PageProp/Category" href="./Category:Toxine_bact%C3%A9rienne" />
+<link rel="mw:PageProp/Category" href="Category:Toxine_bact%C3%A9rienne" />
+!! wikitext
+[[Category:Toxine bactérienne]]
+[[Category:Toxine bactérienne]]
+[[Category:Toxine bactérienne]]
+!! end
+
+!! test
+New interlanguage links (href variations)
+!! options
+parsoid=html2wt
+!! html
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Toxine bactérienne" />
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Toxine_bactérienne" />
+<link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Toxine_bact%C3%A9rienne" />
+!! wikitext
+[[es:Toxine bactérienne]]
+[[es:Toxine_bactérienne]]
+[[es:Toxine_bactérienne]]
+!! end
+
!! test
Image: Modifying size of an image (1)
!! options
#!! options
#parsoid=html2wt
#language=ar
-#!! input
+#!! wikitext
#[[Imagen:Foobar.jpg|derecha|miniaturadeimagen]]
-#!! result
+#!! html
#<figure class="mw-default-size mw-halign-right" typeof="mw:Image/Thumb"><a href="Imagen:Foobar.jpg"><img resource="./Imagen:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="20" width="180"/></a></figure>
#!! end
!! test
Image: Block level image should have \n before and after
-!! options
-parsoid
!! wikitext
123
[[File:Foobar.jpg|right|thumb|150x150px]]
456
-!! html
-<p>123</p><figure typeof="mw:Image/Thumb" class="mw-halign-right"><a href="./File:Foobar.png"><img src="http://192.168.142.128/mw/images/thumb/b/bc/Foobar.png/131px-Foobar.png" width="131" height="150" resource="./File:Foobar.png" data-parsoid='{"a":{"resource":"./File:Foobar.png","width":"131"},"sa":{"resource":"File:Foobar.png","width":"150"}}'></a></figure><p>456</p>
+!! html/parsoid
+<p>123</p>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="17" width="150"/></a></figure>
+<p>456</p>
!!end
!! test
Image: New block level image should have \n before and after (existing content)
-!! options
-parsoid
!! wikitext
123
[[File:Foobar.jpg|right|thumb|150x150px]]
456
-!! html
+!! html/parsoid
<p>123</p>
<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"right","ak":"right"},{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"150x150px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" height="17" width="150" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"17","width":"150"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure>
<p>456</p>
!! wikitext
''A''<i>B</i>
-''A'''''<i>B</i>'''
+''A''<nowiki/>'''<i>B</i>'''
!! html
<p><i>A</i><i data-parsoid='{"stx":"html"}'>B</i></p>
<p><i>A</i><b><i data-parsoid='{"stx":"html"}'>B</i></b></p>
<link rel="mw:PageProp/redirect" href="Bar" data-parsoid='{"src":"#REDIRECT ","a":{"href":"./Foo"},"sa":{"href":"Foo"}}'>
!! end
+!! test
+T75121: Infer extension name from typeOf if data-mw is not present
+!! options
+parsoid=html2wt
+!! wikitext
+<foo />
+!! html
+<div typeOf="mw:Extension/foo"></div>
+!! end
+
# -----------------------------------------------------------------
# End of section for Parsoid-only html2wt tests for serialization
# of new content
# You will need the Xdebug PHP extension for the later.
# [no]parser Skip or only run Parser tests
#
- # list-groups List availabe Tests groups.
+ # list-groups List available Tests groups.
#
# Options:
# CONFIG_FILE Path to a PHPUnit configuration file (default: suite.xml)
if ( isset( $compatibility[$func] ) ) {
return call_user_func_array( array( $this, $compatibility[$func] ), $args );
} else {
- throw new MWException( "Called non-existant $func method on "
+ throw new MWException( "Called non-existent $func method on "
. get_class( $this ) );
}
}
. 'Depending on compatibility mode IE might use "button", instead.',
);
- # <select> specifc handling
+ # <select> specific handling
$cases[] = array( '<select multiple></select>',
'select', array( 'size' => '4', 'multiple' => true ),
);
$this->insertPage( 'Example Foo/Bar' );
$this->insertPage( 'Example/Baz' );
$this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' );
- $this->insertPage( 'Redirect Test');
- $this->insertPage( 'Redirect Test Worse Result');
+ $this->insertPage( 'Redirect Test' );
+ $this->insertPage( 'Redirect Test Worse Result' );
$this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' );
$this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' );
- $this->insertPage( 'Redirect Test2');
- $this->insertPage( 'Redirect Test2 Worse Result');
+ $this->insertPage( 'Redirect Test2' );
+ $this->insertPage( 'Redirect Test2 Worse Result' );
$this->insertPage( 'Talk:Sandbox' );
$this->insertPage( 'Talk:Example' );
array_shift( $case['results'] );
// And sometimes we expect a different last result
$expected = isset( $case['offsetresult'] ) ?
- array_merge( $case['results'], $case['offsetresult'] ):
+ array_merge( $case['results'], $case['offsetresult'] ) :
$case['results'];
$this->assertEquals(
public static function provideGetCanonicalName() {
return array(
array( ' trailing space ', array( 'creatable' => 'Trailing space' ), 'Trailing spaces' ),
- // @todo FIXME: Maybe the createable name should be 'Talk:Username' or false to reject?
+ // @todo FIXME: Maybe the creatable name should be 'Talk:Username' or false to reject?
array( 'Talk:Username', array( 'creatable' => 'Username', 'usable' => 'Username',
'valid' => 'Username', 'false' => 'Talk:Username' ), 'Namespace prefix' ),
array( ' name with # hash', array( 'creatable' => false, 'usable' => false ), 'With hash' ),
'razor'
);
- # inexistant keys should give us 'null'
+ # inexistent keys should give us 'null'
$this->assertEquals(
$this->select->getAttribute( 'I DO NOT EXIT' ),
null
}
}
+ /**
+ * Test if all classes in the main module manager exists
+ */
+ public function testClassNamesInModuleManager() {
+ global $wgAutoloadLocalClasses;
+
+ $api = new ApiMain(
+ new FauxRequest( array( 'action' => 'query', 'meta' => 'siteinfo' ) )
+ );
+ $modules = $api->getModuleManager()->getNamesWithClasses();
+ foreach( $modules as $name => $class ) {
+ $this->assertArrayHasKey(
+ $class,
+ $wgAutoloadLocalClasses,
+ 'Class ' . $class . ' for api module ' . $name . ' not in autoloader (with exact case)'
+ );
+ }
+ }
}
*/
class ApiFormatWddxTest extends ApiFormatTestBase {
- /**
- * @requires function wddx_deserialize
- */
public function testValidSyntax( ) {
+ if ( !function_exists( 'wddx_deserialize' ) ) {
+ $this->markTestSkipped( "Function 'wddx_deserialize' not exist, skipping." );
+ }
+
$data = $this->apiRequest( 'wddx', array( 'action' => 'query', 'meta' => 'siteinfo' ) );
$this->assertInternalType( 'array', wddx_deserialize( $data ) );
array( 'apiquerytestiw:foo', NS_MAIN, null, true ),
);
}
+
+ /**
+ * Test if all classes in the query module manager exists
+ */
+ public function testClassNamesInModuleManager() {
+ global $wgAutoloadLocalClasses;
+
+ $api = new ApiMain(
+ new FauxRequest( array( 'action' => 'query', 'meta' => 'siteinfo' ) )
+ );
+ $queryApi = new ApiQuery( $api, 'query' );
+ $modules = $queryApi->getModuleManager()->getNamesWithClasses();
+ foreach( $modules as $name => $class ) {
+ $this->assertArrayHasKey(
+ $class,
+ $wgAutoloadLocalClasses,
+ 'Class ' . $class . ' for api module ' . $name . ' not in autoloader (with exact case)'
+ );
+ }
+ }
}
*/
class LocalisationCacheTest extends MediaWikiTestCase {
protected function setUp() {
- global $IP;
-
parent::setUp();
$this->setMwGlobals( array(
'wgExtensionMessagesFiles' => array(),
$out = $wgProfiler['output'];
if ( $out === 'db' ) {
$profileToDb = true;
- } elseif( is_array( $out ) && in_array( 'db', $out ) ) {
+ } elseif ( is_array( $out ) && in_array( 'db', $out ) ) {
$profileToDb = true;
}
}
'multiValue' => array( array( 'first', 'second', 'third', '_type' => 'ol' ), 'first' ),
'noType' => array( array( 'first', 'second', 'third' ), 'first' ),
'typeFirst' => array( array( '_type' => 'ol', 'first', 'second', 'third' ), 'first' ),
- 'multilang' => array(
- array( 'en' => 'first', 'de' => 'Erste', '_type' => 'lang' ),
- array( 'en' => 'first', 'de' => 'Erste', '_type' => 'lang' ),
- ),
- 'multilang-multivalue' => array(
- array( 'en' => array( 'first', 'second' ), 'de' => array( 'Erste', 'Zweite' ), '_type' => 'lang' ),
- array( 'en' => 'first', 'de' => 'Erste', '_type' => 'lang' ),
- ),
+ 'multilang' => array(
+ array( 'en' => 'first', 'de' => 'Erste', '_type' => 'lang' ),
+ array( 'en' => 'first', 'de' => 'Erste', '_type' => 'lang' ),
+ ),
+ 'multilang-multivalue' => array(
+ array( 'en' => array( 'first', 'second' ), 'de' => array( 'Erste', 'Zweite' ), '_type' => 'lang' ),
+ array( 'en' => 'first', 'de' => 'Erste', '_type' => 'lang' ),
+ ),
);
}
}
$this->savedGlobals = array();
/** @since 1.20 */
- wfRunHooks( 'ParserTestGlobals', array( &$settings ) );
+ Hooks::run( 'ParserTestGlobals', array( &$settings ) );
$langObj = Language::factory( $lang );
$settings['wgContLang'] = $langObj;
$class = $wgParserConf['class'];
$parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf );
- wfRunHooks( 'ParserTestParser', array( &$parser ) );
+ Hooks::run( 'ParserTestParser', array( &$parser ) );
return $parser;
}
} );mw.loader.register( [
[
"test.blank",
- "1388534400"
+ 1388534400
]
] );',
) ),
} );mw.loader.register( [
[
"test.blank",
- "1388534400"
+ 1388534400
],
[
"test.group.foo",
- "1388534400",
+ 1388534400,
[],
"x-foo"
],
[
"test.group.bar",
- "1388534400",
+ 1388534400,
[],
"x-bar"
]
} );mw.loader.register( [
[
"test.blank",
- "1388534400"
+ 1388534400
]
] );'
) ),
} );mw.loader.register( [
[
"test.blank",
- "1388534400",
+ 1388534400,
[],
null,
"example"
'test.z.foo' => new ResourceLoaderTestModule( array(
'dependencies' => array(
'test.x.core',
- 'test.x.polyfil',
- 'test.y.polyfil',
+ 'test.x.polyfill',
+ 'test.y.polyfill',
),
) ),
),
} );mw.loader.register( [
[
"test.x.core",
- "1388534400"
+ 1388534400
],
[
"test.x.polyfill",
- "1388534400",
+ 1388534400,
[],
null,
- "local",
+ null,
"return true;"
],
[
"test.y.polyfill",
- "1388534400",
+ 1388534400,
[],
null,
- "local",
+ null,
"return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
],
[
"test.z.foo",
- "1388534400",
+ 1388534400,
[
- "test.x.core",
- "test.x.polyfil",
- "test.y.polyfil"
+ 0,
+ 1,
+ 2
]
]
] );',
} );mw.loader.register( [
[
"test.blank",
- "1388534400"
+ 1388534400
],
[
"test.x.core",
- "1388534400"
+ 1388534400
],
[
"test.x.util",
- "1388534400",
+ 1388534400,
[
- "test.x.core"
+ 1
]
],
[
"test.x.foo",
- "1388534400",
+ 1388534400,
[
- "test.x.core"
+ 1
]
],
[
"test.x.bar",
- "1388534400",
+ 1388534400,
[
- "test.x.util"
+ 2
]
],
[
"test.x.quux",
- "1388534400",
+ 1388534400,
[
- "test.x.foo",
- "test.x.bar",
+ 3,
+ 4,
"test.x.unknown"
]
],
[
"test.group.foo.1",
- "1388534400",
+ 1388534400,
[],
"x-foo"
],
[
"test.group.foo.2",
- "1388534400",
+ 1388534400,
[],
"x-foo"
],
[
"test.group.bar.1",
- "1388534400",
+ 1388534400,
[],
"x-bar"
],
[
"test.group.bar.2",
- "1388534400",
+ 1388534400,
[],
"x-bar",
"example"
$this->assertEquals(
'mw.loader.addSource({"local":"/w/load.php"});'
. 'mw.loader.register(['
-. '["test.blank","1388534400"],'
-. '["test.min","1388534400",["test.blank"],null,"local",'
+. '["test.blank",1388534400],'
+. '["test.min",1388534400,[0],null,null,'
. '"return!!(window.JSON\u0026\u0026JSON.parse\u0026\u0026JSON.stringify);"'
. ']]);',
$module->getModuleRegistrations( $context ),
} );mw.loader.register( [
[
"test.blank",
- "1388534400"
+ 1388534400
],
[
"test.min",
- "1388534400",
+ 1388534400,
[
- "test.blank"
+ 0
],
null,
- "local",
+ null,
"return !!( window.JSON \u0026\u0026 JSON.parse \u0026\u0026 JSON.stringify);"
]
] );',
return strtoupper( $text );
}
-}
\ No newline at end of file
+}
parent::__construct();
$paths = array();
// Extensions can return a list of files or directories
- wfRunHooks( 'UnitTestsList', array( &$paths ) );
+ Hooks::run( 'UnitTestsList', array( &$paths ) );
foreach ( $paths as $path ) {
if ( is_dir( $path ) ) {
// If the path is a directory, search for test cases.
rtl: true
}
},
+ // Internet Explorer 12
+ 'Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36 Edge/12.0': {
+ title: 'Internet Explorer 12',
+ platform: 'WOW64',
+ profile: {
+ name: 'msie',
+ layout: 'edge',
+ layoutVersion: 12,
+ platform: 'win',
+ version: '12.0',
+ versionBase: '12',
+ versionNumber: 12
+ },
+ wikiEditor: {
+ ltr: true,
+ rtl: true
+ }
+ },
// Firefox 2
// Firefox 3.5
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19': {
assert.equal( $.escapeRE( '0123456789' ), '0123456789', 'escapeRE - Leave numbers alone' );
} );
- QUnit.test( 'Is functions', 15, function ( assert ) {
- assert.strictEqual( $.isDomElement( document.getElementById( 'qunit-header' ) ), true,
- 'isDomElement: #qunit-header Node' );
- assert.strictEqual( $.isDomElement( document.getElementById( 'random-name' ) ), false,
- 'isDomElement: #random-name (null)' );
+ QUnit.test( 'isDomElement', 6, function ( assert ) {
+ assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true,
+ 'isDomElement: HTMLElement' );
+ assert.strictEqual( $.isDomElement( document.createTextNode( '' ) ), true,
+ 'isDomElement: TextNode' );
+ assert.strictEqual( $.isDomElement( null ), false,
+ 'isDomElement: null' );
assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' ) ), false,
- 'isDomElement: getElementsByTagName Array' );
- assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' )[0] ), true,
- 'isDomElement: getElementsByTagName(..)[0] Node' );
+ 'isDomElement: NodeList' );
assert.strictEqual( $.isDomElement( $( 'div' ) ), false,
- 'isDomElement: jQuery object' );
- assert.strictEqual( $.isDomElement( $( 'div' ).get( 0 ) ), true,
- 'isDomElement: jQuery object > Get node' );
- assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true,
- 'isDomElement: createElement' );
+ 'isDomElement: jQuery' );
assert.strictEqual( $.isDomElement( { foo: 1 } ), false,
- 'isDomElement: Object' );
+ 'isDomElement: Plain Object' );
+ } );
+ QUnit.test( 'isEmpty', 7, function ( assert ) {
assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmpty: "string"' );
assert.strictEqual( $.isEmpty( '0' ), true, 'isEmpty: "0"' );
assert.strictEqual( $.isEmpty( '' ), true, 'isEmpty: ""' );
assert.equal( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' );
} );
+ QUnit.test( 'Variable defaultUri', 2, function ( assert ) {
+ var uri,
+ href = 'http://example.org/w/index.php#here',
+ UriClass = mw.UriRelative( function () {
+ return href;
+ } );
+
+ uri = new UriClass();
+ assert.deepEqual(
+ {
+ protocol: uri.protocol,
+ user: uri.user,
+ password: uri.password,
+ host: uri.host,
+ port: uri.port,
+ path: uri.path,
+ query: uri.query,
+ fragment: uri.fragment
+ },
+ {
+ protocol: 'http',
+ user: undefined,
+ password: undefined,
+ host: 'example.org',
+ port: undefined,
+ path: '/w/index.php',
+ query: {},
+ fragment: 'here'
+ },
+ 'basic object properties'
+ );
+
+ // Default URI may change, e.g. via history.replaceState, pushState or location.hash (T74334)
+ href = 'https://example.com/wiki/Foo?v=2';
+ uri = new UriClass();
+ assert.deepEqual(
+ {
+ protocol: uri.protocol,
+ user: uri.user,
+ password: uri.password,
+ host: uri.host,
+ port: uri.port,
+ path: uri.path,
+ query: uri.query,
+ fragment: uri.fragment
+ },
+ {
+ protocol: 'https',
+ user: undefined,
+ password: undefined,
+ host: 'example.com',
+ port: undefined,
+ path: '/wiki/Foo',
+ query: { 'v': '2' },
+ fragment: undefined
+ },
+ 'basic object properties'
+ );
+ } );
+
QUnit.test( 'Advanced URL', 11, function ( assert ) {
var uri, queryString, relativePath;
uri = new UriClass( testPath );
href = uri.toString();
assert.equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
-
} );
}( mediaWiki, jQuery ) );
} );
} );
+ QUnit.asyncTest( 'mw.loader with Object method as module name', 2, function ( assert ) {
+ var isAwesomeDone;
+
+ mw.loader.testCallback = function () {
+ QUnit.start();
+ assert.strictEqual( isAwesomeDone, undefined, 'Implementing module hasOwnProperty: isAwesomeDone should still be undefined' );
+ isAwesomeDone = true;
+ };
+
+ mw.loader.implement( 'hasOwnProperty', [QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/callMwLoaderTestCallback.js' )], {}, {} );
+
+ mw.loader.using( 'hasOwnProperty', function () {
+
+ // /sample/awesome.js declares the "mw.loader.testCallback" function
+ // which contains a call to start() and ok()
+ assert.strictEqual( isAwesomeDone, true, 'hasOwnProperty module should\'ve caused isAwesomeDone to be true' );
+ delete mw.loader.testCallback;
+
+ }, function () {
+ QUnit.start();
+ assert.ok( false, 'Error callback fired while loader.using "hasOwnProperty" module' );
+ } );
+ } );
+
QUnit.asyncTest( 'mw.loader.using( .. ).promise', 2, function ( assert ) {
var isAwesomeDone;