core/includes/common.inc | 2 +- core/modules/comment/comment.module | 8 +- .../lib/Drupal/comment/CommentViewBuilder.php | 4 +- .../editor/Plugin/Filter/EditorFileReference.php | 12 +- core/modules/filter/filter.module | 47 ++--- .../lib/Drupal/filter/FilterProcessResult.php | 204 +++++++++++++++++++++ .../Drupal/filter/Plugin/Filter/FilterAutoP.php | 3 +- .../Drupal/filter/Plugin/Filter/FilterCaption.php | 18 +- .../lib/Drupal/filter/Plugin/Filter/FilterHtml.php | 3 +- .../filter/Plugin/Filter/FilterHtmlCorrector.php | 3 +- .../filter/Plugin/Filter/FilterHtmlEscape.php | 3 +- .../filter/Plugin/Filter/FilterHtmlImageSecure.php | 3 +- .../lib/Drupal/filter/Plugin/Filter/FilterNull.php | 3 +- .../lib/Drupal/filter/Plugin/Filter/FilterUrl.php | 3 +- .../lib/Drupal/filter/Plugin/FilterInterface.php | 23 +-- .../lib/Drupal/filter/Tests/FilterAPITest.php | 7 + .../lib/Drupal/filter/Tests/FilterUnitTest.php | 81 ++++---- .../filter_test/Plugin/Filter/FilterTestAssets.php | 14 +- .../Plugin/Filter/FilterTestCacheTags.php | 12 +- .../Plugin/Filter/FilterTestPostRenderCache.php | 16 +- .../Plugin/Filter/FilterTestReplace.php | 3 +- .../Filter/FilterTestRestrictTagsAndAttributes.php | 3 +- .../Field/FieldFormatter/TextDefaultFormatter.php | 4 +- .../Field/FieldFormatter/TextTrimmedFormatter.php | 4 +- .../text/Plugin/Field/FieldType/TextItemBase.php | 18 +- .../Drupal/text/Tests/TextWithSummaryItemTest.php | 65 +++++++ 26 files changed, 414 insertions(+), 152 deletions(-) diff --git a/core/includes/common.inc b/core/includes/common.inc index 65aef09..2a06394 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3705,7 +3705,7 @@ function drupal_render_cache_generate_placeholder($callback, array $context, $to foreach ($context as $key => $value) { $context_attribute .= $key . ':' . $value . ';'; } - return ''; + return ''; } /** diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index be95620..fea8dee 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -13,6 +13,7 @@ use Drupal\comment\CommentInterface; use Drupal\comment\Entity\Comment; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Component\Utility\String; use Drupal\Core\Entity\EntityInterface; use Drupal\entity\Entity\EntityViewDisplay; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; @@ -22,6 +23,7 @@ use Drupal\field\FieldInstanceConfigInterface; use Drupal\field\FieldConfigInterface; use Drupal\file\FileInterface; +use Drupal\filter\FilterProcessResult; use Drupal\user\EntityOwnerInterface; use Drupal\node\NodeInterface; use Symfony\Component\HttpFoundation\Request; @@ -1359,7 +1361,11 @@ function template_preprocess_comment(&$variables) { } if (isset($variables['elements']['signature'])) { - $variables['signature'] = $variables['elements']['signature']['#markup']; + $signature = $variables['elements']['signature']['#markup']; + if (!$signature instanceof FilterProcessResult) { + $signature = String::checkPlain($signature); + } + $variables['signature'] = (string) $signature; unset($variables['elements']['signature']); } else { diff --git a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php index 89667a7..581ed84 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php +++ b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php @@ -139,9 +139,7 @@ public function buildComponents(array &$build, array $entities, array $displays, '#type' => 'processed_text', '#text' => $account->getSignature(), '#format' => $account->getSignatureFormat(), - '#context' => array( - 'langcode' => $entity->language()->getId(), - ), + '#langcode' => $entity->language()->getId(), ); // @todo Document; similar to what we saw in https://drupal.org/node/2099131 drupal_render($build[$id]['signature'], TRUE); diff --git a/core/modules/editor/lib/Drupal/editor/Plugin/Filter/EditorFileReference.php b/core/modules/editor/lib/Drupal/editor/Plugin/Filter/EditorFileReference.php index bfd5dd4..6306f27 100644 --- a/core/modules/editor/lib/Drupal/editor/Plugin/Filter/EditorFileReference.php +++ b/core/modules/editor/lib/Drupal/editor/Plugin/Filter/EditorFileReference.php @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Html; use Drupal\Component\Utility\NestedArray; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -29,6 +30,8 @@ class EditorFileReference extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { + $result = new FilterProcessResult($text); + if (stristr($text, 'data-editor-file-uuid') !== FALSE) { $all_file_cache_tags = array(); $dom = Html::load($text); @@ -40,15 +43,10 @@ public function process($text, $langcode) { $all_file_cache_tags[] = $file->getCacheTag(); } } - return array( - '#markup' => $text, - '#cache' => array( - 'tags' => NestedArray::mergeDeepArray($all_file_cache_tags), - ), - ); + $result->setCacheTags(NestedArray::mergeDeepArray($all_file_cache_tags)); } - return $text; + return $result; } } diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index c1e91ae..ef15e48 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -103,9 +103,7 @@ function filter_element_info() { '#text' => '', '#format' => NULL, '#filter_types_to_skip' => array(), - '#context' => array( - 'langcode' => 'und', - ), + '#langcode' => 'und', '#pre_render' => array('filter_pre_render_text'), ); return $type; @@ -128,10 +126,9 @@ function filter_element_info() { * - #format: containing the machine name of the filter format to be used to * filter the text. Defaults to the fallback format. See * filter_fallback_format(). - * - #context: containing the following key-value pairs: - * - langcode: the language code of the text to be filtered, e.g. 'en' for - * English. This allows filters to be language-aware so language-specific - * text replacement can be implemented. Defaults to 'und'. + * - #langcode: the language code of the text to be filtered, e.g. 'en' for + * English. This allows filters to be language-aware so language-specific + * text replacement can be implemented. Defaults to 'und'. * - #filter_types_to_skip: an array of filter types to skip, or an empty * array (default) to skip no filter types. All of the format's filters will * be applied, except for filters of the types that are marked to be skipped. @@ -147,12 +144,13 @@ function filter_pre_render_text(array $element) { $format_id = $element['#format']; $filter_types_to_skip = $element['#filter_types_to_skip']; $text = $element['#text']; - $langcode = $element['#context']['langcode']; + $langcode = $element['#langcode']; if (!isset($format_id)) { $format_id = filter_fallback_format(); } // If the requested text format does not exist, the text cannot be filtered. + /** @var \Drupal\filter\Entity\FilterFormat $format **/ if (!$format = entity_load('filter_format', $format_id)) { watchdog('filter', 'Missing text format: %format.', array('%format' => $format_id), WATCHDOG_ALERT); $element['#markup'] = ''; @@ -169,9 +167,11 @@ function filter_pre_render_text(array $element) { $text = str_replace(array("\r\n", "\r"), "\n", $text); // Get a complete list of filters, ordered properly. + /** @var \Drupal\filter\FilterBag $filters **/ $filters = $format->filters(); // Give filters the chance to escape HTML-like data such as code or formulas. + /** @var \Drupal\filter\Plugin\FilterInterface $filter **/ foreach ($filters as $filter) { // If necessary, skip filters of a certain type. if (in_array($filter->getType(), $filter_types_to_skip)) { @@ -184,7 +184,7 @@ function filter_pre_render_text(array $element) { // Perform filtering. $all_cache_tags = array(); - $all_attached_assets = array(); + $all_assets = array(); $all_post_render_cache_callbacks = array(); foreach ($filters as $filter) { // If necessary, skip filters of a certain type. @@ -193,21 +193,10 @@ function filter_pre_render_text(array $element) { } if ($filter->status) { $result = $filter->process($text, $langcode); - if (is_string($result)) { - $text = $result; - } - else { - $text = $result['#markup']; - if (isset($result['#cache']) && isset($result['#cache']['tags'])) { - $all_cache_tags[] = $result['#cache']['tags']; - } - if (isset($result['#attached'])) { - $all_attached_assets[] = $result['#attached']; - } - if (isset($result['#post_render_cache'])) { - $all_post_render_cache_callbacks[] = $result['#post_render_cache']; - } - } + $all_assets[] = $result->getAssets(); + $all_cache_tags[] = $result->getCacheTags(); + $all_post_render_cache_callbacks[] = $result->getPostRenderCacheCallbacks(); + $text = $result->getProcessedText(); } } @@ -226,14 +215,14 @@ function filter_pre_render_text(array $element) { // Collect all attached assets. if (isset($element['#attached'])) { // Prepend the original attached assets array. - array_unshift($all_attached_assets, $element['#attached']); + array_unshift($all_assets, $element['#attached']); } - $element['#attached'] = NestedArray::mergeDeepArray($all_attached_assets); + $element['#attached'] = NestedArray::mergeDeepArray($all_assets); // Collect all #post_render_cahe callbacks. if (isset($element['#post_render_cache'])) { // Prepend the original attached #post_render_cache array. - array_unshift($all_attached_assets, $element['#post_render_cache']); + array_unshift($all_assets, $element['#post_render_cache']); } $element['#post_render_cache'] = NestedArray::mergeDeepArray($all_post_render_cache_callbacks); @@ -485,9 +474,7 @@ function check_markup($text, $format_id = NULL, $langcode = 'und', $filter_types '#text' => $text, '#format' => $format_id, '#filter_types_to_skip' => $filter_types_to_skip, - '#context' => array( - 'langcode' => $langcode - ), + '#langcode' => $langcode, ); return drupal_render($build); } diff --git a/core/modules/filter/lib/Drupal/filter/FilterProcessResult.php b/core/modules/filter/lib/Drupal/filter/FilterProcessResult.php new file mode 100644 index 0000000..de40f07 --- /dev/null +++ b/core/modules/filter/lib/Drupal/filter/FilterProcessResult.php @@ -0,0 +1,204 @@ +setAssets(array( + * 'library' => array( + * 'filter/caption', + * ), + * )); + * + * // Associate cache tags to be invalidated by. + * $result->setCacheTags($node->getCacheTag()); + * + * return $result; + * } + * @endcode + */ +class FilterProcessResult { + + /** + * The processed text. + * + * @see \Drupal\filter\Plugin\FilterInterface::process() + * + * @var string + */ + protected $processedText; + + /** + * An array of associated assets to be attached. + * + * @see drupal_process_attached() + * + * @var array + */ + protected $assets; + + /** + * The attached cache tags. + * + * @see drupal_render_collect_cache_tags() + * + * @var array + */ + protected $cacheTags; + + /** + * The associated #post_render_cache callbacks. + * + * @see _drupal_render_process_post_render_cache() + * + * @var array + */ + protected $postRenderCacheCallbacks; + + /** + * Constructs a FilterProcessResult object. + * + * @param string $processed_text + * The text as processed by a text filter. + */ + public function __construct($processed_text) { + $this->processedText = $processed_text; + + $this->assets = array(); + $this->cacheTags = array(); + $this->postRenderCacheCallbacks = array(); + } + + /** + * Gets the processed text. + * + * @return string + */ + public function getProcessedText() { + return $this->processedText; + } + + /** + * Gets the processed text. + * + * @return string + */ + public function __toString() { + return $this->getProcessedText(); + } + + /** + * Sets the processed text. + * + * @param string $processed_text + * The text as processed by a text filter. + * + * @return $this + */ + public function setProcessedText($processed_text) { + $this->processedText = $processed_text; + return $this; + } + + /** + * Gets cache tags associated with the processed text. + * + * @return array + */ + public function getCacheTags() { + return $this->cacheTags; + } + + /** + * Sets cache tags associated with the processed text. + * + * @param array $cache_tags + * The cache tags to be associated. + * + * @return $this + */ + public function setCacheTags(array $cache_tags) { + $this->cacheTags = $cache_tags; + return $this; + } + + /** + * Gets assets associated with the processed text. + * + * @return array + */ + public function getAssets() { + return $this->assets; + } + + /** + * Sets assets associated with the processed text. + * + * @param array $assets + * The associated assets to be attached. + * + * @return $this + */ + public function setAssets(array $assets) { + $this->assets = $assets; + return $this; + } + + /** + * Gets #post_render_cache callbacks associated with the processed text. + * + * @return array + */ + public function getPostRenderCacheCallbacks() { + return $this->postRenderCacheCallbacks; + } + + /** + * Sets #post_render_cache callbacks associated with the processed text. + * + * @param array $post_render_cache_callbacks + * The associated #post_render_cache callbacks to be executed. + * + * @return $this + */ + public function setPostRenderCacheCallbacks(array $post_render_cache_callbacks) { + $this->postRenderCacheCallbacks = $post_render_cache_callbacks; + return $this; + } + +} diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterAutoP.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterAutoP.php index 049785a..0627527 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterAutoP.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterAutoP.php @@ -7,6 +7,7 @@ namespace Drupal\filter\Plugin\Filter; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -24,7 +25,7 @@ class FilterAutoP extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { - return _filter_autop($text); + return new FilterProcessResult(_filter_autop($text)); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterCaption.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterCaption.php index 94edfc5..1b7c7e1 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterCaption.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterCaption.php @@ -11,6 +11,7 @@ use Drupal\Component\Utility\String; use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Xss; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -29,6 +30,8 @@ class FilterCaption extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { + $result = new FilterProcessResult($text); + if (stristr($text, 'data-caption') !== FALSE || stristr($text, 'data-align') !== FALSE) { $caption_found = FALSE; $dom = Html::load($text); @@ -99,21 +102,18 @@ public function process($text, $langcode) { $node->parentNode->replaceChild($updated_node, $node); } - $text = Html::serialize($dom); + $result->setProcessedText(Html::serialize($dom)); if ($caption_found) { - return array( - '#markup' => $text, - '#attached' => array( - 'library' => array( - 'filter/caption', - ), + $result->setAssets(array( + 'library' => array( + 'filter/caption', ), - ); + )); } } - return $text; + return $result; } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtml.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtml.php index ebb02ea..543f147 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtml.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtml.php @@ -7,6 +7,7 @@ namespace Drupal\filter\Plugin\Filter; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -59,7 +60,7 @@ public function settingsForm(array $form, array &$form_state) { * {@inheritdoc} */ public function process($text, $langcode) { - return _filter_html($text, $this); + return new FilterProcessResult(_filter_html($text, $this)); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlCorrector.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlCorrector.php index a68651a..0be711c 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlCorrector.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlCorrector.php @@ -8,6 +8,7 @@ namespace Drupal\filter\Plugin\Filter; use Drupal\Component\Utility\Html; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -26,7 +27,7 @@ class FilterHtmlCorrector extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { - return Html::normalize($text); + return new FilterProcessResult(Html::normalize($text)); } } diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlEscape.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlEscape.php index fd31c9c..a508298 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlEscape.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlEscape.php @@ -7,6 +7,7 @@ namespace Drupal\filter\Plugin\Filter; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -25,7 +26,7 @@ class FilterHtmlEscape extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { - return _filter_html_escape($text); + return new FilterProcessResult(_filter_html_escape($text)); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlImageSecure.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlImageSecure.php index acfd423..f03c75a 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlImageSecure.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterHtmlImageSecure.php @@ -7,6 +7,7 @@ namespace Drupal\filter\Plugin\Filter; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -26,7 +27,7 @@ class FilterHtmlImageSecure extends FilterBase { * {@inheritdoc} */ public function process($text, $langcode) { - return _filter_html_image_secure_process($text); + return new FilterProcessResult(_filter_html_image_secure_process($text)); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterNull.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterNull.php index d73aa58..9c30edc 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterNull.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterNull.php @@ -7,6 +7,7 @@ namespace Drupal\filter\Plugin\Filter; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -48,7 +49,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition * {@inheritdoc} */ public function process($text, $langcode) { - return ''; + return new FilterProcessResult(''); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterUrl.php b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterUrl.php index 8ca02e0..469ff41 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterUrl.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterUrl.php @@ -7,6 +7,7 @@ namespace Drupal\filter\Plugin\Filter; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Plugin\FilterBase; /** @@ -42,7 +43,7 @@ public function settingsForm(array $form, array &$form_state) { * {@inheritdoc} */ public function process($text, $langcode) { - return _filter_url($text, $this); + return new FilterProcessResult(_filter_url($text, $this)); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php b/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php index 09865aa..fea8559 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/FilterInterface.php @@ -158,29 +158,16 @@ public function prepare($text, $langcode); /** * Performs the filter processing. * - * The typical use case is to just apply some filtering to the given text, but - * for more advanced use cases, it may be necessary to also: - * 1. declare asset libraries to be loaded; - * 2. declare cache tags that the filtered text depends upon, so when either of - * those cache tags is invalidated, the filtered text should also be - * invalidated; - * 3. apply uncacheable filtering, for example because it differs per user. - * In case a filter needs one or more of these advanced use cases, it can - * return a renderable array instead of a string, with the following keys: - * - #markup: containing the filtered text; - * - #attached: listing the asset libraries to be attached (to adddress 1.), - * - #cache: listing the cache tags to be associated (to address 2.), - * - #post_render_cache: listing the callbacks to be applied (to address 3.). - * * @param string $text * The text string to be filtered. * @param string $langcode * The language code of the text to be filtered. * - * @return string|array - * The filtered text, or, if it's necessary a renderable array containing at - * least the #markup key, but possibly also the #attached, #cache or - * #post_render_cache keys. + * @return \Drupal\filter\FilterProcessResult + * The filtered text, wrapped in a FilterProcessResult object, and possibly + * with associated assets, cache tags and #post_render_cache callbacks. + * + * @see \Drupal\filter\FilterProcessResult */ public function process($text, $langcode); diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php index ddfc4ac..e0c06d5 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php @@ -249,6 +249,13 @@ function testProcessedTextElement() { 'weight' => 1, 'status' => TRUE, ), + // Run the HTML corrector filter last, because it has the potential to + // break the render cache placeholders added by the + // filter_test_post_render_cache filter. + 'filter_htmlcorrector' => array( + 'weight' => 10, + 'status' => TRUE, + ), ), ))->save(); diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php index bff4331..6426bf6 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php @@ -52,14 +52,7 @@ function testCaptionFilter() { $filter = $this->filters['filter_caption']; $test = function($input) use ($filter) { - $filtered = $filter->process($input, 'und'); - if (is_string($filtered)) { - return $filtered; - } - else { - drupal_render($filtered); - return $filtered; - } + return $filter->process($input, 'und'); }; $attached_library = array( @@ -71,33 +64,33 @@ function testCaptionFilter() { // No data-caption nor data-align attributes. $input = ''; $expected = $input; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); // Only data-caption attribute. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Empty data-caption attribute. $input = ''; $expected = ''; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); // HTML entities in the caption. $input = ''; $expected = '
“Loquacious llama!”
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // HTML encoded as HTML entities in data-caption attribute. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // HTML (not encoded as HTML entities) in data-caption attribute, which is // not allowed by the HTML spec, but may happen when people manually write @@ -105,95 +98,95 @@ function testCaptionFilter() { $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Security test: attempt an XSS. $input = ''; $expected = '
alert(\'Loquacious llama!\')
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Only data-align attribute: all 3 allowed values. $input = ''; $expected = ''; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); $input = ''; $expected = ''; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); $input = ''; $expected = ''; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); // Only data-align attribute: a disallowed value. $input = ''; $expected = ''; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); // Empty data-align attribute. $input = ''; $expected = ''; - $this->assertIdentical($expected, $test($input)); + $this->assertIdentical($expected, $test($input)->getProcessedText()); // Both data-caption and data-align attributes: all 3 allowed values for the // data-align attribute. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Both data-caption and data-align attributes, but a disallowed data-align // attribute value. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Ensure the filter also works with uncommon yet valid attribute quoting. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Security test: attempt to inject an additional class. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Security test: attempt an XSS. $input = ''; $expected = '
Loquacious llama!
'; $output = $test($input); - $this->assertIdentical($expected, $output['#markup']); - $this->assertIdentical($attached_library, $output['#attached']); + $this->assertIdentical($expected, $output->getProcessedText()); + $this->assertIdentical($attached_library, $output->getAssets()); // Finally, ensure that this also works on any other tag. $input = '