diff --git a/core/modules/image/src/Plugin/Filter/FilterImageStyle.php b/core/modules/image/src/Plugin/Filter/FilterImageStyle.php
index d80eb53..5791530 100644
--- a/core/modules/image/src/Plugin/Filter/FilterImageStyle.php
+++ b/core/modules/image/src/Plugin/Filter/FilterImageStyle.php
@@ -89,46 +89,27 @@ public static function create(ContainerInterface $container, array $configuratio
*/
public function process($text, $langcode) {
if (stristr($text, 'data-image-style') !== FALSE) {
+ // Load all the image styles so each img found in the text can be checked
+ // to ensure it has a valid image style.
$image_styles = $this->loadImageStyles();
+ // Load the text that is being processed into XML to find images.
$dom = HTML::load($text);
$xpath = new \DOMXPath($dom);
+
+ // Process each img element DOM node found with the necessary attributes.
foreach ($xpath->query('//*[@data-entity-type="file" and @data-entity-uuid and @data-image-style]') as $dom_node) {
+ // Get the UUID and image style for the file.
$file_uuid = $dom_node->getAttribute('data-entity-uuid');
- $dom_node->removeAttribute('data-entity-uuid');
$image_style_id = $dom_node->getAttribute('data-image-style');
- $dom_node->removeAttribute('data-image-style');
// If the image style is not a valid one, then don't transform the HTML.
if (empty($file_uuid) || !in_array($image_style_id, $image_styles)) {
continue;
}
- $image_info = $this->getImageInfo($file_uuid);
- $image_uri = $image_info['uri'];
- $image_width = $image_info['width'];
- $image_height = $image_info['height'];
-
- // Make sure all non-regenerated attributes are retained.
- $dom_node->removeAttribute('width');
- $dom_node->removeAttribute('height');
- $dom_node->removeAttribute('src');
- $attributes = array();
- for ($i = 0; $i < $dom_node->attributes->length; $i++) {
- $attr = $dom_node->attributes->item($i);
- $attributes[$attr->name] = $attr->value;
- }
-
- // Re-render as an image style.
- $image = array(
- '#theme' => 'image_style',
- '#style_name' => $image_style_id,
- '#uri' => $image_uri,
- '#width' => $image_width,
- '#height' => $image_height,
- '#attributes' => $attributes,
- );
- $altered_html = $this->renderer->render($image);
+ // Transform the HTML for the img element by applying an image style.
+ $altered_html = $this->getImageStyleHtml($file_uuid, $image_style_id, $dom_node);
// Load the altered HTML into a new DOMDocument and retrieve the element.
$updated_node = HTML::load($altered_html)->getElementsByTagName('body')
@@ -139,13 +120,16 @@ public function process($text, $langcode) {
// Import the updated node from the new DOMDocument into the original
// one, importing also the child nodes of the updated node.
$updated_node = $dom->importNode($updated_node, TRUE);
- // Finally, replace the original image node with the new image node!
+
+ // Finally, replace the original image node with the new image node.
$dom_node->parentNode->replaceChild($updated_node, $dom_node);
}
+ // Process the filter with the newly updated DOM.
return new FilterProcessResult(HTML::serialize($dom));
}
+ // Process the filter if no image style img elements are found.
return new FilterProcessResult($text);
}
@@ -161,7 +145,8 @@ protected function loadImageStyles() {
/**
* Get the the width and height of an image based on the file UUID.
*
- * @param $file_uuid
+ * @param string $file_uuid
+ * The UUID for the file.
*
* @return array
*/
@@ -188,6 +173,64 @@ protected function getImageInfo($file_uuid) {
}
/**
+ * Removes attributes that will be generated from image style theme function.
+ *
+ * @param \DOMNode $dom_node
+ * The DOM node for the img element.
+ *
+ * @return \DOMNode
+ */
+ protected function prepareImageAttributes($dom_node) {
+ // Make sure all non-regenerated attributes are retained.
+ $dom_node->removeAttribute('data-entity-uuid');
+ $dom_node->removeAttribute('data-image-style');
+ $dom_node->removeAttribute('width');
+ $dom_node->removeAttribute('height');
+ $dom_node->removeAttribute('src');
+ $attributes = array();
+ for ($i = 0; $i < $dom_node->attributes->length; $i++) {
+ $attr = $dom_node->attributes->item($i);
+ $attributes[$attr->name] = $attr->value;
+ }
+
+ return $dom_node;
+ }
+
+ /**
+ * Get the HTML for the img element after image style is applied.
+ *
+ * @param string $file_uuid
+ * The UUID for the file.
+ * @param string $image_style_id
+ * The ID for the image style.
+ * @param \DOMNode $dom_node
+ * The DOM node for the image element.
+ *
+ * @return string
+ */
+ protected function getImageStyleHtml($file_uuid, $image_style_id, $dom_node) {
+ $image_info = $this->getImageInfo($file_uuid);
+ $image_uri = $image_info['uri'];
+ $image_width = $image_info['width'];
+ $image_height = $image_info['height'];
+
+ // Remove attributes that will be generated by the image style.
+ $attributes = $this->prepareImageAttributes($dom_node);
+
+ // Re-render as an image style.
+ $image = array(
+ '#theme' => 'image_style',
+ '#style_name' => $image_style_id,
+ '#uri' => $image_uri,
+ '#width' => $image_width,
+ '#height' => $image_height,
+ '#attributes' => $attributes,
+ );
+
+ return $this->renderer->render($image);
+ }
+
+ /**
* {@inheritdoc}
*/
public function tips($long = FALSE) {
diff --git a/core/modules/image/tests/src/Unit/FilterImageStyleTest.php b/core/modules/image/tests/src/Unit/FilterImageStyleTest.php
index 810c5e9..a5455cc 100644
--- a/core/modules/image/tests/src/Unit/FilterImageStyleTest.php
+++ b/core/modules/image/tests/src/Unit/FilterImageStyleTest.php
@@ -55,7 +55,9 @@ protected function setUp() {
])
->setMethods([
'loadImageStyles',
- 'getImageInfo'
+ 'getImageInfo',
+ 'prepareImageAttributes',
+ 'getImageStyleHtml'
])
->getMock();
}
@@ -65,10 +67,62 @@ public function testProcessWithoutImage() {
$this->assertEquals('', $output);
}
+ /**
+ * @covers ::process
+ */
public function testProcessWithImage() {
- $this->filterImageStyle->method('loadImageStyles')->willReturn(['thumbnail', 'medium', 'large']);
- $this->filterImageStyle->method('getImageInfo')->with($this->equalTo('abcd-1234-ghij-5678'))->willReturn(['uri' => 'styles/medium/public/image.png', 'width' => '200', 'height'=> '150']);
- $output = $this->filterImageStyle->process('
', 'en');
- $this->assertEquals('
', $output);
+ $original_src = 'image.png';
+ $original_uuid = 'abcd-1234-ghij-5678';
+ $original_image_style = 'medium';
+ $original_width = '400';
+ $original_height = '300';
+ $original_alt = 'A wooly mammoth trumpets as a crevasse breaks open in the glacier.';
+
+ $original_img = '
';
+
+ $processed_img = '
';
+
+ $generated_src = 'styles/medium/public/image.png';
+ $generated_width = '200';
+ $generated_height = '150';
+ $generated_img = '
';
+
+ $this->filterImageStyle
+ ->method('loadImageStyles')
+ ->willReturn([
+ 'thumbnail',
+ 'medium',
+ 'large'
+ ]);
+
+ $this->filterImageStyle
+ ->method('getImageInfo')
+ ->with(
+ $this->equalTo($original_uuid)
+ )
+ ->willReturn([
+ 'uri' => 'styles/medium/public/image.png',
+ 'width' => '200',
+ 'height'=> '150'
+ ]);
+
+ $this->filterImageStyle
+ ->method('prepareImageAttributes')
+ ->with(
+ $this->equalTo($original_img)
+ )
+ ->willReturn($processed_img);
+
+ $this->filterImageStyle
+ ->method('getImageStyleHtml')
+ ->with(
+ $this->equalTo($original_uuid),
+ $this->equalTo($original_image_style),
+ $this->equalTo($original_img)
+ )
+ ->willReturn($generated_img);
+
+ $output = $this->filterImageStyle->process($original_img, 'en');
+ $this->assertEquals($generated_img, $output);
}
}