<?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