Last active
October 7, 2015 11:46
-
-
Save piouPiouM/89d6b0aedef3260152eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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