Commit 6e3832f4 authored by webchick's avatar webchick

#264876 by Rob Loach, jhedstrom, mfer: Allow external CSS files through drupal_add_css().

parent bc2a814c
......@@ -2423,13 +2423,16 @@ function drupal_add_link($attributes) {
* - 'inline': A string of CSS that should be placed in the given scope. Note
* that it is better practice to use 'file' stylesheets, rather than 'inline'
* as the CSS would then be aggregated and cached.
* - 'external': The absolute path to an external CSS file that is not hosted
* on the local server. These files will not be aggregated if CSS aggregation
* is enabled.
*
* @param $options
* (optional) A string defining the 'type' of CSS that is being added in the
* $data parameter ('file'/'inline'), or an array which can have any or all of
* the following keys:
* - 'type': The type of stylesheet being added. Available options are 'file'
* or 'inline'. Defaults to 'file'.
* - 'type': The type of stylesheet being added. Available options are 'file',
* 'inline' or 'external'. Defaults to 'file'.
* - 'weight': The weight of the stylesheet specifies the order in which the
* CSS will appear when presented on the page.
*
......@@ -2454,7 +2457,8 @@ function drupal_add_link($attributes) {
* files into one file that is then compressed by removing all extraneous
* white space. Note that preprocessed inline stylesheets will not be
* aggregated into this single file, instead it will just be compressed
* when being output on the page.
* when being output on the page. External stylesheets will not be
* aggregated.
*
* The reason for merging the CSS files is outlined quite thoroughly here:
* http://www.die.net/musings/page_load_time/
......@@ -2501,14 +2505,15 @@ function drupal_add_css($data = NULL, $options = NULL) {
// Add the data to the CSS array depending on the type.
switch ($options['type']) {
case 'file':
$css[$data] = $options;
break;
case 'inline':
// For inline stylesheets, we don't want to use the $data as the array
// key as $data could be a very long string of CSS.
$css[] = $options;
break;
default:
// Local and external files must keep their name as the associative key
// so the same CSS file is not be added twice.
$css[$data] = $options;
}
}
......@@ -2576,6 +2581,7 @@ function drupal_get_css($css = NULL) {
// Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones.
$rendered_css = array();
$inline_css = '';
$external_css = '';
$preprocess_items = array();
foreach ($css as $data => $item) {
// Loop through each of the stylesheets, including them appropriately based
......@@ -2597,6 +2603,10 @@ function drupal_get_css($css = NULL) {
// Include inline stylesheets.
$inline_css .= drupal_load_stylesheet_content($item['data'], $item['preprocess']);
break;
case 'external':
// Preprocessing for external CSS files is ignored.
$external_css .= '<link type="text/css" rel="stylesheet" media="' . $item['media'] . '" href="' . $item['data'] . '" />' . "\n";
break;
}
}
......@@ -2615,7 +2625,7 @@ function drupal_get_css($css = NULL) {
}
// Output all the CSS files with the inline stylesheets showing up last.
return implode("\n", $rendered_css) . $inline_css;
return implode("\n", $rendered_css) . $external_css . $inline_css;
}
/**
......@@ -2826,7 +2836,9 @@ function drupal_clear_css_cache() {
* (optional) If given, the value depends on the $options parameter:
* - 'file': Path to the file relative to base_path().
* - 'inline': The JavaScript code that should be placed in the given scope.
* - 'external': The absolute path to a JavaScript file hosted externally.
* - 'external': The absolute path to an external JavaScript file that is not
* hosted on the local server. These files will not be aggregated if
* JavaScript aggregation is enabled.
* - 'setting': An array with configuration options as associative array. The
* array is directly placed in Drupal.settings. All modules should wrap
* their actual configuration settings in another variable to prevent
......@@ -2940,7 +2952,6 @@ function drupal_add_js($data = NULL, $options = NULL) {
// Local and external files must keep their name as the associative key
// so the same JavaScript file is not be added twice.
$javascript[$options['data']] = $options;
break;
}
}
return $javascript;
......
......@@ -224,6 +224,15 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
$this->assertEqual($css[$path]['data'], $path, t('Adding a CSS file caches it properly.'));
}
/**
* Tests adding an external stylesheet.
*/
function testAddExternal() {
$path = 'http://example.com/style.css';
$css = drupal_add_css($path, 'external');
$this->assertEqual($css[$path]['type'], 'external', t('Adding an external CSS file caches it properly.'));
}
/**
* Makes sure that reseting the CSS empties the cache.
*/
......@@ -238,7 +247,18 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
function testRenderFile() {
$css = drupal_get_path('module', 'simpletest') . '/simpletest.css';
drupal_add_css($css);
$this->assertTrue(strpos(drupal_get_css(), $css) > 0, t('Rendered CSS includes the added stylesheet.'));
$styles = drupal_get_css();
$this->assertTrue(strpos($styles, $css) > 0, t('Rendered CSS includes the added stylesheet.'));
}
/**
* Tests rendering an external stylesheet.
*/
function testRenderExternal() {
$css = 'http://example.com/style.css';
drupal_add_css($css, 'external');
$styles = drupal_get_css();
$this->assertTrue(strpos($styles, 'href="' . $css) > 0, t('Rendering an external CSS file.'));
}
/**
......@@ -248,8 +268,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
$css = 'body { padding: 0px; }';
$css_preprocessed = '<style type="text/css">' . drupal_load_stylesheet_content($css, TRUE) . '</style>';
drupal_add_css($css, 'inline');
$css = drupal_get_css();
$this->assertEqual($css, "\n" . $css_preprocessed, t('Rendering preprocessed inline CSS adds it to the page.'));
$styles = drupal_get_css();
$this->assertEqual($styles, "\n" . $css_preprocessed, t('Rendering preprocessed inline CSS adds it to the page.'));
}
/**
......@@ -258,7 +278,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
function testRenderInlineNoPreprocess() {
$css = 'body { padding: 0px; }';
drupal_add_css($css, array('type' => 'inline', 'preprocess' => FALSE));
$this->assertTrue(strpos(drupal_get_css(), $css) > 0, t('Rendering non-preprocessed inline CSS adds it to the page.'));
$styles = drupal_get_css();
$this->assertTrue(strpos($styles, $css) > 0, t('Rendering non-preprocessed inline CSS adds it to the page.'));
}
/**
......@@ -300,8 +321,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
drupal_get_path('module', 'simpletest') . '/simpletest.css',
);
$css = drupal_get_css();
if (preg_match_all('/href="' . preg_quote(base_path(), '/') . '([^?]+)\?/', $css, $matches)) {
$styles = drupal_get_css();
if (preg_match_all('/href="' . preg_quote(base_path(), '/') . '([^?]+)\?/', $styles, $matches)) {
$result = $matches[1];
}
else {
......@@ -319,17 +340,17 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
drupal_add_css(drupal_get_path('module', 'simpletest') . '/tests/system.css');
// The dummy stylesheet should be the only one included.
$css = drupal_get_css();
$this->assert(strpos($css, drupal_get_path('module', 'simpletest') . '/tests/system.css') !== FALSE, t('The overriding CSS file is output.'));
$this->assert(strpos($css, drupal_get_path('module', 'system') . '/system.css') === FALSE, t('The overriden CSS file is not output.'));
$styles = drupal_get_css();
$this->assert(strpos($styles, drupal_get_path('module', 'simpletest') . '/tests/system.css') !== FALSE, t('The overriding CSS file is output.'));
$this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system.css') === FALSE, t('The overriden CSS file is not output.'));
drupal_add_css(drupal_get_path('module', 'simpletest') . '/tests/system.css');
drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
// The standard stylesheet should be the only one included.
$css = drupal_get_css();
$this->assert(strpos($css, drupal_get_path('module', 'system') . '/system.css') !== FALSE, t('The overriding CSS file is output.'));
$this->assert(strpos($css, drupal_get_path('module', 'simpletest') . '/tests/system.css') === FALSE, t('The overriden CSS file is not output.'));
$styles = drupal_get_css();
$this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system.css') !== FALSE, t('The overriding CSS file is output.'));
$this->assert(strpos($styles, drupal_get_path('module', 'simpletest') . '/tests/system.css') === FALSE, t('The overriden CSS file is not output.'));
}
/**
......@@ -342,8 +363,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
// Check to see if system-rtl.css was also added.
$css = drupal_get_css();
$this->assert(strpos($css, drupal_get_path('module', 'system') . '/system-rtl.css') !== FALSE, t('CSS is alterable as right to left overrides are added.'));
$styles = drupal_get_css();
$this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system-rtl.css') !== FALSE, t('CSS is alterable as right to left overrides are added.'));
// Change the language back to left to right.
$language->direction = LANGUAGE_LTR;
......@@ -559,6 +580,15 @@ class JavaScriptTestCase extends DrupalWebTestCase {
$this->assertEqual('rocks', $javascript['settings']['data'][1]['drupal'], t('The other JavaScript setting is set correctly.'));
}
/**
* Tests adding an external JavaScript File.
*/
function testAddExternal() {
$path = 'http://example.com/script.js';
$javascript = drupal_add_js($path, 'external');
$this->assertTrue(array_key_exists('http://example.com/script.js', $javascript), t('Added an external JavaScript file.'));
}
/**
* Test drupal_get_js() for JavaScript settings.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment