summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/ajax.inc25
-rw-r--r--includes/common.inc6
-rw-r--r--misc/ajax.js20
-rw-r--r--modules/simpletest/drupal_web_test_case.php2
-rw-r--r--modules/simpletest/tests/ajax.test8
-rw-r--r--modules/simpletest/tests/ajax_forms_test.module18
-rw-r--r--modules/simpletest/tests/common.test4
7 files changed, 81 insertions, 2 deletions
diff --git a/includes/ajax.inc b/includes/ajax.inc
index 31067c3e0..10877a246 100644
--- a/includes/ajax.inc
+++ b/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);
@@ -1257,3 +1257,26 @@ function ajax_command_update_build_id($form) {
'new' => $form['#build_id'],
);
}
+
+/**
+ * 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/includes/common.inc b/includes/common.inc
index e7e293917..1bfff345b 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -3474,7 +3474,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/misc/ajax.js b/misc/ajax.js
index 3b9dec614..01b894d75 100644
--- a/misc/ajax.js
+++ b/misc/ajax.js
@@ -619,6 +619,26 @@ Drupal.ajax.prototype.commands = {
},
/**
+ * 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]);
+ }
+ }
+ },
+
+ /**
* Command to update a form's build ID.
*/
updateBuildId: function(ajax, response, status) {
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index 39dacfa1d..8ecddb50b 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -2301,6 +2301,8 @@ class DrupalWebTestCase extends DrupalTestCase {
break;
case 'restripe':
break;
+ case 'add_css':
+ break;
}
}
$content = $dom->saveHTML();
diff --git a/modules/simpletest/tests/ajax.test b/modules/simpletest/tests/ajax.test
index a0c7be8a2..c38a325fb 100644
--- a/modules/simpletest/tests/ajax.test
+++ b/modules/simpletest/tests/ajax.test
@@ -368,6 +368,14 @@ class AJAXCommandsTestCase extends AJAXTestCase {
'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/modules/simpletest/tests/ajax_forms_test.module b/modules/simpletest/tests/ajax_forms_test.module
index 28404224e..260d9112e 100644
--- a/modules/simpletest/tests/ajax_forms_test.module
+++ b/modules/simpletest/tests/ajax_forms_test.module
@@ -254,6 +254,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'),
@@ -407,6 +416,15 @@ function ajax_forms_test_advanced_commands_settings_callback($form, $form_state)
}
/**
+ * 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.
*
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index 6e03253a6..21fe833d5 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -661,6 +661,10 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
drupal_add_css($css);
$styles = drupal_get_css();
$this->assertTrue(strpos($styles, $css) > 0, '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 type=\"text/css\" media=\"all\">\n@import url(\"" . check_plain(file_create_url($css)) . "?" . $query_string ."\");\n</style>";
+ $this->assertEqual(trim($styles), $css_processed, 'Rendered CSS includes newlines inside style tags for JavaScript use.');
}
/**