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
* 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',
- 'ResourceLoaderUserDefaultsModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserDefaultsModule.php',
'ResourceLoaderUserOptionsModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserOptionsModule.php',
'ResourceLoaderUserTokensModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderUserTokensModule.php',
'ResourceLoaderWikiModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderWikiModule.php',
'TraditionalImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
'TransactionProfiler' => __DIR__ . '/includes/profiler/TransactionProfiler.php',
'TransformParameterError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
+ 'TransformTooBigImageAreaError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
'TransformationalImageHandler' => __DIR__ . '/includes/media/TransformationalImageHandler.php',
'UDPRCFeedEngine' => __DIR__ . '/includes/rcfeed/UDPRCFeedEngine.php',
'UIDGenerator' => __DIR__ . '/includes/utils/UIDGenerator.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",
- "wikimedia/cdb": "1.0.1"
+ "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);
}
}
'ApiOpenSearchSuggest': Called when constructing the OpenSearch results. Hooks
can alter or append to the array.
-&$results: array of associative arrays. Keys are:
+&$results: array with integer keys to associative arrays. Keys in associative
+array:
- title: Title object.
- redirect from: Title or null.
- extract: Description for this result.
'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 ...
}
}
- 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;
}
$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;
* ),
* );
* // Note the '+' character:
- * $wgResourceModuleSkinStyles['+foo'] = array(
- * 'bar' => 'skins/Foo/bar.css',
+ * $wgResourceModuleSkinStyles['foo'] = array(
+ * '+bar' => 'skins/Foo/bar.css',
* );
* @endcode
*
/**
* 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 */
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->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__ );
}
$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 ) )
) {
&& $content->isRedirect()
&& $content->getRedirectTarget()->equals( $this->getTitle() )
) {
- $this->selfRedirect = true;
- $status->fatal( 'selfredirect' );
- $status->value = self::AS_SELF_REDIRECT;
- wfProfileOut( __METHOD__ );
- return $status;
+ // If the page already redirects to itself, don't warn.
+ $currentTarget = $this->getCurrentContent()->getRedirectTarget();
+ if ( !$currentTarget || !$currentTarget->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
* 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();
}
# 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 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 ) );
* 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 ) );
}
/**
* @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" );
* Accessor/initialisation for mRestrictions
*
* @param string $action Action that permission needs to be checked for
- * @return array Restriction levels needed to take the action. All levels
- * are required.
+ * @return array Restriction levels needed to take the action. All levels are
+ * required. Note that restriction levels are normally user rights, but 'sysop'
+ * and 'autoconfirmed' are also allowed for backwards compatibility. These should
+ * be mapped to 'editprotected' and 'editsemiprotected' respectively.
*/
public function getRestrictions( $action ) {
if ( !$this->mRestrictionsLoaded ) {
$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 ) {
// 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 ) );
}
/**
}
}
- 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" );
}
$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;
*/
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();
$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' );
* @param int $limit Maximum items to return
* @param array $namespaces Namespaces to search
* @param bool $resolveRedir Whether to resolve redirects
- * @param array &$results Put results here
+ * @param array &$results Put results here. Keys have to be integers.
*/
protected function search( $search, $limit, $namespaces, $resolveRedir, &$results ) {
// Find matching titles as Title objects
$searcher = new TitlePrefixSearch;
$titles = $searcher->searchWithVariants( $search, $limit, $namespaces );
+ if ( !$titles ) {
+ return;
+ }
+
+ // Special pages need unique integer ids in the return list, so we just
+ // assign them negative numbers because those won't clash with the
+ // always positive articleIds that non-special pages get.
+ $nextSpecialPageId = -1;
if ( $resolveRedir ) {
// Query for redirects
- $db = $this->getDb();
- $lb = new LinkBatch( $titles );
- $res = $db->select(
- array( 'page', 'redirect' ),
- array( 'page_namespace', 'page_title', 'rd_namespace', 'rd_title' ),
- array(
- 'rd_from = page_id',
- 'rd_interwiki IS NULL OR rd_interwiki = ' . $db->addQuotes( '' ),
- $lb->constructSet( 'page', $db ),
- ),
- __METHOD__
- );
$redirects = array();
- foreach ( $res as $row ) {
- $redirects[$row->page_namespace][$row->page_title] =
- array( $row->rd_namespace, $row->rd_title );
+ $lb = new LinkBatch( $titles );
+ if ( !$lb->isEmpty() ) {
+ $db = $this->getDb();
+ $res = $db->select(
+ array( 'page', 'redirect' ),
+ array( 'page_namespace', 'page_title', 'rd_namespace', 'rd_title' ),
+ array(
+ 'rd_from = page_id',
+ 'rd_interwiki IS NULL OR rd_interwiki = ' . $db->addQuotes( '' ),
+ $lb->constructSet( 'page', $db ),
+ ),
+ __METHOD__
+ );
+ foreach ( $res as $row ) {
+ $redirects[$row->page_namespace][$row->page_title] =
+ array( $row->rd_namespace, $row->rd_title );
+ }
}
// Bypass any redirects
}
if ( !isset( $seen[$ns][$dbkey] ) ) {
$seen[$ns][$dbkey] = true;
- $results[$title->getArticleId()] = array(
+ $resultId = $title->getArticleId();
+ if ( $resultId === 0 ) {
+ $resultId = $nextSpecialPageId;
+ $nextSpecialPageId -= 1;
+ }
+ $results[$resultId] = array(
'title' => $title,
'redirect from' => $from,
'extract' => false,
}
} else {
foreach ( $titles as $title ) {
- $results[$title->getArticleId()] = array(
+ $resultId = $title->getArticleId();
+ if ( $resultId === 0 ) {
+ $resultId = $nextSpecialPageId;
+ $nextSpecialPageId -= 1;
+ }
+ $results[$resultId] = array(
'title' => $title,
'redirect from' => null,
'extract' => false,
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 ( !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'] ) );
}
$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;
+ }
+ $sec = microtime( true ) - $start;
+ if ( $sec > .01 ) {
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'] ) );
}
"apihelp-block-param-anononly": "Заблякаваць толькі ананімных удзельнікаў (напрыклад, забараніць ананімныя праўкі з гэтага IP-адрасу).",
"apihelp-block-param-nocreate": "Забарона стварэньня рахункаў.",
"apihelp-block-param-autoblock": "Аўтаматычна блякаваць апошні ўжыты IP-адрас, а таксама ўсе наступныя IP-адрасы, зь якіх будуць спробы ўваходу.",
- "apihelp-block-param-noemail": "Забараняе ўдзельніку дасылаць лісты электроннай пошты празь вікі (трэба мець права «blockemail»)."
+ "apihelp-block-param-noemail": "Забараняе ўдзельніку дасылаць лісты электроннай пошты празь вікі (трэба мець права «blockemail»).",
+ "apihelp-block-param-hidename": "Схаваць імя ўдзельніка з журналу блякаваньняў (патрабуе права «hideuser»).",
+ "apihelp-block-param-allowusertalk": "Дазволіць удзельніку рэдагаваць уласную старонку гутарак (залежыць ад $wgBlockAllowsUTEdit).",
+ "apihelp-block-param-reblock": "Калі ўдзельнік ужо заблякаваны, перапісаць дзейнае блякаваньне.",
+ "apihelp-block-param-watchuser": "Назіраць за старонкай удзельніка або старонкай IP-адрасу, а таксама старонкай гутарак.",
+ "apihelp-block-example-ip-simple": "Заблякаваць IP-адрас 192.0.2.5 на тры дні з прычынай «First strike»"
}
--- /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]]",
--- /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-query+alllinks-example-unique-generator": "Ги дава сите наслови со врски, означувајќи ги отсутните",
"apihelp-query+alllinks-example-generator": "Дава страници што ги содржат врските",
"apihelp-query+allmessages-description": "Дава пораки од ова мрежно место.",
+ "apihelp-query+allmessages-param-prop": "Кои својства да се дадат.",
"apihelp-query+allmessages-param-filter": "Дај само пораки со називи што ја содржат оваа низа.",
"apihelp-query+allmessages-param-customised": "Дај само пораки во оваа состојба на прилагоденост.",
"apihelp-query+allmessages-param-lang": "Дај само пораки на овој јазик.",
"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-recursive": "Segala bantuan dalam satu halaman",
"apihelp-help-example-help": "Bantuan untuk modul bantuan",
"apihelp-query+prefixsearch-param-offset": "Bilangan hasil untuk dilangkau.",
+ "apihelp-query+usercontribs-param-show": "Hanya paparkan item-item yang mematuhi kriteria ini, cth. suntingan selain yang kecil sahaja: $2show=!minor.\n\nJika ditetapkannya $2show=patrolled atau $2show=!patrolled, maka semakan-semakan yang lebih lama daripada [https://www.mediawiki.org/wiki/Manual:$wgRCMaxAge $wgRCMaxAge] ($1 saat) tidak akan dipaparkan.",
"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",
"apihelp-xmlfm-description": "{{doc-apihelp-description|xmlfm|seealso=* {{msg-mw|apihelp-xml-description}}}}",
"apihelp-yaml-description": "{{doc-apihelp-description|yaml|seealso=* {{msg-mw|apihelp-yamlfm-description}}}}",
"apihelp-yamlfm-description": "{{doc-apihelp-description|yamlfm|seealso=* {{msg-mw|apihelp-yaml-description}}}}",
- "api-format-title": "Page title when API output is pretty-printed in HTML.",
+ "api-format-title": "{{technical}}\nPage title when API output is pretty-printed in HTML.",
"api-format-prettyprint-header": "{{technical}} Displayed as a header when API output is pretty-printed in HTML.\n\nParameters:\n* $1 - Format name\n* $2 - Non-pretty-printing module name",
"api-orm-param-props": "{{doc-apihelp-param|orm|props|description=the \"props\" parameter in subclasses of ApiQueryORM}}",
"api-orm-param-limit": "{{doc-apihelp-param|orm|limit|description=the \"limit\" parameter in subclasses of ApiQueryORM}}",
--- /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-imagerotate-example-generator": "将[[:Category:Flip]]之中的所有图像旋转180度",
"apihelp-import-param-summary": "导入摘要。",
"apihelp-import-param-xml": "上传的XML文件。",
+ "apihelp-import-param-interwikisource": "用于跨wiki导入:导入的来源wiki。",
"apihelp-import-param-interwikipage": "用于跨wiki导入:导入的页面。",
+ "apihelp-import-param-fullhistory": "用于跨wiki导入:完整导入历史,而不只是最新版本。",
+ "apihelp-import-param-templates": "用于跨wiki导入:连带导入所有包含的模板。",
+ "apihelp-import-param-namespace": "用于跨wiki导入:导入到此名字空间。",
"apihelp-import-param-rootpage": "导入作为此页面的子页面。",
"apihelp-import-example-import": "将页面[[meta:Help:Parserfunctions]]连带完整历史导入至100名字空间。",
"apihelp-login-param-name": "用户名。",
"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+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",
"api-help-param-token": "从[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]取回的“$1”令牌",
"api-help-param-disabled-in-miser-mode": "由于[https://www.mediawiki.org/wiki/Manual:$wgMiserMode miser模式]而禁用。",
"api-help-param-limited-in-miser-mode": "'''注意:'''由于[https://www.mediawiki.org/wiki/Manual:$wgMiserMode miser模式],使用这个可能导致继续前返回少于“$1limit”个结果;极端情况下可能不会返回任何结果。",
- "api-help-param-continue": "什么时候更多结果可用什么时候继续使用。",
+ "api-help-param-direction": "列举的方向:\n;newer:最早的优先。注意:$1start应早于$1end。\n;older:最新的优先(默认)。注意:$1start应晚于$1end。",
+ "api-help-param-continue": "当更多结果可用时,使用这个继续。",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(没有说明)</span>",
"api-help-examples": "{{PLURAL:$1|例子}}:",
"api-help-permissions": "{{PLURAL:$1|权限}}:",
"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 ) );
}
/**
* @param string $fileName
*/
protected function loadPluralFile( $fileName ) {
+ // Use file_get_contents instead of DOMDocument::load (T58439)
+ $xml = file_get_contents( $fileName );
+ if ( !$xml ) {
+ throw new MWException( "Unable to read plurals file $fileName" );
+ }
$doc = new DOMDocument;
- $doc->load( $fileName );
+ $doc->loadXML( $xml );
$rulesets = $doc->getElementsByTagName( "pluralRules" );
foreach ( $rulesets as $ruleset ) {
$codes = $ruleset->getAttribute( 'locales' );
# 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;
}
wfProfileIn( __METHOD__ );
if ( !$title || !$title instanceof Title ) {
global $wgTitle;
- wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetAllCallers() . ' with no title set.' );
+ wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetAllCallers( 5 ) . ' with no title set.' );
$title = $wgTitle;
}
// Sometimes $wgTitle isn't set either...
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 ( 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 ) ) {
/**
* @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
*
/**
* 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;
$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 ) );
}
/**
"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-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.",
"Revi"
]
},
- "config-desc": "미디어위키 설치 프로그램",
+ "config-desc": "미디어위키를 위한 설치 관리자",
"config-title": "미디어위키 $1 설치",
"config-information": "정보",
"config-localsettings-upgrade": "<code>LocalSettings.php</code> 파일을 감지했습니다.\n이 설치를 업그레이드하려면, 아래 상자에 <code>$wgUpgradeKey</code>의 값을 입력하세요.\n<code>LocalSettings.php</code>에서 찾을 수 있습니다.",
"config-invalid-db-prefix": "\"$1\" 데이터베이스 접두어가 잘못됐습니다.\nASCII 글자 (a-z, A-Z), 숫자 (0-9), 밑줄 (_)과 하이픈 (-)만 사용하세요.",
"config-connection-error": "$1.\n\n호스트, 계정 이름과 비밀번호를 확인하고 다시 시도하세요.",
"config-invalid-schema": "미디어위키 \"$1\"에 대한 스키마가 잘못됐습니다.\nASCII 글자 (a-z, A-Z), 숫자 (0-9), 밑줄 (_)과 하이픈 (-)만 사용하세요.",
- "config-db-sys-create-oracle": "설치 프로그램은 새 계정을 만들기 위한 SYSDBA 계정만을 지원합니다.",
+ "config-db-sys-create-oracle": "설치 관리자는 새 계정을 만들기 위한 SYSDBA 계정만을 지원합니다.",
"config-db-sys-user-exists-oracle": "\"$1\" 사용자 계정이 이미 존재합니다. SYSDBA는 새 계정을 만드는 데에만 사용할 수 있습니다!",
"config-postgres-old": "PostgreSQL $1 이상이 필요하나 $2(이)가 있습니다.",
"config-mssql-old": "Microsoft SQL 서버 $1 이상의 버전이 필요합니다. 현재 버전은 $2입니다.",
"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 );
}
}
}
* 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 );
}
$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 ) );
}
wfMessage( 'thumbnail_invalid_params' )->text() );
}
}
+
+/**
+ * Shortcut class for parameter file size errors
+ *
+ * @ingroup Media
+ * @since 1.25
+ */
+class TransformTooBigImageAreaError extends MediaTransformError {
+ function __construct( $params, $maxImageArea ) {
+ $msg = wfMessage( 'thumbnail_toobigimagearea' );
+
+ parent::__construct( 'thumbnail_error',
+ max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
+ max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
+ $msg->rawParams(
+ $msg->getLanguage()->formatComputingNumbers(
+ $maxImageArea, 1000, "size-$1pixel" )
+ )->text()
+ );
+ }
+}
}
}
- # Check if the file is smaller than the maximum image area for thumbnailing
- # For historical reasons, hook starts with BitmapHandler
- $checkImageAreaHookResult = null;
- wfRunHooks(
- 'BitmapHandlerCheckImageArea',
- array( $image, &$params, &$checkImageAreaHookResult )
- );
-
- if ( is_null( $checkImageAreaHookResult ) ) {
- global $wgMaxImageArea;
-
- if ( $srcWidth * $srcHeight > $wgMaxImageArea
- && !( $image->getMimeType() == 'image/jpeg'
- && $this->getScalerType( false, false ) == 'im' )
- ) {
- # Only ImageMagick can efficiently downsize jpg images without loading
- # the entire file in memory
- return false;
- }
- } else {
- return $checkImageAreaHookResult;
- }
-
return true;
}
return $this->getClientScalingThumbnailImage( $image, $scalerParams );
}
+ if ( !$this->isImageAreaOkForThumbnaling( $image, $params ) ) {
+ global $wgMaxImageArea;
+ return new TransformTooBigImageAreaError( $params, $wgMaxImageArea );
+ }
+
if ( $flags & self::TRANSFORM_LATER ) {
wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
$newParams = array(
# 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';
public function mustRender( $file ) {
return $this->canRotate() && $this->getRotation( $file ) != 0;
}
+
+ /**
+ * Check if the file is smaller than the maximum image area for thumbnailing.
+ *
+ * Runs the 'BitmapHandlerCheckImageArea' hook.
+ *
+ * @param File $file
+ * @param array $params
+ * @return bool
+ * @since 1.25
+ */
+ public function isImageAreaOkForThumbnaling( $file, &$params ) {
+ global $wgMaxImageArea;
+
+ # For historical reasons, hook starts with BitmapHandler
+ $checkImageAreaHookResult = null;
+ Hooks::run(
+ 'BitmapHandlerCheckImageArea',
+ array( $file, &$params, &$checkImageAreaHookResult )
+ );
+
+ if ( !is_null( $checkImageAreaHookResult ) ) {
+ // was set by hook, so return that value
+ return (bool)$checkImageAreaHookResult;
+ }
+
+ $srcWidth = $file->getWidth( $params['page'] );
+ $srcHeight = $file->getHeight( $params['page'] );
+
+ if ( $srcWidth * $srcHeight > $wgMaxImageArea
+ && !( $file->getMimeType() == 'image/jpeg'
+ && $this->getScalerType( false, false ) == 'im' )
+ ) {
+ # Only ImageMagick can efficiently downsize jpg images without loading
+ # the entire file in memory
+ return false;
+ }
+ return true;
+ }
}
$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;
}
}
public $mVersion = Parser::VERSION, # Compatibility check
$mCacheTime = '', # Time when this object was generated, or -1 for uncacheable. Used in ParserCache.
- $mCacheExpiry = null, # Seconds after which the object should expire, use 0 for uncachable. Used in ParserCache.
+ $mCacheExpiry = null, # Seconds after which the object should expire, use 0 for uncacheable. Used in ParserCache.
$mContainsOldMagic, # Boolean variable indicating if the input contained variables like {{CURRENTDAY}}
$mCacheRevisionId = null; # Revision ID that was parsed
if ( $this->mCacheTime < 0 ) {
return 0;
- } // old-style marker for "not cachable"
+ } // old-style marker for "not cacheable"
$expire = $this->mCacheExpiry;
}
if ( $expire <= 0 ) {
- return 0; // not cachable
+ return 0; // not cacheable
} else {
return $expire;
}
}
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 '-'.
*/
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->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;
+ }
+ } );
}
/**
*/
protected $sprofiler;
- /**
- * 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
- */
- protected $visible;
-
/**
* @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();
}
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 ) );
}
/**
$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.
} 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 */
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;
+ }
+}
/**
* @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];
}
/**
- * @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 ) {
$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 );
$msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
$linkPage = wfMessage( 'pagecategorieslink' )->inContentLanguage()->text();
+ $title = Title::newFromText( $linkPage );
+ $link = $title ? Linker::link( $title, $msg ) : $msg;
$s .= '<div id="mw-normal-catlinks" class="mw-normal-catlinks">' .
- Linker::link( Title::newFromText( $linkPage ), $msg )
- . $colon . '<ul>' . $t . '</ul>' . '</div>';
+ $link . $colon . '<ul>' . $t . '</ul>' . '</div>';
}
# Hidden categories
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;
}
// but we make the link target be the one site-wide page.
$title = Title::newFromText( $this->msg( $page )->inContentLanguage()->text() );
+ if ( !$title ) {
+ return '';
+ }
+
return Linker::linkKnown(
$title,
$this->msg( $desc )->escaped()
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();
'blocklist-nousertalk',
'unblocklink',
'change-blocklink',
- 'infiniteblock',
);
$msg = array_combine( $msg, array_map( array( $this, 'msg' ), $msg ) );
}
# 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 )
);
return Html::rawElement(
'span',
array( 'class' => 'mw-watchlist-toollinks' ),
- wfMessage( 'parentheses', $wgLang->pipeList( $tools ) )->text()
+ wfMessage( 'parentheses' )->rawParams( $wgLang->pipeList( $tools ) )->escaped()
);
}
}
$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;
}
*/
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
*/
"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": "বটের করা সম্পাদনাগুলি নজরতালিকায় না দেখানো হোক",
"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": "অনুসন্ধানের ফলাফল",
"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\".",
+ "directoryreadonlyerror": "Direktorij \"$1\" je samo za čitanje.",
+ "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",
"viewyourtext": "Možete da pogledate i kopirate izvor '''vaših izmjena''' na ovoj stranici:",
"protectedinterface": "Ova stranica sadrži tekst korisničkog okruženja za softver na ovom wikiju i zaštićena je radi sprečavanja zloupotrebe.\nDa biste dodali ili izmjenili prijevode svih wikija, posjetite [//translatewiki.net/ translatewiki.net], projekat za lokalizaciju Mediawikija.",
"editinginterface": "'''Upozorenje:''' Mijenjate stranicu koja sadrži aktivan tekst programa.\nPromjene na ovoj stranici dovode i do promjena za druge korisnike ovog wikija.\nZa dodavanje ili promjene prijevoda svih wikija, molimo Vas koristite [//translatewiki.net/ translatewiki.net], projekt prijevoda za MediaWiki.",
+ "translateinterface": "Za dodavanje ili promjenu prijevoda za sve wikije koristite [//translatewiki.net/ translatewiki.net], projekt za lokalizaciju MediaWikija.",
"cascadeprotected": "Uređivanje ove stranice je zabranjeno jer sadrži {{PLURAL:$1|stranicu zaštićenu|stranice zaštićene}} od uređivanja iz razloga:\n$2",
"namespaceprotected": "Vi nemate dozvulu da mijenjate stranicu '''$1'''.",
"customcssprotected": "Nemate dozvolu za mijenjanje ove CSS stranice jer sadrži osobne postavke nekog drugog korisnika.",
"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",
+ "createacct-error": "Došlo je do greške pri otvaranju naloga",
"createaccounterror": "Ne može se napraviti račun: $1",
"nocookiesnew": "Korisnički nalog je napravljen, ali niste prijavljeni. {{SITENAME}} koristi kolačiće (''cookies'') da bi se korisnici prijavili. Vi ste onemogućili kolačiće na Vašem računaru. Molimo Vas da ih omogućite, a onda se prijavite sa svojim novim korisničkim imenom i šifrom.",
"nocookieslogin": "{{SITENAME}} koristi kolačiće (''cookies'') da bi se korisnici prijavili. Vi ste onemogućili kolačiće na Vašem kompjuteru. Molimo Vas da ih omogućite i da pokušate ponovo sa prijavom.",
"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",
"user-mail-no-addy": "Pokušaj slanja e-maila bez navedene e-mail adrese.",
"user-mail-no-body": "Pokušano slanje e-poruke s praznim ili nerazumno kratkim sadržajem.",
"changepassword": "Promijeni lozinku",
- "resetpass_announce": "Prijavili ste se sa privremenim kodom koji ste dobili na e-mail.\nDa biste završili prijavu, morate unijeti novu šifru ovdje:",
+ "resetpass_announce": "Da biste završili prijavu, morate postaviti novu šifru.",
"resetpass_text": "<!-- Unesi tekst ovdje -->",
"resetpass_header": "Obnovi šifru za račun",
"oldpassword": "Stara šifra:",
"changeemail-none": "(ništa)",
"changeemail-password": "Tvoja šifra/lozinka za {{SITENAME}}:",
"changeemail-submit": "Promijeni e-mail",
+ "changeemail-throttled": "Previše puta ste se pokušali prijaviti.\nMolimo Vas da sačekate $1 prije nego što pokušate ponovo.",
+ "resettokens": "Resetovanje žetona",
+ "resettokens-no-tokens": "Nema žetona za resetovanje.",
+ "resettokens-legend": "Resetovanje žetona",
+ "resettokens-tokens": "Žetoni:",
"resettokens-token-label": "$1 (trenutna vrijednost: $2)",
+ "resettokens-done": "Žetoni su resetovani",
+ "resettokens-resetbutton": "Resetuj izabrane žetone",
"bold_sample": "Podebljan tekst",
"bold_tip": "Podebljan tekst",
"italic_sample": "Kurzivan tekst",
"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-file-match": "(podudara se sadržaj datoteke)",
"search-suggest": "Da li ste mislili: $1",
"search-interwiki-caption": "Srodni projekti",
"search-interwiki-default": "$1 rezultati:",
"prefs-advancedwatchlist": "Napredne opcije",
"prefs-displayrc": "Postavke izgleda",
"prefs-displaywatchlist": "Postavke izgleda",
+ "prefs-tokenwatchlist": "Žeton",
"prefs-diffs": "Razlike",
"prefs-help-prefershttps": "Ova podešavanja će stupiti na snagu pri sljedećoj prijavi.",
"email-address-validity-valid": "Izgleda valjano",
"right-move": "Preusmjeravanje stranica",
"right-move-subpages": "Preusmjeravanje stranica sa svim podstranicama",
"right-move-rootuserpages": "Premještanje stranica osnovnih korisnika",
+ "right-move-categorypages": "Pomakni stranice kategorije",
"right-movefile": "Premještanje datoteka",
"right-suppressredirect": "Ne pravi preusmjeravanje sa starog imena pri preusmjeravanju stranica",
"right-upload": "Postavljanje datoteka",
"action-move": "pomjerite ovu stranicu",
"action-move-subpages": "pomjerite ovu stranicu, i njene podstranice",
"action-move-rootuserpages": "pomjerite stranice osnovnog korisnika",
+ "action-move-categorypages": "pomakni stranice kategorije",
"action-movefile": "pomjeri ovu datoteku",
"action-upload": "postavljate ovu datoteku",
"action-reupload": "stavite novu verziju postojeće datoteke",
"action-block": "blokirate uređivanje ovog korisnika",
"action-protect": "promijeniti nivo zaštite za ovu stranicu",
"action-rollback": "brzo vraćanje izmjena zadnjeg korisnika koji je uređivao određenu stranicu",
- "action-import": "uvozite ovu stranicu iz druge wiki",
- "action-importupload": "uvezete ovu stranicu putem postavljanja datoteke",
+ "action-import": "uvozite stranice iz druge wiki",
+ "action-importupload": "uvoz stranica putem postavljanja datoteke",
"action-patrol": "označite izmjene drugih kao patrolirane",
"action-autopatrol": "da Vaše izmjene budu označene kao patrolirane",
"action-unwatchedpages": "pregledate spisak nepraćenih stranica",
"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\".",
"randompage": "Slučajna stranica",
"randompage-nopages": "Nema stranica u {{PLURAL:$2|slijedećem imenskom prostoru|slijedećim imenskim prostorima}}: \"$1\".",
"randomincategory": "Slučajna stranica u kategoriji",
+ "randomincategory-invalidcategory": "\"$1\" nije valjano ime kategorije.",
"randomincategory-nopages": "Nema stranica u kategoriji [[:Category:$1|$1]].",
"randomincategory-category": "Kategorija:",
"randomincategory-legend": "Slučajna stranica u kategoriji",
"protectedpages-cascade": "Samo prenosive zaštite",
"protectedpages-noredirect": "Sakrij preusmjerenja",
"protectedpagesempty": "Trenutno nijedna stranica nije zaštićena ovim parametrima.",
+ "protectedpages-timestamp": "Vremenska oznaka",
"protectedpages-page": "Stranica",
"protectedpages-expiry": "Istječe",
+ "protectedpages-performer": "Zaštita korisnika",
+ "protectedpages-params": "Parametri zaštite",
"protectedpages-reason": "Razlog",
"protectedpages-unknown-timestamp": "Nepoznato",
"protectedpages-unknown-performer": "Nepoznati korisnik",
"protectedtitles": "Zaštićeni naslovi",
+ "protectedtitles-summary": "Na ovoj stranici se nalazi spisak trenutno zaštićenih naslova. Za spisak trenutno zaštićenih stranica vidi [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
"protectedtitlesempty": "Nijedan naslov članka trenutno nije zaštićen ovim parametrima.",
"listusers": "Spisak korisnika",
"listusers-editsonly": "Pokaži samo korisnike koji su uređivali",
"listusers-creationsort": "Sortiraj po datumu pravljenja",
+ "listusers-desc": "Sortiraj u opadajućem redoslijedu",
"usereditcount": "$1 {{PLURAL:$1|izmjena|izmjene}}",
"usercreated": "{{GENDER:$3|Napravio|Napravila}} dana $1 u $2",
"newpages": "Nove stranice",
"pager-older-n": "{{PLURAL:$1|starija 1|starije $1}}",
"suppress": "Nazdor",
"querypage-disabled": "Ova posebna stranica je onemogućena jer smanjuje performanse.",
+ "apihelp": "API pomoć",
+ "apihelp-no-such-module": "Modul \"$1\" nije pronađen.",
"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-removegroup-self": "Može ukloniti {{PLURAL:$2|grupu|grupe|grupa}} sa svog računa: $1",
"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-header": "Ograničenja imenskog prostora",
"listgrouprights-namespaceprotection-namespace": "Imenski prostor",
+ "listgrouprights-namespaceprotection-restrictedto": "Prava kojima se dozvoljava korisniku da uređuje",
+ "trackingcategories": "Praćenje kategorija",
+ "trackingcategories-msg": "Praćenje kategorije",
+ "trackingcategories-name": "Ime poruke",
+ "trackingcategories-desc": "Kriterij uključenja kategorije",
"trackingcategories-nodesc": "Opis nije dostupan.",
+ "trackingcategories-disabled": "Kategorija je onemogućena",
"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.",
"emailuser": "Pošalji e-poštu ovom korisniku",
"mywatchlist": "Praćeni članci",
"watchlistfor2": "Za $1 $2",
"nowatchlist": "Nemate ništa na svom spisku praćenih članaka.",
- "watchlistanontext": "Molimo da $1 da možete vidjeti ili urediti stavke na Vašem spisku praćenja.",
+ "watchlistanontext": "Molimo logujte se da vidite ili uredite stavke na Vašem spisku praćenja.",
"watchnologin": "Niste prijavljeni",
"addwatch": "Dodaj na spisak praćenja",
"addedwatchtext": "Stranica \"[[:$1]]\" je dodata vašem [[Special:Watchlist|spisku praćenih članaka]]. \nBuduće promjene ove stranice i njoj pridružene stranice za razgovor će biti navedene ovde.",
"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",
"newimages-summary": "Ova specijalna stranica prikazuje posljednje postavljene datoteke.",
"newimages-legend": "Filter",
"newimages-label": "Ime datoteke (ili dio imena):",
+ "newimages-showbots": "Pokaži datoteke koje su poslali botovi",
"noimages": "Ništa za prikazati.",
"ilsubmit": "Traži",
"bydate": "po datumu",
"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}}:",
+ "watchlistedit-clear-title": "Očišćen spisak nadgledanja",
+ "watchlistedit-clear-legend": "Očisti spisak nadgledanja",
+ "watchlistedit-clear-explain": "Svi naslovi će biti uklonjeni iz vašeg spiska nadgledanja",
+ "watchlistedit-clear-titles": "Naslovi:",
+ "watchlistedit-clear-submit": "Isprazni spisak nadgledanja (Ovo je trajno!)",
+ "watchlistedit-clear-done": "Vaš spisak praćenja je očišćen.",
+ "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-hook-name": "Naziv kuke",
"version-hook-subscribedby": "Pretplaćeno od",
"version-version": "(Verzija $1)",
+ "version-no-ext-name": "[nema imena]",
"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>",
"htmlform-yes": "Da",
"htmlform-chosen-placeholder": "Izaberite opciju",
"htmlform-cloner-create": "Dodaj još",
+ "htmlform-cloner-delete": "Ukloni",
"sqlite-has-fts": "$1 sa podrškom pretrage cijelog teksta",
"sqlite-no-fts": "$1 bez podrške pretrage cijelog teksta",
"logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
"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-cputime": "Vrijeme korištenja CPU",
+ "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_remove_comments": "Ukloni komentare",
"expand_templates_remove_nowiki": "Onemogući oznake <nowiki> u rezultatima",
"expand_templates_generate_xml": "Prikaži XML stablo parsera",
+ "expand_templates_generate_rawhtml": "Pokaži izvorni HTML",
"expand_templates_preview": "Pregled",
"pagelang-name": "Stranica",
"pagelang-language": "Jezik",
- "pagelang-select-lang": "Izaberi jezik"
+ "pagelang-select-lang": "Izaberi jezik",
+ "mediastatistics-table-count": "Broj datoteka",
+ "mediastatistics-header-unknown": "Nepoznato",
+ "mediastatistics-header-drawing": "Crteži (vektorske slike)",
+ "mediastatistics-header-audio": "Zvuk",
+ "mediastatistics-header-video": "Videa",
+ "mediastatistics-header-multimedia": "Rich media",
+ "mediastatistics-header-office": "Kancelarija",
+ "mediastatistics-header-text": "Tekstualno",
+ "mediastatistics-header-executable": "Izvršni",
+ "mediastatistics-header-archive": "Kompresovani formati",
+ "json-error-syntax": "Sintaksna greška"
}
"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": "Къайлаяха ас нисйинарш тергаме могӀам чура",
"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»",
"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>|Карийнарш <strong>$1 — $2</strong> чура <strong>$3</strong>}}",
+ "search-showingresults": "{{PLURAL:$4|Карийна <strong>$1</strong> — цхьаъ агӀо|Карийна <strong>$3</strong> агӀо, царах агӀонгахь гойту $2 агӀо}}",
"search-nonefound": "Дехаре терра цхьа хӀума ца карийна.",
"powersearch-legend": "Шуьйра лахар",
"powersearch-ns": "ЦӀерийн меттигашкахь лахар:",
"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.",
"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|хӀума|хӀумнаш}}",
"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": "Арахьара хьажорг",
"linksearch-pat": "Лехарна кеп:",
"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": "← хьажоргаш",
"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": "ЦӀе хийца агӀон",
"moveuserpage-warning": "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
"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": "Шира версийн оьцу хааме хьажа таро яц.",
"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е болу хаам",
"tog-shownumberswatching": "ژمارەی بەکارھێنەرە چاودێرەکان نیشان بدە",
"tog-oldsig": "واژووی ئێستا:",
"tog-fancysig": "وەکوو ویکیدەق واژووەکە لەبەر چاو بگرە (بێ بەستەرێکی خۆگەڕ)",
- "tog-uselivepreview": "Ù\84Û\95 Ù¾Û\8eشبÛ\8cÙ\86Û\8cÙ\86Û\8c زÛ\8cÙ\86دÙ\88Ù\88 Ú©Û\95ÚµÚ© Ù\88Û\95ربگرÛ\95 (تاÙ\82Û\8cکارÛ\8câ\80\8c)",
+ "tog-uselivepreview": "Ù¾Û\8eشبÛ\8cÙ\86Û\8cÙ\86Û\8c زÛ\8cÙ\86دÙ\88Ù\88 بÛ\95 کار بھÛ\8eÙ\86Û\95",
"tog-forceeditsummary": "ئەگەر کورتەی دەستکاریم نەنووسی پێم بڵێ",
"tog-watchlisthideown": "دەستکارییەکانم بشارەوە لە پێرستی چاودێری",
"tog-watchlisthidebots": "دەستکارییەکانی بات بشارەوە لە لیستی چاودێری",
"otherlanguages": "بە زمانەکانی تر",
"redirectedfrom": "(ڕەوانەکراوە لە $1ەوە)",
"redirectpagesub": "پەڕەی ڕەوانەکەر",
+ "redirectto": "ڕەوانەکردن بۆ:",
"lastmodifiedat": "ئەم پەڕەیە دواجار لە $2ی $1 نوێ کراوەتەوە.",
"viewcount": "ئەم پەڕەیە {{PLURAL:$1|یەکجار|$1 جار}} بینراوە.",
"protectedpage": "پەڕەی پارێزراو",
"viewsourcetext": "دەتوانی سەرچاوەی ئەم پەڕە ببینی و کۆپیی بکەی:",
"viewyourtext": "دەتوانی ژێدەری '''دەستکارییەکەت''' لەم پەڕەیەدا ببینی و کۆپی بکەی:",
"protectedinterface": "ئەم پەڕەیە دەقی ڕواڵەتی نەرمامێری ئەم ویکییە نیشان دەدات و بۆ بەرگری لە خراپکاری پارێزراوە.\nبۆ زیادکردن یان گۆڕینی وەرگێڕانەکان بۆ ھەموو ویکییەکان، تکایە لە [//translatewiki.net/ translatewiki.net]، پرۆژەی ناوچەیی کردنی میدیاویکی کەڵک وەربگرە.",
- "editinginterface": "'''ئاگاداری:''' تۆ خەریکی دەستکاریی پەڕەیەکی کە بۆ دابینکردنی دەقی ڕواڵەتی نەرمامێر بە کار دەھێنرێت.\nگۆڕانکاریی ئەم پەڕەیە کاریگەر دەبێت لە سەر ڕواڵەتی پەڕەکانی بەکارھێنەرانی تر لەم ویکییەدا.\nبۆ زیادکردن یان گۆڕینی وەرگێڕانەکان بۆ ھەموو ویکییەکان، تکایە لە [//translatewiki.net/ translatewiki.net]، پرۆژەی ناوچەیی کردنی میدیاویکی کەڵک وەربگرە.",
+ "editinginterface": "<strong>ھۆشیار بە:</strong> خەریکی دەستکاریی پەڕەیەک دەکەیت کە بۆ دابینکردنی دەقی ڕووکاری نەرمامێر بەکاردێت.\nگۆڕانکارییەکانی لەم پەڕەیەدا کاریگەر دەبێت لە سەر ڕواڵەتی پەڕەکانی بەکارھێنەرانی تر لەم ویکییەدا.",
"cascadeprotected": "ئەم لاپەڕە پارێزراوە لە دەستکاریی، چونکا خراوەتە سەر ڕیزی ئەم {{PLURAL:$1|لاپەڕانه، کە}} که به ههڵکردنی بژاردهی داڕژان ههڵکراوه:\n$2",
"namespaceprotected": "تۆ ناتوانی لاپەڕەکانی ناو نەیمسپەیسی '''$1''' بگۆڕی.",
"customcssprotected": "دەسەڵاتی دەستکارییکردنی ئەم پەڕەی CSS ـەت نییە چوونکە ڕێکخستنەکانی کەسێکی تر لەخۆ دەگرێت.",
"accountcreatedtext": "هەژماری بەکارهێنەری [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|لێدوان]]) دروست کراوە.",
"createaccount-title": "درووستکردنی هەژمارە بۆ {{SITENAME}}",
"createaccount-text": "کەسێک هەژمارەیەکی بۆ ئیمێڵ ئەدرەسەکی تۆ لەسەر {{SITENAME}} ($4) بەناوی \"$2\"، بە وشەی نهێنی \"$3\".\nئێستا دەبێ بڕۆیتە ژوورەوە و وشەی نهێنی بگۆڕیت.\n\nئەگەر ئەو هەژمارە بە هەڵە درووستکراوە، ئەم برووسکە لە بەرچاو مەگرە.",
- "login-throttled": "ژمارەیەکی زۆر هەوڵت داوە بۆ چوونە ژوورەوە.\nتکایە پێش هەوڵی دووبارە، نەختێک بوەستە.",
+ "login-throttled": "زۆر زۆر ھەوڵت داوە بۆ چوونە ژوورەوە.\nتکایە $1 بوەستە پێش ھەوڵی دووبارە.",
"loginlanguagelabel": "زمان: $1",
"pt-login": "بچۆ ژوورەوە",
"pt-login-button": "بچۆ ژوورەوە",
"pt-createaccount": "ھەژمار دروست بکە",
"pt-userlogout": "بچۆ دەرەوە",
"changepassword": "تێپەڕوشە بگۆڕە",
- "resetpass_announce": "بÛ\95 Ú©Û\86دÛ\8c کاتÛ\8cÛ\8c ئÛ\8cÙ\85Û\95Û\8cÙ\84â\80\8cکراÙ\88 ھاتÙ\88Ù\88Û\8cتÛ\95 Ú\98Ù\88Ù\88رÛ\95Ù\88Û\95.\nبÛ\86 دÙ\88اÛ\8cÛ\8c ھاتÙ\86Û\8c Ú\86Ù\88Ù\88Ù\86Û\95 Ú\98Ù\88Ù\88رÛ\95Ù\88Û\95Ø\8c ئÛ\95Ø´Û\8e تÛ\8eÙ¾Û\95Ú\95Ù\88Ø´Û\95Û\8cÛ\95Ú©Û\8c Ù\86Ù\88Û\8e Ú¾Û\95ڵبÚ\98Û\8eرÛ\8c Ù\84Û\8eرÛ\95:",
+ "resetpass_announce": "بÛ\86 Ú©Û\86تاÛ\8cÛ\8c Ú\86Ù\88Ù\88Ù\86Û\95 Ú\98Ù\88Ù\88رÛ\95Ù\88Û\95Ø\8c دÛ\95بÛ\8eت تÛ\8eÙ¾Û\95Ú\95Ù\88Ø´Û\95Û\8cÛ\95Ú©Û\8c Ù\86Ù\88Û\8e دابÙ\86Û\8eÛ\8cت.",
"resetpass_text": "<!-- تێپهڕهوشهی ههژمارهكه سفر بكهرهوه -->",
"resetpass_header": "گۆڕینی تێپەڕوشەی ھەژمار",
"oldpassword": "تێپەڕوشەی پێشو:",
"compareselectedversions": "پیاچوونەوە ھەڵبژێردراوەکان ھەڵسەنگێنە",
"showhideselectedversions": "دیاریکردنی پێداچوونەوە ھەڵبژێردراوەکان بگۆڕە",
"editundo": "پووچەڵکردنەوە",
+ "diff-empty": "(بەبێ جیاوازی)",
"searchresults": "ئاکامەکانی گەڕان",
"searchresults-title": "ئاکامەکانی گەڕان بۆ «$1»",
"titlematches": "سەردێڕی پەڕە پێی ئەخوا",
"search-result-category-size": "{{PLURAL:$1|١ ئەندام|$1 ئەندام}} ({{PLURAL:$2|١ ژێرپۆل|$2 ژێرپۆل}}, {{PLURAL:$3|١ پەڕگە|$3 پەڕگە}})",
"search-redirect": "(ڕەوانەکەر $1)",
"search-section": "(بەشی $1)",
+ "search-category": "(پۆلی $1)",
"search-suggest": "ئایا مەبەستت ئەمە بوو: $1",
"search-interwiki-caption": "پرۆژە خوشکەکان",
"search-interwiki-default": "ئاکام لە $1:",
"gender-female": "ژن",
"prefs-help-gender": "دڵخواز: بۆ بانگ کردنی دروست بە دەستی نەرمامێر.\nئەم زانیارییە گشتی ئەبێ.",
"email": "ئیمەیل",
- "prefs-help-realname": "Ù\86اÙ\88Û\8c Ú\95استÛ\8c دڵخÙ\88ازÛ\95.\nئÛ\95Ú¯Û\95ر Ù¾Û\8eت Ø®Û\86Ø´ بÛ\8eت بÛ\8cدÛ\95Û\8cØ\8c زÛ\86رتر Ú\95اتدÛ\95Ú©Û\8eØ´Û\8eت بÛ\86 کارÛ\95کاÙ\86ت.",
+ "prefs-help-realname": "Ù\86اÙ\88Û\8c Ú\95استÛ\95Ù\82Û\8cÙ\86Û\95 دڵخÙ\88ازÛ\95.\nئÛ\95Ú¯Û\95ر بÙ\86Ù\88Ù\88سرÛ\8eتØ\8c Ù\84Û\95Ù\88اÙ\86Û\95Û\8cÛ\95 بÛ\86 ئاÙ\85اÚ\98Û\95داÙ\86 بÛ\95رھÛ\95Ù\85Û\95Ú©Û\95ت بÛ\95 کار بھÛ\8eÙ\86رÛ\8eت.",
"prefs-help-email": "دانانی ناونیشانی ئیمەیل دڵخوازانەیە، بەڵام ئەگەر تێپەڕوشەکەت لەیادکرد، بۆ نوێکردنەوەی تێپەڕوشە پێویست دەبێت.",
"prefs-help-email-others": "ھەروەھا دەتوانی ھەڵبژێری کە بەکارھێنەرانی دیکە لە ڕێگەی پەڕەی بەکارھێنەرییەکەت یان لێدوانەکەت بێ ئاشکراکردنی کەسایەتیت پێوەندیت لەگەڵ بگرن.",
"prefs-help-email-required": "ناونیشانی ئیمەیل پێویستە.",
"userrights-no-interwiki": "دەسەڵاتی گۆڕینی مافەکانی بەکارهێنەر لە ویکییەکانی دیکەت نیە.",
"userrights-nodatabase": "بنکەدراوی $1 بوونی نیە یا لەم شوێنە نیە.",
"userrights-nologin": "بۆ دانانی مافەکانی بەکارهێنەر دەبێ بە هەژماری بەڕێوبەری [[Special:UserLogin|بچیتە ژووروە]].",
- "userrights-notallowed": "ھەژمارەکەی تۆ دەسەڵاتی دانان یان لابردنی مافەکانی بەکارھێنەری نییە.",
+ "userrights-notallowed": "تۆ دەسەڵاتی دانان یان لابردنی مافەکانی بەکارھێنەرانت نییە.",
"userrights-changeable-col": "ئەو گرووپانەی دەتوانی بیگۆڕی",
"userrights-unchangeable-col": "ئەو گرووپانەی ناتوانی بیگۆڕی",
"group": "گرووپ:",
"right-deletedtext": "دیتنی دەقە سڕاوەکان و گۆڕانکارییەکانی نێوان پێداچوونەوە سڕاوەکان",
"right-browsearchive": "گەڕانی پەڕە سڕاوەکان",
"right-undelete": "ھێنانەوەی پەڕەیەک",
- "right-suppressrevision": "بÛ\95سÛ\95رداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95 Ù\88 Ú¾Û\8eÙ\86اÙ\86Û\95Ù\88Û\95Û\8c Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95 شاردراÙ\88Û\95کاÙ\86 Ù\84Û\95 بÛ\95Ú\95Û\8eÙ\88بÛ\95راÙ\86",
+ "right-suppressrevision": "بÛ\8cÙ\86Û\8cÙ\86Ø\8c شاردÙ\86Û\95Ù\88Û\95 Ù\88 Ú¾Û\8eÙ\86اÙ\86Û\95Ù\88Û\95Û\8c Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95 تاÛ\8cبÛ\95تÛ\95کاÙ\86Û\8c Ù¾Û\95Ú\95Û\95کاÙ\86 Ù\84Û\95 Ù\84اÛ\8cÛ\95Ù\86 Ú¾Û\95ر بÛ\95کارھÛ\8eÙ\86Û\95رÛ\8eÚ©Û\95Ù\88Û\95",
"right-suppressionlog": "دیتنی لۆگە نھێنییەکان",
"right-block": "بەربەستنی بەکارھێنەرانی تر لە دەستکاریکردن",
"right-blockemail": "بەربەستنی بەکارھێنەرێک لە ناردنی ئیمەیل",
"rcshowhideanons-hide": "بشارەوە",
"rcshowhidepatr": "گۆرانکارییە پاس دراوەکان $1",
"rcshowhidepatr-show": "نیشان بدە",
+ "rcshowhidepatr-hide": "بیشارەوە",
"rcshowhidemine": "دەستکارییەکانم $1",
"rcshowhidemine-show": "نیشان بدە",
"rcshowhidemine-hide": "بشارەوە",
"nolicense": "ھیچ ھەڵنەبژێردراوە",
"license-nopreview": "(پێشبینین ئامادەی کەڵک وەرگرتن نییە)",
"upload_source_url": " (URLـی بەکار، بۆ دەستپێگەیشتنی گشتی)",
- "upload_source_file": " (پەڕگەیەک لەسەر کۆمپیوتەرەکەت)",
+ "upload_source_file": "(پەڕگەی ھەڵبژێرراوت لەسەر کۆمپیوتەرەکەت)",
"listfiles-delete": "بیسڕەوە",
"listfiles-summary": "ئەم پەڕە تایبەتە ھەموو پەڕگە بارکراوەکان نیشان دەدات.",
"listfiles_search_for": "بگەڕێ بۆ ناوی میدیای:",
"wlheader-enotif": "ئاگاداری بە ئیمەیل چالاکە.",
"wlheader-showupdated": "ئەو پەڕانە کە لە پاش دواین سەردانت دەستکاری کراون بە '''ئەستوور''' نیشان دراون",
"wlnote": "خوارەوە {{PLURAL:$1|دوایین گۆڕانکارییە|دوایین '''$1''' گۆڕانکارییە}} لە دوایین {{PLURAL:$2|کاتژمێر|'''$2''' کاتژمێر}}دا ھەتا $4 لە $3.",
- "wlshowlast": "دوایین $1 کاتژمێر $2 ڕۆژی نیشان بدە",
+ "wlshowlast": "دوایین $1 کاتژمێری $2 ڕۆژ نیشان بدە",
"watchlist-options": "ھەڵبژاردەکانی لیستی چاودێری",
"watching": "چاودێری...",
"unwatching": "لابردنی چاودێری...",
"exbeforeblank": "ناوەرۆک بەر لە واڵاکردنەوە ئەمە بوو: «$1»",
"delete-confirm": "سڕینەوەی «$1»",
"delete-legend": "بیسڕەوە",
- "historywarning": "'''وشیار بە:''' پەڕەیەک کە دەتەوێ بیسڕیتەوە مێژوویەکی ھەیە بە نزیکەی $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}وە:",
+ "historywarning": "<strong>ھۆشیار بە:</strong> پەڕەیەک کە خەریکیت دەیسڕیتەوە مێژوویەکی ھەیە بە $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}وە:",
"confirmdeletetext": "تۆ خەریکی پەڕەیەک بە ھەموو مێژووەکەیەوە دەسڕیتەو.\nتکایە پشتڕاستی بکەوە کە دەتەوێت ئەم کارە بکەی، لە ئاکامەکەی تێدەگەی، و ئەم کارە بە پێی [[{{MediaWiki:Policy-url}}|سیاسەتنامە]] ئەنجام دەدەی.",
"actioncomplete": "کردەوە بە ئاکام گەییشت",
"actionfailed": "کردارەکە سەرنەکەوت",
"exif-subjectnewscode-value": "$2 ($1)",
"exif-compression-1": "نەپەستێنراو",
"exif-copyrighted-true": "خاوەنی مافی بڵاوکردنەوە",
- "exif-copyrighted-false": "پاوانی گشتی",
+ "exif-copyrighted-false": "ڕەوشی مافی لەبەرگرتنەوە دیاری نەکراوە",
"exif-unknowndate": "ڕێکەوتی نەزانراو",
"exif-orientation-1": "ئاسایی",
"exif-orientation-2": "ئاسۆیی هەڵگێڕدراوەتەوە",
"duplicate-defaultsort": "'''ئاگاداری''' کلیلی پۆلێنکردنی \"$2'' چووەتە شوێنی کلیلی پۆلێنکردنی \"$1\"",
"version": "وەشان",
"version-extensions": "پێوەکراوە دامەزراوەکان",
- "version-skins": "پێستەکان",
+ "version-skins": "پێستە دامەزراوەکان",
"version-specialpages": "پەڕە تایبەتەکان",
"version-parserhooks": "قولاپە لێککەرەکان",
"version-variables": "گۆڕاوەکان",
"duration-decades": "$1 {{PLURAL:$1|دەیە|دەیە}}",
"duration-centuries": "$1 {{PLURAL:$1|سەدە|سەدە}}",
"duration-millennia": "$1 {{PLURAL:$1|ھەزارە|ھەزارە}}",
- "expand_templates_ok": "باشە"
+ "expand_templates_output": "ئاکام",
+ "expand_templates_ok": "باشە",
+ "expand_templates_preview": "پێشبینین",
+ "pagelang-name": "پەڕە",
+ "pagelang-language": "زمان",
+ "pagelang-select-lang": "زمان ھەڵبژێرە",
+ "right-pagelang": "زمانی پەڕە بگۆڕە",
+ "action-pagelang": "زمانی پەڕەکە بگۆڕە",
+ "mediastatistics": "ئامارەکانی میدیا",
+ "mediastatistics-nbytes": "{{PLURAL:$1|$1 بایت|$1 بایت}} ($2؛ $3%)",
+ "mediastatistics-table-mimetype": "جۆری MIME",
+ "mediastatistics-table-count": "ژمارەی پەڕگەکان",
+ "mediastatistics-header-unknown": "نەزانراو",
+ "mediastatistics-header-bitmap": "وێنەی Bitmap",
+ "mediastatistics-header-audio": "دەنگ",
+ "mediastatistics-header-video": "ڤیدیۆکان",
+ "json-error-syntax": "ھەڵەی ئیملایی"
}
"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ů",
"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 leitest auf diese Seite selbst weiter.\nDu hast vermutlich das falsche Weiterleitungsziel angegeben oder du bearbeitest die falsche Seite.\nWenn du auf erneut auf „{{int:savearticle}}“ klickst, wird die Weiterleitung dennoch 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:",
"thumbnail-temp-create": "Die Datei für die temporäre Miniaturansicht konnte nicht erstellt werden",
"thumbnail-dest-create": "Die Miniaturansicht konnte nicht am vorgesehenen Ort gespeichert werden",
"thumbnail_invalid_params": "Ungültige Thumbnail-Parameter",
+ "thumbnail_toobigimagearea": "Datei mit Abmessungen größer als $1",
"thumbnail_dest_directory": "Zielverzeichnis kann nicht erstellt werden.",
"thumbnail_image-type": "Bildtyp nicht unterstützt",
"thumbnail_gd-library": "Unvollständige Konfiguration der GD-Bibliothek: Fehlende Funktion $1",
"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-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é",
"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.",
+ "selfredirect": "<strong>Warning:</strong> You are redirecting this page to itself.\nYou may have specified the wrong target for the redirect, or you may be editing the wrong page.\nIf you click \"{{int:savearticle}}\" again, the redirect will be created anyway.",
"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:",
"thumbnail-temp-create": "Unable to create temporary thumbnail file",
"thumbnail-dest-create": "Unable to save thumbnail to destination",
"thumbnail_invalid_params": "Invalid thumbnail parameters",
+ "thumbnail_toobigimagearea": "File with dimensions greater than $1",
"thumbnail_dest_directory": "Unable to create destination directory",
"thumbnail_image-type": "Image type not supported",
"thumbnail_gd-library": "Incomplete GD library configuration: Missing function $1",
"size-exabytes": "$1 EB",
"size-zetabytes": "$1 ZB",
"size-yottabytes": "$1 YB",
+ "size-pixel": "$1 P",
+ "size-kilopixel": "$1 KP",
+ "size-megapixel": "$1 MP",
+ "size-gigapixel": "$1 GP",
+ "size-terapixel": "$1 TP",
+ "size-petapixel": "$1 PP",
+ "size-exapixel": "$1 EP",
+ "size-zetapixel": "$1 ZP",
+ "size-yottapixel": "$1 YP",
"bitrate-bits": "$1 bps",
"bitrate-kilobits": "$1 kbps",
"bitrate-megabits": "$1 Mbps",
"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",
"tog-shownumberswatching": "Näita jälgivate kasutajate hulka",
"tog-oldsig": "Praegune allkiri:",
"tog-fancysig": "Kasuta vikiteksti vormingus allkirja (ilma automaatse lingita kasutajalehele)",
- "tog-uselivepreview": "Kasuta elavat eelvaadet (katseline)",
+ "tog-uselivepreview": "Kasuta elavat eelvaadet",
"tog-forceeditsummary": "Nõua redigeerimisel resümee välja täitmist",
"tog-watchlisthideown": "Peida minu redaktsioonid jälgimisloendist",
"tog-watchlisthidebots": "Peida robotid jälgimisloendist",
"anoneditwarning": "<strong>Hoiatus:</strong> Sa pole sisse logitud. Sinu IP-aadress on kõigile nähtav, kui muudatusi teed. Kui <strong>[$1 logid sisse]</strong> või <strong>[$2 lood konto]</strong>, siis teiste eeliste seas omistatakse sinu muudatused sulle kasutajanime järgi.",
"anonpreviewwarning": "''Sa pole sisse logitud. Selle lehe redigeerimislogisse salvestatakse su IP-aadress.''",
"missingsummary": "'''Meeldetuletus:''' Sa ei ole lisanud muudatuse resümeed.\nKui vajutad uuesti salvestamise nupule, salvestatakse muudatus ilma resümeeta.",
+ "selfredirect": "<strong>Hoiatus:</strong> Teed ümbersuunamise samasse artiklisse.\nÜmbersuunamine luuakse, kui klõpsad uuesti \"{{int:savearticle}}\".",
"missingcommenttext": "Palun sisesta siit allapoole kommentaar.",
"missingcommentheader": "'''Meeldetuletus:''' Sa pole kirjutanud kommentaarile teemat ega pealkirja.\nKui klõpsad uuesti \"{{int:savearticle}}\", salvestatakse su kommentaar kummatagi.",
"summary-preview": "Resümee eelvaade:",
"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.",
"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",
"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é :",
"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:",
"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.",
"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",
"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",
"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",
"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:",
"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",
"tog-numberheadings": "سربلگه خود شماره گر",
"tog-showtoolbar": "نوار اوزار ويرايشت نشون بيه",
"tog-editondblclick": "بلگيا نه وا دوبار پورنين ويرايشت بكيد",
- "tog-editsectiononrightclick": "بهر ویرایشت نه وا راس کلیک کردن د بهر عنوانیا فعال کو",
- "tog-watchcreations": "بلگیایی که مه راس کمه و فایلیایی که مه سوار کمه اضاف کو د سیل برگه مه",
+ "tog-editsectiononrightclick": "بهرجا ویرایشت نه وا راس پورنین د بهرجا داسونیا کنشتگر کو",
+ "tog-watchcreations": "بلگیایی که مه راس کمه و جانیایایی که مه سوار کمه اضاف کو د سیل برگه مه",
"tog-watchdefault": "بلگیا و جانیایی که مه ویرایشت کمه اضاف کو د سیل برگم",
"tog-watchmoves": "بلگیاو جانیایی که مه جاوه جا کمه د سیل برگم اضاف کو",
"tog-watchdeletion": "بلگیا و جانیایی که مه پاک کمه اضاف کو د سیل برگم",
"tog-watchrollback": "همه بلگه یا نه د جایی که مه د سیل برگم می کم اضاف کو.",
"tog-minordefault": "همه ویرایشتیا کؤچک نه وا پیش فرض بیئن نشو دار کو.",
"tog-previewontop": "پیش سیل نه دما جعوه ویرایشت نشو بیئه",
- "tog-previewonfirst": "پیش سیل نه د اولین ویرایشت نشو بیئه",
- "tog-enotifwatchlistpages": "اوسه که یه گل بلگه یا فایلی د سیل برگ مه آلشت بوئه منه وا ایمیل خور کو",
- "tog-enotifusertalkpages": "وختی که بلگه گپسن کاریار آلشت پیدا کرد منه وا ایمیل خور کو",
+ "tog-previewonfirst": "پیش سیل نه د اولی ویرایشت نشو بیئه",
+ "tog-enotifwatchlistpages": "اوسه که یه گل بلگه یا جانیا د سیل برگ مه آلشت بوئه منه وا انجومانامه خور کو",
+ "tog-enotifusertalkpages": "د گاتی که بلگه گپسن کاریار آلشت پیدا کرد منه وا انجومانامه خور کو",
"tog-enotifminoredits": "همچنو اوسه که ویرایشتیا کؤچکی د بلگیا یا جانیایا انجوم بوئه منه خور کو",
- "tog-enotifrevealaddr": "نشونی ایمیل منه د انجومانامه اشگار نشو بیه",
- "tog-shownumberswatching": "انازه کاریاریایی که د حالت دیئنن نشو بیه",
+ "tog-enotifrevealaddr": "نشونی انجومانامه منه د انجومانامه اشگار نشو بیه",
+ "tog-shownumberswatching": "انازه کاریاریایی که د حال و بال دیئنن نشو بیه",
"tog-oldsig": "امضايی هيئش:",
- "tog-fancysig": "Ù\88ا اÙ\85ضا Ú\86Û\8c Ù\88Û\8cÚ©Û\8c Ù\85تÙ\86 برخÙ\88رد Ú©و",
- "tog-uselivepreview": "د پیش سیل زنه استفاده کو",
- "tog-forceeditsummary": "منه وختی که یه گل چکسه ویرایشت حالی وارد بوئه سریع خور کو",
+ "tog-fancysig": "Ù\88ا اÙ\85ضا Ú\86Û\8c Ù\88Û\8cÚ©Û\8c Ù\85تÙ\86 رÙ\81تار داشتو",
+ "tog-uselivepreview": "پیش سیل زنه وه کار بیئر",
+ "tog-forceeditsummary": "منه د گاتی که یه گل چکسه ویرایشت حالی وارد بوئه سریع خور کو",
"tog-watchlisthideown": "قام كو ويرايشت منه د",
"tog-watchlisthidebots": "ویرایشت یا بوت نه د سیل برگ قام کو",
"tog-watchlisthideminor": "قام كو ويرايشت کؤچک منه د",
"tog-watchlisthideliu": "ویرایشت یا کاریاریا وامئن سامونه نه د سیل برگ قام کو",
"tog-watchlisthideanons": "ویرایشت یا کاروریا نادیار نه د سیل برگ قام کو",
"tog-watchlisthidepatrolled": "ویرایش تیا د تی رس نه د سیل برگ قام کو",
- "tog-ccmeonemails": "کپی انجومانامه یا منه که سی کاریاریا تر می فرسنم سیم کل کو",
+ "tog-ccmeonemails": "ورداشته انجومانامه یا منه که سی کاریاریا تر می فرسنم سیم کل کو",
"tog-diffonly": "بلگیایی که د ور گرته فرخیا هارن نشون نیه",
"tog-showhiddencats": "دسه يا قام بيئنه نشون بيه",
"tog-norollbackdiff": "فرخیا نه د بین بوریت نها یه گل عقو گرد کردن",
- "tog-useeditwarning": "د گاتÛ\8c Ú©Ù\87 Ø¢Ù\84شتÛ\8cا ذخÛ\8cره نبیه د بلگه ویرایشت وه جا می نم خورم کو",
- "tog-prefershttps": "همیشه د گاتی که مه وامئن هئم د ارتواط امن استفاده کو",
+ "tog-useeditwarning": "د گاتÛ\8c Ú©Ù\87 Ø¢Ù\84شتÛ\8cا اÙ\85اÛ\8cÛ\8cه نبیه د بلگه ویرایشت وه جا می نم خورم کو",
+ "tog-prefershttps": "همیشه د گاتی که مه وامئن هئم د ارتواط امن وه کار بیئر",
"underline-always": "هميشه",
"underline-never": "هيژوخت",
"underline-default": "پوسه یا دوارته نیئر پیش فرض",
"category-empty": "ای دسه واقعن ده ور گرته هیژ بلگه ای یا وارسگر ای نی",
"hidden-categories": "{{PLURAL:$1|دسته قام بيه|دسته يا قام بيه}}",
"hidden-category-category": "دسه یا قام بیه",
- "category-subcat-count": "{{جمی:$2|ای دسه فقط زیر دسه دینداگر هان دش .|ای دسه {{جمی:$1| زیردسه|$1 زیردسه یا}}هئ , خارج د $2 کل.}}",
+ "category-subcat-count": "{{جمی:$2|ای دسه فقط زیر دسه دینداگر هان دش .|ای دسه {{جمی:$1| زیردسه|$1 زیردسه یا}}هئ , وه در د $2 کل.}}",
"category-subcat-count-limited": "ای دسه وا دم {{جمی:$1|زیردسه|$1زیردسه یا}} بوئه",
- "category-article-count": "{{جمی:$2|ای دسه ده ور گرته بلگه نهاییه .| {{جمی:$1| بلگه هئ|$1 بلگیا هئن}} د ای دسه, خارج د $2 کل.}}",
+ "category-article-count": "{{جمی:$2|ای دسه ده ور گرته بلگه نهاییه .| {{جمی:$1| بلگه هئ|$1 بلگیا هئن}} د ای دسه, وه در $2 کل.}}",
"category-article-count-limited": "نها {{جمی:$1|بلگه هئ|$1بلگیا هئن}} د دسه ایسنی .",
"category-file-count": "{{جمی:$2|ای دسه فقط شامل فایل نهایی هئ file.| نهایی {{جمی:$1|فایل هئ|$1 فایلیا هئن}} د ای دسه, وه در د کل $2 .}}",
"category-file-count-limited": " {{جمی:$1|[جانیا هئ|1$جانیایا هئن}}نهایی هان د دسه ایسنی.",
"viewdeleted_short": "بوینیت {{[جمی:$1|یه گل ویرایشت پاکسا بیه|$1ویرایشتیا پاکسا بیه}}",
"protect": "پر و پیم بكيد",
"protect_change": "آلشت بكيد",
- "protectthispage": "ای بلگه نه حفاظت بكيد",
- "unprotect": "حمايت آلشت بكيد",
- "unprotectthispage": "حفاظت دی بلگه نه آلشت بكيد",
+ "protectthispage": "ای بلگه نه پر و پیم بكيد",
+ "unprotect": "پر و پیم کردن نه آلشت بکیت",
+ "unprotectthispage": "پر و پیم کردن د ای بلگه نه آلشت بكيد",
"newpage": "بلگه نو",
"talkpage": "دباره ای بلگه قصه بكيد",
- "talkpagelinktext": "وت و واچ",
+ "talkpagelinktext": "چک چنه",
"specialpage": "بلگه ويجه",
"personaltools": "اوزاريا شصقی",
- "articlepage": "ديئن محتوا بلگه",
+ "articlepage": "ديئن مینونه بلگه",
"talk": "گپ",
"views": "ديئنيا",
"toolbox": "اوزاريا",
"projectpage": "ديئن بلگه پروجه",
"imagepage": "ديئن بلگه جانیا",
"mediawikipage": "ديئن بلگه پيغوم",
- "templatepage": "ديئن بلگه قالو",
+ "templatepage": "ديئن بلگه چوئه",
"viewhelppage": "ديئن بلگه هومياری",
"categorypage": "ديئن بلگه دسه بنی",
"viewtalkpage": "ديئن چك چنه يا",
"otherlanguages": "د زونيا هنی",
"redirectedfrom": "(ورگشتن د$1)",
- "redirectpagesub": "بلگه دوباره ورگشتن",
+ "redirectpagesub": "بلگه واگردونی",
"redirectto": "واگردونی سی:",
"lastmodifiedat": "ای بلگه تازه ايا وضع آلشت بيه د $1, د $2.",
"viewcount": "ای بلگه قاول دسترسی بيه {{PLURAL:$1|once|$1 times}}.",
"copyrightpage": "{{ان اس:پروجه}}:کپی رایت",
"currentevents": "پيشومدل تازه باو",
"currentevents-url": "پروجه:پيشومدل تازه باو",
- "disclaimers": "منکریا",
+ "disclaimers": "کذو کننه یا",
"disclaimerpage": "پروجه:منكر بيئن كاروريا",
"edithelp": "هومياری سی ويرايشت",
"mainpage": "سرآسونه",
"portal": "درآسونه کومله یکی",
"portal-url": "پروجه:سرآسونه کومله یکی",
"privacy": "رهبرد رازداری",
- "privacypage": "پروجه: خط مشی راز واداشتن",
- "badaccess": "خطا :اجازÙ\87 بئÛ\8cر",
- "badaccess-group0": "Ø´Ù\85ا اجازÙ\87 انجوم کاری که حاستیت نارین",
- "badaccess-groups": "ای کاری که شما هاستیته سی کاریاریا د {{جمی:$2|گرو|یکی د گرویا}}: $1 مئدود بیه",
- "versionrequired": "یه نسقه د نیازمنیا ویکی وارسگر\n$1",
- "versionrequiredtext": "نسقه $1 ویکی وارسگر سی وه کار گرتن د ای بلگه لازم هئی .\nوه نه بوینیت [[ویجه:نسقه|نسقه بلگه]].",
+ "privacypage": "پروجه: خط مشی رازینه کاری کردن",
+ "badaccess": "خطا :صÙ\84ادارÛ\8c Ú©Ù\88",
+ "badaccess-group0": "Ø´Ù\85ا صÙ\84ا انجوم کاری که حاستیت نارین",
+ "badaccess-groups": "ای کاری که شما هاستیته سی کاریاریا د {{جمی:$2|گرو|یکی د گرویا}}: $1 کم بیه",
+ "versionrequired": "یه نسقه د حاستنیا ویکی وارسگر\n$1",
+ "versionrequiredtext": "نسقه $1 ویکی وارسگر سی وه کار گرتن د ای بلگه لازمه.\nوه نه بوینیت [[ویجه:نسقه|نسقه بلگه]].",
"ok": "خوئه",
"pagetitle": "$1 - {{SITENAME}}",
"pagetitle-view-mainpage": "{{SITENAME}}",
"retrievedfrom": "بازيافته د\"$1\"",
"youhavenewmessages": "شما داريت $1($2)",
"youhavenewmessagesfromusers": "{{جمی:$4|شما }} $1 د {{جمی:$3|کاریار هنی|$3 کاریاریا}}داریتو($2).",
- "youhavenewmessagesmanyusers": "شما $1 د خيلی کاریار داريت ($2).",
+ "youhavenewmessagesmanyusers": "شما $1 د فره کاریار داريت ($2).",
"newmessageslinkplural": "{{جمی:$1|یه گل پیغوم تازه|999=پیغوم ئل تازه}}",
"newmessagesdifflinkplural": "آخر {{جمی:$1|آلشت|آلشتیا}}",
"youhavenewmessagesmulti": "شما یه گل پیغوم تازه د $1 داریتو",
"viewsourceold": "سرچشمه نه بوينيت",
"editlink": "ويرايشت",
"viewsourcelink": "سرچشمه نه بوينيت",
- "editsectionhint": "ويرايشت يه بشق:$1",
+ "editsectionhint": "ويرايشت يه گل بهرجا:$1",
"toc": "مینونه یا",
"showtoc": "نشو دئن",
"hidetoc": "قام كردن",
"viewdeleted": "دیئن$1?",
"restorelink": "{{جمی:$1|یه گل ویرایشت پاک بیه|$1 ویرایشتیا پاک بیه}}",
"feedlinks": "خورحو:",
- "feed-invalid": "نوع مشترک بین خورحو نامعتور",
- "feed-unavailable": "خور حونیا د دسرس نئین",
- "site-rss-feed": "خورخو RSS سی $1",
- "site-atom-feed": "خور حون Atom سی $1",
- "page-rss-feed": "خورحو RSS سی «$1»",
- "page-atom-feed": "خور حون Atom سی $1",
+ "feed-invalid": "نوع مشترک بین هوال حون نامعتور",
+ "feed-unavailable": "هوال حونیا د دسرس نئین",
+ "site-rss-feed": "هوال حون RSS سی $1",
+ "site-atom-feed": "هوال حون Atom سی $1",
+ "page-rss-feed": "هوال حون RSS سی «$1»",
+ "page-atom-feed": "هوال حون Atom سی $1",
"feed-atom": "اتم",
"feed-rss": "آر اس اس",
"red-link-title": "$1(بلگه وجود ناره)",
- "sort-descending": "كم بيئن منظم",
- "sort-ascending": "زياد بيئن منظم",
+ "sort-descending": "كم بيئن سرجاخود",
+ "sort-ascending": "زياد بيئن سرجاخود",
"nstab-main": "بلگه",
"nstab-user": "بلگه کاریار",
- "nstab-media": "بلگه رسانه",
+ "nstab-media": "بلگه وارسگر",
"nstab-special": "بلگيا ويجه",
"nstab-project": "بلگه پروجه",
"nstab-image": "جانیا",
"nstab-help": "بلگه هومياری",
"nstab-category": "دسه",
"nosuchaction": "چنو كاری وجود ناره",
- "nosuchactiontext": "کارÛ\8c Ú©Ù\87 Ù\88ا Û\8cÙ\88 آر اÙ\84 Ù\85Ø´Ù\82ص بÛ\8cÙ\87 Ù\85عتÙ\88ر Ù\86ئ.\nشاÛ\8cت Ø´Ù\85ا Û\8cÙ\88 آر اÙ\84 Ù\86Ù\87 درÙ\88س Ù\86Ù\86شتÛ\8cتÙ\87Ø\8c Û\8cا Û\8cÙ\87 Ú¯Ù\84 Ù\87Ù\88Ù\85 Ù¾Û\8cÙ\88Ù\86د Ù\86ادرست Ù\88ارد بÛ\8cÙ\87.\nÙ\88Ù\87 شاÛ\8cد Ù\88Ù\87 Û\8cÙ\87 Ú¯Ù\84 باگ د Ù\86رÙ\85 اÙ\81زار استÙ\81اده بیه وا {{نوم مالگه}} هشاره داشتوه.",
+ "nosuchactiontext": "کارÛ\8c Ú©Ù\87 Ù\88ا Û\8cÙ\88 آر اÙ\84 Ù\85Ø´Ù\82ص بÛ\8cÙ\87 Ù\85عتÙ\88ر Ù\86ئ.\nشاÛ\8cت Ø´Ù\85ا Û\8cÙ\88 آر اÙ\84 Ù\86Ù\87 درÙ\88س Ù\86Ù\86شتÛ\8cتÙ\87Ø\8c Û\8cا Û\8cÙ\87 Ú¯Ù\84 Ù\87Ù\88Ù\85 Ù¾Û\8cÙ\88Ù\86د Ù\86ادرست Ù\88ارد بÛ\8cÙ\87.\nÙ\88Ù\87 شاÛ\8cد Ù\88Ù\87 Û\8cÙ\87 Ú¯Ù\84 سÛ\8cسرÛ\8cÚ© د Ù\86رÙ\85 اÙ\81زار Ù\88Ù\87 کار گرته بیه وا {{نوم مالگه}} هشاره داشتوه.",
"nosuchspecialpage": "چنو بلگه خاصی وجود ناره",
"nospecialpagetext": "<strong>شما سی یه گل بلگه نامعتور درحاست داشتیته.</strong>\nیه گل نوم گه سی اعتوار بلگه یا بوئه د [[ویجه:بلگه یا ویجه|{{رقم:بلگه یا ویجه}}]] پیدا با.",
"error": "خطا",
"databaseerror": "خطا د جاگه دونسمنيا",
"databaseerror-text": "یه خطا جست کردن د پایگا داده پیش اوما.یه ممکنه یه در کار ونن د نرم اوزار پیش بیاره",
- "databaseerror-textcl": "خطاجست گرتن پايگاه دونسمنيا پيشومد كرده",
+ "databaseerror-textcl": "خطاجست گرتن رسینه جا دونسمنيا پيشومد كرده",
"databaseerror-query": "نوم گشتن: $1",
"databaseerror-function": "تابع:$1",
"databaseerror-error": "خطا: $1",
- "laggedslavemode": "زÙ\86Ù\87ار:بÙ\84Ú¯Ù\87 شاÙ\8aت Ø´Ù\88Ù\85Ù\84 رÙ\88زاÙ\85دÙ\8aا تازه باو نبوئه",
+ "laggedslavemode": "زÙ\86Ù\87ار:بÙ\84Ú¯Ù\87 شاÙ\8aت د Ù\88ر گرÛ\8cÙ\86Ù\87 Ù\88Ù\87 Ù\87Ù\86Ú¯Ù\88Ù\85 سازÛ\8c تازه باو نبوئه",
"readonly": "جاگه دونسمنيا بسه بيه",
"enterlockreason": "دلیل قلف کردن نه بنیست،یه وختی سی وا کردن قلف د ویر داشتویت.",
"readonlytext": "پایگا دونسمنیا ایسه سی دئن ورودی یا تازه یا آلشتگریا هنی قلف بیه،شایت سی منن معمولی پایگا دونسمنی نها وه که ورئرده وه حالت عادیش.\nمدیری که ونه قلف کرده ونه گوته:$1",
"upload-curl-error28": "تموم بیئن مئلت سی سوار کرد",
"upload-curl-error28-text": "ای دیارگه فره دیر دتو واکنشت نشو دئه.\nلطف بکیت سی یه که دیارگه کنشگتر و ری خطه یه گل وارسی بکیت، اوسه یه گر واستید و هنی تلاش بکیت.\nشایت بیتر با که د گات خلوتری هنی تلاش بکیت.",
"license": "ليانس دار بيئن",
- "license-header": "د Ø´Ù\83ل ليسانس دار بيئن",
+ "license-header": "د ØاÙ\84 Ù\88بال ليسانس دار بيئن",
"nolicense": "هیچی انتخاو نبیه",
"licenses-edit": "گزینه یا مجوز ویرایشت",
"license-nopreview": "(پیش سیل د دسرس نئ)",
"unblocked-id": "قلف $1 ورداشته بیه.",
"unblocked-ip": "[[Special:Contributions/$1|$1]] رفع نهاگری بیه.",
"blocklist": "كاروريا منع بيه",
- "ipblocklist": "Ù\83ارÙ\88رÙ\8aا Ù\85Ù\86ع بÙ\8aه",
+ "ipblocklist": "Ù\83ارÙ\88رÙ\8aا Ù\86Ù\87اگرÛ\8c بÛ\8cه",
"ipblocklist-legend": "یه گل کارور منع بیه بجوریت",
"blocklist-userblocks": "قام کردن حساو قلف بیه",
"blocklist-tempblocks": "قام کردن نهاگرتنیا موقت",
"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Може да сте укажале грешна целна страница, или пак уредувате погрешна страница.\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": "Пребарување на извори за книга",
"thumbnail-temp-create": "Не можам да создадам привремена податотека на минијатурата",
"thumbnail-dest-create": "Не можам да ја зачувам минијатурата во одредницата",
"thumbnail_invalid_params": "Параметрите на минијатурата се погрешни",
+ "thumbnail_toobigimagearea": "Податотека со димензии поголеми од $1",
"thumbnail_dest_directory": "Целниот именик не може да се создаде",
"thumbnail_image-type": "Неподдржан тип на слика",
"thumbnail_gd-library": "Нецелосни поставки на графичката библиотека: недостасува функцијата $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",
"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"
}
"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é:",
"thumbnail-temp-create": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail-dest-create}}\n* {{msg-mw|Thumbnail invalid params}}\n* {{msg-mw|Thumbnail dest directory}}",
"thumbnail-dest-create": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail error}}\n* {{msg-mw|Thumbnail-temp-create}}\n* {{msg-mw|Thumbnail invalid params}}\n* {{msg-mw|Thumbnail dest directory}}",
"thumbnail_invalid_params": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail-temp-create}}\n* {{msg-mw|Thumbnail-dest-create}}\n* {{msg-mw|Thumbnail dest directory}}",
+ "thumbnail_toobigimagearea": "Used as thumbnail error message.\n\n* $1 - Size in pixel (see {{msg-mw|size-megapixel}} and friends)",
"thumbnail_dest_directory": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail error}}\n* {{msg-mw|Thumbnail-temp-create}}\n* {{msg-mw|Thumbnail-dest-create}}\n* {{msg-mw|Thumbnail invalid params}}",
"thumbnail_image-type": "This is the parameter 1 of the message {{msg-mw|thumbnail error}}",
"thumbnail_gd-library": "This is the parameter 1 of the message {{msg-mw|thumbnail error}}.\n*$1 is a function name of the GD library",
"size-exabytes": "{{optional}}\nSize (of a file, typically) in exbibytes (1 exbibytes = 1024×1024×1024×1024×1024×1024 bytes).",
"size-zetabytes": "{{optional}}\nSize (of a file, typically) in zebibytes (1 zebibytes = 1024×1024×1024×1024×1024×1024×1024 bytes).",
"size-yottabytes": "{{optional}}\nSize (of a file, typically) in yobibytes (1 yobibytes = 1024×1024×1024×1024×1024×1024×1024×1024 bytes).",
+ "size-pixel": "{{optional}}\nSize (of a file, typically) in pixel.",
+ "size-kilopixel": "{{optional}}\nSize (of a file, typically) in kilopixel (1 kilopixel = 1000 pixel).",
+ "size-megapixel": "{{optional}}\nSize (of a file, typically) in megapixel (1 megapixel = 1000×1000 pixel).",
+ "size-gigapixel": "{{optional}}\nSize (of a file, typically) in gigapixel (1 gigapixel = 1000×1000×1000 pixel).",
+ "size-terapixel": "{{optional}}\nSize (of a file, typically) in terapixel (1 terapixel = 1000×1000×1000×1000 pixel).",
+ "size-petapixel": "{{optional}}\nSize (of a file, typically) in petapixel (1 petapixel = 1000×1000×1000×1000×1000 pixel).",
+ "size-exapixel": "{{optional}}\nSize (of a file, typically) in exapixel (1 exapixel = 1000×1000×1000×1000×1000×1000 pixel).",
+ "size-zetapixel": "{{optional}}\nSize (of a file, typically) in zetapixel (1 zetapixel = 1000×1000×1000×1000×1000×1000×1000 pixel).",
+ "size-yottapixel": "{{optional}}\nSize (of a file, typically) in yottapixel (1 yottapixel = 1000×1000×1000×1000×1000×1000×1000×1000 pixel).",
"bitrate-bits": "{{optional}}\nBitrate (of a file, typically) in bits.",
"bitrate-kilobits": "{{optional}}\nBitrate (of a file, typically) in kilobits (1 kilobit = 1000 bits).",
"bitrate-megabits": "{{optional}}\nBitrate (of a file, typically) in megabits (1 megabits = 1000×1000 bits).",
"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": "Скрывать правки ботов из списка наблюдения",
"anoneditwarning": "<strong>Внимание!</strong> Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы <strong>[$1 войдёте]</strong> или <strong>[$2 создадите учётную запись]</strong>, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.",
"anonpreviewwarning": "''Вы не представились системе. Сохранение приведёт к записи вашего IP-адреса в историю изменений страницы.''",
"missingsummary": "'''Напоминание.''' Вы не дали краткого описания изменений. При повторном нажатии на кнопку «{{int:savearticle}}», ваши изменения будут сохранены без комментария.",
+ "selfredirect": "<strong>Внимание:</strong> Вы создаете перенаправление на ту же самую статью.\nЕсли Вы нажмёте кнопку «{{int:savearticle}}» ещё раз, перенаправление всё же будет создано.",
"missingcommenttext": "Пожалуйста, введите ниже ваше сообщение.",
"missingcommentheader": "'''Напоминание.''' Вы не указали тему/заголовок для этого комментария.\nПри повторном нажатии на кнопку «{{int:savearticle}}», ваша правка будет записана без заголовка.",
"summary-preview": "Описание будет:",
"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 {{PLURAL:$1|изменение|изменения|изменений}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|с последнего посещения}}",
"enhancedrc-history": "история",
"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:",
"thumbnail-temp-create": "Kunde inte skapa temporär miniatyrfil",
"thumbnail-dest-create": "Kunde inte spara miniatyr till destinationen",
"thumbnail_invalid_params": "Ogiltiga parametrar för miniatyrbilden",
+ "thumbnail_toobigimagearea": "Fil med dimensioner som är större än $1",
"thumbnail_dest_directory": "Kan inte skapa målkatalogen",
"thumbnail_image-type": "Bildtypen stöds inte",
"thumbnail_gd-library": "Inkomplett GD library konfigurering: saknar funktionen $1",
"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": "Опис буде:",
"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”的保护等级",
"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": "隱藏監視清單中機器人的編輯",
"projectpage": "檢視專案頁面",
"imagepage": "檢視檔案頁面",
"mediawikipage": "檢視訊息頁面",
- "templatepage": "檢è¦\96樣板頁面",
+ "templatepage": "檢è¦\96模板頁面",
"viewhelppage": "檢視說明頁面",
"categorypage": "檢視分類頁面",
"viewtalkpage": "檢視討論頁面",
"generic-pool-error": "抱歉,太多使用者正嘗試檢視此資源,伺服器超出負荷。\n請稍候片刻再嘗試。",
"pool-timeout": "正在等待取消鎖定",
"pool-queuefull": "程序序列已滿",
- "pool-errorunknown": "未知錯誤",
+ "pool-errorunknown": "不明錯誤",
"pool-servererror": "無法使用程序計數服務 ($1)。",
"aboutsite": "關於 {{SITENAME}}",
"aboutpage": "Project:About",
"nstab-project": "專案頁面",
"nstab-image": "檔案",
"nstab-mediawiki": "訊息",
- "nstab-template": "樣板",
+ "nstab-template": "模板",
"nstab-help": "說明頁面",
"nstab-category": "分類",
"nosuchaction": "無此動作",
"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": "æ¤é \81é\9d¢ä½¿ç\94¨äº\86以ä¸\8b{{PLURAL:$1|樣ç\89\88}}:",
- "templatesusedpreview": "æ¤é \90覽使ç\94¨äº\86以ä¸\8b{{PLURAL:$1|樣板}}:",
- "templatesusedsection": "此頁面使用了以下{{PLURAL:$1|樣版}}:",
+ "templatesused": "æ¤é \81é\9d¢ä½¿ç\94¨äº\86以ä¸\8b{{PLURAL:$1|模æ\9d¿}}:",
+ "templatesusedpreview": "æ¤é \90覽使ç\94¨äº\86以ä¸\8b{{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": "樣ç\89\88呼叫時使用重複的參數的頁面",
- "duplicate-args-category-desc": "該é \81é\9d¢å\8c\85å\90«é\87\8dè¤\87使ç\94¨å\8f\83æ\95¸ç\9a\84樣ç\89\88呼叫,如 <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> 或 <code><nowiki>{{foo|bar|1=baz}}</nowiki>。",
+ "duplicate-args-category": "模æ\9d¿呼叫時使用重複的參數的頁面",
+ "duplicate-args-category-desc": "該é \81é\9d¢å\8c\85å\90«é\87\8dè¤\87使ç\94¨å\8f\83æ\95¸ç\9a\84模æ\9d¿呼叫,如 <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>è¦å\91\8aï¼\9a</strong>å¼\95ç\94¨æ¨£æ\9d¿å¾\8c大å°\8fè¶\85å\87ºé\99\90å\88¶ã\80\82\né\83¨ä»½æ¨£板內容將不會被使用。",
- "post-expand-template-inclusion-category": "å¼\95ç\94¨æ¨£板後大小超出限制的頁面",
- "post-expand-template-argument-warning": "<strong>è¦å\91\8aï¼\9a</strong>æ¤é \81é\9d¢æ\9c\89ä¸\80å\80\8b以ä¸\8aç\9a\84樣ç\89\88參數過長。\n過長的參數會被直接忽略。",
- "post-expand-template-argument-category": "樣板參數有部份被忽略的頁面",
- "parser-template-loop-warning": "å\81µæ¸¬å\88°æ¨£板遞迴:[[$1]]",
- "parser-template-recursion-depth-warning": "è¶\85å\87ºæ¨£ç\89\88遞迴深度限制 ($1)",
+ "post-expand-template-inclusion-warning": "<strong>è¦å\91\8aï¼\9a</strong>å¼\95ç\94¨æ¨¡æ\9d¿å¾\8c大å°\8fè¶\85å\87ºé\99\90å\88¶ã\80\82\né\83¨ä»½æ¨¡板內容將不會被使用。",
+ "post-expand-template-inclusion-category": "å¼\95ç\94¨æ¨¡板後大小超出限制的頁面",
+ "post-expand-template-argument-warning": "<strong>è¦å\91\8aï¼\9a</strong>æ¤é \81é\9d¢æ\9c\89ä¸\80å\80\8b以ä¸\8aç\9a\84模æ\9d¿參數過長。\n過長的參數會被直接忽略。",
+ "post-expand-template-argument-category": "模板參數有部份被忽略的頁面",
+ "parser-template-loop-warning": "å\81µæ¸¬å\88°æ¨¡板遞迴:[[$1]]",
+ "parser-template-recursion-depth-warning": "è¶\85å\87ºæ¨¡æ\9d¿遞迴深度限制 ($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": "(符合檔案內容)",
"listduplicatedfiles": "重複檔案清單",
"listduplicatedfiles-summary": "此清單中包含最新版本的檔案與其他檔案重複的清單,本清單只顯示本地檔案。",
"listduplicatedfiles-entry": "[[:File:$1|$1]] 有[[$3|其他 $2 個重複檔案]]。",
- "unusedtemplates": "æ\9cªä½¿ç\94¨ç\9a\84樣板",
- "unusedtemplatestext": "æ¤é \81é\9d¢å\88\97å\87ºæ\89\80æ\9c\89æ\96¼ {{ns:template}} å\91½å\90\8d空é\96\93ä¸\8bæ\9cªè¢«å\85¶ä»\96é \81é\9d¢å¼\95ç\94¨ç\9a\84樣ç\89\88ã\80\82\nå\9c¨å\88ªé\99¤å\89\8dï¼\8cä»\8dé\9c\80檢æ\9f¥æ\98¯å\90¦æ\9c\89é\80£çµ\90é\80\99äº\9b樣ç\89\88的其他頁面。",
+ "unusedtemplates": "æ\9cªä½¿ç\94¨ç\9a\84模板",
+ "unusedtemplatestext": "æ¤é \81é\9d¢å\88\97å\87ºæ\89\80æ\9c\89æ\96¼ {{ns:template}} å\91½å\90\8d空é\96\93ä¸\8bæ\9cªè¢«å\85¶ä»\96é \81é\9d¢å¼\95ç\94¨ç\9a\84模æ\9d¿ã\80\82\nå\9c¨å\88ªé\99¤å\89\8dï¼\8cä»\8dé\9c\80檢æ\9f¥æ\98¯å\90¦æ\9c\89é\80£çµ\90é\80\99äº\9b模æ\9d¿的其他頁面。",
"unusedtemplateswlh": "其他連結",
"randompage": "隨機頁面",
"randompage-nopages": "在{{PLURAL:$2|命名空間}}中沒有任何頁面:$1。",
"uncategorizedpages": "未分類的頁面",
"uncategorizedcategories": "未分類的分類",
"uncategorizedimages": "未分類的檔案",
- "uncategorizedtemplates": "å¾\85å\88\86é¡\9e樣ç\89\88",
+ "uncategorizedtemplates": "å¾\85å\88\86é¡\9e模æ\9d¿",
"unusedcategories": "未使用的分類",
"unusedimages": "未使用的檔案",
"wantedcategories": "需要的分類",
"wantedfiletext-cat-noforeign": "下列檔案已被使用但不存在。 除此之外,頁面已內嵌但不存在的檔案列於 [[:$1]]。",
"wantedfiletext-nocat": "下列檔案被時用,但檔案不存在。 外部儲存庫的檔案儘管存在,但此清單仍會列出。 這類誤報的項目會以 <del>刪除線</del> 標示。",
"wantedfiletext-nocat-noforeign": "下列檔案已被使用但不存在。",
- "wantedtemplates": "é\9c\80è¦\81ç\9a\84樣ç\89\88",
+ "wantedtemplates": "é\9c\80è¦\81ç\9a\84模æ\9d¿",
"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": "å±\95é\96\8b樣ç\89\88å¾\8c大å°\8fè¶\85é\81\8e <code>$wgMaxArticleSize</code> å°\8eè\87´é\83¨ä»½æ¨£ç\89\88未正常展開的頁面。",
- "post-expand-template-argument-category-desc": "å±\95é\96\8b樣ç\89\88參數後大小超過 <code>$wgMaxArticleSize</code> 的頁面 (有些於三括號中,如 <code>{{{Foo}}}</code>)。",
+ "post-expand-template-inclusion-category-desc": "å±\95é\96\8b模æ\9d¿å¾\8c大å°\8fè¶\85é\81\8e <code>$wgMaxArticleSize</code> å°\8eè\87´é\83¨ä»½æ¨¡æ\9d¿未正常展開的頁面。",
+ "post-expand-template-argument-category-desc": "å±\95é\96\8b模æ\9d¿參數後大小超過 <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 檔案連結",
"expiringblock": "$1 $2 到期",
"anononlyblock": "限匿名使用者",
"noautoblockblock": "停用自動封鎖",
- "createaccountblock": "å\81\9cç\94¨å¸³è\99\9f建ç«\8b",
+ "createaccountblock": "帳è\99\9f建ç«\8bå\81\9cç\94¨",
"emailblock": "停用電子郵件",
"blocklist-nousertalk": "無法編輯自己的對話頁面",
"ipblocklist-empty": "封鎖清單無任何資訊。",
"export-addnstext": "使用命名空間新增頁面:",
"export-addns": "新增",
"export-download": "儲存為檔案",
- "export-templates": "å\8c\85å\90«æ¨£板",
+ "export-templates": "å\8c\85å\90«æ¨¡板",
"export-pagelinks": "包含連結的頁面深度:",
"allmessages": "系統訊息",
"allmessagesname": "名稱",
"import-interwiki-sourcewiki": "來源 Wiki:",
"import-interwiki-sourcepage": "來源頁面:",
"import-interwiki-history": "複製此頁的所有歷史修訂",
- "import-interwiki-templates": "å\8c\85å\90«æ\89\80æ\9c\89樣板",
+ "import-interwiki-templates": "å\8c\85å\90«æ\89\80æ\9c\89模板",
"import-interwiki-submit": "匯入",
"import-interwiki-namespace": "目標命名空間:",
"import-interwiki-rootpage": "目標根頁面 (選填):",
"tooltip-search": "搜尋 {{SITENAME}}",
"tooltip-search-go": "若與此名稱相符的頁面存在,前往該頁面",
"tooltip-search-fulltext": "搜尋使用此文字的頁面",
- "tooltip-p-logo": "前往主頁面",
- "tooltip-n-mainpage": "前往主頁面",
- "tooltip-n-mainpage-description": "前往主頁面",
+ "tooltip-p-logo": "前往主頁",
+ "tooltip-n-mainpage": "前往主頁",
+ "tooltip-n-mainpage-description": "前往主頁",
"tooltip-n-portal": "關於本專案、您可以做什麼、哪裡可以找到您需要的事物",
"tooltip-n-currentevents": "於最新動態中尋找背景資訊",
"tooltip-n-recentchanges": "列出此 Wiki 中的近期變更清單",
"tooltip-ca-nstab-project": "檢視專案頁面",
"tooltip-ca-nstab-image": "檢視檔案頁面",
"tooltip-ca-nstab-mediawiki": "檢視系統訊息",
- "tooltip-ca-nstab-template": "檢è¦\96樣板",
+ "tooltip-ca-nstab-template": "檢è¦\96模板",
"tooltip-ca-nstab-help": "檢視說明頁面",
"tooltip-ca-nstab-category": "檢視分類頁面",
"tooltip-minoredit": "標記為小修訂",
"pageinfo-recent-authors": "最近作者數",
"pageinfo-magic-words": "魔術{{PLURAL:$1|字}} ($1)",
"pageinfo-hidden-categories": "隱藏分類 ($1)",
- "pageinfo-templates": "å¼\95ç\94¨æ¨£ç\89\88 ($1)",
+ "pageinfo-templates": "å¼\95ç\94¨æ¨¡æ\9d¿ ï¼\88$1ï¼\89",
"pageinfo-transclusions": "頁面被引用於 ($1)",
"pageinfo-toolboxlink": "頁面資訊",
"pageinfo-redirectsto": "重新導向至",
"exif-datetimemetadata": "資料定義最後修改日期",
"exif-nickname": "非正式的影像名稱",
"exif-rating": "評分 (共 5 分)",
- "exif-rightscertificate": "版權管理證書",
+ "exif-rightscertificate": "版權管理憑證",
"exif-copyrighted": "版權狀態",
"exif-copyrightowner": "版權所有人",
"exif-usageterms": "使用條款",
"confirmemail_invalidated": "已取消電子郵件位址確認",
"invalidateemail": "取消電子郵件確認",
"scarytranscludedisabled": "[Interwiki 轉換代碼不可用]",
- "scarytranscludefailed": "[樣板 $1 讀取失敗]",
- "scarytranscludefailed-httpstatus": "[樣板 $1 讀取失敗:HTTP $2]",
+ "scarytranscludefailed": "[模板 $1 讀取失敗]",
+ "scarytranscludefailed-httpstatus": "[模板 $1 讀取失敗:HTTP $2]",
"scarytranscludetoolong": "[URL 過長]",
"deletedwhileediting": "<strong>警告:</strong>此頁在您開始編輯之後已經被刪除﹗",
"confirmrecreate": "在您編輯的同時,使用者 [[User:$1|$1]] ([[User talk:$1|對話]]) 刪除了此頁面,原因為:\n: <em>$2</em>\n請確認您是否真的要重新建立此頁面。",
"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-ppgeneratednodes": "預處理器產生節點次數",
"limitreport-postexpandincludesize": "展開後的引用大小",
"limitreport-postexpandincludesize-value": "$1/$2 個{{PLURAL:$2|位元組}}",
- "limitreport-templateargumentsize": "樣板參數大小",
+ "limitreport-templateargumentsize": "模板參數大小",
"limitreport-templateargumentsize-value": "$1/$2 個{{PLURAL:$2|位元組}}",
"limitreport-expansiondepth": "最高展開深度",
"limitreport-expensivefunctioncount": "高消耗解析器函數次數",
- "expandtemplates": "å±\95é\96\8b樣板",
- "expand_templates_intro": "æ\9c¬ç\89¹æ®\8aé \81é\9d¢æ\9c\83å°\87æ\96\87å\97ä¸ç\9a\84樣ç\89\88展開,可以包含支援的解析器語法,如 <code><nowiki>{{</nowiki>#language:…}}</code> 與變數如 <code><nowiki>{{</nowiki>CURRENTDAY}}</code>。\n實際上,絕大部分在雙括號中的內容都會被展開。",
+ "expandtemplates": "å±\95é\96\8b模板",
+ "expand_templates_intro": "æ\9c¬ç\89¹æ®\8aé \81é\9d¢æ\9c\83å°\87æ\96\87å\97ä¸ç\9a\84模æ\9d¿展開,可以包含支援的解析器語法,如 <code><nowiki>{{</nowiki>#language:…}}</code> 與變數如 <code><nowiki>{{</nowiki>CURRENTDAY}}</code>。\n實際上,絕大部分在雙括號中的內容都會被展開。",
"expand_templates_title": "上下文標題,用於 {{FULLPAGENAME}} 等:",
"expand_templates_input": "輸入文字:",
"expand_templates_output": "結果",
'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 ) {
*/
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" );
'zh-cn' => 'resources/lib/moment/locale/zh-cn.js',
'zh-tw' => 'resources/lib/moment/locale/zh-tw.js',
),
+ 'targets' => array( 'desktop', 'mobile' ),
),
/* MediaWiki */
'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.4.0
+ * 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-06T00:33:19Z
+ * 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');
.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.4.0
+ * 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-06T00:33:09Z
+ * Date: 2014-12-12T20:13:09Z
*/
/* Instantiation */
/*!
- * OOjs UI v0.4.0
+ * 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-06T00:33:19Z
+ * 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');
.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.4.0
+ * 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-06T00:33:19Z
+ * 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 {
.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-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-checkboxInputWidget input[type="checkbox"]:active + span::after,
-.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span::after {
+.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-checkboxInputWidget input[type="checkbox"]:disabled + span::before {
+.oo-ui-radioInputWidget input[type="radio"]:checked + span::before {
+ background-size: 100% 100%;
+}
+.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: lightgrey;
+ background-color: #eeeeee;
+ border-color: #eeeeee;
+}
+.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.4.0
+ * 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-06T00:33:09Z
+ * 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.4.0
+ * 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-06T00:33:19Z
+ * 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 {
.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-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-checkboxInputWidget input[type="checkbox"]:disabled + span::before {
+.oo-ui-radioInputWidget input[type="radio"]:checked + span::before {
+ background-size: 100% 100%;
+}
+.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: lightgrey;
+ background-color: #eeeeee;
+ border-color: #eeeeee;
+}
+.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.4.0
+ * 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-06T00:33:09Z
+ * Date: 2014-12-12T20:13:09Z
*/
( function ( OO ) {
}
};
+/**
+ * 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.
*
}
while ( $parent.length ) {
- if ( $parent[0] === el.ownerDocument.body ) {
+ if ( $parent[0] === this.getRootScrollableElement( el ) ) {
return $parent[0];
}
i = props.length;
$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,
* @return {HTMLDocument} Document object
*/
OO.ui.Element.prototype.getElementDocument = function () {
+ // 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 );
};
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 );
OO.ui.Dialog.prototype.onDocumentKeyDown = function ( e ) {
if ( e.which === OO.ui.Keys.ESCAPE ) {
this.close();
- return false;
+ e.preventDefault();
+ e.stopPropagation();
}
};
this.$button
.removeClass( 'oo-ui-buttonElement-button' )
.removeAttr( 'role accesskey tabindex' )
- .off( this.onMouseDownHandler );
+ .off( 'mousedown', this.onMouseDownHandler );
}
this.$button = $button
*
* @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.$clippableScroller = this.$clippableContainer.is( 'html, body' ) ?
this.$( OO.ui.Element.static.getWindow( this.$clippableContainer ) ) :
this.$clippableContainer;
this.$clippableScroller.on( 'scroll', this.onClippableContainerScrollHandler );
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,
* @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.static.getDir( this.$.context ) === 'rtl' ) {
- dimensions.right = Math.round( left * 100 ) + '%';
+ 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 {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
--- /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
$.each( $steps, function ( i, step ) {
var $step = $( step );
if ( $step.is( selector ) ) {
- if ($previous) {
+ if ( $previous ) {
$previous.addClass( 'tail' );
}
$step.addClass( 'head' );
// Store the context for next time
$( this ).data( 'expandableField-context', context );
} );
- return returnValue !== undefined ? returnValue : $(this);
+ return returnValue !== undefined ? returnValue : $( this );
};
}( jQuery ) );
match;
if ( typeof srcset === 'string' && srcset !== '' ) {
match = $.matchSrcSet( devicePixelRatio, srcset );
- if (match !== null ) {
+ if ( match !== null ) {
$img.attr( 'src', match );
}
}
- });
+ } );
}
return $target;
* 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).
var util,
hasOwn = Object.prototype.hasOwnProperty,
- log = (window.console && window.console.log)
- ? function () { return window.console.log.apply(window.console, arguments); }
+ log = ( window.console && window.console.log )
+ ? function () { return window.console.log.apply( window.console, arguments ); }
: function () {};
// Simplified version of a few jQuery methods, except that they don't
// Restore warnings
mw.log.warn = warn;
warn = undefined;
- });
+ } );
QUnit.done( function () {
that.populateMissingTests();
var elItem = document.createElement( 'li' );
elItem.textContent = key;
elList.appendChild( elItem );
- });
+ } );
elFoot = document.createElement( 'p' );
elFoot.innerHTML = '<em>— CompletenessTest</em>';
util.each( style, function ( key, value ) {
elOutputWrapper.style[key] = value;
- });
+ } );
return elOutputWrapper;
}
if ( toolbar ) {
toolbar.insertBefore( testResults, toolbar.firstChild );
}
- });
+ } );
return this;
}
var ct = this;
util.each( ct.injectionTracker, function ( key ) {
ct.hasTest( key );
- });
+ } );
},
/**
*/
$.fn.firstTabIndex = function () {
var minTabIndex = null;
- $(this).find( '[tabindex]' ).each( function () {
- var tabIndex = parseInt( $(this).prop( 'tabindex' ), 10 );
+ $( this ).find( '[tabindex]' ).each( function () {
+ var tabIndex = parseInt( $( this ).prop( 'tabindex' ), 10 );
// In IE6/IE7 the above jQuery selector returns all elements,
// becuase it has a default value for tabIndex in IE6/IE7 of 0
// (rather than null/undefined). Therefore check "> 0" as well.
*/
$.fn.lastTabIndex = function () {
var maxTabIndex = null;
- $(this).find( '[tabindex]' ).each( function () {
- var tabIndex = parseInt( $(this).prop( 'tabindex' ), 10 );
+ $( this ).find( '[tabindex]' ).each( function () {
+ var tabIndex = parseInt( $( this ).prop( 'tabindex' ), 10 );
if ( tabIndex > 0 && !isNaN( tabIndex ) ) {
// Initial value
if ( maxTabIndex === null ) {
// as each header can span over multiple columns (using colspan=N),
// we have to bidirectionally map headers to their columns and columns to their headers
$tableHeaders.each( function ( headerIndex ) {
- $cell = $(this);
+ $cell = $( this );
columns = [];
for ( i = 0; i < this.colSpan; i++ ) {
headerIndex: headerIndex,
order: 0,
count: 0
- });
+ } );
if ( $cell.hasClass( config.unsortableClass ) ) {
$cell.data( 'sortDisabled', true );
s = config.sortList[j];
o = config.headerList[s[0]];
if ( isValueInArray( s[0], newSortList ) ) {
- $(o).data( 'count', s[1] + 1 );
+ $( o ).data( 'count', s[1] + 1 );
s[1] = $( o ).data( 'count' ) % 2;
}
}
newList = [];
$.each( response.parse.templates, function ( i, template ) {
li = $( '<li>' )
- .append( $('<a>')
+ .append( $( '<a>' )
.attr( {
'href': mw.util.getUrl( template['*'] ),
'class': ( template.exists !== undefined ? '' : 'new' )
*/
( 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
table.wikitable {
margin: 1em 0;
background-color: #f9f9f9;
- border: 1px #aaa solid;
+ border: 1px solid #aaa;
border-collapse: collapse;
color: black;
}
table.wikitable > tr > td,
table.wikitable > * > tr > th,
table.wikitable > * > tr > td {
- border: 1px #aaa solid;
+ border: 1px solid #aaa;
padding: 0.2em;
}
// Run a function after the window onload event is fired
mw.log.deprecate( win, 'addOnloadHook', function ( hookFunct ) {
if ( onloadFuncts ) {
- onloadFuncts.push(hookFunct);
+ onloadFuncts.push( hookFunct );
} else {
// If func queue is gone the event has happened already,
// run immediately instead of queueing.
if ( media ) {
l.media = media;
}
- document.getElementsByTagName('head')[0].appendChild( l );
+ document.getElementsByTagName( 'head' )[0].appendChild( l );
return l;
};
/**
* @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.
*
normalizeExtension = function ( extension ) {
// Remove only trailing space (that is removed by MW anyway)
- extension = extension.toLowerCase().replace(/\s*$/, '');
+ extension = extension.toLowerCase().replace( /\s*$/, '' );
return extension;
};
/**
* 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;
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 );
var check = checkCssHandles;
pending++;
return function () {
- if (check) {
+ if ( check ) {
pending--;
check();
check = undefined; // Revoke
// 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 );
}
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
* in the registry.
*/
getVersion: function ( module ) {
- if ( !registry[module] || registry[module].version === undefined ) {
+ if ( !hasOwn.call( registry, module ) || registry[module].version === undefined ) {
return null;
}
return formatVersionNumber( registry[module].version );
* in the registry.
*/
getState: function ( module ) {
- if ( !registry[module] || registry[module].state === undefined ) {
+ if ( !hasOwn.call( registry, module ) || registry[module].state === undefined ) {
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;
},
var compiledTemplate,
compilerName = this.getCompilerName( templateName );
- if (!compiledTemplates[moduleName]) {
+ if ( !compiledTemplates[moduleName] ) {
compiledTemplates[moduleName] = {};
}
* 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
mediawiki/skins$ ln -s ../../skins-trunk/FooBar
-Most skins are available through Git:
+The default skin Vector can be installed by cloning from Git:
+ git clone https://git.wikimedia.org/git/mediawiki/skins/Vector.git
+
+Other skins are also available:
https://gerrit.wikimedia.org/r/#/admin/projects/?filter=mediawiki%252Fskins%252F
https://git.wikimedia.org/project/mediawiki
$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 ),
);
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
*/
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 ) );
$file = new FakeDimensionFile( array( 4000, 4000 ) );
$handler = new BitmapHandler;
$params = array( 'width' => '3700' ); // Still bigger than max size.
- $this->assertEquals( 'TransformParameterError',
+ $this->assertEquals( 'TransformTooBigImageAreaError',
get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
}
$file->mustRender = true;
$handler = new BitmapHandler;
$params = array( 'width' => '5000' ); // Still bigger than max size.
- $this->assertEquals( 'TransformParameterError',
+ $this->assertEquals( 'TransformTooBigImageAreaError',
get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
}
$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;
}
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.
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: ""' );
} );
} );
+ 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;