protected $images = array();
protected $variants = array();
- protected $prefix = array();
+ protected $prefix = null;
+ protected $selectorWithoutVariant = '.{prefix}-{type}-{name}';
+ protected $selectorWithVariant = '.{prefix}-{type}-{name}-{variant}';
protected $targets = array( 'desktop', 'mobile' );
/**
* 'localBasePath' => [base path],
* // CSS class prefix to use in all style rules
* 'prefix' => [CSS class prefix],
+ * // Alternatively: Format of CSS selector to use in all style rules
+ * 'selector' => [CSS selector template, variables: {prefix} {type} {name} {variant}],
+ * // Alternatively: When using variants
+ * 'selectorWithoutVariant' => [CSS selector template, variables: {prefix} {type} {name}],
+ * 'selectorWithVariant' => [CSS selector template, variables: {prefix} {type} {name} {variant}],
* // List of variants that may be used for the image files
* 'variants' => array(
* // ([image type] is a string, used in generated CSS class
public function __construct( $options = array(), $localBasePath = null ) {
$this->localBasePath = self::extractLocalBasePath( $options, $localBasePath );
- if ( !isset( $options['prefix'] ) || !$options['prefix'] ) {
- throw new MWException(
- "Required 'prefix' option not given or empty."
- );
+ // Accepted combinations:
+ // * prefix
+ // * selector
+ // * selectorWithoutVariant + selectorWithVariant
+ // * prefix + selector
+ // * prefix + selectorWithoutVariant + selectorWithVariant
+
+ $prefix = isset( $options['prefix'] ) && $options['prefix'];
+ $selector = isset( $options['selector'] ) && $options['selector'];
+ $selectorWithoutVariant = isset( $options['selectorWithoutVariant'] ) && $options['selectorWithoutVariant'];
+ $selectorWithVariant = isset( $options['selectorWithVariant'] ) && $options['selectorWithVariant'];
+
+ if ( $selectorWithoutVariant && !$selectorWithVariant ) {
+ throw new MWException( "Given 'selectorWithoutVariant' but no 'selectorWithVariant'." );
+ }
+ if ( $selectorWithVariant && !$selectorWithoutVariant ) {
+ throw new MWException( "Given 'selectorWithVariant' but no 'selectorWithoutVariant'." );
+ }
+ if ( $selector && $selectorWithVariant ) {
+ throw new MWException( "Incompatible 'selector' and 'selectorWithVariant'+'selectorWithoutVariant' given." );
+ }
+ if ( !$prefix && !$selector && !$selectorWithVariant ) {
+ throw new MWException( "None of 'prefix', 'selector' or 'selectorWithVariant'+'selectorWithoutVariant' given." );
}
foreach ( $options as $member => $option ) {
break;
case 'prefix':
+ case 'selectorWithoutVariant':
+ case 'selectorWithVariant':
$this->{$member} = (string)$option;
break;
+
+ case 'selector':
+ $this->selectorWithoutVariant = $this->selectorWithVariant = (string)$option;
}
}
}
return $this->prefix;
}
+ /**
+ * Get CSS selector templates used by this module.
+ * @return string
+ */
+ public function getSelectors() {
+ return array(
+ 'selectorWithoutVariant' => $this->selectorWithoutVariant,
+ 'selectorWithVariant' => $this->selectorWithVariant,
+ );
+ }
+
/**
* Get a ResourceLoaderImage object for given image.
* @param string $name Image name
// Build CSS rules
$rules = array();
$script = $context->getResourceLoader()->getLoadScript( $this->getSource() );
- $prefix = $this->getPrefix();
+ $selectors = $this->getSelectors();
+
+ $needsTypeWithoutVariant = strpos( $selectors['selectorWithoutVariant'], '{type}' ) !== false;
+ $needsTypeWithVariant = strpos( $selectors['selectorWithVariant'], '{type}' ) !== false;
foreach ( $this->getImages() as $name => $image ) {
$type = $this->getImageType( $name );
$image->getUrl( $context, $script, null, 'rasterized' )
);
$declarations = implode( "\n\t", $declarations );
- $rules[] = ".$prefix-$type-$name {\n\t$declarations\n}";
+ $selector = strtr(
+ $selectors['selectorWithoutVariant'],
+ array(
+ '{prefix}' => $this->getPrefix(),
+ '{name}' => $name,
+ '{variant}' => '',
+ // Somewhat expensive, don't compute if not needed
+ '{type}' => $needsTypeWithoutVariant ? $this->getImageType( $name ) : null,
+ )
+ );
+ $rules[] = "$selector {\n\t$declarations\n}";
// TODO: Get variant configurations from $context->getSkin()
foreach ( $image->getVariants() as $variant ) {
$image->getUrl( $context, $script, $variant, 'rasterized' )
);
$declarations = implode( "\n\t", $declarations );
- $rules[] = ".$prefix-$type-$name-$variant {\n\t$declarations\n}";
+ $selector = strtr(
+ $selectors['selectorWithVariant'],
+ array(
+ '{prefix}' => $this->getPrefix(),
+ '{name}' => $name,
+ '{variant}' => $variant,
+ // Somewhat expensive, don't compute if not needed
+ '{type}' => $needsTypeWithVariant ? $this->getImageType( $name ) : null,
+ )
+ );
+ $rules[] = "$selector {\n\t$declarations\n}";
}
}
}
.oo-ui-icon-bold-invert {
...
+}',
+ ),
+ array(
+ array(
+ 'class' => 'ResourceLoaderImageModule',
+ 'selectorWithoutVariant' => '.mw-ui-icon-{name}:after, .mw-ui-icon-{name}:before',
+ 'selectorWithVariant' => '.mw-ui-icon-{name}-{variant}:after, .mw-ui-icon-{name}-{variant}:before',
+ 'variants' => array(
+ 'icon' => $commonVariants,
+ ),
+ 'images' => array(
+ 'icon' => $commonImageData,
+ ),
+ ),
+ '.mw-ui-icon-advanced:after, .mw-ui-icon-advanced:before {
+ ...
+}
+.mw-ui-icon-advanced-invert:after, .mw-ui-icon-advanced-invert:before {
+ ...
+}
+.mw-ui-icon-remove:after, .mw-ui-icon-remove:before {
+ ...
+}
+.mw-ui-icon-remove-invert:after, .mw-ui-icon-remove-invert:before {
+ ...
+}
+.mw-ui-icon-remove-destructive:after, .mw-ui-icon-remove-destructive:before {
+ ...
+}
+.mw-ui-icon-next:after, .mw-ui-icon-next:before {
+ ...
+}
+.mw-ui-icon-next-invert:after, .mw-ui-icon-next-invert:before {
+ ...
+}
+.mw-ui-icon-help:after, .mw-ui-icon-help:before {
+ ...
+}
+.mw-ui-icon-help-invert:after, .mw-ui-icon-help-invert:before {
+ ...
+}
+.mw-ui-icon-bold:after, .mw-ui-icon-bold:before {
+ ...
+}
+.mw-ui-icon-bold-invert:after, .mw-ui-icon-bold-invert:before {
+ ...
}',
),
);