*/
$wgLogo = false;
+/**
+ * Array with URL paths to HD versions of the wiki logo. The scaled logo size
+ * should be under 135x155 pixels.
+ * Only 1.5x and 2x versions are supported.
+ *
+ * @par Example:
+ * @code
+ * $wgLogoHD = array(
+ * "1.5x" => "path/to/1.5x_version.png",
+ * "2x" => "path/to/2x_version.png"
+ * );
+ * @endcode
+ *
+ * @since 1.25
+ */
+$wgLogoHD = false;
+
/**
* The URL path of the shortcut icon.
* @since 1.6
* Constructs the location of the the source Mustache template
* @param string $templateName The name of the template
* @return string
- * @throws Exception Disallows upwards directory traversal via $templateName
+ * @throws UnexpectedValueException Disallows upwards directory traversal via $templateName
*/
public function getTemplateFilename( $templateName ) {
// Prevent upwards directory traversal using same methods as Title::secureAndSplit
substr( $templateName, -3 ) === '/..'
)
) {
- throw new Exception( "Malformed \$templateName: $templateName" );
+ throw new UnexpectedValueException( "Malformed \$templateName: $templateName" );
}
return "{$this->templateDir}/{$templateName}.mustache";
* Returns a given template function if found, otherwise throws an exception.
* @param string $templateName The name of the template (without file suffix)
* @return Function
- * @throws Exception
+ * @throws RuntimeException
*/
public function getTemplate( $templateName ) {
// If a renderer has already been defined for this template, reuse it
$filename = $this->getTemplateFilename( $templateName );
if ( !file_exists( $filename ) ) {
- throw new Exception( "Could not locate template: {$filename}" );
+ throw new RuntimeException( "Could not locate template: {$filename}" );
}
// Read the template file
* @param string $fileContents Mustache code
* @param string $filename Name of the template
* @return string PHP code (without '<?php')
- * @throws Exception
+ * @throws RuntimeException
*/
public function compileForEval( $fileContents, $filename ) {
// Compile the template into PHP code
$code = self::compile( $fileContents );
if ( !$code ) {
- throw new Exception( "Could not compile template: {$filename}" );
+ throw new RuntimeException( "Could not compile template: {$filename}" );
}
// Strip the "<?php" added by lightncandy so that it can be eval()ed
* Compile the Mustache code into PHP code using LightnCandy
* @param string $code Mustache code
* @return string PHP code (with '<?php')
- * @throws Exception
+ * @throws RuntimeException
*/
public static function compile( $code ) {
if ( !class_exists( 'LightnCandy' ) ) {
- throw new Exception( 'LightnCandy class not defined' );
+ throw new RuntimeException( 'LightnCandy class not defined' );
}
return LightnCandy::compile(
$code,
public function getEditNotices( $oldid = 0 ) {
$notices = array();
- # Optional notices on a per-namespace and per-page basis
+ // Optional notice for the entire namespace
$editnotice_ns = 'editnotice-' . $this->getNamespace();
- $editnotice_ns_message = wfMessage( $editnotice_ns );
- if ( $editnotice_ns_message->exists() ) {
- $notices[$editnotice_ns] = '<div class="mw-editnotice mw-editnotice-namespace ' .
- Sanitizer::escapeClass( "mw-$editnotice_ns" ) . '">' .
- $editnotice_ns_message->parseAsBlock() . '</div>';
+ $msg = wfMessage( $editnotice_ns );
+ if ( $msg->exists() ) {
+ $html = $msg->parseAsBlock();
+ // Edit notices may have complex logic, but output nothing (T91715)
+ if ( trim( $html ) !== '' ) {
+ $notices[$editnotice_ns] = Html::rawElement(
+ 'div',
+ array( 'class' => array(
+ 'mw-editnotice',
+ 'mw-editnotice-namespace',
+ Sanitizer::escapeClass( "mw-$editnotice_ns" )
+ ) ),
+ $html
+ );
+ }
}
+
if ( MWNamespace::hasSubpages( $this->getNamespace() ) ) {
+ // Optional notice for page itself and any parent page
$parts = explode( '/', $this->getDBkey() );
$editnotice_base = $editnotice_ns;
while ( count( $parts ) > 0 ) {
$editnotice_base .= '-' . array_shift( $parts );
- $editnotice_base_msg = wfMessage( $editnotice_base );
- if ( $editnotice_base_msg->exists() ) {
- $notices[$editnotice_base] = '<div class="mw-editnotice mw-editnotice-base ' .
- Sanitizer::escapeClass( "mw-$editnotice_base" ) . '">' .
- $editnotice_base_msg->parseAsBlock() . '</div>';
+ $msg = wfMessage( $editnotice_base );
+ if ( $msg->exists() ) {
+ $html = $msg->parseAsBlock();
+ if ( trim( $html ) !== '' ) {
+ $notices[$editnotice_base] = Html::rawElement(
+ 'div',
+ array( 'class' => array(
+ 'mw-editnotice',
+ 'mw-editnotice-base',
+ Sanitizer::escapeClass( "mw-$editnotice_base" )
+ ) ),
+ $html
+ );
+ }
}
}
} else {
- # Even if there are no subpages in namespace, we still don't want / in MW ns.
+ // Even if there are no subpages in namespace, we still don't want "/" in MediaWiki message keys
$editnoticeText = $editnotice_ns . '-' . str_replace( '/', '-', $this->getDBkey() );
- $editnoticeMsg = wfMessage( $editnoticeText );
- if ( $editnoticeMsg->exists() ) {
- $notices[$editnoticeText] = '<div class="mw-editnotice mw-editnotice-page ' .
- Sanitizer::escapeClass( "mw-$editnoticeText" ) . '">' .
- $editnoticeMsg->parseAsBlock() . '</div>';
+ $msg = wfMessage( $editnoticeText );
+ if ( $msg->exists() ) {
+ $html = $msg->parseAsBlock();
+ if ( trim( $html ) !== '' ) {
+ $notices[$editnoticeText] = Html::rawElement(
+ 'div',
+ array( 'class' => array(
+ 'mw-editnotice',
+ 'mw-editnotice-page',
+ Sanitizer::escapeClass( "mw-$editnoticeText" )
+ ) ),
+ $html
+ );
+ }
}
}
*
* @see Content::prepareSave
*/
- public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user ) {
+ public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) {
if ( $this->isValid() ) {
return Status::newGood();
} else {
*
* @param WikiPage $page The page to be saved.
* @param int $flags Bitfield for use with EDIT_XXX constants, see WikiPage::doEditContent()
- * @param int $baseRevId The ID of the current revision
+ * @param int $parentRevId The ID of the current revision
* @param User $user
*
* @return Status A status object indicating whether the content was
*
* @see WikiPage::doEditContent()
*/
- public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user );
+ public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user );
/**
* Returns a list of updates to perform when this content is deleted.
protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
// '<!--LINE \d+ -->' get replaced by a localised line number
// in DifferenceEngine::localiseLineNumbers
- $r = '<tr><td colspan="2" class="diff-lineno"><!--LINE ' . $xbeg . "--></td>\n" .
+ $r = '<tr><td colspan="2" class="diff-lineno" id="L' . $xbeg . '" ><!--LINE ' . $xbeg . "--></td>\n" .
'<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
return $r;
}
/**
+ * @param bool|IContextSource $context Context to use (optional)
* @return bool
*/
- function formatMetadata() {
+ function formatMetadata( $context = false ) {
if ( !$this->getHandler() ) {
return false;
}
- return $this->getHandler()->formatMetadata( $this, $this->getMetadata() );
+ return $this->getHandler()->formatMetadata( $this, $context );
}
/**
}
protected function supportsDelayedJobs() {
- return true; // defer checks to the partitions
+ foreach ( $this->partitionQueues as $queue ) {
+ if ( !$queue->supportsDelayedJobs() ) {
+ return false;
+ }
+ }
+
+ return true;
}
protected function doIsEmpty() {
/**
* @param File $image
+ * @param bool|IContextSource $context Context to use (optional)
* @return array|bool
*/
- function formatMetadata( $image ) {
+ function formatMetadata( $image, $context = false ) {
$meta = $this->getCommonMetaArray( $image );
if ( count( $meta ) === 0 ) {
return false;
}
- return $this->formatMetadataHelper( $meta );
+ return $this->formatMetadataHelper( $meta, $context );
}
public function getCommonMetaArray( File $file ) {
/**
* @param File $image
+ * @param bool|IContextSource $context Context to use (optional)
* @return array|bool
*/
- function formatMetadata( $image ) {
+ function formatMetadata( $image, $context = false ) {
$meta = $this->getCommonMetaArray( $image );
if ( count( $meta ) === 0 ) {
return false;
}
- return $this->formatMetadataHelper( $meta );
+ return $this->formatMetadataHelper( $meta, $context );
}
/**
* to some standard. That makes it possible to do things like visual
* indication of grouped and chained streams in ogg container files.
* @param File $image
+ * @param bool|IContextSource $context Context to use (optional)
* @return array|bool
*/
- function formatMetadata( $image ) {
+ function formatMetadata( $image, $context = false ) {
return false;
}
* This is used by the media handlers that use the FormatMetadata class
*
* @param array $metadataArray Metadata array
+ * @param bool|IContextSource $context Context to use (optional)
* @return array Array for use displaying metadata.
*/
- function formatMetadataHelper( $metadataArray ) {
+ function formatMetadataHelper( $metadataArray, $context = false ) {
$result = array(
'visible' => array(),
'collapsed' => array()
);
- $formatted = FormatMetadata::getFormattedData( $metadataArray );
+ $formatted = FormatMetadata::getFormattedData( $metadataArray, $context );
// Sort fields into visible and collapsed
$visibleFields = $this->visibleMetadataFields();
foreach ( $formatted as $name => $value ) {
/**
* @param File $image
+ * @param bool|IContextSource $context Context to use (optional)
* @return array|bool
*/
- function formatMetadata( $image ) {
+ function formatMetadata( $image, $context = false ) {
$meta = $this->getCommonMetaArray( $image );
if ( count( $meta ) === 0 ) {
return false;
}
- return $this->formatMetadataHelper( $meta );
+ return $this->formatMetadataHelper( $meta, $context );
}
/**
/**
* @param File $file
+ * @param bool|IContextSource $context Context to use (optional)
* @return array|bool
*/
- function formatMetadata( $file ) {
+ function formatMetadata( $file, $context = false ) {
$result = array(
'visible' => array(),
'collapsed' => array()
if ( $wgShowEXIF && $this->displayImg->exists() ) {
// @todo FIXME: Bad interface, see note on MediaHandler::formatMetadata().
- $formattedMetadata = $this->displayImg->formatMetadata();
+ $formattedMetadata = $this->displayImg->formatMetadata( $this->getContext() );
$showmeta = $formattedMetadata !== false;
} else {
$showmeta = false;
* error will be returned. These two conditions are also possible with
* auto-detection due to MediaWiki's performance-optimised locking strategy.
*
- * @param bool|int $baseRevId The revision ID this edit was based off, if any
+ * @param bool|int $baseRevId The revision ID this edit was based off, if any.
+ * This is not the parent revision ID, rather the revision ID for older
+ * content used as the source for a rollback, for example.
* @param User $user The user doing the edit
*
* @throws MWException
* error will be returned. These two conditions are also possible with
* auto-detection due to MediaWiki's performance-optimised locking strategy.
*
- * @param bool|int $baseRevId The revision ID this edit was based off, if any
+ * @param bool|int $baseRevId The revision ID this edit was based off, if any.
+ * This is not the parent revision ID, rather the revision ID for older
+ * content used as the source for a rollback, for example.
* @param User $user The user doing the edit
* @param string $serialFormat Format for storing the content in the
* database.
$dbw->begin( __METHOD__ );
try {
- $prepStatus = $content->prepareSave( $this, $flags, $baseRevId, $user );
+ $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
$status->merge( $prepStatus );
if ( !$status->isOK() ) {
$dbw->begin( __METHOD__ );
try {
- $prepStatus = $content->prepareSave( $this, $flags, $baseRevId, $user );
+ $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
$status->merge( $prepStatus );
if ( !$status->isOK() ) {
}
// Generate the edit summary if necessary
- $target = Revision::newFromId( $s->rev_id );
+ $target = Revision::newFromId( $s->rev_id, Revision::READ_LATEST );
if ( empty( $summary ) ) {
if ( $from == '' ) { // no public user name
$summary = wfMessage( 'revertpage-nouser' );
*/
public function getStyles( ResourceLoaderContext $context ) {
$logo = $this->getConfig()->get( 'Logo' );
+ $logoHD = $this->getConfig()->get( 'LogoHD' );
$styles = parent::getStyles( $context );
$styles['all'][] = '.mw-wiki-logo { background-image: ' .
CSSMin::buildUrlValue( $logo ) .
'; }';
-
+ if ( $logoHD ) {
+ if ( isset( $logoHD['1.5x'] ) ) {
+ $styles[
+ '(-webkit-min-device-pixel-ratio: 1.5), ' .
+ '(min--moz-device-pixel-ratio: 1.5), ' .
+ '(min-resolution: 1.5dppx), ' .
+ '(min-resolution: 144dpi)'
+ ][] = '.mw-wiki-logo { background-image: ' .
+ CSSMin::buildUrlValue( $logoHD['1.5x'] ) .';' .
+ 'background-size: 135px auto; }';
+ }
+ if ( isset( $logoHD['2x'] ) ) {
+ $styles[
+ '(-webkit-min-device-pixel-ratio: 2), ' .
+ '(min--moz-device-pixel-ratio: 2),'.
+ '(min-resolution: 2dppx), ' .
+ '(min-resolution: 192dpi)'
+ ][] = '.mw-wiki-logo { background-image: ' .
+ CSSMin::buildUrlValue( $logoHD['2x'] ) . ';' .
+ 'background-size: 135px auto; }';
+ }
+ }
return $styles;
}
*/
public function getModifiedHash( ResourceLoaderContext $context ) {
$logo = $this->getConfig()->get( 'Logo' );
- return md5( parent::getModifiedHash( $context ) . $logo );
+ $logoHD = $this->getConfig()->get( 'LogoHD' );
+ return md5( parent::getModifiedHash( $context ) . $logo . json_encode( $logoHD ) );
}
}
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-bell {
background-image: url("themes/mediawiki/images/icons/bell.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-article {
background-image: url("themes/mediawiki/images/icons/article-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-table {
background-image: url("themes/mediawiki/images/icons/table.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-edit {
background-image: url("themes/mediawiki/images/icons/edit-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-indent {
background-image: url("themes/mediawiki/images/icons/indent-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-bigger {
background-image: url("themes/mediawiki/images/icons/bigger-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-beta {
background-image: url("themes/mediawiki/images/icons/beta.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-stripeFlow {
background-image: url("themes/mediawiki/images/icons/stripeFlow-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-map {
background-image: url("themes/mediawiki/images/icons/map-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-image {
background-image: url("themes/mediawiki/images/icons/image-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-block {
background-image: url("themes/mediawiki/images/icons/block.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-arrowNext {
background-image: url("themes/mediawiki/images/icons/arrow-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-userActive {
background-image: url("themes/mediawiki/images/icons/userActive-ltr.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-icon-logoCC {
background-image: url("themes/mediawiki/images/icons/logo-cc.png");
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:09:07Z
+ * Date: 2015-03-12T23:44:05Z
*/
.oo-ui-progressBarWidget-slide-frames from {
margin-left: -40%;
.oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
white-space: normal;
}
+.oo-ui-toolbar-tools .oo-ui-tool {
+ white-space: normal;
+}
.oo-ui-toolbar-tools,
.oo-ui-toolbar-actions,
.oo-ui-toolbar-shadow {
-o-transform: scale(1);
transform: scale(1);
}
-.oo-ui-windowManager-fullscreen.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
- border: 0;
- border-radius: 0;
- box-shadow: none;
+.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
+ border: 1px solid #aaaaaa;
+ border-radius: 0.2em;
+ box-shadow: inset 0 -0.2em 0 0 rgba(0, 0, 0, 0.2);
}
.oo-ui-icon-add {
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:08:47Z
+ * Date: 2015-03-12T23:43:45Z
*/
/**
* @class
/*!
- * OOjs UI v0.9.1
+ * OOjs UI v0.9.2
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2015-03-12T19:08:47Z
+ * Date: 2015-03-12T23:43:45Z
*/
( function ( OO ) {
// Properties
this.manager = null;
this.size = config.size || this.constructor.static.size;
- this.frame = new OO.ui.PanelLayout( {
- expanded: false,
- framed: true
- } );
- this.$frame = this.frame.$element;
+ this.$frame = $( '<div>' );
this.$overlay = $( '<div>' );
this.$content = $( '<div>' );
);
QUnit.start();
- }, 10 );
+ } );
} );
}
return;
}
// Otherwise, keep polling
- setTimeout( styleTestLoop, 150 );
+ setTimeout( styleTestLoop );
}
// Start the loop