+* (bug 14931) Default character set now set to 'utf8' when a new MySQL
+ database is created.
+* (bug 47191) Fixed "Column 'si_title' cannot be part of FULLTEXT index"
+ MySQL error when installing using the binary character set option.
+* (bug 45288) Support mysqli PHP extension
+* (bug 56707) Correct tooltip of "Next n results" on query special pages.
+* (bug 56770) mw.util.addPortletLink: Check length before access array index.
+
+=== API changes in 1.22 ===
+* (bug 25553) The JSON output formatter now leaves forward slashes unescaped
+ to improve human readability of URLs and similar strings. Also, a "utf8"
+ option is now provided to use UTF-8 encoding instead of hex escape codes
+ for most non-ASCII characters.
+* (bug 46626) xmldoublequote parameter was removed. Because of a bug, the
+ parameter has had no effect since MediaWiki 1.16, and so its removal is
+ unlikely to impact existing clients.
+* (bug 47216) action=query&meta=siteinfo&siprop=skins will now indicate which
+ skin is the default and which are unusable (e.g. listed in $wgSkipSkins).
+* (bug 25325) Added support for wlshow filtering (bots/anon/minor/patrolled)
+ to action=feedwatchlist.
+* WDDX formatted output will actually be formatted (and normal output will no
+ longer be), and will no longer choke on booleans.
+* action=opensearch no longer silently ignores the format parameter.
+* action=opensearch now supports format=jsonfm.
+* list=usercontribs&ucprop=ids will now include the parent revision id.
+* (bug 47219) Allow specifying change type of Wikipedia feed items
+* prop=imageinfo now allows setting iiurlheight without setting iiurlwidth
+* prop=info now adds the content model and page language of the title.
+* New upload log entries will now contain information on the relevant
+ image (sha1 and timestamp).
+* (bug 49239) action=parse now can parse in preview and section preview modes.
+* (bug 49259) action=patrol now accepts revision ids.
+* (bug 48129) list=blocks&bkip= now correctly handles IPv6 CIDR ranges and
+ honors $wgBlockCIDRLimit. Note any clients passing invalid values to bkip
+ will now receive an error, rather than the previous behavior listing all
+ user blocks.
+* (bug 48201) action=parse&text=foo now assumes wikitext if no title is given,
+ rather than using the content model of the page "API".
+* action=watch no longer silently ignores hook abort.
+* (bug 50785) action=purge with forcelinkupdate=1 no longer queues refreshLinks
+ jobs in the job queue for link table updates of pages that use the given page
+ as a template. Instead, forcerecursivelinkupdate=1 is introduced and should
+ be used if that behaviour is desirable.
+* The 'debugLog' property (enabled by $wgDebugToolbar) no longer sets the log
+ entry values through ApiResult::content but directly. This changes the JSON
+ output from an array of objects with content in '*' to an array of strings
+ with the content.
+* (bug 51342) prop=imageinfo iicontinue now contains the dbkey, not the text
+ version of the title.
+* (bug 52538) action=edit will now use empty text instead of the contents
+ of section 0 when passed prependtext or appendtext with section=new.
+* Support for the 'gettoken' parameter to action=block and action=unblock,
+ deprecated since 1.20, has been removed.
+* (bug 49090) Token-getting functions will fail when using jsonp callbacks.
+* (bug 52699) action=upload returns normalized file name on warning
+ "exists-normalized" instead of filename to be uploaded to.
+* (bug 53884) action=edit will now return an error when the specified section
+ does not exist in the page.
+* Added meta=filerepoinfo API module for getting information about foreign
+ file repositories, and related ForeignAPIRepo methods getInfo and getApiUrl.
+* The new query module list=allfileusages to enumerate file usages was added.
+
+=== Languages updated in 1.22 ===
+
+MediaWiki supports over 350 languages. Many localisations are updated
+regularly. Below only new and removed languages are listed, as well as
+changes to languages because of Bugzilla reports.
+
+* Batak Toba (bbc-latn) added.
+* (bug 46751) Made Buryat (Russia) (буряад) (bxr) fallback to Russian.
+
+=== Other changes in 1.22 ===
+* redirect.php was removed. It was unused.
+* ClickTracking integration was dropped from the mediaWiki.user.bucket
+ JavaScript function. The 'tracked' option is now ignored.
+* Event namespace used by jquery.makeCollapsible has been changed from
+ 'mw-collapse' to 'mw-collapsible' for consistency with the module name.
+* The Quickbar feature of the legacy skin model and the last remnants of it
+ throughout the code base have been removed.
+* Externaledit/externaldiff preference was removed. Very few users used this
+ feature, and improper configuration can actually prevent a user from editing
+* Calling Linker methods using a skin will now output deprecation warnings.
+* (bug 46680) "Return to" links are no longer tagged with rel="next".
+* HipHop compiler (hphpc) support was removed. HipHop VM support (hhvm) was
+ added.
+* A new Special:Redirect page was added, providing lookup by revision ID,
+ user ID, or file name. The old Special:Filepath page was reimplemented
+ to redirect through Special:Redirect.
+* Monobook: Removed the old conditional stylesheets for Opera 6, 7 and 9.
+* Support for XHTML 1.0 has been removed. MediaWiki now only outputs (X)HTML5.
+* wikibits: User-agent related globals have been deprecated. The following
+ properties now default to false and emit mw.log.warn: is_gecko, is_chrome_mac,
+ is_chrome, webkit_version, is_safari_win, is_safari, webkit_match, is_ff2,
+ ff2_bugs, is_ff2_win, is_ff2_x11, opera95_bugs, opera7_bugs, opera6_bugs,
+ is_opera_95, is_opera_preseven, is_opera, and ie6_bugs.
+* (bug 48276) MediaWiki will now flash a confirmation message upon successfully
+ editing a page.
+* (bug 40785) mediawiki.legacy.ajax has been marked as deprecated. The following
+ properties now emit mw.log.warn when accessed: sajax_debug, sajax_init_object,
+ sajax_do_call and wfSupportsAjax.
+* Methods Title::userCanEditCssSubpage and Title::userCanEditJsSubpage,
+ deprecated since 1.19, have been removed.
+* (bug 50134) Hook functions are no longer required to return a value. When a
+ hook function does not return a value (or when it returns an explicit null),
+ processing continues. To abort the hook, a hook function must return an
+ explicit, boolean false or a string error message. Other falsey values are
+ tantamount to a 'return true' in earlier versions of MediaWiki.
+* (bug 48256) The 'editsection-brackets' optional message was removed.
+ Section edit links' brackets can now be customized using CSS by
+ styling span.mw-editsection-bracket.
+* The usePatrol function in ChangesList has been marked as deprecated.
+* (bug 50785) A "null edit", that is, a save action in which no changes to the
+ page text are made and no revision recorded, will no longer send refreshLinks
+ jobs to the job table to update pages which use the edited page as a template.
+* The LivePreviewPrepare and LivePreviewDone events triggered on "jQuery( mw )"
+ have been deprecated in favour of using mw.hook.
+* The 'showjumplinks' user preference has been removed, jump links are now
+ always included.
+* Methods RecentChange::notifyRC2UDP, RecentChange::sendToUDP, and
+ RecentChange::cleanupForIRC have been deprecated, as it is now the
+ responsibility of classes implementing the RCFeedFormatter and RCFeedEngine
+ interfaces to implement the formatting and delivery for recent change
+ notifications.
+* SpecialPrefixindex methods namespacePrefixForm() and showPrefixChunk() have
+ been made protected. They were accepting form variance arguments, this is now
+ using properties in the SpecialPrefixindex class.
+* (bug 49629) The hook ExtractThumbParamaters 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.
+* SpecialRecentChanges::addRecentChangesJS() function has been renamed
+ to addModules() and made protected.
+* Methods WatchAction::doWatch and WatchAction::doUnwatch now return a Status
+ object instead of a boolean.
+* Information boxes (CSS classes errorbox, warningbox, successbox) have been
+ made more subtle.
+* Code specific to the Math extension was marked as deprecated.
+* mediawiki.util: mw.util.wikiGetlink has been renamed to getUrl. (The old name
+ still works, but is deprecated.)
+
+== Compatibility ==
+
+MediaWiki 1.22 requires PHP 5.3.2 or later.
+
+MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
+support for them is somewhat less mature. There is experimental support for
+Oracle.
+
+The supported versions are:
+
+* MySQL 5.0.2 or later
+* PostgreSQL 8.3 or later
+* SQLite 3.3.7 or later
+* Oracle 9.0.1 or later
+
+== Upgrading ==
+
+1.22 has several database changes since 1.21, and will not work without schema
+updates. Note that due to changes to some very large tables like the revision
+table, the schema update may take quite long (minutes on a medium sized site,
+many hours on a large site).
+
+If upgrading from before 1.11, and you are using a wiki as a commons
+repository, make sure that it is updated as well. Otherwise, errors may arise
+due to database schema changes.
+
+If upgrading from before 1.7, you may want to run refreshLinks.php to ensure
+new database fields are filled with data.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, you should upgrade to
+1.5 first. The upgrade script maintenance/upgrade1_5.php has been removed
+with MediaWiki 1.21.
+
+Don't forget to always back up your database before upgrading!
+
+See the file UPGRADE for more detailed upgrade instructions.
+
+For notes on 1.21.x and older releases, see HISTORY.
+
+== Online documentation ==
+
+Documentation for both end-users and site administrators is available on
+MediaWiki.org, and is covered under the GNU Free Documentation License (except
+for pages that explicitly state that their contents are in the public domain):
+
+ https://www.mediawiki.org/wiki/Documentation
+
+== Mailing list ==
+
+A mailing list is available for MediaWiki user support and discussion:
+
+ https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
+
+A low-traffic announcements-only list is also available:
+
+ https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
+
+It's highly recommended that you sign up for one of these lists if you're
+going to run a public MediaWiki, so you can be notified of security fixes.
+
+== IRC help ==
+
+There's usually someone online in #mediawiki on irc.freenode.net.
diff --git a/UPGRADE b/UPGRADE
index 7987b221..96b58361 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -296,18 +296,3 @@ If you have a very old database (earlier than organized MediaWiki releases
in late August 2003) you may need to manually run some of the update SQL
scripts in maintenance/archives before the installer is able to pick up
with remaining updates.
-
-
-== Upgrading from UseModWiki or old "phase 2" Wikipedia code ==
-
-There is a semi-maintained UseModWiki to MediaWiki conversion script at
-maintenance/importUseModWiki.php; it may require tweaking and customization
-to work for you.
-
-Install a new MediaWiki first, then use the conversion script which will
-output SQL statements; direct these to a file and then run that into your
-database.
-
-You will have to rebuild the links tables etc after importing.
-
-
diff --git a/api.php b/api.php
index bc902297..8fab878c 100644
--- a/api.php
+++ b/api.php
@@ -36,16 +36,12 @@ define( 'MW_API', true );
// Bail if PHP is too low
if ( !function_exists( 'version_compare' ) || version_compare( phpversion(), '5.3.2' ) < 0 ) {
// We need to use dirname( __FILE__ ) here cause __DIR__ is PHP5.3+
- require( dirname( __FILE__ ) . '/includes/PHPVersionError.php' );
+ require dirname( __FILE__ ) . '/includes/PHPVersionError.php';
wfPHPVersionError( 'api.php' );
}
// Initialise common code.
-if ( isset( $_SERVER['MW_COMPILED'] ) ) {
- require ( 'core/includes/WebStart.php' );
-} else {
- require ( __DIR__ . '/includes/WebStart.php' );
-}
+require __DIR__ . '/includes/WebStart.php';
wfProfileIn( 'api.php' );
$starttime = microtime( true );
@@ -58,8 +54,8 @@ if ( !$wgRequest->checkUrlExtension() ) {
// Verify that the API has not been disabled
if ( !$wgEnableAPI ) {
header( $_SERVER['SERVER_PROTOCOL'] . ' 500 MediaWiki configuration Error', true, 500 );
- echo( 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php'
- . '
$wgEnableAPI=true;
' );
+ echo 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php'
+ . '
$wgEnableAPI=true;
';
die( 1 );
}
diff --git a/composer-example.json b/composer-example.json
new file mode 100644
index 00000000..6c4d37f5
--- /dev/null
+++ b/composer-example.json
@@ -0,0 +1,11 @@
+{
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "suggest": {
+ "ext-fileinfo": "*",
+ "ext-mbstring": "*",
+ "ext-wikidiff2": "*",
+ "ext-apc": "*"
+ }
+}
diff --git a/composer.json b/composer.json
deleted file mode 100644
index ded33652..00000000
--- a/composer.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "mediawiki/core",
- "description": "Free software wiki application developed by the Wikimedia Foundation and others",
- "keywords": ["mediawiki", "wiki"],
- "homepage": "https://www.mediawiki.org/",
- "authors": [
- {
- "name": "MediaWiki Community",
- "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits"
- }
- ],
- "license": "GPL-2.0",
- "support": {
- "issues": "https://bugzilla.wikimedia.org/",
- "irc": "irc://irc.freenode.net/mediawiki",
- "wiki": "https://www.mediawiki.org/"
- },
- "require": {
- "php": ">=5.3.2"
- },
- "require-dev": {
- "phpunit/phpunit": "*"
- },
- "suggest": {
- "ext-fileinfo": "*",
- "ext-mbstring": "*",
- "ext-wikidiff2": "*",
- "ext-apc": "*"
- }
-}
diff --git a/docs/hooks.txt b/docs/hooks.txt
index d4a1c909..5aaf5961 100644
--- a/docs/hooks.txt
+++ b/docs/hooks.txt
@@ -120,7 +120,7 @@ If the code is well enough isolated, it can even be excluded when not used --
making for some slight savings in memory and load-up performance at runtime.
Admins who want to have all the reversed titles can add:
- require_once('extensions/ReverseTitle.php');
+ require_once 'extensions/ReverseTitle.php';
...to their LocalSettings.php file; those of us who don't want or need it can
just leave it out.
@@ -270,6 +270,10 @@ $reason: the reason for the move (added in 1.13)
$user: the User object about to be created (read-only, incomplete)
&$msg: out parameter: HTML to display on abort
+'AbortTalkPageEmailNotification': Return false to cancel talk page email notification
+$targetUser: the user whom to send talk page email notification
+$title: the page title
+
'AbortChangePassword': Return false to cancel password change.
$user: the User object to which the password change is occuring
$mOldpass: the old password provided by the user
@@ -377,6 +381,11 @@ result.
&$module: ApiBase Module object
&$properties: Array of properties
+'APIGetPossibleErrors': Use this hook to modify the module's list of possible
+errors.
+$module: ApiBase Module object
+&$possibleErrors: Array of possible errors
+
'APIQueryAfterExecute': After calling the execute() method of an
action=query submodule. Use this to extend core API modules.
&$module: Module object
@@ -423,6 +432,10 @@ sites general information.
$module: the current ApiQuerySiteInfo module
&$results: array of results, add things here
+'APIQuerySiteInfoStatisticsInfo': Use this hook to add extra information to the
+sites statistics information.
+&$results: array of results, add things here
+
'APIQueryUsersTokens': Use this hook to add custom token to list=users. Every
token has an action, which will be used in the ustoken parameter and in the
output (actiontoken="..."), and a callback function which should return the
@@ -488,7 +501,8 @@ $logEntry: the ManualLogEntry used to record the deletion
'ArticleEditUpdateNewTalk': Before updating user_newtalk when a user talk page
was changed.
-$wikiPage: WikiPage (object) of the user talk page
+&$wikiPage: WikiPage (object) of the user talk page
+$recipient: User (object) who's talk page was edited
'ArticleEditUpdates': When edit updates (mainly link tracking) are made when an
article has been changed.
@@ -609,6 +623,7 @@ the user is redirected back to the page.
'ArticleViewFooter': After showing the footer section of an ordinary page view
$article: Article object
+$patrolFooterShown: boolean whether patrol footer is shown
'ArticleViewHeader': Before the parser cache is about to be tried for article
viewing.
@@ -747,8 +762,22 @@ $user: the user who did the block (not the one being blocked)
$isbn: ISBN to show information for
$output: OutputPage object in use
+'CanIPUseHTTPS': Determine whether the client at a given source IP is likely
+to be able to access the wiki via HTTPS.
+$ip: The IP address in human-readable form
+&$canDo: This reference should be set to false if the client may not be able
+to use HTTPS
+
'CanonicalNamespaces': For extensions adding their own namespaces or altering
the defaults.
+Note that if you need to specify namespace protection or content model for
+a namespace that is added in a CanonicalNamespaces hook handler, you
+should do so by altering $wgNamespaceProtection and
+$wgNamespaceContentModels outside the handler, in top-level scope. The
+point at which the CanonicalNamespaces hook fires is too late for altering
+these variables. This applies even if the namespace addition is
+conditional; it is permissible to declare a content model and protection
+for a namespace and then decline to actually register it.
&$namespaces: Array of namespace numbers with corresponding canonical names
'CategoryAfterPageAdded': After a page is added to a category.
@@ -837,10 +866,6 @@ etc.
'DatabaseOraclePostInit': Called after initialising an Oracle database
&$db: the DatabaseOracle object
-'Debug': Called when outputting a debug log line via wfDebug() or wfDebugLog()
-$text: plaintext string to be output
-$group: null or a string naming a logging group (as defined in $wgDebugLogGroups)
-
'NewDifferenceEngine': Called when a new DifferenceEngine object is made
$title: the diff page title (nullable)
&$oldId: the actual old Id to use in the diff
@@ -1008,14 +1033,6 @@ notice.
$title: title of page being edited
&$msg: localization message name, overridable. Default is 'editpage-tos-summary'
-'EditSectionLink': Do not use, use DoEditSectionLink instead.
-$skin: Skin rendering the UI
-$title: Title being linked to
-$section: Section to link to
-$link: Default link
-&$result: Result (alter this to override the generated links)
-$lang: The language code to use for the link in the wfMessage function
-
'EmailConfirmed': When checking that the user's email address is "confirmed".
$user: User being checked
$confirmed: Whether or not the email address is confirmed
@@ -1060,6 +1077,7 @@ change the tables headers.
'ExtractThumbParameters': Called when extracting thumbnail parameters from a
thumbnail file name.
+DEPRECATED: Media handler should override MediaHandler::parseParamString instead.
$thumbname: the base name of the thumbnail file
&$params: the currently extracted params (has source name, temp or archived zone)
@@ -1106,6 +1124,12 @@ $reason: reason
$title: An optional title object used to links to sections. Can be null.
$local: Boolean indicating whether section links should refer to local page.
+'GalleryGetModes': Get list of classes that can render different modes of a
+ gallery
+$modeArray: An associative array mapping mode names to classes that implement
+ that mode. It is expected all registered classes are a subclass of
+ ImageGalleryBase.
+
'GetAutoPromoteGroups': When determining which autopromote groups a user is
entitled to be in.
&$user: user to promote.
@@ -1138,6 +1162,15 @@ $title: Title object of page
$url: string value as output (out parameter, can modify)
$query: query options passed to Title::getFullURL()
+'GetHumanTimestamp': Pre-emptively override the human-readable timestamp generated
+by MWTimestamp::getHumanTimestamp(). Return false in this hook to use the custom
+output.
+&$output: string for the output timestamp
+$timestamp: MWTimestamp object of the current (user-adjusted) timestamp
+$relativeTo: MWTimestamp object of the relative (user-adjusted) timestamp
+$user: User whose preferences are being used to make timestamp
+$lang: Language that will be used to render the timestamp
+
'GetInternalURL': Modify fully-qualified URLs used for squid cache purging.
$title: Title object of page
$url: string value as output (out parameter, can modify)
@@ -1178,10 +1211,28 @@ to do this unless they broke backwards compatibility with a previous version of
the media handler metadata output.
&$version: Array of version strings
+'GetNewMessagesAlert': Disable or modify the new messages alert
+&$newMessagesAlert: An empty string by default. If the user has new talk page
+messages, this should be populated with an alert message to that effect
+$newtalks: An empty array if the user has no new messages or an array containing
+links and revisions if there are new messages (See User::getNewMessageLinks)
+$user: The user object of the user who is loading the page
+$out: OutputPage object (to check what type of page the user is on)
+
'GetPreferences': Modify user preferences.
$user: User whose preferences are being modified.
&$preferences: Preferences description array, to be fed to an HTMLForm object
+'GetRelativeTimestamp': Pre-emptively override the relative timestamp generated
+by MWTimestamp::getRelativeTimestamp(). Return false in this hook to use the custom
+output.
+&$output: string for the output timestamp
+&$diff: DateInterval representing the difference between the timestamps
+$timestamp: MWTimestamp object of the current (user-adjusted) timestamp
+$relativeTo: MWTimestamp object of the relative (user-adjusted) timestamp
+$user: User whose preferences are being used to make timestamp
+$lang: Language that will be used to render the timestamp
+
'getUserPermissionsErrors': Add a permissions error when permissions errors are
checked for. Use instead of userCan for most cases. Return false if the user
can't do it, and populate $result with the reason in the form of
@@ -1340,6 +1391,10 @@ $article: article (object) being checked
$ip: IP being check
$result: Change this value to override the result of wfIsTrustedProxy()
+'IsUploadAllowedFromUrl': Override the result of UploadFromUrl::isAllowedUrl()
+$url: URL used to upload from
+&$allowed: Boolean indicating if uploading is allowed for given URL
+
'isValidEmailAddr': Override the result of User::isValidEmailAddr(), for
instance to return false if the domain name doesn't match your organization.
$addr: The e-mail address entered by the user
@@ -1375,6 +1430,16 @@ $lang: language code (string)
&$names: array of language code => language name
$code language of the preferred translations
+'LanguageLinks': Manipulate a page's language links. This is called
+in various places to allow extensions to define the effective language
+links for a page.
+$title: The page's Title.
+&$links: Associative array mapping language codes to prefixed links of the
+ form "language:title".
+&$linkFlags: Associative array mapping prefixed links to arrays of flags.
+ Currently unused, but planned to provide support for marking individual
+ language links in the UI, e.g. for featured articles.
+
'LinkBegin': Used when generating internal and interwiki links in
Linker::link(), before processing starts. Return false to skip default
processing and return $ret. See documentation for Linker::link() for details on
@@ -1760,10 +1825,29 @@ cache or return false to not use it.
$parser: Parser object
$varCache: variable cache (array)
-'ParserLimitReport': Called at the end of Parser:parse() when the parser will
+'ParserLimitReport': DEPRECATED, use ParserLimitReportPrepare and
+ParserLimitReportFormat instead.
+Called at the end of Parser:parse() when the parser will
include comments about size of the text parsed.
$parser: Parser object
-$limitReport: text that will be included (without comment tags)
+&$limitReport: text that will be included (without comment tags)
+
+'ParserLimitReportFormat': Called for each row in the parser limit report that
+needs formatting. If nothing handles this hook, the default is to use "$key" to
+get the label, and "$key-value" or "$key-value-text"/"$key-value-html" to
+format the value.
+$key: Key for the limit report item (string)
+$value: Value of the limit report item
+&$report: String onto which to append the data
+$isHTML: If true, $report is an HTML table with two columns; if false, it's
+ text intended for display in a monospaced font.
+$localize: If false, $report should be output in English.
+
+'ParserLimitReportPrepare': Called at the end of Parser:parse() when the parser will
+include comments about size of the text parsed. Hooks should use
+$output->setLimitReportData() to populate data.
+$parser: Parser object
+$output: ParserOutput object
'ParserMakeImageParams': Called before the parser make an image link, use this
to modify the parameters of the image.
@@ -1783,7 +1867,7 @@ $section: the section number, zero-based, but section 0 is usually empty
$showEditLinks: boolean describing whether this section has an edit link
'ParserTestParser': Called when creating a new instance of Parser in
-maintenance/parserTests.inc.
+tests/parser/parserTest.inc.
$parser: Parser object created
'ParserTestGlobals': Allows to define globals for parser tests.
@@ -1806,6 +1890,7 @@ $action : Action being performed
&$result : Whether or not the action should be prevented
Change $result and return false to give a definitive answer, otherwise
the built-in rate limiting checks are used, if enabled.
+$incrBy: Amount to increment counter by
'PlaceNewSection': Override placement of new sections. Return false and put the
merged text into $text to override the default behavior.
@@ -1843,9 +1928,10 @@ $article: the title being (un)protected
$output: a string of the form HTML so far
'ProtectionForm::save': Called when a protection form is submitted.
-$article: the title being (un)protected
-$errorMsg: an html message string of an error or an array of message name and
+$article: the Page being (un)protected
+&$errorMsg: an html message string of an error or an array of message name and
its parameters
+$reasonstr: a string describing the reason page protection level is altered
'ProtectionForm::showLogExtract': Called after the protection log extract is
shown.
@@ -1871,6 +1957,10 @@ IContextSource $context: The RequestContext the skin is being created for.
&$skin: A variable reference you may set a Skin instance or string key on to
override the skin that will be used for the context.
+'ResetSessionID': Called from wfResetSessionID
+$oldSessionID: old session id
+$newSessionID: new session id
+
'ResourceLoaderGetConfigVars': Called at the end of
ResourceLoaderStartUpModule::getConfig(). Use this to export static
configuration variables to JavaScript. Things that depend on the current page
@@ -1911,12 +2001,6 @@ $data: the data stored in old_text. The meaning depends on $flags: if external
$flags: a comma-delimited list of strings representing the options used. May
include: utf8 (this will always be set for new revisions); gzip; external.
-'SearchUpdate': Prior to search update completion.
-$id : Page id
-$namespace : Page namespace
-$title : Page title
-$text : Current text being indexed
-
'SearchGetNearMatchBefore': Perform exact-title-matches in "go" searches before
the normal operations.
$allSearchTerms : Array of the search terms in all content languages
@@ -1952,8 +2036,6 @@ $title : Current Title object being displayed in search results.
'SearchableNamespaces': An option to modify which namespaces are searchable.
&$arr : Array of namespaces ($nsId => $name) which will be used.
-'SeleniumSettings': TODO
-
'SetupAfterCache': Called in Setup.php, after cache objects are set
'ShowMissingArticle': Called when generating the output for a non-existent page.
@@ -2078,8 +2160,6 @@ $checkEdit: Whether or not the action=edit query should be added if appropriate.
&$text: Link text.
&$result: Complete assoc. array if you want to return true.
-'SkinTemplateTabs': TODO
-
'SkinTemplateToolboxEnd': Called by SkinTemplate skins after toolbox links have
been rendered (useful for adding more).
$sk: The QuickTemplate based skin template running the hook.
@@ -2191,6 +2271,11 @@ $opts: FormOptions for this request
&$query_options: array of options for the database request
&$select: Array of columns to select
+'SpecialResetTokensTokens': Called when building token list for
+SpecialResetTokens.
+&$tokens: array of token information arrays in the format of
+ array( 'preference' => '
', 'label-message' => '' )
+
'SpecialSearchCreateLink': Called when making the message to create a page or
go to the existing page.
$t: title object searched for
@@ -2280,6 +2365,11 @@ $special: the special page object
&$fields: array of query fields
$values: array of variables with watchlist options
+'SpecialWatchlistGetNonRevisionTypes': Called when building sql query for
+SpecialWatchlist. Allows extensions to register custom values they have
+inserted to rc_type so they can be returned as part of the watchlist.
+&$nonRevisionTypes: array of values in the rc_type field of recentchanges table
+
'TestCanonicalRedirect': Called when about to force a redirect to a canonical
URL for a title when we have no other parameters on the URL. Gives a chance for
extensions that alter page view behavior radically to abort that redirect or
@@ -2299,6 +2389,20 @@ database result.
&$titleArray: set this to an object to override the default object returned
$res: database result used to create the object
+'TitleQuickPermissions': Called from Title::checkQuickPermissions to add to
+or override the quick permissions check.
+$title: The Title object being accessed
+$user: The User performing the action
+$action: Action being performed
+&$errors: Array of errors
+$doExpensiveQueries: Whether to do expensive DB queries
+$short: Whether to return immediately on first error
+
+'TitleGetEditNotices': Allows extensions to add edit notices
+$title: The Title object for the page the edit notices are for
+$oldid: Revision ID that the edit notices are for (or 0 for latest)
+&$notices: Array of notices. Keys are i18n message keys, values are parseAsBlock()ed messages.
+
'TitleGetRestrictionTypes': Allows extensions to modify the types of protection
that can be applied.
$title: The title in question.
@@ -2332,6 +2436,11 @@ $result: Boolean; whether MediaWiki currently thinks this is a wikitext page.
Hooks may change this value to override the return value of
Title::isWikitextPage()
+'TitleMove': Before moving an article (title).
+$old: old title
+$nt: new title
+$user: user who does the move
+
'TitleMoveComplete': After moving an article (title).
$old: old title
$nt: new title
@@ -2346,6 +2455,10 @@ $title: Title object being checked against
$user: Current user object
&$whitelisted: Boolean value of whether this title is whitelisted
+'TitleSquidURLs': Called to determine which URLs to purge from HTTP caches.
+$this: Title object to purge
+&$urls: An array of URLs to purge from the caches, to be manipulated.
+
'UndeleteForm::showHistory': Called in UndeleteForm::showHistory, after a
PageArchive object has been created but before any further processing is done.
&$archive: PageArchive object
@@ -2378,6 +2491,7 @@ $article: article "acted on"
'UnwatchArticle': Before a watch is removed from an article.
$user: user watching
$page: WikiPage object to be removed
+&$status: Status object to be returned if the hook returns false
'UnwatchArticleComplete': After a watch is removed from an article.
$user: user that watched
@@ -2538,6 +2652,10 @@ $title: Title of the page in question
$ip: User's IP address
&$blocked: Whether the user is blocked, to be modified by the hook
+'UserIsEveryoneAllowed': Check if all users are allowed some user right; return
+false if a UserGetRights hook might remove the named right.
+$right: The user right being checked
+
'UserLoadAfterLoadFromSession': Called to authenticate users on external or
environmental means; occurs after session is loaded.
$user: user object being loaded
@@ -2586,6 +2704,12 @@ $user : User object that was changed
$add : Array of strings corresponding to groups added
$remove: Array of strings corresponding to groups removed
+'UserRequiresHTTPS': Called to determine whether a user needs
+to be switched to HTTPS.
+$user: User in question.
+&$https: Boolean whether $user should be switched to HTTPS.
+
+
'UserRetrieveNewTalks': Called when retrieving "You have new messages!"
message(s).
$user: user retrieving new talks messages
@@ -2627,6 +2751,7 @@ used to alter the SQL query which gets the list of wanted pages.
'WatchArticle': Before a watch is added to an article.
$user: user that will watch
$page: WikiPage object to be watched
+&$status: Status object to be returned if the hook returns false
'WatchArticleComplete': After a watch is added to an article.
$user: user that watched
@@ -2643,6 +2768,13 @@ $skin: Skin object
REQUEST_URI.
$router: The PathRouter instance
+'WebResponseSetCookie': when setting a cookie in WebResponse::setcookie().
+Return false to prevent setting of the cookie.
+&$name: Cookie name passed to WebResponse::setcookie()
+&$value: Cookie value passed to WebResponse::setcookie()
+&$expire: Cookie expiration, as for PHP's setcookie()
+$options: Options passed to WebResponse::setcookie()
+
'WikiExporter::dumpStableQuery': Get the SELECT query for "stable" revisions
dumps. One, and only one hook should set this, and return false.
&$tables: Database tables to use in the SELECT query
diff --git a/docs/maintenance.txt b/docs/maintenance.txt
index 27619c86..87a32a80 100644
--- a/docs/maintenance.txt
+++ b/docs/maintenance.txt
@@ -34,7 +34,7 @@ In it, write the following:
/monobook.css]], [[User:/monobook.js]], etc.
+[[User:/vector.css]], [[User:/vector.js]], etc.
-This feature has led to a wide variety of "user styles" becoming available,
-which change the appearance of Monobook or MySkin:
+This feature has led to a wide variety of "user styles" becoming available:
http://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
@@ -72,7 +74,7 @@ $wgSkipSkins[] = '';
This technique is used by the more ambitious MediaWiki site operators, to
create complex custom skins for their wikis. It should be preferred over
-editing the core Monobook skin directly.
+editing the core Monobook skin directly.
See http://www.mediawiki.org/wiki/Manual:Skinning for more information.
diff --git a/docs/title.txt b/docs/title.txt
index d2d91c9c..454711dc 100644
--- a/docs/title.txt
+++ b/docs/title.txt
@@ -8,7 +8,7 @@ and can be queried for the others, and for other attributes of the title. This
is intended to be an immutable "value" class, so there are no mutator functions.
To get a new instance, call Title::newFromText(). Once instantiated, the
-non-static accessor methods can be used, such as getText(), getDBKey(),
+non-static accessor methods can be used, such as getText(), getDBkey(),
getNamespace(), etc. Note that Title::newFromText() may return false if the text
is illegal according to the rules below.
@@ -36,11 +36,11 @@ An initial colon in a title listed in wiki text may however suppress special
handling for interlanguage links, image links, and category links. It is also
used to indicate the main namespace in template inclusions.
-Once prefixes have been stripped, the rest of the title processed this way:
+Once prefixes have been stripped, the rest of the title processed this way:
* Spaces and underscores are treated as equivalent and each is converted to the
other in the appropriate context (underscore in URL and database keys, spaces
- in plain text).
+ in plain text).
* Multiple consecutive spaces are converted to a single space.
* Leading or trailing space is removed.
* If $wgCapitalLinks is enabled (the default), the first letter is capitalised,
@@ -58,7 +58,7 @@ UTF-8, because that is the size of the database field. Special page titles may
be up to 512 bytes.
Note that Unicode Normal Form C (NFC) is enforced by MediaWiki's user interface
-input functions, and so titles will typically be in this form.
+input functions, and so titles will typically be in this form.
getArticleID() needs some explanation: for "internal" articles, it should return
the "page_id" field if the article exists, else it returns 0. For all external
diff --git a/docs/uidesign/child-selector-emu.html b/docs/uidesign/child-selector-emu.html
index 8294b6d7..dedb3a67 100644
--- a/docs/uidesign/child-selector-emu.html
+++ b/docs/uidesign/child-selector-emu.html
@@ -2,7 +2,7 @@
CSS Child selector emulation for IE 6
-
-
-
-HTML validation error
-
-EOT;
+ $out = Html::element( 'h1', null, 'HTML validation error' );
+ $out .= Html::openElement( 'ul' );
$error = strtok( $errors, "\n" );
$badLines = array();
@@ -198,26 +194,40 @@ EOT;
if ( preg_match( '/^line (\d+)/', $error, $m ) ) {
$lineNum = intval( $m[1] );
$badLines[$lineNum] = true;
- $out .= "- " . htmlspecialchars( $error ) . "
\n";
+ $out .= Html::rawElement( 'li', null,
+ Html::element( 'a', array( 'href' => "#line-{$lineNum}" ), $error ) ) . "\n";
}
$error = strtok( "\n" );
}
- $out .= '
';
- $out .= '' . htmlspecialchars( $errors ) . '
';
- $out .= "\n";
+ $out .= Html::closeElement( 'ul' );
+ $out .= Html::element( 'pre', null, $errors );
+ $out .= Html::openElement( 'ol' ) . "\n";
$line = strtok( $s, "\n" );
$i = 1;
while ( $line !== false ) {
+ $attrs = array();
if ( isset( $badLines[$i] ) ) {
- $out .= "- ";
- } else {
- $out .= '
- ';
+ $attrs['class'] = 'highlight';
+ $attrs['id'] = "line-$i";
}
- $out .= htmlspecialchars( $line ) . "
\n";
+ $out .= Html::element( 'li', $attrs, $line ) . "\n";
$line = strtok( "\n" );
$i++;
}
- $out .= '
';
+ $out .= Html::closeElement( 'ol' );
+
+ $style = << 'en', 'dir' => 'ltr' ) ) .
+ Html::rawElement( 'head', null,
+ Html::element( 'title', null, 'HTML validation error' ) .
+ Html::inlineStyle( $style ) ) .
+ Html::rawElement( 'body', null, $out ) .
+ Html::closeElement( 'html' );
+
return $out;
}
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index 1e0c396a..7f0454f6 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -39,9 +39,6 @@ class OutputPage extends ContextSource {
/// Should be private. Used with addMeta() which adds ""
var $mMetatags = array();
- /// "" most of the time the first 10 links to an article
- var $mKeywords = array();
-
var $mLinktags = array();
var $mCanonicalUrl = false;
@@ -253,6 +250,16 @@ class OutputPage extends ContextSource {
*/
private $mProperties = array();
+ /**
+ * @var string|null: ResourceLoader target for load.php links. If null, will be omitted
+ */
+ private $mTarget = null;
+
+ /**
+ * @var bool: Whether output should contain table of contents
+ */
+ private $mEnableTOC = true;
+
/**
* Constructor for OutputPage. This should not be called directly.
* Instead a new RequestContext should be created and it will implicitly create
@@ -308,19 +315,6 @@ class OutputPage extends ContextSource {
array_push( $this->mMetatags, array( $name, $val ) );
}
- /**
- * Add a keyword or a list of keywords in the page header
- *
- * @param string $text or array of strings
- */
- function addKeyword( $text ) {
- if( is_array( $text ) ) {
- $this->mKeywords = array_merge( $this->mKeywords, $text );
- } else {
- array_push( $this->mKeywords, $text );
- }
- }
-
/**
* Add a new \ tag to the page header.
*
@@ -408,13 +402,14 @@ class OutputPage extends ContextSource {
public function addScriptFile( $file, $version = null ) {
global $wgStylePath, $wgStyleVersion;
// See if $file parameter is an absolute URL or begins with a slash
- if( substr( $file, 0, 1 ) == '/' || preg_match( '#^[a-z]*://#i', $file ) ) {
+ if ( substr( $file, 0, 1 ) == '/' || preg_match( '#^[a-z]*://#i', $file ) ) {
$path = $file;
} else {
$path = "{$wgStylePath}/common/{$file}";
}
- if ( is_null( $version ) )
+ if ( is_null( $version ) ) {
$version = $wgStyleVersion;
+ }
$this->addScript( Html::linkedScript( wfAppendQuery( $path, $version ) ) );
}
@@ -447,11 +442,12 @@ class OutputPage extends ContextSource {
protected function filterModules( $modules, $position = null, $type = ResourceLoaderModule::TYPE_COMBINED ) {
$resourceLoader = $this->getResourceLoader();
$filteredModules = array();
- foreach( $modules as $val ) {
+ foreach ( $modules as $val ) {
$module = $resourceLoader->getModule( $val );
- if( $module instanceof ResourceLoaderModule
+ if ( $module instanceof ResourceLoaderModule
&& $module->getOrigin() <= $this->getAllowedModules( $type )
- && ( is_null( $position ) || $module->getPosition() == $position ) )
+ && ( is_null( $position ) || $module->getPosition() == $position )
+ && ( !$this->mTarget || in_array( $this->mTarget, $module->getTargets() ) ) )
{
$filteredModules[] = $val;
}
@@ -556,6 +552,22 @@ class OutputPage extends ContextSource {
$this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules );
}
+ /**
+ * @return null|string: ResourceLoader target
+ */
+ public function getTarget() {
+ return $this->mTarget;
+ }
+
+ /**
+ * Sets ResourceLoader target for load.php links. If null, will be omitted
+ *
+ * @param $target string|null
+ */
+ public function setTarget( $target ) {
+ $this->mTarget = $target;
+ }
+
/**
* Get an array of head items
*
@@ -662,20 +674,20 @@ class OutputPage extends ContextSource {
*
* @param $timestamp string
*
- * @return Boolean: true iff cache-ok headers was sent.
+ * @return Boolean: true if cache-ok headers was sent.
*/
public function checkLastModified( $timestamp ) {
- global $wgCachePages, $wgCacheEpoch;
+ global $wgCachePages, $wgCacheEpoch, $wgUseSquid, $wgSquidMaxage;
if ( !$timestamp || $timestamp == '19700101000000' ) {
wfDebug( __METHOD__ . ": CACHE DISABLED, NO TIMESTAMP\n" );
return false;
}
- if( !$wgCachePages ) {
+ if ( !$wgCachePages ) {
wfDebug( __METHOD__ . ": CACHE DISABLED\n", false );
return false;
}
- if( $this->getUser()->getOption( 'nocache' ) ) {
+ if ( $this->getUser()->getOption( 'nocache' ) ) {
wfDebug( __METHOD__ . ": USER DISABLED CACHE\n", false );
return false;
}
@@ -686,6 +698,10 @@ class OutputPage extends ContextSource {
'user' => $this->getUser()->getTouched(),
'epoch' => $wgCacheEpoch
);
+ if ( $wgUseSquid ) {
+ // bug 44570: the core page itself may not change, but resources might
+ $modifiedTimes['sepoch'] = wfTimestamp( TS_MW, time() - $wgSquidMaxage );
+ }
wfRunHooks( 'OutputPageCheckLastModified', array( &$modifiedTimes ) );
$maxModified = max( $modifiedTimes );
@@ -724,7 +740,7 @@ class OutputPage extends ContextSource {
wfTimestamp( TS_ISO_8601, $clientHeaderTime ) . "\n", false );
wfDebug( __METHOD__ . ": effective Last-Modified: " .
wfTimestamp( TS_ISO_8601, $maxModified ) . "\n", false );
- if( $clientHeaderTime < $maxModified ) {
+ if ( $clientHeaderTime < $maxModified ) {
wfDebug( __METHOD__ . ": STALE, $info\n", false );
return false;
}
@@ -766,10 +782,10 @@ class OutputPage extends ContextSource {
public function setRobotPolicy( $policy ) {
$policy = Article::formatRobotPolicy( $policy );
- if( isset( $policy['index'] ) ) {
+ if ( isset( $policy['index'] ) ) {
$this->setIndexPolicy( $policy['index'] );
}
- if( isset( $policy['follow'] ) ) {
+ if ( isset( $policy['follow'] ) ) {
$this->setFollowPolicy( $policy['follow'] );
}
}
@@ -783,7 +799,7 @@ class OutputPage extends ContextSource {
*/
public function setIndexPolicy( $policy ) {
$policy = trim( $policy );
- if( in_array( $policy, array( 'index', 'noindex' ) ) ) {
+ if ( in_array( $policy, array( 'index', 'noindex' ) ) ) {
$this->mIndexPolicy = $policy;
}
}
@@ -797,7 +813,7 @@ class OutputPage extends ContextSource {
*/
public function setFollowPolicy( $policy ) {
$policy = trim( $policy );
- if( in_array( $policy, array( 'follow', 'nofollow' ) ) ) {
+ if ( in_array( $policy, array( 'follow', 'nofollow' ) ) ) {
$this->mFollowPolicy = $policy;
}
}
@@ -1269,7 +1285,6 @@ class OutputPage extends ContextSource {
* Return whether user JavaScript is allowed for this page
* @deprecated since 1.18 Load modules with ResourceLoader, and origin and
* trustworthiness is identified and enforced automagically.
- * Will be removed in 1.20.
* @return Boolean
*/
public function isUserJsAllowed() {
@@ -1284,7 +1299,7 @@ class OutputPage extends ContextSource {
* @return Int ResourceLoaderModule ORIGIN_ class constant
*/
public function getAllowedModules( $type ) {
- if( $type == ResourceLoaderModule::TYPE_COMBINED ) {
+ if ( $type == ResourceLoaderModule::TYPE_COMBINED ) {
return min( array_values( $this->mAllowedModules ) );
} else {
return isset( $this->mAllowedModules[$type] )
@@ -1401,7 +1416,7 @@ class OutputPage extends ContextSource {
* @param $timestamp Mixed: string, or null
* @return Mixed: previous value
*/
- public function setRevisionTimestamp( $timestamp) {
+ public function setRevisionTimestamp( $timestamp ) {
return wfSetVar( $this->mRevisionTimestamp, $timestamp );
}
@@ -1524,7 +1539,7 @@ class OutputPage extends ContextSource {
$popts = $this->parserOptions();
$oldTidy = $popts->setTidy( $tidy );
- $popts->setInterfaceMessage( (bool) $interface );
+ $popts->setInterfaceMessage( (bool)$interface );
$parserOutput = $wgParser->parse(
$text, $title, $popts,
@@ -1582,6 +1597,10 @@ class OutputPage extends ContextSource {
}
}
+ // 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 ) );
}
@@ -1592,6 +1611,7 @@ class OutputPage extends ContextSource {
*/
function addParserOutput( &$parserOutput ) {
$this->addParserOutputNoText( $parserOutput );
+ $parserOutput->setTOCEnabled( $this->mEnableTOC );
$text = $parserOutput->getText();
wfRunHooks( 'OutputPageBeforeHTML', array( &$this, &$text ) );
$this->addHTML( $text );
@@ -1626,7 +1646,7 @@ class OutputPage extends ContextSource {
public function parse( $text, $linestart = true, $interface = false, $language = null ) {
global $wgParser;
- if( is_null( $this->getTitle() ) ) {
+ if ( is_null( $this->getTitle() ) ) {
throw new MWException( 'Empty $mTitle in ' . __METHOD__ );
}
@@ -1707,6 +1727,7 @@ class OutputPage extends ContextSource {
array(
"{$wgCookiePrefix}Token",
"{$wgCookiePrefix}LoggedOut",
+ "forceHTTPS",
session_name()
),
$wgCacheVaryCookies
@@ -1750,8 +1771,8 @@ class OutputPage extends ContextSource {
public function addVaryHeader( $header, $option = null ) {
if ( !array_key_exists( $header, $this->mVaryHeader ) ) {
$this->mVaryHeader[$header] = (array)$option;
- } elseif( is_array( $option ) ) {
- if( is_array( $this->mVaryHeader[$header] ) ) {
+ } elseif ( is_array( $option ) ) {
+ if ( is_array( $this->mVaryHeader[$header] ) ) {
$this->mVaryHeader[$header] = array_merge( $this->mVaryHeader[$header], $option );
} else {
$this->mVaryHeader[$header] = $option;
@@ -1785,7 +1806,7 @@ class OutputPage extends ContextSource {
$this->addVaryHeader( 'Cookie', $cookiesOption );
$headers = array();
- foreach( $this->mVaryHeader as $header => $option ) {
+ foreach ( $this->mVaryHeader as $header => $option ) {
$newheader = $header;
if ( is_array( $option ) && count( $option ) > 0 ) {
$newheader .= ';' . implode( ';', $option );
@@ -1807,11 +1828,11 @@ class OutputPage extends ContextSource {
*/
function addAcceptLanguage() {
$lang = $this->getTitle()->getPageLanguage();
- if( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) {
+ if ( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) {
$variants = $lang->getVariants();
$aloption = array();
foreach ( $variants as $variant ) {
- if( $variant === $lang->getCode() ) {
+ if ( $variant === $lang->getCode() ) {
continue;
} else {
$aloption[] = 'string-contains=' . $variant;
@@ -1892,12 +1913,11 @@ class OutputPage extends ContextSource {
$response->header( $this->getXVO() );
}
- if( $this->mEnableClientCache ) {
- if(
+ if ( $this->mEnableClientCache ) {
+ if (
$wgUseSquid && session_id() == '' && !$this->isPrintable() &&
$this->mSquidMaxage != 0 && !$this->haveCacheVaryCookies()
- )
- {
+ ) {
if ( $wgUseESI ) {
# We'll purge the proxy cache explicitly, but require end user agents
# to revalidate against the proxy on each visit.
@@ -1924,7 +1944,7 @@ class OutputPage extends ContextSource {
$response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
$response->header( "Cache-Control: private, must-revalidate, max-age=0" );
}
- if( $this->mLastModified ) {
+ if ( $this->mLastModified ) {
$response->header( "Last-Modified: {$this->mLastModified}" );
}
} else {
@@ -1957,9 +1977,10 @@ class OutputPage extends ContextSource {
* the object, let's actually output it:
*/
public function output() {
- global $wgLanguageCode, $wgDebugRedirects, $wgMimeType, $wgVaryOnXFP;
+ global $wgLanguageCode, $wgDebugRedirects, $wgMimeType, $wgVaryOnXFP,
+ $wgUseAjax, $wgResponsiveImages;
- if( $this->mDoNothing ) {
+ if ( $this->mDoNothing ) {
return;
}
@@ -1974,9 +1995,9 @@ class OutputPage extends ContextSource {
$redirect = $this->mRedirect;
$code = $this->mRedirectCode;
- if( wfRunHooks( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) {
- if( $code == '301' || $code == '303' ) {
- if( !$wgDebugRedirects ) {
+ if ( wfRunHooks( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) {
+ if ( $code == '301' || $code == '303' ) {
+ if ( !$wgDebugRedirects ) {
$message = HttpStatus::getMessage( $code );
$response->header( "HTTP/1.1 $code $message" );
}
@@ -1988,7 +2009,7 @@ class OutputPage extends ContextSource {
$this->sendCacheControl();
$response->header( "Content-Type: text/html; charset=utf-8" );
- if( $wgDebugRedirects ) {
+ if ( $wgDebugRedirects ) {
$url = htmlspecialchars( $redirect );
print "\n\nRedirect\n\n\n";
print "Location: $url
\n";
@@ -2020,11 +2041,34 @@ class OutputPage extends ContextSource {
}
if ( $this->mArticleBodyOnly ) {
- $this->out( $this->mBodytext );
+ echo $this->mBodytext;
} else {
- $this->addDefaultModules();
$sk = $this->getSkin();
+ // add skin specific modules
+ $modules = $sk->getDefaultModules();
+
+ // enforce various default modules for all skins
+ $coreModules = array(
+ // keep this list as small as possible
+ 'mediawiki.page.startup',
+ 'mediawiki.user',
+ );
+
+ // Support for high-density display images if enabled
+ if ( $wgResponsiveImages ) {
+ $coreModules[] = 'mediawiki.hidpi';
+ }
+
+ $this->addModules( $coreModules );
+ foreach ( $modules as $group ) {
+ $this->addModules( $group );
+ }
+ MWDebug::addModules( $this );
+ if ( $wgUseAjax ) {
+ // FIXME: deprecate? - not clear why this is useful
+ wfRunHooks( 'AjaxAddScript', array( &$this ) );
+ }
// Hook that allows last minute changes to the output page, e.g.
// adding of CSS or Javascript by extensions.
@@ -2046,11 +2090,13 @@ class OutputPage extends ContextSource {
}
/**
- * Actually output something with print().
+ * Actually output something with print.
*
* @param string $ins the string to output
+ * @deprecated since 1.22 Use echo yourself.
*/
public function out( $ins ) {
+ wfDeprecated( __METHOD__, '1.22' );
print $ins;
}
@@ -2097,7 +2143,7 @@ class OutputPage extends ContextSource {
* @param array $params message parameters; ignored if $msg is a Message object
*/
public function showErrorPage( $title, $msg, $params = array() ) {
- if( !$title instanceof Message ) {
+ if ( !$title instanceof Message ) {
$title = $this->msg( $title );
}
@@ -2238,7 +2284,7 @@ class OutputPage extends ContextSource {
if ( count( $errors ) > 1 ) {
$text .= '' . "\n";
- foreach( $errors as $error ) {
+ foreach ( $errors as $error ) {
$text .= '- ';
$text .= call_user_func_array( array( $this, 'msg' ), $error )->plain();
$text .= "
\n";
@@ -2286,7 +2332,7 @@ class OutputPage extends ContextSource {
if ( !empty( $reasons ) ) {
// Permissions error
- if( $source ) {
+ if ( $source ) {
$this->setPageTitle( $this->msg( 'viewsource-title', $this->getTitle()->getPrefixedText() ) );
$this->addBacklinkSubtitle( $this->getTitle() );
} else {
@@ -2299,7 +2345,7 @@ class OutputPage extends ContextSource {
}
// Show source, if supplied
- if( is_string( $source ) ) {
+ if ( is_string( $source ) ) {
$this->addWikiMsg( 'viewsourcetext' );
$pageLang = $this->getTitle()->getPageLanguage();
@@ -2325,7 +2371,7 @@ $templates
# If the title doesn't exist, it's fairly pointless to print a return
# link to it. After all, you just tried editing it and couldn't, so
# what's there to do there?
- if( $this->getTitle()->exists() ) {
+ if ( $this->getTitle()->exists() ) {
$this->returnToMain( null, $this->getTitle() );
}
}
@@ -2349,7 +2395,7 @@ $templates
*/
public function showLagWarning( $lag ) {
global $wgSlaveLagWarning, $wgSlaveLagCritical;
- if( $lag >= $wgSlaveLagWarning ) {
+ if ( $lag >= $wgSlaveLagWarning ) {
$message = $lag < $wgSlaveLagCritical
? 'lag-warn-normal'
: 'lag-warn-high';
@@ -2393,15 +2439,6 @@ $templates
* @param $options Options array to pass to Linker
*/
public function addReturnTo( $title, $query = array(), $text = null, $options = array() ) {
- if( in_array( 'http', $options ) ) {
- $proto = PROTO_HTTP;
- } elseif( in_array( 'https', $options ) ) {
- $proto = PROTO_HTTPS;
- } else {
- $proto = PROTO_RELATIVE;
- }
-
- $this->addLink( array( 'rel' => 'next', 'href' => $title->getFullURL( '', false, $proto ) ) );
$link = $this->msg( 'returnto' )->rawParams(
Linker::link( $title, $text, array(), $query, $options ) )->escaped();
$this->addHTML( "{$link}
\n" );
@@ -2446,15 +2483,11 @@ $templates
* @return String: The doctype, opening "", and head element.
*/
public function headElement( Skin $sk, $includeStyle = true ) {
- global $wgContLang;
+ global $wgContLang, $wgMimeType;
$userdir = $this->getLanguage()->getDir();
$sitedir = $wgContLang->getDir();
- if ( $sk->commonPrintStylesheet() ) {
- $this->addModuleStyles( 'mediawiki.legacy.wikiprintable' );
- }
-
$ret = Html::htmlHeader( array( 'lang' => $this->getLanguage()->getHtmlCode(), 'dir' => $userdir, 'class' => 'client-nojs' ) );
if ( $this->getHTMLTitle() == '' ) {
@@ -2467,10 +2500,22 @@ $templates
$ret .= "$openHead\n";
}
+ if ( !Html::isXmlMimeType( $wgMimeType ) ) {
+ // Add
+ // This should be before since it defines the charset used by
+ // text including the text inside .
+ // The spec recommends defining XHTML5's charset using the XML declaration
+ // instead of meta.
+ // Our XML declaration is output by Html::htmlHeader.
+ // http://www.whatwg.org/html/semantics.html#attr-meta-http-equiv-content-type
+ // http://www.whatwg.org/html/semantics.html#charset
+ $ret .= Html::element( 'meta', array( 'charset' => 'UTF-8' ) );
+ }
+
$ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n";
$ret .= implode( "\n", array(
- $this->getHeadLinks( null, true ),
+ $this->getHeadLinks(),
$this->buildCssLinks(),
$this->getHeadScripts(),
$this->getHeadItems()
@@ -2481,20 +2526,29 @@ $templates
$ret .= "$closeHead\n";
}
- $bodyAttrs = array();
+ $bodyClasses = array();
+ $bodyClasses[] = 'mediawiki';
# Classes for LTR/RTL directionality support
- $bodyAttrs['class'] = "mediawiki $userdir sitedir-$sitedir";
+ $bodyClasses[] = $userdir;
+ $bodyClasses[] = "sitedir-$sitedir";
if ( $this->getLanguage()->capitalizeAllNouns() ) {
# A class is probably not the best way to do this . . .
- $bodyAttrs['class'] .= ' capitalize-all-nouns';
+ $bodyClasses[] = 'capitalize-all-nouns';
}
- $bodyAttrs['class'] .= ' ' . $sk->getPageClasses( $this->getTitle() );
- $bodyAttrs['class'] .= ' skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
- $bodyAttrs['class'] .= ' action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
- $sk->addToBodyAttributes( $this, $bodyAttrs ); // Allow skins to add body attributes they need
+ $bodyClasses[] = $sk->getPageClasses( $this->getTitle() );
+ $bodyClasses[] = 'skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
+ $bodyClasses[] = 'action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
+
+ $bodyAttrs = array();
+ // While the implode() is not strictly needed, it's used for backwards compatibility
+ // (this used to be built as a string and hooks likely still expect that).
+ $bodyAttrs['class'] = implode( ' ', $bodyClasses );
+
+ // Allow skins and extensions to add body attributes they need
+ $sk->addToBodyAttributes( $this, $bodyAttrs );
wfRunHooks( 'OutputPageBodyAttributes', array( $this, $sk, &$bodyAttrs ) );
$ret .= Html::openElement( 'body', $bodyAttrs ) . "\n";
@@ -2502,59 +2556,6 @@ $templates
return $ret;
}
- /**
- * Add the default ResourceLoader modules to this object
- */
- private function addDefaultModules() {
- global $wgIncludeLegacyJavaScript, $wgPreloadJavaScriptMwUtil, $wgUseAjax,
- $wgAjaxWatch, $wgResponsiveImages;
-
- // Add base resources
- $this->addModules( array(
- 'mediawiki.user',
- 'mediawiki.page.startup',
- 'mediawiki.page.ready',
- ) );
- if ( $wgIncludeLegacyJavaScript ) {
- $this->addModules( 'mediawiki.legacy.wikibits' );
- }
-
- if ( $wgPreloadJavaScriptMwUtil ) {
- $this->addModules( 'mediawiki.util' );
- }
-
- MWDebug::addModules( $this );
-
- // Add various resources if required
- if ( $wgUseAjax ) {
- $this->addModules( 'mediawiki.legacy.ajax' );
-
- wfRunHooks( 'AjaxAddScript', array( &$this ) );
-
- if( $wgAjaxWatch && $this->getUser()->isLoggedIn() ) {
- $this->addModules( 'mediawiki.page.watch.ajax' );
- }
-
- if ( !$this->getUser()->getOption( 'disablesuggest', false ) ) {
- $this->addModules( 'mediawiki.searchSuggest' );
- }
- }
-
- if ( $this->getUser()->getBoolOption( 'editsectiononrightclick' ) ) {
- $this->addModules( 'mediawiki.action.view.rightClickEdit' );
- }
-
- # Crazy edit-on-double-click stuff
- if ( $this->isArticle() && $this->getUser()->getOption( 'editondblclick' ) ) {
- $this->addModules( 'mediawiki.action.view.dblClickEdit' );
- }
-
- // Support for high-density display images
- if ( $wgResponsiveImages ) {
- $this->addModules( 'mediawiki.hidpi' );
- }
- }
-
/**
* Get a ResourceLoader object associated with this OutputPage
*
@@ -2579,7 +2580,7 @@ $templates
protected function makeResourceLoaderLink( $modules, $only, $useESI = false, array $extraQuery = array(), $loadCall = false ) {
global $wgResourceLoaderUseESI;
- $modules = (array) $modules;
+ $modules = (array)$modules;
if ( !count( $modules ) ) {
return '';
@@ -2600,6 +2601,9 @@ $templates
return $links;
}
}
+ if ( !is_null( $this->mTarget ) ) {
+ $extraQuery['target'] = $this->mTarget;
+ }
// Create keyed-by-group list of module objects from modules list
$groups = array();
@@ -2612,8 +2616,8 @@ $templates
&& $only == ResourceLoaderModule::TYPE_SCRIPTS )
|| ( $module->getOrigin() > $this->getAllowedModules( ResourceLoaderModule::TYPE_STYLES )
&& $only == ResourceLoaderModule::TYPE_STYLES )
- )
- {
+ || ( $this->mTarget && !in_array( $this->mTarget, $module->getTargets() ) )
+ ) {
continue;
}
@@ -2648,7 +2652,7 @@ $templates
);
$context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
// Extract modules that know they're empty
- $emptyModules = array ();
+ $emptyModules = array();
foreach ( $grpModules as $key => $module ) {
if ( $module->isKnownEmpty( $context ) ) {
$emptyModules[$key] = 'ready';
@@ -2659,13 +2663,9 @@ $templates
if ( count( $emptyModules ) > 0 && $only !== ResourceLoaderModule::TYPE_STYLES ) {
// If we're only getting the styles, we don't need to do anything for empty modules.
$links .= Html::inlineScript(
-
ResourceLoader::makeLoaderConditionalScript(
-
ResourceLoader::makeLoaderStateScript( $emptyModules )
-
)
-
) . "\n";
}
@@ -2732,7 +2732,7 @@ $templates
// Automatically select style/script elements
if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
$link = Html::linkedStyle( $url );
- } else if ( $loadCall ) {
+ } elseif ( $loadCall ) {
$link = Html::inlineScript(
ResourceLoader::makeLoaderConditionalScript(
Xml::encodeJsCall( 'mw.loader.load', array( $url, 'text/javascript', true ) )
@@ -2743,7 +2743,7 @@ $templates
}
}
- if( $group == 'noscript' ) {
+ if ( $group == 'noscript' ) {
$links .= Html::rawElement( 'noscript', array(), $link ) . "\n";
} else {
$links .= $link . "\n";
@@ -2847,14 +2847,14 @@ $templates
);
$defaultModules['site'] = 'loading';
} else {
- // The wiki is configured to not allow a site module.
- $defaultModules['site'] = 'missing';
+ // Site module is empty, save request by marking ready in advance (bug 46857)
+ $defaultModules['site'] = 'ready';
}
// Add user JS if enabled
if ( $wgAllowUserJs ) {
if ( $this->getUser()->isLoggedIn() ) {
- if( $this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview() ) {
+ if ( $this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview() ) {
# XXX: additional security check/prompt?
// We're on a preview of a JS subpage
// Exclude this page from the user module in case it's in there (bug 26283)
@@ -2874,15 +2874,14 @@ $templates
}
$defaultModules['user'] = 'loading';
} else {
- // Non-logged-in users have no user module. Treat it as empty and 'ready' to avoid
- // blocking default gadgets that might depend on it. Although arguably default-enabled
- // gadgets should not depend on the user module, it's harmless and less error-prone to
- // handle this case.
+ // Non-logged-in users have an empty user module.
+ // Save request by marking ready in advance (bug 46857)
$defaultModules['user'] = 'ready';
}
} else {
- // User JS disabled
- $defaultModules['user'] = 'missing';
+ // User modules are disabled on this wiki.
+ // Save request by marking ready in advance (bug 46857)
+ $defaultModules['user'] = 'ready';
}
// Group JS is only enabled if site JS is enabled.
@@ -2893,13 +2892,13 @@ $templates
);
$defaultModules['user.groups'] = 'loading';
} else {
- // Non-logged-in users have no user.groups module. Treat it as empty and 'ready' to
- // avoid blocking gadgets that might depend upon the module.
+ // Non-logged-in users have no user.groups module.
+ // Save request by marking ready in advance (bug 46857)
$defaultModules['user.groups'] = 'ready';
}
} else {
// Site (and group JS) disabled
- $defaultModules['user.groups'] = 'missing';
+ $defaultModules['user.groups'] = 'ready';
}
$loaderInit = '';
@@ -2927,11 +2926,18 @@ $templates
*/
function getBottomScripts() {
global $wgResourceLoaderExperimentalAsyncLoading;
+
+ // Optimise jQuery ready event cross-browser.
+ // This also enforces $.isReady to be true at which fixes the
+ // mw.loader bug in Firefox with using document.write between
+ // and the DOMContentReady event (bug 47457).
+ $html = Html::inlineScript( 'window.jQuery && jQuery.ready();' );
+
if ( !$wgResourceLoaderExperimentalAsyncLoading ) {
- return $this->getScriptsForBottomQueue( false );
- } else {
- return '';
+ $html .= $this->getScriptsForBottomQueue( false );
}
+
+ return $html;
}
/**
@@ -2966,24 +2972,24 @@ $templates
public function getJSVars() {
global $wgContLang;
- $latestRevID = 0;
- $pageID = 0;
- $canonicalName = false; # bug 21115
+ $curRevisionId = 0;
+ $articleId = 0;
+ $canonicalSpecialPageName = false; # bug 21115
$title = $this->getTitle();
$ns = $title->getNamespace();
- $nsname = MWNamespace::exists( $ns ) ? MWNamespace::getCanonicalName( $ns ) : $title->getNsText();
+ $canonicalNamespace = MWNamespace::exists( $ns ) ? MWNamespace::getCanonicalName( $ns ) : $title->getNsText();
// Get the relevant title so that AJAX features can use the correct page name
// when making API requests from certain special pages (bug 34972).
$relevantTitle = $this->getSkin()->getRelevantTitle();
if ( $ns == NS_SPECIAL ) {
- list( $canonicalName, /*...*/ ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
+ list( $canonicalSpecialPageName, /*...*/ ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
} elseif ( $this->canUseWikiPage() ) {
$wikiPage = $this->getWikiPage();
- $latestRevID = $wikiPage->getLatest();
- $pageID = $wikiPage->getId();
+ $curRevisionId = $wikiPage->getLatest();
+ $articleId = $wikiPage->getId();
}
$lang = $title->getPageLanguage();
@@ -3005,20 +3011,23 @@ $templates
$user = $this->getUser();
$vars = array(
- 'wgCanonicalNamespace' => $nsname,
- 'wgCanonicalSpecialPageName' => $canonicalName,
+ 'wgCanonicalNamespace' => $canonicalNamespace,
+ 'wgCanonicalSpecialPageName' => $canonicalSpecialPageName,
'wgNamespaceNumber' => $title->getNamespace(),
'wgPageName' => $title->getPrefixedDBkey(),
'wgTitle' => $title->getText(),
- 'wgCurRevisionId' => $latestRevID,
- 'wgArticleId' => $pageID,
+ 'wgCurRevisionId' => $curRevisionId,
+ 'wgRevisionId' => (int)$this->getRevisionId(),
+ 'wgArticleId' => $articleId,
'wgIsArticle' => $this->isArticle(),
+ 'wgIsRedirect' => $title->isRedirect(),
'wgAction' => Action::getActionName( $this->getContext() ),
'wgUserName' => $user->isAnon() ? null : $user->getName(),
'wgUserGroups' => $user->getEffectiveGroups(),
'wgCategories' => $this->getCategories(),
'wgBreakFrames' => $this->getFrameOptions() == 'DENY',
'wgPageContentLanguage' => $lang->getCode(),
+ 'wgPageContentModel' => $title->getContentModel(),
'wgSeparatorTransformTable' => $compactSeparatorTransTable,
'wgDigitTransformTable' => $compactDigitTransTable,
'wgDefaultDateFormat' => $lang->getDefaultDateFormat(),
@@ -3031,10 +3040,16 @@ $templates
$vars['wgUserEditCount'] = $user->getEditCount();
$userReg = wfTimestampOrNull( TS_UNIX, $user->getRegistration() );
$vars['wgUserRegistration'] = $userReg !== null ? ( $userReg * 1000 ) : null;
+ // Get the revision ID of the oldest new message on the user's talk
+ // page. This can be used for constructing new message alerts on
+ // the client side.
+ $vars['wgUserNewMsgRevisionId'] = $user->getNewMessageRevisionId();
}
if ( $wgContLang->hasVariants() ) {
$vars['wgUserVariant'] = $wgContLang->getPreferredVariant();
}
+ // Same test as SkinTemplate
+ $vars['wgIsProbablyEditable'] = $title->quickUserCan( 'edit', $user ) && ( $title->exists() || $title->quickUserCan( 'create', $user ) );
foreach ( $title->getRestrictionTypes() as $type ) {
$vars['wgRestriction' . ucfirst( $type )] = $title->getRestrictions( $type );
}
@@ -3080,13 +3095,11 @@ $templates
}
/**
- * @param bool $addContentType Whether "" specifying content type should be returned
- *
* @return array in format "link name or number => 'link html'".
*/
- public function getHeadLinksArray( $addContentType = false ) {
+ public function getHeadLinksArray() {
global $wgUniversalEditButton, $wgFavicon, $wgAppleTouchIcon, $wgEnableAPI,
- $wgSitename, $wgVersion, $wgHtml5, $wgMimeType,
+ $wgSitename, $wgVersion,
$wgFeed, $wgOverrideSiteFeed, $wgAdvertisedFeedTypes,
$wgDisableLangConversion, $wgCanonicalLanguageLinks,
$wgRightsPage, $wgRightsUrl;
@@ -3095,30 +3108,13 @@ $templates
$canonicalUrl = $this->mCanonicalUrl;
- if ( $addContentType ) {
- if ( $wgHtml5 ) {
- # More succinct than , has the
- # same effect
- $tags['meta-charset'] = Html::element( 'meta', array( 'charset' => 'UTF-8' ) );
- } else {
- $tags['meta-content-type'] = Html::element( 'meta', array(
- 'http-equiv' => 'Content-Type',
- 'content' => "$wgMimeType; charset=UTF-8"
- ) );
- $tags['meta-content-style-type'] = Html::element( 'meta', array( // bug 15835
- 'http-equiv' => 'Content-Style-Type',
- 'content' => 'text/css'
- ) );
- }
- }
-
$tags['meta-generator'] = Html::element( 'meta', array(
'name' => 'generator',
'content' => "MediaWiki $wgVersion",
) );
$p = "{$this->mIndexPolicy},{$this->mFollowPolicy}";
- if( $p !== 'index,follow' ) {
+ if ( $p !== 'index,follow' ) {
// http://www.robotstxt.org/wc/meta-user.html
// Only show if it's different from the default robots policy
$tags['meta-robots'] = Html::element( 'meta', array(
@@ -3127,21 +3123,6 @@ $templates
) );
}
- if ( count( $this->mKeywords ) > 0 ) {
- $strip = array(
- "/<.*?" . ">/" => '',
- "/_/" => ' '
- );
- $tags['meta-keywords'] = Html::element( 'meta', array(
- 'name' => 'keywords',
- 'content' => preg_replace(
- array_keys( $strip ),
- array_values( $strip ),
- implode( ',', $this->mKeywords )
- )
- ) );
- }
-
foreach ( $this->mMetatags as $tag ) {
if ( 0 == strcasecmp( 'http:', substr( $tag[0], 0, 5 ) ) ) {
$a = 'http-equiv';
@@ -3233,7 +3214,7 @@ $templates
foreach ( $variants as $_v ) {
$tags["variant-$_v"] = Html::element( 'link', array(
'rel' => 'alternate',
- 'hreflang' => $_v,
+ 'hreflang' => wfBCP47( $_v ),
'href' => $this->getTitle()->getLocalURL( array( 'variant' => $_v ) ) )
);
}
@@ -3266,7 +3247,7 @@ $templates
# Feeds
if ( $wgFeed ) {
- foreach( $this->getSyndicationLinks() as $format => $link ) {
+ foreach ( $this->getSyndicationLinks() as $format => $link ) {
# Use the page name for the title. In principle, this could
# lead to issues with having the same name for different feeds
# corresponding to the same page, but we can't avoid that at
@@ -3301,7 +3282,7 @@ $templates
foreach ( $wgAdvertisedFeedTypes as $format ) {
$tags[] = $this->feedLink(
$format,
- $rctitle->getLocalURL( "feed={$format}" ),
+ $rctitle->getLocalURL( array( 'feed' => $format ) ),
$this->msg( "site-{$format}-feed", $wgSitename )->text() # For grep: 'site-rss-feed', 'site-atom-feed'.
);
}
@@ -3329,13 +3310,10 @@ $templates
}
/**
- * @param $unused
- * @param bool $addContentType Whether "" specifying content type should be returned
- *
* @return string HTML tag links to be put in the header.
*/
- public function getHeadLinks( $unused = null, $addContentType = false ) {
- return implode( "\n", $this->getHeadLinksArray( $addContentType ) );
+ public function getHeadLinks() {
+ return implode( "\n", $this->getHeadLinksArray() );
}
/**
@@ -3368,13 +3346,13 @@ $templates
$options = array();
// Even though we expect the media type to be lowercase, but here we
// force it to lowercase to be safe.
- if( $media ) {
+ if ( $media ) {
$options['media'] = $media;
}
- if( $condition ) {
+ if ( $condition ) {
$options['condition'] = $condition;
}
- if( $dir ) {
+ if ( $dir ) {
$options['dir'] = $dir;
}
$this->styles[$style] = $options;
@@ -3386,7 +3364,7 @@ $templates
* @param string $flip Set to 'flip' to flip the CSS if needed
*/
public function addInlineStyle( $style_css, $flip = 'noflip' ) {
- if( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
+ if ( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
# If wanted, and the interface is right-to-left, flip the CSS
$style_css = CSSJanus::transform( $style_css, true, false );
}
@@ -3416,7 +3394,7 @@ $templates
if ( $wgUseSiteCss ) {
$moduleStyles[] = 'site';
$moduleStyles[] = 'noscript';
- if( $this->getUser()->isLoggedIn() ) {
+ if ( $this->getUser()->isLoggedIn() ) {
$moduleStyles[] = 'user.groups';
}
}
@@ -3497,9 +3475,9 @@ $templates
}
$this->mExtStyles = array();
- foreach( $this->styles as $file => $options ) {
+ foreach ( $this->styles as $file => $options ) {
$link = $this->styleLink( $file, $options );
- if( $link ) {
+ if ( $link ) {
$links[$file] = $link;
}
}
@@ -3515,22 +3493,22 @@ $templates
* @return String: HTML fragment
*/
protected function styleLink( $style, $options ) {
- if( isset( $options['dir'] ) ) {
- if( $this->getLanguage()->getDir() != $options['dir'] ) {
+ if ( isset( $options['dir'] ) ) {
+ if ( $this->getLanguage()->getDir() != $options['dir'] ) {
return '';
}
}
- if( isset( $options['media'] ) ) {
+ if ( isset( $options['media'] ) ) {
$media = self::transformCssMedia( $options['media'] );
- if( is_null( $media ) ) {
+ if ( is_null( $media ) ) {
return '';
}
} else {
$media = 'all';
}
- if( substr( $style, 0, 1 ) == '/' ||
+ if ( substr( $style, 0, 1 ) == '/' ||
substr( $style, 0, 5 ) == 'http:' ||
substr( $style, 0, 6 ) == 'https:' ) {
$url = $style;
@@ -3541,7 +3519,7 @@ $templates
$link = Html::linkedStyle( $url, $media );
- if( isset( $options['condition'] ) ) {
+ if ( isset( $options['condition'] ) ) {
$condition = htmlspecialchars( $options['condition'] );
$link = "";
}
@@ -3556,7 +3534,7 @@ $templates
* this stylesheet
*/
public static function transformCssMedia( $media ) {
- global $wgRequest, $wgHandheldForIPhone;
+ global $wgRequest;
// http://www.w3.org/TR/css3-mediaqueries/#syntax
$screenMediaQueryRegex = '/^(?:only\s+)?screen\b/i';
@@ -3566,11 +3544,11 @@ $templates
'printable' => 'print',
'handheld' => 'handheld',
);
- foreach( $switches as $switch => $targetMedia ) {
- if( $wgRequest->getBool( $switch ) ) {
- if( $media == $targetMedia ) {
+ foreach ( $switches as $switch => $targetMedia ) {
+ if ( $wgRequest->getBool( $switch ) ) {
+ if ( $media == $targetMedia ) {
$media = '';
- } elseif( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
+ } elseif ( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
// This regex will not attempt to understand a comma-separated media_query_list
//
// Example supported values for $media: 'screen', 'only screen', 'screen and (min-width: 982px)' ),
@@ -3581,25 +3559,13 @@ $templates
// we don't want simple 'screen' but we might want screen queries that
// have a max-width or something, so we'll pass all others on and let the
// client do the query.
- if( $targetMedia == 'print' || $media == 'screen' ) {
+ if ( $targetMedia == 'print' || $media == 'screen' ) {
return null;
}
}
}
}
- // Expand longer media queries as iPhone doesn't grok 'handheld'
- if( $wgHandheldForIPhone ) {
- $mediaAliases = array(
- 'screen' => 'screen and (min-device-width: 481px)',
- 'handheld' => 'handheld, only screen and (max-device-width: 480px)',
- );
-
- if( isset( $mediaAliases[$media] ) ) {
- $media = $mediaAliases[$media];
- }
- }
-
return $media;
}
@@ -3688,4 +3654,20 @@ $templates
return array();
}
+ /**
+ * Enables/disables TOC, doesn't override __NOTOC__
+ * @param bool $flag
+ * @since 1.22
+ */
+ public function enableTOC( $flag = true ) {
+ $this->mEnableTOC = $flag;
+ }
+
+ /**
+ * @return bool
+ * @since 1.22
+ */
+ public function isTOCEnabled() {
+ return $this->mEnableTOC;
+ }
}
diff --git a/includes/PHPVersionError.php b/includes/PHPVersionError.php
index 7749bf1f..02d3546f 100644
--- a/includes/PHPVersionError.php
+++ b/includes/PHPVersionError.php
@@ -38,7 +38,7 @@
* version are hardcoded here
*/
function wfPHPVersionError( $type ) {
- $mwVersion = '1.21';
+ $mwVersion = '1.22';
$minimumVersionPHP = '5.3.2';
$phpVersion = phpversion();
@@ -61,12 +61,12 @@ function wfPHPVersionError( $type ) {
header( 'Pragma: no-cache' );
$finalOutput = <<
-
+
+
+
MediaWiki {$mwVersion}
-
-