Skip to content

Commit

Permalink
Issue backdrop#2846: Add wrapper paragraph to centered img tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
quicksketch committed Nov 8, 2019
1 parent 715b341 commit 7c485ff
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 23 deletions.
3 changes: 3 additions & 0 deletions core/modules/ckeditor/css/ckeditor-caption.css
Expand Up @@ -19,6 +19,9 @@
.cke_widget_wrapper.align-center {
text-align: center;
}
.cke_widget_wrapper.align-center .caption {
margin: 0 auto;
}
.caption > * {
display: block;
max-width: 100%;
Expand Down
42 changes: 28 additions & 14 deletions core/modules/filter/filter.module
Expand Up @@ -2514,23 +2514,37 @@ function _filter_image_align($text) {
$target = $node;
}

// Center aligned content requires an additional wrapper to set
// Apply the align-* class to the target element.
$classes = $target->getAttribute('class');
$classes = (strlen($classes) > 0) ? explode(' ', $classes) : array();
$classes[] = 'align-' . $align;
$target->setAttribute('class', implode(' ', $classes));

// Center aligned images require an additional wrapper to set
// text-align: center.
if ($align === 'center') {
// Get closest p parent.
while ($target->nodeName !== 'p') {
$target = $target->parentNode;
if ($align === 'center' && !in_array($target->nodeName, array('p', 'figure'))) {
// Get closest paragraph tag. If we hit "body" there is no wrapping
// element at all.
$closest_block_wrapper = $target;
while (!in_array($closest_block_wrapper->nodeName, array('p', 'body'))) {
$closest_block_wrapper = $closest_block_wrapper->parentNode;
}

$p_attribute = $dom->createAttribute('class');
$p_attribute->value = 'centered-wrapper';
$target->appendChild($p_attribute);
}
else {
$classes = $target->getAttribute('class');
$classes = (strlen($classes) > 0) ? explode(' ', $classes) : array();
$classes[] = 'align-' . $align;
$target->setAttribute('class', implode(' ', $classes));
// If no wrapper tag at all, create a paragraph and put the img inside.
if ($closest_block_wrapper->nodeName === 'body') {
$new_paragraph = $dom->createElement('p');
$new_paragraph->setAttribute('class', 'centered-wrapper');
// Wrap the img tag with the new P.
$target->parentNode->replaceChild($new_paragraph, $target);
$new_paragraph->appendChild($target);
}
// Parent wrapper found. Add the centered-wrapper class.
elseif ($closest_block_wrapper->nodeName === 'p') {
$classes = $closest_block_wrapper->getAttribute('class');
$classes = (strlen($classes) > 0) ? explode(' ', $classes) : array();
$classes[] = 'centered-wrapper';
$closest_block_wrapper->setAttribute('class', implode(' ', $classes));
}
}
}
}
Expand Down
40 changes: 31 additions & 9 deletions core/modules/filter/tests/filter.test
Expand Up @@ -1499,8 +1499,8 @@ www.example.com with a newline in comments -->
/**
* Asserts multiple filter output expectations for multiple input strings.
*
* @param $filter
* A input filter object.
* @param stdClass[]|stdClass $filters
* An array of input filter objects, or a single filter object.
* @param $tests
* An associative array, whereas each key is an arbitrary input string and
* each value is again an associative array whose keys are filter output
Expand All @@ -1517,10 +1517,18 @@ www.example.com with a newline in comments -->
* );
* @endcode
*/
function assertFilteredString($filter, $tests) {
function assertFilteredString($filters, $tests) {
if (!is_array($filters)) {
$filters = array($filters);
}

foreach ($tests as $source => $tasks) {
$function = $filter->callback;
$result = $function($source, $filter);
// Run each of the filters on the input data.
$result = $source;
foreach ($filters as $filter) {
$function = $filter->callback;
$result = $function($result, $filter);
}
foreach ($tasks as $value => $is_expected) {
// Not using assertIdentical, since combination with strpos() is hard to grok.
if ($is_expected) {
Expand Down Expand Up @@ -1606,7 +1614,7 @@ EOF;
$input => array(
'<img src="foo.png" width="100" height="100" class="align-right" />' => TRUE,
'<img src="foo.png" width="100" height="100" class="align-left" />' => TRUE,
'<img src="foo.png" width="100" height="100" class="align-center" />' => TRUE,
'<p class="centered-wrapper"><img src="foo.png" width="100" height="100" class="align-center" /></p>' => TRUE,
// An unknown alignment (bottom) should be removed.
'<img src="foo.png" width="100" height="100" />' => TRUE,
'<img src="foo.png" width="100" height="100" class="align-bottom" />' => FALSE,
Expand All @@ -1630,13 +1638,20 @@ EOF;
*/
function testImageAlignCaption() {
// Set up dummy filter object.
$filter = new stdClass();
$filter->callback = '_filter_image_caption';
$filters = array();
$filters[] = (object) array('callback' => '_filter_image_caption');
$filters[] = (object) array('callback' => '_filter_image_align');

$input = <<<EOF
<img data-caption="Simple caption" src="foo.png" />
<img data-caption="The caption with a &lt;a href=&quot;/foo&quot;&gt; link&lt;/a&gt;.&lt;strong&gt; Bold tag.&lt;/strong&gt;" src="foo.png" />
<img data-caption="The caption with a &lt;div&gt;not allowed tag&lt;/div&gt;." src="foo.png" />

<img data-caption="Centered" src="foo.png" data-align="center" />
<img data-caption="Left" src="foo.png" data-align="left" />
<img data-caption="Right" src="foo.png" data-align="right" />
<img data-caption="Invalid" src="foo.png" data-align="invalid" />

EOF;

$tests = array(
Expand All @@ -1645,11 +1660,18 @@ EOF;
'<figure class="caption caption-img"><img src="foo.png" /><figcaption>The caption with a <a href="/foo"> link</a>.<strong> Bold tag.</strong></figcaption></figure>' => TRUE,
'<figure class="caption caption-img"><img src="foo.png" /><figcaption>The caption with a not allowed tag.</figcaption></figure>' => TRUE,
'<figure class="caption caption-img"><img src="foo.png" /><figcaption>The caption with a <div>not allowed tag</div>.</figcaption></figure>' => FALSE,

// Alignment checks.
'<figure class="caption caption-img align-center"><img src="foo.png" /><figcaption>Centered</figcaption></figure>' => TRUE,
'<figure class="caption caption-img align-left"><img src="foo.png" /><figcaption>Left</figcaption></figure>' => TRUE,
'<figure class="caption caption-img align-right"><img src="foo.png" /><figcaption>Right</figcaption></figure>' => TRUE,
'<figure class="caption caption-img"><img src="foo.png" /><figcaption>Invalid</figcaption></figure>' => TRUE,

// Ensure the temporarily wrapped body tag is stripped before output.
'<body>' => FALSE,
),
);
$this->assertFilteredString($filter, $tests);
$this->assertFilteredString($filters, $tests);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions core/themes/basis/css/component/caption.css
Expand Up @@ -8,6 +8,11 @@
.caption {
display: table;
max-width: 100%;
margin: 0 1em 1em;
}
.caption.align-center {
margin-left: auto;
margin-right: auto;
}
.caption > * {
display: block;
Expand Down

0 comments on commit 7c485ff

Please sign in to comment.