diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-02-25 08:58:31 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-02-25 08:58:31 +0000 |
commit | 0f712430a6747668f22f8d617590e8057c28180b (patch) | |
tree | 90e3c642ae2fb9b4b6607ce69029092b0c288431 /modules | |
parent | 72793f7c7aa11919f2036af0438a2764048b3c5f (diff) | |
download | brdo-0f712430a6747668f22f8d617590e8057c28180b.tar.gz brdo-0f712430a6747668f22f8d617590e8057c28180b.tar.bz2 |
- Patch #721536 by JacobSingh: fixed inline Javascript not working due to unescaped CDATA element created by saveXML().
Diffstat (limited to 'modules')
-rw-r--r-- | modules/filter/filter.module | 42 | ||||
-rw-r--r-- | modules/filter/filter.test | 21 |
2 files changed, 63 insertions, 0 deletions
diff --git a/modules/filter/filter.module b/modules/filter/filter.module index 01974868f..563bdb5b7 100644 --- a/modules/filter/filter.module +++ b/modules/filter/filter.module @@ -819,6 +819,15 @@ function filter_dom_load($text) { function filter_dom_serialize($dom_document) { $body_node = $dom_document->getElementsByTagName('body')->item(0); $body_content = ''; + + foreach($body_node->getElementsByTagName('script') as $node) { + filter_dom_serialize_escape_cdata_element($dom_document, $node); + } + + foreach($body_node->getElementsByTagName('style') as $node) { + filter_dom_serialize_escape_cdata_element($dom_document, $node, '/*', '*/'); + } + foreach ($body_node->childNodes as $child_node) { $body_content .= $dom_document->saveXML($child_node); } @@ -826,6 +835,39 @@ function filter_dom_serialize($dom_document) { } /** + * Adds comments around the <!CDATA section in a dom element. + * + * DOMDocument::loadHTML in filter_dom_load() makes CDATA sections from the + * contents of inline script and style tags. This can cause HTML 4 browsers to + * throw exceptions. + * + * This function attempts to solve the problem by creating a DocumentFragment + * and immitating the behavior in drupal_get_js(), commenting the CDATA tag. + * + * @param $dom_document + * The DOMDocument containing the $dom_element. + * @param $dom_element + * The element potentially containing a CDATA node. + * @param $comment_start + * String to use as a comment start marker to escape the CDATA declaration. + * @param $comment_end + * String to use as a comment end marker to escape the CDATA declaration. + */ +function filter_dom_serialize_escape_cdata_element($dom_document, $dom_element, $comment_start = '//', $comment_end = '') { + foreach ($dom_element->childNodes as $node) { + if (get_class($node) == 'DOMCdataSection') { + // @see drupal_get_js(). This code is more or less duplicated there. + $embed_prefix = "\n<!--{$comment_start}--><![CDATA[{$comment_start} ><!--{$comment_end}\n"; + $embed_suffix = "\n{$comment_start}--><!]]>{$comment_end}\n"; + $fragment = $dom_document->createDocumentFragment(); + $fragment->appendXML($embed_prefix . $node->data . $embed_suffix); + $dom_element->appendChild($fragment); + $dom_element->removeChild($node); + } + } +} + +/** * Format a link to the more extensive filter tips. * * @ingroup themeable diff --git a/modules/filter/filter.test b/modules/filter/filter.test index 64d3cb514..65e24e113 100644 --- a/modules/filter/filter.test +++ b/modules/filter/filter.test @@ -1065,6 +1065,27 @@ class FilterUnitTestCase extends DrupalUnitTestCase { $f = _filter_htmlcorrector('<p>دروبال'); $this->assertEqual($f, '<p>دروبال</p>', t('HTML corrector -- Encoding is correctly kept.')); + + $f = _filter_htmlcorrector('<script type="text/javascript">alert("test")</script>'); + $this->assertEqual($f, '<script type="text/javascript"> +<!--//--><![CDATA[// ><!-- +alert("test") +//--><!]]> +</script>', t('HTML corrector -- CDATA added to script element')); + + $f = _filter_htmlcorrector('<p><script type="text/javascript">alert("test")</script></p>'); + $this->assertEqual($f, '<p><script type="text/javascript"> +<!--//--><![CDATA[// ><!-- +alert("test") +//--><!]]> +</script></p>', t('HTML corrector -- CDATA added to a nested script element')); + + $f = _filter_htmlcorrector('<p><style> /* Styling */ body {color:red} </style></p>'); + $this->assertEqual($f, '<p><style> +<!--/*--><![CDATA[/* ><!--*/ + /* Styling */ body {color:red} +/*--><!]]>*/ +</style></p>', t('HTML corrector -- CDATA added to a style element.')); } /** |