suppressed content but not suppress it ("suppressrevision" right).
* Added a new hook, "OutputPageScriptsForBottomQueue", to add modules to the
bottom queue that should be requested in a dedicated <script> request.
+* (bug 66440) The MediaWiki web installer will now allow you to choose the skins
+ to enable (from the ones included in download tarball) and decide which one
+ should be the default.
=== Bug fixes in 1.24 ===
* (bug 49116) Footer copyright notice is now always displayed in user language
* Removed maintenance/nextJobDB.php; no longer in use.
* Removed global function wfViewPrevNext(). (deprecated since 1.19)
* Removed global function xmlsafe() from Export.php. (moved to OAIRepo extension)
+* Removed Title::userCanRead(). (deprecated since 1.19)
==== Renamed classes ====
* CLDRPluralRuleConverter_Expression to CLDRPluralRuleConverterExpression
* WatchlistEditor - Use SpecialEditWatchlist directly
* FormatExif - Use FormatMetadata directly
* RevertFileAction - Use RevertAction directly
+* HistoryPage - Use HistoryAction directly
== Compatibility ==
'ChannelFeed' => 'includes/Feed.php',
'Collation' => 'includes/Collation.php',
'CollationCkb' => 'includes/Collation.php',
+ 'CollationEt' => 'includes/Collation.php',
'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php',
'Cookie' => 'includes/Cookie.php',
'CookieJar' => 'includes/Cookie.php',
'FormlessAction' => 'includes/actions/FormlessAction.php',
'FormAction' => 'includes/actions/FormAction.php',
'HistoryAction' => 'includes/actions/HistoryAction.php',
- 'HistoryPage' => 'includes/actions/HistoryAction.php',
'HistoryPager' => 'includes/actions/HistoryAction.php',
'InfoAction' => 'includes/actions/InfoAction.php',
'MarkpatrolledAction' => 'includes/actions/MarkpatrolledAction.php',
return new IcuCollation( 'root' );
case 'xx-uca-ckb':
return new CollationCkb;
+ case 'xx-uca-et':
+ return new CollationEt;
default:
$match = array();
if ( preg_match( '/^uca-([a-z@=-]+)$/', $collationName, $match ) ) {
'el' => array(),
'eo' => array( "Ĉ", "Ĝ", "Ĥ", "Ĵ", "Ŝ", "Ŭ" ),
'es' => array( "Ñ" ),
- 'et' => array( "Š", "Ž", "Õ", "Ä", "Ö", "Ü" ),
+ 'et' => array( "Š", "Ž", "Õ", "Ä", "Ö", "Ü", "W" ), // added W for CollationEt (xx-uca-et)
'eu' => array( "Ñ" ),
'fo' => array( "Á", "Ð", "Í", "Ó", "Ú", "Ý", "Æ", "Ø", "Å" ),
'fur' => array( "À", "Á", "Â", "È", "Ì", "Ò", "Ù" ),
$this->digitTransformLanguage = Language::factory( 'ckb' );
}
}
+
+/**
+ * Workaround for incorrect collation of Estonian language ('et') in ICU (bug 54168).
+ *
+ * 'W' and 'V' should not be considered the same letter for the purposes of collation in modern
+ * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21 'LATIN LETTER SMALL
+ * CAPITAL W' for sortkey generation, which is collated like 'W' and is not tailored to have the
+ * same primary weight as 'V' in Estonian.
+ */
+class CollationEt extends IcuCollation {
+ function __construct() {
+ parent::__construct( 'et' );
+ }
+
+ private static function mangle( $string ) {
+ return str_replace(
+ array( 'w', 'W' ),
+ 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+ $string
+ );
+ }
+
+ private static function unmangle( $string ) {
+ // Casing data is lost…
+ return str_replace(
+ 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+ 'W',
+ $string
+ );
+ }
+
+ function getSortKey( $string ) {
+ return parent::getSortKey( self::mangle( $string ) );
+ }
+
+ function getFirstLetter( $string ) {
+ return self::unmangle( parent::getFirstLetter( self::mangle( $string ) ) );
+ }
+}
* last page depending on the dir parameter.
*
* Subclassing the pager to implement concrete functionality should be fairly
- * simple, please see the examples in HistoryPage.php and
+ * simple, please see the examples in HistoryAction.php and
* SpecialBlockList.php. You just need to override formatRow(),
* getQueryInfo() and getIndexField(). Don't forget to call the parent
* constructor if you override it.
return $this->mWatched;
}
- /**
- * Can $wgUser read this page?
- *
- * @deprecated since 1.19; use userCan(), quickUserCan() or getUserPermissionsErrors() instead
- * @return bool
- */
- public function userCanRead() {
- wfDeprecated( __METHOD__, '1.19' );
- return $this->userCan( 'read' );
- }
-
/**
* Can $user perform $action on this page?
* This skips potentially expensive cascading permission checks
*
* @param int $limit The limit number of revisions to get
* @param int $offset
- * @param int $direction Either HistoryPage::DIR_PREV or HistoryPage::DIR_NEXT
+ * @param int $direction Either self::DIR_PREV or self::DIR_NEXT
* @return ResultWrapper
*/
function fetchRevisions( $limit, $offset, $direction ) {
$dbr = wfGetDB( DB_SLAVE );
- if ( $direction == HistoryPage::DIR_PREV ) {
+ if ( $direction === self::DIR_PREV ) {
list( $dirs, $oper ) = array( "ASC", ">=" );
- } else { /* $direction == HistoryPage::DIR_NEXT */
+ } else { /* $direction === self::DIR_NEXT */
list( $dirs, $oper ) = array( "DESC", "<=" );
}
$limit = $request->getInt( 'limit', 10 );
$limit = min( max( $limit, 1 ), $wgFeedLimit );
- $items = $this->fetchRevisions( $limit, 0, HistoryPage::DIR_NEXT );
+ $items = $this->fetchRevisions( $limit, 0, self::DIR_NEXT );
// Generate feed elements enclosed between header and footer.
$feed->outHeader();
return $this->preventClickjacking;
}
}
-
-/**
- * Backwards-compatibility alias
- */
-class HistoryPage extends HistoryAction {
- // @codingStandardsIgnoreStart Needed "useless" override to make it public.
- public function __construct( Page $article ) {
- parent::__construct( $article );
- }
- // @codingStandardsIgnoreEnd
-
- public function history() {
- $this->onView();
- }
-}
* Copyright © 2004 Gabriel Wicke <wicke@wikidev.net>
* http://wikidev.net/
*
- * Based on HistoryPage and SpecialExport
+ * Based on HistoryAction and SpecialExport
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
# All newlines, tabs, etc replaced by single space
$sql = preg_replace( '/\s+/', ' ', $sql );
- # All numbers => N
+ # All numbers => N,
+ # except the ones surrounded by characters, e.g. l10n
$sql = preg_replace( '/-?\d+(,-?\d+)+/s', 'N,...,N', $sql );
- $sql = preg_replace( '/-?\d+/s', 'N', $sql );
+ $sql = preg_replace( '/(?<![a-zA-Z])-?\d+(?![a-zA-Z])/s', 'N', $sql );
return $sql;
}
'_LicenseCode' => 'none',
'_CCDone' => false,
'_Extensions' => array(),
+ '_Skins' => array(),
'_MemCachedServers' => '',
'_UpgradeKeySupplied' => false,
'_ExistingDBSettings' => false,
}
/**
- * Finds extensions that follow the format /extensions/Name/Name.php,
+ * Finds extensions that follow the format /$directory/Name/Name.php,
* and returns an array containing the value for 'Name' for each found extension.
*
+ * Reasonable values for $directory include 'extensions' (the default) and 'skins'.
+ *
+ * @param string $directory Directory to search in
* @return array
*/
- public function findExtensions() {
+ public function findExtensions( $directory = 'extensions' ) {
if ( $this->getVar( 'IP' ) === null ) {
return array();
}
- $extDir = $this->getVar( 'IP' ) . '/extensions';
+ $extDir = $this->getVar( 'IP' ) . '/' . $directory;
if ( !is_readable( $extDir ) || !is_dir( $extDir ) ) {
return array();
}
$this->installer = $installer;
$this->extensions = $installer->getVar( '_Extensions' );
+ $this->skins = $installer->getVar( '_Skins' );
$db = $installer->getDBInstaller( $installer->getVar( 'wgDBtype' ) );
/**
* Return the full text of the generated LocalSettings.php file,
- * including the extensions
+ * including the extensions and skins.
*
* @return string
*/
public function getText() {
$localSettings = $this->getDefaultText();
+ if ( count( $this->skins ) ) {
+ $localSettings .= "
+# Enabled skins.
+# The following skins were automatically enabled:\n";
+
+ foreach ( $this->skins as $skinName ) {
+ $encSkinName = self::escapePhpString( $skinName );
+ $localSettings .= "require_once \"\$IP/skins/$encSkinName/$encSkinName.php\";\n";
+ }
+
+ $localSettings .= "\n";
+ }
+
if ( count( $this->extensions ) ) {
$localSettings .= "
# Enabled Extensions. Most extensions are enabled by including the base extension file here
$encExtName = self::escapePhpString( $extName );
$localSettings .= "require_once \"\$IP/extensions/$encExtName/$encExtName.php\";\n";
}
+
+ $localSettings .= "\n";
}
- $localSettings .= "\n\n# End of automatically generated settings.
+ $localSettings .= "
+# End of automatically generated settings.
# Add more configuration options below.\n\n";
return $localSettings;
wfBoolToStr( $perm ) . ";\n";
}
}
+ $groupRights .= "\n";
+
if ( ( isset( $this->groupPermissions['*']['edit'] ) &&
$this->groupPermissions['*']['edit'] === false )
&& ( isset( $this->groupPermissions['*']['createaccount'] ) &&
&& ( isset( $this->groupPermissions['*']['read'] ) &&
$this->groupPermissions['*']['read'] !== false )
) {
- $noFollow = "\n# Set \$wgNoFollowLinks to true if you open up your wiki to editing by\n"
+ $noFollow = "# Set \$wgNoFollowLinks to true if you open up your wiki to editing by\n"
. "# the general public and wish to apply nofollow to external links as a\n"
. "# deterrent to spammers. Nofollow is not a comprehensive anti-spam solution\n"
. "# and open wikis will generally require other anti-spam measures; for more\n"
. "# information, see https://www.mediawiki.org/wiki/Manual:Combating_spam\n"
- . "\$wgNoFollowLinks = false;";
+ . "\$wgNoFollowLinks = false;\n\n";
}
}
# web installer while LocalSettings.php is in place
\$wgUpgradeKey = \"{$this->values['wgUpgradeKey']}\";
-## Default skin: you can change the default skin. Use the internal symbolic
-## names, ie 'vector', 'monobook':
-\$wgDefaultSkin = \"{$this->values['wgDefaultSkin']}\";
-
## For attaching licensing metadata to pages, and displaying an
## appropriate copyright notice / icon. GNU Free Documentation
## License and Creative Commons licenses are supported so far.
# Path to the GNU diff3 utility. Used for conflict resolution.
\$wgDiff3 = \"{$this->values['wgDiff3']}\";
-{$groupRights}{$noFollow}";
+{$groupRights}{$noFollow}## Default skin: you can change the default skin. Use the internal symbolic
+## names, ie 'vector', 'monobook':
+\$wgDefaultSkin = \"{$this->values['wgDefaultSkin']}\";
+";
}
}
* var: The variable to be configured (required)
* label: The message name for the label (required)
* itemLabelPrefix: The message name prefix for the item labels (required)
+ * itemLabels: List of message names to use for the item labels instead of itemLabelPrefix, keyed by values
* values: List of allowed values (required)
* itemAttribs: Array of attribute arrays, outer key is the value name (optional)
* commonAttribs: Attribute array applied to all items
* @return string
*/
public function getRadioSet( $params ) {
- if ( !isset( $params['controlName'] ) ) {
- $params['controlName'] = 'config_' . $params['var'];
- }
-
- if ( !isset( $params['value'] ) ) {
- $params['value'] = $this->getVar( $params['var'] );
- }
+ $items = $this->getRadioElements( $params );
if ( !isset( $params['label'] ) ) {
$label = '';
} else {
$label = $params['label'];
}
+
+ if ( !isset( $params['controlName'] ) ) {
+ $params['controlName'] = 'config_' . $params['var'];
+ }
+
if ( !isset( $params['help'] ) ) {
$params['help'] = "";
}
+
$s = "<ul>\n";
+ foreach ( $items as $value => $item ) {
+ $s .= "<li>$item</li>\n";
+ }
+ $s .= "</ul>\n";
+
+ return $this->label( $label, $params['controlName'], $s, $params['help'] );
+ }
+
+ /**
+ * Get a set of labelled radio buttons. You probably want to use getRadioSet(), not this.
+ *
+ * @see getRadioSet
+ *
+ * @return array
+ */
+ public function getRadioElements( $params ) {
+ if ( !isset( $params['controlName'] ) ) {
+ $params['controlName'] = 'config_' . $params['var'];
+ }
+
+ if ( !isset( $params['value'] ) ) {
+ $params['value'] = $this->getVar( $params['var'] );
+ }
+
+ $items = array();
+
foreach ( $params['values'] as $value ) {
$itemAttribs = array();
$itemAttribs['id'] = $id;
$itemAttribs['tabindex'] = $this->nextTabIndex();
- $s .=
- '<li>' .
+ $items[$value] =
Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
' ' .
Xml::tags( 'label', array( 'for' => $id ), $this->parse(
- wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
- ) ) .
- "</li>\n";
+ isset( $params['itemLabels'] ) ?
+ wfMessage( $params['itemLabels'][$value] )->plain() :
+ wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
+ ) );
}
- $s .= "</ul>\n";
-
- return $this->label( $label, $params['controlName'], $s, $params['help'] );
+ return $items;
}
/**
/**
* @param string $var
+ * @param mixed $default
*
* @return mixed
*/
- public function getVar( $var ) {
- return $this->parent->getVar( $var );
+ public function getVar( $var, $default = null ) {
+ return $this->parent->getVar( $var, $default );
}
/**
*/
public function execute() {
if ( $this->getVar( '_SkipOptional' ) == 'skip' ) {
+ $this->submitSkins();
return 'skip';
}
if ( $this->parent->request->wasPosted() ) {
$this->getFieldSetEnd()
);
+ $skins = $this->parent->findExtensions( 'skins' );
+ $skinHtml = $this->getFieldSetStart( 'config-skins' );
+
+ if ( $skins ) {
+ $skinNames = array_map( 'strtolower', $skins );
+
+ $radioButtons = $this->parent->getRadioElements( array(
+ 'var' => 'wgDefaultSkin',
+ 'itemLabels' => array_fill_keys( $skinNames, 'config-skins-use-as-default' ),
+ 'values' => $skinNames,
+ 'value' => $this->getVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) ),
+ ) );
+
+ foreach ( $skins as $skin ) {
+ $skinHtml .=
+ '<div class="config-skins-item">' .
+ $this->parent->getCheckBox( array(
+ 'var' => "skin-$skin",
+ 'rawtext' => $skin,
+ 'value' => $this->getVar( "skin-$skin", true ), // all found skins enabled by default
+ ) ) .
+ '<div class="config-skins-use-as-default">' . $radioButtons[ strtolower( $skin ) ] . '</div>' .
+ '</div>';
+ }
+ } else {
+ $skinHtml .= $this->parent->getWarningBox( wfMessage( 'config-skins-missing' )->plain() );
+ }
+
+ $skinHtml .= $this->parent->getHelpBox( 'config-skins-help' ) .
+ $this->getFieldSetEnd();
+ $this->addHTML( $skinHtml );
+
$extensions = $this->parent->findExtensions();
if ( $extensions ) {
$this->addHTML( $this->getCCDoneBox() );
}
+ /**
+ * Returns a default value to be used for $wgDefaultSkin: the preferred skin, if available among
+ * the installed skins, or any other one otherwise.
+ *
+ * @param string[] $skinNames Names of installed skins.
+ * @return string
+ */
+ public function getDefaultSkin( array $skinNames ) {
+ $defaultSkin = $GLOBALS['wgDefaultSkin'];
+ if ( in_array( $defaultSkin, $skinNames ) ) {
+ return $defaultSkin;
+ } else {
+ return $skinNames[0];
+ }
+ }
+
+ /**
+ * If the user skips this installer page, we still need to set up the default skins, but ignore
+ * everything else.
+ *
+ * @return bool
+ */
+ public function submitSkins() {
+ $skins = $this->parent->findExtensions( 'skins' );
+ $this->parent->setVar( '_Skins', $skins );
+
+ if ( $skins ) {
+ $skinNames = array_map( 'strtolower', $skins );
+ $this->parent->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
+ }
+
+ return true;
+ }
+
/**
* @return bool
*/
'wgEnableEmail', 'wgPasswordSender', 'wgEnableUploads', 'wgLogo',
'wgEnableUserEmail', 'wgEnotifUserTalk', 'wgEnotifWatchlist',
'wgEmailAuthentication', 'wgMainCacheType', '_MemCachedServers',
- 'wgUseInstantCommons' ) );
+ 'wgUseInstantCommons', 'wgDefaultSkin' ) );
$retVal = true;
$this->setVar( 'wgRightsIcon', '' );
}
+ $skinsAvailable = $this->parent->findExtensions( 'skins' );
+ $skinsToInstall = array();
+ foreach ( $skinsAvailable as $skin ) {
+ $this->parent->setVarsFromRequest( array( "skin-$skin" ) );
+ if ( $this->getVar( "skin-$skin" ) ) {
+ $skinsToInstall[] = $skin;
+ }
+ }
+ $this->parent->setVar( '_Skins', $skinsToInstall );
+
+ if ( !$skinsToInstall && $skinsAvailable ) {
+ $this->parent->showError( 'config-skins-must-enable-some' );
+ $retVal = false;
+ }
+ $defaultSkin = $this->getVar( 'wgDefaultSkin' );
+ $skinsToInstallLowercase = array_map( 'strtolower', $skinsToInstall );
+ if ( $skinsToInstall && array_search( $defaultSkin, $skinsToInstallLowercase ) === false ) {
+ $this->parent->showError( 'config-skins-must-enable-default' );
+ $retVal = false;
+ }
+
$extsAvailable = $this->parent->findExtensions();
$extsToInstall = array();
foreach ( $extsAvailable as $ext ) {
"config-memcache-badport": "Memcached port numbers should be between $1 and $2.",
"config-extensions": "Extensions",
"config-extensions-help": "The extensions listed above were detected in your <code>./extensions</code> directory.\n\nThey may require additional configuration, but you can enable them now.",
+ "config-skins": "Skins",
+ "config-skins-help": "The skins listed above were detected in your <code>./skins</code> directory. You must enable at least one, and choose the default.",
+ "config-skins-use-as-default": "Use this skin as default",
+ "config-skins-missing": "No skins were found; MediaWiki will use a fallback skin until you install some proper ones.",
+ "config-skins-must-enable-some": "You must choose at least one skin to enable.",
+ "config-skins-must-enable-default": "The skin chosen as default must be enabled.",
"config-install-alreadydone": "<strong>Warning:</strong> You seem to have already installed MediaWiki and are trying to install it again.\nPlease proceed to the next page.",
"config-install-begin": "By pressing \"{{int:config-continue}}\", you will begin the installation of MediaWiki.\nIf you still want to make changes, press \"{{int:config-back}}\".",
"config-install-step-done": "done",
"config-memcache-badport": "Used as error message. Parameters:\n* $1 - 1 (hard-coded)\n* $2 - 65535 (hard-coded)\nSee also:\n* {{msg-mw|Config-memcache-badip}}\n* {{msg-mw|Config-memcache-noport}}",
"config-extensions": "{{Identical|Extension}}",
"config-extensions-help": "{{doc-important|Do not translate <code>./extensions</code>.}}\nUsed in help box.",
+ "config-skins": "{{Identical|Skin}}",
+ "config-skins-help": "{{doc-important|Do not translate <code>./skins</code>.}}\nUsed in help box.",
+ "config-skins-use-as-default": "Label shown next to skin names.",
+ "config-skins-missing": "Warning message shown when there are no skins to install.",
+ "config-skins-must-enable-some": "Error message shown when the user does silly things.",
+ "config-skins-must-enable-default": "Error message shown when the user does silly things.",
"config-install-alreadydone": "Error message shown to users visiting the installer when the wiki appears to already be set up.",
"config-install-begin": "Prompt at the end of the initial configuration options screen before the wiki software is installed.",
"config-install-step-done": "{{Identical|Done}}",
// background colour. After merging we reset the background
// to be white for the default background colour setting
// in the PNG image (which is used in old IE)
- $animation_post = array(
+ $animation_pre = array(
'-background', 'transparent',
'-layers', 'merge',
'-background', 'white',
// bug 66323 - Greyscale images not rendered properly.
// So only take the "red" channel.
$channelOnly = array( '-channel', 'R', '-separate' );
- $animation_post = array_merge( $animation_post, $channelOnly );
+ $animation_pre = array_merge( $animation_pre, $channelOnly );
}
}
# Use a callback function to configure MediaWiki
call_user_func( MW_CONFIG_CALLBACK );
} else {
- if ( file_exists( "$IP/../wmf-config/wikimedia-mode" ) ) {
- // Load settings, using wikimedia-mode if needed
- // @todo FIXME: Replace this hack with general farm-friendly code
- # @todo FIXME: Wikimedia-specific stuff needs to go away to an ext
- # Maybe a hook?
- // @codingStandardsIgnoreStart MediaWiki.NamingConventions.ValidGlobalName.wgPrefix
- global $cluster;
- $cluster = 'pmtpa';
- // @codingStandardsIgnoreEnd
- require "$IP/../wmf-config/wgConf.php";
- }
// Require the configuration (probably LocalSettings.php)
require $maintenance->loadSettings();
}
function handleUpload( $revision ) {
if ( $this->uploads ) {
if ( $this->skippedNamespace( $revision ) ) {
- return;
+ return false;
}
$this->uploadCount++;
// $this->report();
return $dbw->deadlockLoop( array( $revision, 'importUpload' ) );
}
}
+
+ return false;
}
function handleLogItem( $rev ) {
exit 1
fi
-TARGET_REPO=$(cd $(dirname $0)/../..; pwd)
+TARGET_REPO=$(cd "$(dirname $0)/../.."; pwd)
TARGET_DIR=resources/lib/oojs-ui
UI_REPO=$1
function oojsuihash() {
- grep "OOjs UI v" $TARGET_REPO/$TARGET_DIR/oojs-ui.js \
+ grep "OOjs UI v" "$TARGET_REPO/$TARGET_DIR/oojs-ui.js" \
| head -n 1 \
| grep -Eo '\([a-z0-9]+\)' \
| sed 's/^(//' \
}
function oojsuitag() {
- grep "OOjs UI v" $TARGET_REPO/$TARGET_DIR/oojs-ui.js \
+ grep "OOjs UI v" "$TARGET_REPO/$TARGET_DIR/oojs-ui.js" \
| head -n 1 \
| grep -Eo '\bv[0-9a-z.-]+\b'
}
function oojsuiversion() {
- grep "OOjs UI v" $TARGET_REPO/$TARGET_DIR/oojs-ui.js \
+ grep "OOjs UI v" "$TARGET_REPO/$TARGET_DIR/oojs-ui.js" \
| head -n 1 \
| grep -Eo '\bv[0-9a-z.-]+\b.*$'
}
# Prepare working tree
-cd $TARGET_REPO &&
+cd "$TARGET_REPO" &&
git reset $TARGET_DIR && git checkout $TARGET_DIR && git fetch origin &&
git checkout -B upstream-oojsui origin/master || exit 1
fi
if [ "$OLDHASH" == "" ]
then
- OLDHASH=$(git rev-parse $OLDTAG)
+ OLDHASH=$(git rev-parse "$OLDTAG")
if [ $? != 0 ]
then
- echo Could not find OOjs UI version
+ echo "Could not find OOjs UI version"
cd -
exit 1
fi
NEWCHANGESDISPLAY=$(git log $OLDHASH.. --oneline --no-merges --reverse --color=always)
# Copy files
-# - Exclude the default non-svg stylesheet
-rsync --recursive --delete --force --exclude 'oojs-ui.css' --exclude 'oojs-ui*.rtl.css' ./dist/ $TARGET_REPO/$TARGET_DIR || exit 1
+rsync --recursive --delete --force \
+ # Exclude the default non-svg stylesheet, and those for enviroments without CSSJanus
+ --exclude 'oojs-ui.css' --exclude 'oojs-ui*.rtl.css' \
+ ./dist/ "$TARGET_REPO/$TARGET_DIR" || exit 1
# Read the new version
NEWVERSION=$(oojsuiversion)
# Generate commit
-cd $TARGET_REPO
+cd "$TARGET_REPO"
COMMITMSG=$(cat <<END
Update OOjs UI to $NEWVERSION
exit 1
fi
-REPO_DIR=$(cd $(dirname $0)/../..; pwd) # Root dir of the git repo working tree
-TARGET_DIR=resources/lib/oojs # Destination relative to the root of the repo
-NPM_DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'update-oojs'` # e.g. /tmp/update-oojs.rI0I5Vir
+REPO_DIR=$(cd "$(dirname $0)/../.."; pwd) # Root dir of the git repo working tree
+TARGET_DIR="resources/lib/oojs" # Destination relative to the root of the repo
+NPM_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'update-oojs') # e.g. /tmp/update-oojs.rI0I5Vir
# Prepare working tree
-cd $REPO_DIR &&
+cd "$REPO_DIR" &&
git reset $TARGET_DIR && git checkout $TARGET_DIR && git fetch origin &&
git checkout -B upstream-oojs origin/master || exit 1
cd $NPM_DIR
if [ -n "$1" ]
then
- npm install oojs@$1 || exit 1
+ npm install "oojs@$1" || exit 1
else
npm install oojs || exit 1
fi
fi
# Copy file(s)
-rsync --recursive --delete --force ./node_modules/oojs/dist $REPO_DIR/$TARGET_DIR || exit 1
+rsync --recursive --delete --force ./node_modules/oojs/dist "$REPO_DIR/$TARGET_DIR" || exit 1
# Clean up temporary area
-rm -rf $NPM_DIR
+rm -rf "$NPM_DIR"
# Generate commit
cd $REPO_DIR || exit 1
"Xuacu"
]
},
- "ooui-dialog-action-close": "Zarrar",
"ooui-outline-control-move-down": "Mover abaxo l'elementu",
"ooui-outline-control-move-up": "Mover arriba l'elementu",
"ooui-outline-control-remove": "Desaniciar elementu",
"ooui-toolbar-more": "Más",
- "ooui-dialog-confirm-title": "Confirmar",
- "ooui-dialog-confirm-default-prompt": "¿Tas seguru?",
- "ooui-dialog-confirm-default-ok": "Aceutar",
- "ooui-dialog-confirm-default-cancel": "Encaboxar"
+ "ooui-dialog-message-accept": "Aceutar",
+ "ooui-dialog-message-reject": "Encaboxar",
+ "ooui-dialog-process-error": "Daqué funcionó mal",
+ "ooui-dialog-process-dismiss": "Descartar",
+ "ooui-dialog-process-retry": "Vuelvi a intentalo"
}
"Lam-ang"
]
},
- "ooui-dialog-action-close": "Irekep",
"ooui-outline-control-move-down": "Ipababa ti banag",
"ooui-outline-control-move-up": "Ipangato ti banag",
"ooui-outline-control-remove": "Ikkaten ti banag",
"ooui-toolbar-more": "Adu pay",
- "ooui-dialog-confirm-title": "Pasingkedan",
- "ooui-dialog-confirm-default-prompt": "Siguradoka kadi?",
- "ooui-dialog-confirm-default-ok": "Sige",
- "ooui-dialog-confirm-default-cancel": "Ukasen"
+ "ooui-dialog-message-accept": "Sige",
+ "ooui-dialog-message-reject": "Ukasen",
+ "ooui-dialog-process-error": "Adda madi a napasamak",
+ "ooui-dialog-process-dismiss": "Pugsayen",
+ "ooui-dialog-process-retry": "Padasen manen"
}
"Tumsaa"
]
},
- "ooui-dialog-action-close": "Cufi",
"ooui-outline-control-move-down": "Gad buusi",
"ooui-outline-control-move-up": "Ol baasi",
"ooui-outline-control-remove": "Balleessi",
- "ooui-toolbar-more": "Dabalata"
+ "ooui-toolbar-more": "Dabalata",
+ "ooui-dialog-message-accept": "Tole",
+ "ooui-dialog-message-reject": "Dhiisi",
+ "ooui-dialog-process-error": "Dogoggorri wayii ummameera",
+ "ooui-dialog-process-dismiss": "Didi",
+ "ooui-dialog-process-retry": "Itti deebi'ii yaali"
}
"ooui-outline-control-move-up": "Tool tip for a button that moves items in a list up one place",
"ooui-outline-control-remove": "Tool tip for a button that removes items from a list.\n{{Identical|Remove item}}",
"ooui-toolbar-more": "Label for the toolbar group that contains a list of all other available tools.\n{{Identical|More}}",
- "ooui-dialog-message-accept": "Default label for the accept button of a message dialog",
- "ooui-dialog-message-reject": "Default label for the reject button of a message dialog",
+ "ooui-dialog-message-accept": "Default label for the accept button of a message dialog\n{{Identical|OK}}",
+ "ooui-dialog-message-reject": "Default label for the reject button of a message dialog\n{{Identical|Cancel}}",
"ooui-dialog-process-error": "Title for process dialog error description",
"ooui-dialog-process-dismiss": "Label for process dialog dismiss error button, visible when describing errors\n{{Identical|Dismiss}}",
"ooui-dialog-process-retry": "Label for process dialog retry action button, visible when describing recoverable errors\n{{Identical|Try again}}"
"ooui-dialog-message-accept": "יאָ",
"ooui-dialog-message-reject": "אַנולירן",
"ooui-dialog-process-error": "עפעס איז דורכגעפאלן",
+ "ooui-dialog-process-dismiss": "צומאַכן",
"ooui-dialog-process-retry": "פרובירט נאכאמאל"
}
"Cwlin0416"
]
},
- "ooui-dialog-action-close": "關閉",
"ooui-outline-control-move-down": "項目下移",
"ooui-outline-control-move-up": "項目上移",
"ooui-outline-control-remove": "移除項目",
"ooui-toolbar-more": "更多",
- "ooui-dialog-confirm-title": "確認",
- "ooui-dialog-confirm-default-prompt": "您確定嗎?",
- "ooui-dialog-confirm-default-ok": "確定",
- "ooui-dialog-confirm-default-cancel": "取消"
+ "ooui-dialog-message-accept": "確定",
+ "ooui-dialog-message-reject": "取消",
+ "ooui-dialog-process-error": "發生不明錯誤",
+ "ooui-dialog-process-dismiss": "放棄",
+ "ooui-dialog-process-retry": "再試一次"
}
/*!
- * OOjs UI v0.1.0-pre (a1b99bb256)
+ * OOjs UI v0.1.0-pre (5ab041a801)
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-07-17T19:17:19Z
+ * Date: 2014-07-19T22:45:44Z
*/
.oo-ui-dialog-content > .oo-ui-window-head,
.oo-ui-dialog-content > .oo-ui-window-body,
margin-top: -0.125em;
}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonedElement-framed {
+ margin: 0.75em 0 0.75em 0.75em;
+ border: solid 1px #ccc;
+ border-radius: 0.25em;
+}
+
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button {
background-color: rgba(0, 0, 0, 0.1);
}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed {
+ margin: 0.75em;
+}
+
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button {
+ /* Adjust for border so text aligns with title */
+
+ margin: -1px;
+}
+
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggableElement-primary:hover,
.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggableElement-primary:hover {
background-color: rgba(8, 126, 204, 0.05);
padding-right: 2.25em;
}
-.oo-ui-processDialog-actions-other:not(:empty) {
- padding: 0.75em;
-}
-
-.oo-ui-processDialog-actions-other:not(:empty) .oo-ui-actionWidget {
- margin: 0 0.75em 0 0;
- border: solid 1px #ccc;
- border-radius: 0.25em;
-}
-
.oo-ui-processDialog > .oo-ui-window-frame {
min-height: 5em;
}
/*!
- * OOjs UI v0.1.0-pre (a1b99bb256)
+ * OOjs UI v0.1.0-pre (5ab041a801)
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-07-17T19:17:19Z
+ * Date: 2014-07-19T22:45:44Z
*/
.oo-ui-dialog-content > .oo-ui-window-head,
.oo-ui-dialog-content > .oo-ui-window-body,
margin-top: -0.125em;
}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonedElement-framed {
+ margin: 0.75em 0 0.75em 0.75em;
+}
+
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button {
vertical-align: middle;
}
-.oo-ui-processDialog-actions-safe.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
-.oo-ui-processDialog-actions-primary.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button {
- margin: 0.75em;
-}
-
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover,
.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover {
background-color: rgba(0, 0, 0, 0.05);
background-color: rgba(0, 0, 0, 0.1);
}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed {
+ margin: 0.75em;
+}
+
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button {
+ /* Adjust for border so text aligns with title */
+
+ margin: -1px;
+}
+
.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggableElement-primary:hover,
.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggableElement-primary:hover {
background-color: rgba(8, 126, 204, 0.05);
padding-right: 2.25em;
}
-.oo-ui-processDialog-actions-other:not(:empty) {
- padding: 0.75em;
-}
-
-.oo-ui-processDialog-actions-other:not(:empty) .oo-ui-actionWidget {
- margin: 0 0.75em 0 0;
-}
-
.oo-ui-processDialog > .oo-ui-window-frame {
min-height: 5em;
}
/*!
- * OOjs UI v0.1.0-pre (a1b99bb256)
+ * OOjs UI v0.1.0-pre (5ab041a801)
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-07-17T19:17:19Z
+ * Date: 2014-07-19T22:45:44Z
*/
( function ( OO ) {
others = this.actions.getOthers();
if ( special.primary ) {
this.$primaryActions.append( special.primary.$element );
- special.primary.toggleFramed( false );
+ special.primary.toggleFramed( true );
}
if ( others.length ) {
for ( i = 0, len = others.length; i < len; i++ ) {
}
if ( special.safe ) {
this.$safeActions.append( special.safe.$element );
- special.safe.toggleFramed( false );
+ special.safe.toggleFramed( true );
}
this.fitLabel();
/*!
- * OOjs UI v0.1.0-pre (a1b99bb256)
+ * OOjs UI v0.1.0-pre (5ab041a801)
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-07-17T19:17:19Z
+ * Date: 2014-07-19T22:45:44Z
*/
/* Textures */
}
}
- // Search it as parent, because the form control can also inside the label element itself
+ // Search it as parent, because the form control can also be inside the label element itself
$labelParent = $element.parents( 'label' );
if ( $labelParent.length === 1 ) {
updateTooltipOnElement( element, $labelParent[0] );
/**
* Execute a function as soon as one or more required modules are ready.
*
- * If the required modules are already loaded, the function will be
- * executed immediately and the modules will not be reloaded.
- *
* Example of inline dependency on OOjs:
*
* mw.loader.using( 'oojs', function () {
margin-left: 10em;
}
+.config-skins-item {
+ /* Clearfix */
+ clear: left;
+ overflow: hidden;
+}
+
+.config-skins-item .config-input-check {
+ margin-left: 10em;
+ width: 20em;
+ float: left;
+}
+
+.config-skins-item .config-skins-use-as-default {
+ float: left;
+}
+
.error {
color: red;
background-color: #fff;
<?php
+/**
+ * @group GlobalFunctions
+ */
class GlobalTest extends MediaWikiTestCase {
protected function setUp() {
parent::setUp();
<?php
/**
+ * @group GlobalFunctions
* @group Database
*/
class GlobalWithDBTest extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfAssembleUrl
*/
class WfAssembleUrlTest extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfBCP47
*/
class WfBCP47Test extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfBaseConvert
*/
class WfBaseConvertTest extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfBaseName
*/
class WfBaseNameTest extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfExpandUrl
*/
class WfExpandUrlTest extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfGetCaller
*/
class WfGetCallerTest extends MediaWikiTestCase {
*/
/**
+ * @group GlobalFunctions
* @covers ::wfParseUrl
*/
class WfParseUrlTest extends MediaWikiTestCase {
<?php
+
/**
+ * @group GlobalFunctions
*@covers ::wfRemoveDotSegments
*/
class WfRemoveDotSegmentsTest extends MediaWikiTestCase {
<?php
/**
+ * @group GlobalFunctions
* @covers ::wfShorthandToInteger
*/
class WfShorthandToIntegerTest extends MediaWikiTestCase {
<?php
-/*
+
+/**
+ * @group GlobalFunctions
* @covers ::wfTimestamp
*/
class WfTimestampTest extends MediaWikiTestCase {
<?php
+
/**
* The function only need a string parameter and might react to IIS7.0
+ *
+ * @group GlobalFunctions
* @covers ::wfUrlencode
*/
class WfUrlencodeTest extends MediaWikiTestCase {