summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2012-02-28 22:11:46 -0800
committerwebchick <webchick@24967.no-reply.drupal.org>2012-02-28 22:11:46 -0800
commit4ac6433a74df2e4b443fa6a314adb3ad4a152d8b (patch)
treec5680ef3dd68f49b359937fb42e97061f7d49b42
parent0f8e2094a3cf33a8018ee394e56bad57b3d0f89c (diff)
downloadbrdo-4ac6433a74df2e4b443fa6a314adb3ad4a152d8b.tar.gz
brdo-4ac6433a74df2e4b443fa6a314adb3ad4a152d8b.tar.bz2
Issue #967166 by effulgentsia, Cottser, no_commit_credit, KrisBulman: Fixed Content rendered via AJAX does not respect stylesheets removed in .info files.
-rw-r--r--includes/common.inc20
-rw-r--r--modules/simpletest/drupal_web_test_case.php90
-rw-r--r--modules/simpletest/tests/ajax.test21
-rw-r--r--modules/simpletest/tests/ajax_test.module8
4 files changed, 88 insertions, 51 deletions
diff --git a/includes/common.inc b/includes/common.inc
index d799616d4..021e1a47d 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -2969,6 +2969,18 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
// Sort CSS items, so that they appear in the correct order.
uasort($css, 'drupal_sort_css_js');
+ // Provide the page with information about the individual CSS files used,
+ // information not otherwise available when CSS aggregation is enabled. The
+ // setting is attached later in this function, but is set here, so that CSS
+ // files removed below are still considered "used" and prevented from being
+ // added in a later AJAX request.
+ // Skip if no files were added to the page or jQuery.extend() will overwrite
+ // the Drupal.settings.ajaxPageState.css object with an empty array.
+ if (!empty($css)) {
+ // Cast the array to an object to be on the safe side even if not empty.
+ $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1);
+ }
+
// Remove the overridden CSS files. Later CSS files override former ones.
$previous_item = array();
foreach ($css as $key => $item) {
@@ -2989,13 +3001,7 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
'#items' => $css,
);
- // Provide the page with information about the individual CSS files used,
- // information not otherwise available when CSS aggregation is enabled.
- // Skip if no files were added to the page or jQuery.extend() will overwrite
- // the Drupal.settings.ajaxPageState.css object with an empty array.
- // Cast the array to an object to be on the safe side even if not empty.
- if (!empty($css)) {
- $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1);
+ if (!empty($setting)) {
$styles['#attached']['js'][] = array('type' => 'setting', 'data' => $setting);
}
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index 9095e22e1..a457a89b3 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -2049,6 +2049,8 @@ class DrupalWebTestCase extends DrupalTestCase {
// them.
$dom = new DOMDocument();
@$dom->loadHTML($content);
+ // XPath allows for finding wrapper nodes better than DOM does.
+ $xpath = new DOMXPath($dom);
foreach ($return as $command) {
switch ($command['command']) {
case 'settings':
@@ -2056,52 +2058,52 @@ class DrupalWebTestCase extends DrupalTestCase {
break;
case 'insert':
- // @todo ajax.js can process commands that include a 'selector', but
- // these are hard to emulate with DOMDocument. For now, we only
- // implement 'insert' commands that use $ajax_settings['wrapper'].
+ $wrapperNode = NULL;
+ // When a command doesn't specify a selector, use the
+ // #ajax['wrapper'] which is always an HTML ID.
if (!isset($command['selector'])) {
- // $dom->getElementById() doesn't work when drupalPostAJAX() is
- // invoked multiple times for a page, so use XPath instead. This
- // also sets us up for adding support for $command['selector'] in
- // the future, once we figure out how to transform a jQuery
- // selector to XPath.
- $xpath = new DOMXPath($dom);
$wrapperNode = $xpath->query('//*[@id="' . $ajax_settings['wrapper'] . '"]')->item(0);
- if ($wrapperNode) {
- // ajax.js adds an enclosing DIV to work around a Safari bug.
- $newDom = new DOMDocument();
- $newDom->loadHTML('<div>' . $command['data'] . '</div>');
- $newNode = $dom->importNode($newDom->documentElement->firstChild->firstChild, TRUE);
- $method = isset($command['method']) ? $command['method'] : $ajax_settings['method'];
- // The "method" is a jQuery DOM manipulation function. Emulate
- // each one using PHP's DOMNode API.
- switch ($method) {
- case 'replaceWith':
- $wrapperNode->parentNode->replaceChild($newNode, $wrapperNode);
- break;
- case 'append':
- $wrapperNode->appendChild($newNode);
- break;
- case 'prepend':
- // If no firstChild, insertBefore() falls back to
- // appendChild().
- $wrapperNode->insertBefore($newNode, $wrapperNode->firstChild);
- break;
- case 'before':
- $wrapperNode->parentNode->insertBefore($newNode, $wrapperNode);
- break;
- case 'after':
- // If no nextSibling, insertBefore() falls back to
- // appendChild().
- $wrapperNode->parentNode->insertBefore($newNode, $wrapperNode->nextSibling);
- break;
- case 'html':
- foreach ($wrapperNode->childNodes as $childNode) {
- $wrapperNode->removeChild($childNode);
- }
- $wrapperNode->appendChild($newNode);
- break;
- }
+ }
+ // @todo Ajax commands can target any jQuery selector, but these are
+ // hard to fully emulate with XPath. For now, just handle 'head'
+ // and 'body', since these are used by ajax_render().
+ elseif (in_array($command['selector'], array('head', 'body'))) {
+ $wrapperNode = $xpath->query('//' . $command['selector'])->item(0);
+ }
+ if ($wrapperNode) {
+ // ajax.js adds an enclosing DIV to work around a Safari bug.
+ $newDom = new DOMDocument();
+ $newDom->loadHTML('<div>' . $command['data'] . '</div>');
+ $newNode = $dom->importNode($newDom->documentElement->firstChild->firstChild, TRUE);
+ $method = isset($command['method']) ? $command['method'] : $ajax_settings['method'];
+ // The "method" is a jQuery DOM manipulation function. Emulate
+ // each one using PHP's DOMNode API.
+ switch ($method) {
+ case 'replaceWith':
+ $wrapperNode->parentNode->replaceChild($newNode, $wrapperNode);
+ break;
+ case 'append':
+ $wrapperNode->appendChild($newNode);
+ break;
+ case 'prepend':
+ // If no firstChild, insertBefore() falls back to
+ // appendChild().
+ $wrapperNode->insertBefore($newNode, $wrapperNode->firstChild);
+ break;
+ case 'before':
+ $wrapperNode->parentNode->insertBefore($newNode, $wrapperNode);
+ break;
+ case 'after':
+ // If no nextSibling, insertBefore() falls back to
+ // appendChild().
+ $wrapperNode->parentNode->insertBefore($newNode, $wrapperNode->nextSibling);
+ break;
+ case 'html':
+ foreach ($wrapperNode->childNodes as $childNode) {
+ $wrapperNode->removeChild($childNode);
+ }
+ $wrapperNode->appendChild($newNode);
+ break;
}
}
break;
diff --git a/modules/simpletest/tests/ajax.test b/modules/simpletest/tests/ajax.test
index 8e731b8e7..014a35042 100644
--- a/modules/simpletest/tests/ajax.test
+++ b/modules/simpletest/tests/ajax.test
@@ -195,6 +195,27 @@ class AJAXFrameworkTestCase extends AJAXTestCase {
$this->assertEqual($new_js, $original_js + array($expected['js'] => 1), t('Page state now has the %js file.', array('%js' => $expected['js'])));
$this->assertCommand($commands, array('data' => $expected_js_html), t('Page now has the %js file.', array('%js' => $expected['js'])));
}
+
+ /**
+ * Tests that overridden CSS files are not added during lazy load.
+ */
+ function testLazyLoadOverriddenCSS() {
+ // The test theme overrides system.base.css without an implementation,
+ // thereby removing it.
+ theme_enable(array('test_theme'));
+ variable_set('theme_default', 'test_theme');
+
+ // This gets the form, and emulates an Ajax submission on it, including
+ // adding markup to the HEAD and BODY for any lazy loaded JS/CSS files.
+ $this->drupalPostAJAX('ajax_forms_test_lazy_load_form', array('add_files' => TRUE), array('op' => t('Submit')));
+
+ // Verify that the resulting HTML does not load the overridden CSS file.
+ // We add a "?" to the assertion, because Drupal.settings may include
+ // information about the file; we only really care about whether it appears
+ // in a LINK or STYLE tag, for which Drupal always adds a query string for
+ // cache control.
+ $this->assertNoText('system.base.css?', 'Ajax lazy loading does not add overridden CSS files.');
+ }
}
/**
diff --git a/modules/simpletest/tests/ajax_test.module b/modules/simpletest/tests/ajax_test.module
index 4148a0839..21be01942 100644
--- a/modules/simpletest/tests/ajax_test.module
+++ b/modules/simpletest/tests/ajax_test.module
@@ -32,6 +32,14 @@ function ajax_test_menu() {
}
/**
+ * Implements hook_system_theme_info().
+ */
+function ajax_test_system_theme_info() {
+ $themes['test_theme'] = drupal_get_path('module', 'ajax_test') . '/themes/test_theme/test_theme.info';
+ return $themes;
+}
+
+/**
* Menu callback; Return an element suitable for use by ajax_deliver().
*
* Additionally ensures that ajax_render() incorporates JavaScript settings