From 25248da99adbb0221008974cc1e2aeba08bdfdde Mon Sep 17 00:00:00 2001 From: webchick <webchick@24967.no-reply.drupal.org> Date: Sat, 7 Jul 2012 13:52:10 -0700 Subject: [PATCH] Issue #1071818 by JeremyFrench, nod_, reglogge, anthbel, xjm, sun, NROTC_Webmaster, lliss, Cottser: Fixed Lazy-loading CSS fails in IE. --- core/includes/ajax.inc | 25 ++++++++++++++++++- core/includes/common.inc | 6 ++++- core/misc/ajax.js | 20 +++++++++++++++ .../lib/Drupal/simpletest/WebTestBase.php | 2 ++ .../Drupal/system/Tests/Ajax/CommandsTest.php | 8 ++++++ .../Tests/Common/CascadingStylesheetsTest.php | 4 +++ .../ajax_forms_test/ajax_forms_test.module | 18 +++++++++++++ 7 files changed, 81 insertions(+), 2 deletions(-) diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc index a72fc5543a90..328f54cd55d9 100644 --- a/core/includes/ajax.inc +++ b/core/includes/ajax.inc @@ -276,7 +276,7 @@ function ajax_render($commands = array()) { $extra_commands = array(); if (!empty($styles)) { - $extra_commands[] = ajax_command_prepend('head', $styles); + $extra_commands[] = ajax_command_add_css($styles); } if (!empty($scripts_header)) { $extra_commands[] = ajax_command_prepend('head', $scripts_header); @@ -1186,3 +1186,26 @@ function ajax_command_restripe($selector) { 'selector' => $selector, ); } + +/** + * Creates a Drupal Ajax 'add_css' command. + * + * This method will add css via ajax in a cross-browser compatible way. + * + * This command is implemented by Drupal.ajax.prototype.commands.add_css() + * defined in misc/ajax.js. + * + * @param $styles + * A string that contains the styles to be added. + * + * @return + * An array suitable for use with the ajax_render() function. + * + * @see misc/ajax.js + */ +function ajax_command_add_css($styles) { + return array( + 'command' => 'add_css', + 'data' => $styles, + ); +} diff --git a/core/includes/common.inc b/core/includes/common.inc index 5c5777a6abdd..0b95dcd8dbf9 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3304,7 +3304,11 @@ function drupal_pre_render_styles($elements) { $import_batch = array_slice($import, 0, 31); $import = array_slice($import, 31); $element = $style_element_defaults; - $element['#value'] = implode("\n", $import_batch); + // This simplifies the JavaScript regex, allowing each line + // (separated by \n) to be treated as a completely different string. + // This means that we can use ^ and $ on one line at a time, and not + // worry about style tags since they'll never match the regex. + $element['#value'] = "\n" . implode("\n", $import_batch) . "\n"; $element['#attributes']['media'] = $group['media']; $element['#browsers'] = $group['browsers']; $elements[] = $element; diff --git a/core/misc/ajax.js b/core/misc/ajax.js index aef9f310d7ae..71399c4d2171 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -609,6 +609,26 @@ Drupal.ajax.prototype.commands = { .removeClass('odd even') .filter(':even').addClass('odd').end() .filter(':odd').addClass('even'); + }, + + /** + * Command to add css. + * + * Uses the proprietary addImport method if available as browsers which + * support that method ignore @import statements in dynamically added + * stylesheets. + */ + add_css: function (ajax, response, status) { + // Add the styles in the normal way. + $('head').prepend(response.data); + // Add imports in the styles using the addImport method if available. + var match, importMatch = /^@import url\("(.*)"\);$/igm; + if (document.styleSheets[0].addImport && importMatch.test(response.data)) { + importMatch.lastIndex = 0; + while (match = importMatch.exec(response.data)) { + document.styleSheets[0].addImport(match[1]); + } + } } }; diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 592e9d94aed4..0856611e60c8 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -1369,6 +1369,8 @@ protected function drupalPostAJAX($path, $edit, $triggering_element, $ajax_path break; case 'restripe': break; + case 'add_css': + break; } } $content = $dom->saveHTML(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Ajax/CommandsTest.php b/core/modules/system/lib/Drupal/system/Tests/Ajax/CommandsTest.php index 299b674583f6..faa35bbbe3a3 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Ajax/CommandsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Ajax/CommandsTest.php @@ -157,5 +157,13 @@ function testAjaxCommands() { 'settings' => array('ajax_forms_test' => array('foo' => 42)), ); $this->assertCommand($commands, $expected, "'settings' AJAX command issued with correct data"); + + // Tests the 'add_css' command. + $commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'add_css' command"))); + $expected = array( + 'command' => 'add_css', + 'data' => 'my/file.css', + ); + $this->assertCommand($commands, $expected, "'add_css' AJAX command issued with correct data"); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php index 441a2ba3c67b..397762bf4de6 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php @@ -89,6 +89,10 @@ function testRenderFile() { drupal_add_css($css); $styles = drupal_get_css(); $this->assertTrue(strpos($styles, $css) > 0, t('Rendered CSS includes the added stylesheet.')); + // Verify that newlines are properly added inside style tags. + $query_string = variable_get('css_js_query_string', '0'); + $css_processed = "<style media=\"all\">\n@import url(\"" . check_plain(file_create_url($css)) . "?" . $query_string ."\");\n</style>"; + $this->assertEqual(trim($styles), $css_processed, t('Rendered CSS includes newlines inside style tags for JavaScript use.')); } /** diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module index 6a95710a80ad..d4074d1f8213 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module +++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module @@ -258,6 +258,15 @@ function ajax_forms_test_ajax_commands_form($form, &$form_state) { ), ); + // Shows the Ajax 'add_css' command. + $form['add_css_command_example'] = array( + '#type' => 'submit', + '#value' => t("AJAX 'add_css' command"), + '#ajax' => array( + 'callback' => 'ajax_forms_test_advanced_commands_add_css_callback', + ), + ); + $form['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), @@ -410,6 +419,15 @@ function ajax_forms_test_advanced_commands_settings_callback($form, $form_state) return array('#type' => 'ajax', '#commands' => $commands); } +/** + * Ajax callback for 'add_css'. + */ +function ajax_forms_test_advanced_commands_add_css_callback($form, $form_state) { + $commands = array(); + $commands[] = ajax_command_add_css('my/file.css'); + return array('#type' => 'ajax', '#commands' => $commands); +} + /** * This form and its related submit and callback functions demonstrate * not validating another form element when a single Ajax element is triggered. -- GitLab