diff options
-rw-r--r-- | includes/common.inc | 61 | ||||
-rw-r--r-- | modules/color/color.test | 17 | ||||
-rw-r--r-- | modules/simpletest/tests/common.test | 15 |
3 files changed, 60 insertions, 33 deletions
diff --git a/includes/common.inc b/includes/common.inc index b542def81..3b97014ec 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -3327,10 +3327,19 @@ function drupal_build_css_cache($css) { // Only 'file' stylesheets can be aggregated. if ($stylesheet['type'] == 'file') { $contents = drupal_load_stylesheet($stylesheet['data'], TRUE); - // Return the path to where this CSS file originated from. - $base = base_path() . dirname($stylesheet['data']) . '/'; - _drupal_build_css_path(NULL, $base); - // Prefix all paths within this CSS file, ignoring external and absolute paths. + + // Build the base URL of this CSS file: start with the full URL. + $css_base_url = file_create_url($stylesheet['data']); + // Move to the parent. + $css_base_url = substr($css_base_url, 0, strrpos($css_base_url, '/')); + // Simplify to a relative URL if the stylesheet URL starts with the + // base URL of the website. + if (substr($css_base_url, 0, strlen($GLOBALS['base_root'])) == $GLOBALS['base_root']) { + $css_base_url = substr($css_base_url, strlen($GLOBALS['base_root'])); + } + + _drupal_build_css_path(NULL, $css_base_url . '/'); + // Anchor all paths in the CSS with its base URL, ignoring external and absolute paths. $data .= preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', '_drupal_build_css_path', $contents); } } @@ -3406,34 +3415,40 @@ function _drupal_build_css_path($matches, $base = NULL) { * Name of the stylesheet to be processed. * @param $optimize * Defines if CSS contents should be compressed or not. + * @param $reset_basepath + * Used internally to facilitate recursive resolution of @import commands. + * * @return * Contents of the stylesheet, including any resolved @import commands. */ -function drupal_load_stylesheet($file, $optimize = NULL) { - // $_optimize does not use drupal_static as it is set by $optimize. - static $_optimize; - // Store optimization parameter for preg_replace_callback with nested @import loops. +function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE) { + // These statics are not cache variables, so we don't use drupal_static(). + static $_optimize, $basepath; + if ($reset_basepath) { + $basepath = ''; + } + // Store the value of $optimize for preg_replace_callback with nested + // @import loops. if (isset($optimize)) { $_optimize = $optimize; } - $contents = ''; - if (file_exists($file)) { - // Load the local CSS stylesheet. - $contents = file_get_contents($file); - - // Change to the current stylesheet's directory. - $cwd = getcwd(); - chdir(dirname($file)); - - // Process the stylesheet. - $contents = drupal_load_stylesheet_content($contents, $_optimize); + // Stylesheets are relative one to each other. Start by adding a base path + // prefix provided by the parent stylesheet (if necessary). + if ($basepath && !file_uri_scheme($file)) { + $file = $basepath . '/' . $file; + } + $basepath = dirname($file); - // Change back directory. - chdir($cwd); + // Load the CSS stylesheet. We suppress errors because themes may specify + // stylesheets in their .info file that don't exist in the theme's path, + // but are merely there to disable certain module CSS files. + if ($contents = @file_get_contents($file)) { + // Return the processed stylesheet. + return drupal_load_stylesheet_content($contents, $_optimize); } - return $contents; + return ''; } /** @@ -3506,7 +3521,7 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) { function _drupal_load_stylesheet($matches) { $filename = $matches[1]; // Load the imported stylesheet and replace @import commands in there as well. - $file = drupal_load_stylesheet($filename); + $file = drupal_load_stylesheet($filename, NULL, FALSE); // Determine the file's directory. $directory = dirname($filename); diff --git a/modules/color/color.test b/modules/color/color.test index 6fb00c26e..f59d8d7ff 100644 --- a/modules/color/color.test +++ b/modules/color/color.test @@ -71,8 +71,7 @@ class ColorTestCase extends DrupalWebTestCase { $this->assertPattern('|' . file_create_url($stylesheets[0]) . '|', 'Make sure the color stylesheet is included in the content. (' . $theme . ')'); $stylesheet_content = join("\n", file($stylesheets[0])); - $matched = preg_match('/(.*color: #123456.*)/i', $stylesheet_content, $matches); - $this->assertTrue($matched == 1, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); + $this->assertTrue(strpos($stylesheet_content, 'color: #123456') !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); $this->drupalGet($settings_path); $this->assertResponse(200); @@ -82,7 +81,17 @@ class ColorTestCase extends DrupalWebTestCase { $this->drupalGet('<front>'); $stylesheets = variable_get('color_' . $theme . '_stylesheets', array()); $stylesheet_content = join("\n", file($stylesheets[0])); - $matched = preg_match('/(.*color: ' . $test_values['scheme_color'] . '.*)/i', $stylesheet_content, $matches); - $this->assertTrue($matched == 1, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); + $this->assertTrue(strpos($stylesheet_content, 'color: ' . $test_values['scheme_color']) !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); + + // Test with aggregated CSS turned on. + variable_set('preprocess_css', 1); + $this->drupalGet('<front>'); + $stylesheets = variable_get('drupal_css_cache_files', array()); + $stylesheet_content = ''; + foreach ($stylesheets as $key => $uri) { + $stylesheet_content .= join("\n", file(drupal_realpath($uri))); + } + $this->assertTrue(strpos($stylesheet_content, 'public://') === FALSE, 'Make sure the color paths have been translated to local paths. (' . $theme . ')'); + variable_set('preprocess_css', 0); } } diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index c63633ee7..82f8b2e39 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -881,17 +881,20 @@ class CascadingStylesheetsUnitTest extends DrupalUnitTestCase { foreach ($testfiles as $file) { $expected = file_get_contents("$path/$file.unoptimized.css"); $unoptimized_output = drupal_load_stylesheet("$path/$file.unoptimized.css", FALSE); - $this->verbose('Expected:<pre>' . $expected . '</pre>' - . 'Actual:<pre>' . $unoptimized_output . '</pre>' - ); $this->assertEqual($unoptimized_output, $expected, t('Unoptimized CSS file has expected contents (@file)', array('@file' => $file))); $expected = file_get_contents("$path/$file.optimized.css"); $optimized_output = drupal_load_stylesheet("$path/$file", TRUE); - $this->verbose('Expected:<pre>' . $expected . '</pre>' - . 'Actual:<pre>' . $optimized_output . '</pre>' - ); $this->assertEqual($optimized_output, $expected, t('Optimized CSS file has expected contents (@file)', array('@file' => $file))); + + // Repeat the tests by accessing the stylesheets by URL. + $expected = file_get_contents("$path/$file.unoptimized.css"); + $unoptimized_output_url = drupal_load_stylesheet($GLOBALS['base_url'] . "/$path/$file.unoptimized.css", FALSE); + $this->assertEqual($unoptimized_output, $expected, t('Unoptimized CSS file (loaded from an URL) has expected contents (@file)', array('@file' => $file))); + + $expected = file_get_contents("$path/$file.optimized.css"); + $optimized_output = drupal_load_stylesheet($GLOBALS['base_url'] . "/$path/$file", TRUE); + $this->assertEqual($optimized_output, $expected, t('Optimized CSS file (loaded from an URL) has expected contents (@file)', array('@file' => $file))); } } } |