Skip to content

Instantly share code, notes, and snippets.

@piouPiouM
Last active October 7, 2015 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piouPiouM/89d6b0aedef3260152eb to your computer and use it in GitHub Desktop.
Save piouPiouM/89d6b0aedef3260152eb to your computer and use it in GitHub Desktop.
<?php
/**
* Promote the theme stylesheets.
*
* Implements hook_css_alter().
*
* @param array &$css
* An array of all CSS items (files and inline CSS) being requested on the page.
* @param array $options
* (optional) An associative array containing:
* - replace: (optional) an associative array of media type from => to.
* - reset: (optional) an array list of reset files to be moved at the
* beginning of output stack. Default to `array('reset')`.
* - unset_dir: (optional) A directory name used in the `.info` file to
* remove CSS inserted by the core and modules. Default to `'kill'`.
* Example usage:
* @code
* _ppm_utilities_order_css($css, array(
* 'replace' => array('all' => 'screen, projection'),
* 'reset' => array('reset', 'reset-custom')
* ));
* @endcode
*
* @link http://pioupioum.fr/
*/
function _ppm_utilities_order_css(&$css, $options = array()) {
$theme = array();
$stack = array();
$defaults = array(
'replace' => array(),
'reset' => array('reset'),
'unset_dir' => 'kill',
);
$options += $defaults;
// Checks all reset CSS files and adds right to left should be included
// by the module Locale in {@link locale_css_alter()}.
if (count($options['reset'])) {
$reset_css = $options['reset'];
array_walk($reset_css, function ($name) use (&$options) {
if (FALSE !== strpos($name, '-rtl')) {
$options['reset'][] = $name . '-rtl';
}
});
unset($reset_css);
}
/**
* Cleanup media type.
*
* @param string $media
* The input media type to clean.
*
* @return string
*/
$sanitize_media = function ($media) {
if (FALSE !== strpos($media, ',')) {
$media = explode(',', $media);
array_walk($media, function (&$v) { $v = strtolower(trim($v)); });
natsort($media);
$media = implode(',', $media);
}
return $media;
};
// Why consume CPU cycles to process stylesheets that we do not want?
// Let's remove them from the stack maintained by Drupal.
$killed = array();
$css = array_filter($css, function ($stylesheet) use (&$killed, $options) {
if (FALSE !== strpos($stylesheet['data'], '/' . $options['unset_dir'] . '/')) {
$killed[] = basename($stylesheet['data']);
return FALSE;
}
return TRUE;
});
$css = array_filter($css, function ($stylesheet) use ($killed) {
return !in_array(basename($stylesheet['data']), $killed);
});
unset($killed, $stylesheet);
// Flattening substitutions of media types.
if (count($options['replace'])) {
$from = array_map($sanitize_media, array_keys($options['replace']));
$to = array_map($sanitize_media, array_values($options['replace']));
$options['replace'] = array_combine($from, $to);
unset($from, $to);
}
foreach ($css as $delta => $stylesheet) {
// Never deal with external resources.
if ('external' === $stylesheet['type']) {
$stack[$delta] = $stylesheet;
continue;
}
// We force the loading of CSS on every page to limit the number
// of aggregate files.
if (!$stylesheet['every_page']) {
$stylesheet['every_page'] = TRUE;
}
// Standardize media types and make substitutions if necessary.
$media = $sanitize_media($stylesheet['media']);
if (isset($options['replace'][$media])) {
$media = $options['replace'][$media];
}
$stylesheet['media'] = $media;
// The stylesheet has been declared by the theme, we store the key
// to increase their weight at the end of the process.
if (CSS_THEME === $stylesheet['group']) {
$theme[$delta] = $stylesheet;
}
// Otherwise, it is a stylesheet added by the core or a module, we move it
// in the theme group to group 'theme' into a single file after aggregation.
else {
$stylesheet['group'] = CSS_THEME;
$stack[$delta] = $stylesheet;
}
}
// We force the loading of CSS declared by the theme to the end of the stack.
$i = 0;
if (!empty($stack)) {
foreach (array_keys($stack) as $delta) {
$stack[$delta]['weight'] = (++$i) / 1000;
}
$i = $stack[$delta]['weight'];
}
foreach (array_keys($theme) as $delta) {
// If it exists, we ensure that the reset stylesheets is loaded first.
if (in_array(basename($delta, '.css'), $options['reset'])) {
$theme[$delta]['weight'] = -2 + $theme[$delta]['weight'];
}
else {
$i += 0.001;
$theme[$delta]['weight'] = $i;
}
}
$css = array_merge($stack, $theme);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment