diff --git a/core/modules/ckeditor/js/plugins/drupalimagecaption/theme.js b/core/modules/ckeditor/js/plugins/drupalimagecaption/theme.js index f6a96642ffe..b837f6d2a6e 100644 --- a/core/modules/ckeditor/js/plugins/drupalimagecaption/theme.js +++ b/core/modules/ckeditor/js/plugins/drupalimagecaption/theme.js @@ -67,7 +67,7 @@ CKEDITOR.on('instanceCreated', function (event) { // The image is not wrapped in
. else if (this.element.is('img')) { // The image is not wrapped in
, but it should be. - if (this.data.hasCaption || this.data.data_align !== null) { + if (this.data.hasCaption) { // Destroy this widget, so we can wrap the . editor.widgets.destroy(this); // Replace the widget's element (the ) with the template (a @@ -80,6 +80,9 @@ CKEDITOR.on('instanceCreated', function (event) { // Reinitialize this widget with the current data. editor.widgets.initOn(figure, 'drupalimagecaption', this.data); } + else if (this.data.data_align !== null) { + this.element.addClass('align-' + this.data.data_align); + } } }; }); @@ -94,8 +97,8 @@ CKEDITOR.on('instanceCreated', function (event) { var captionValue = el.attributes['data-caption']; var alignValue = el.attributes['data-align']; - // Wrap image in
only if data-caption or data-align is set. - if (captionValue !== undefined || alignValue !== undefined) { + // Wrap image in
only if data-caption is set. + if (captionValue !== undefined) { var classes = 'caption caption-img'; if (alignValue !== null) { classes += ' caption-' + alignValue; @@ -104,6 +107,12 @@ CKEDITOR.on('instanceCreated', function (event) { var caption = CKEDITOR.htmlParser.fragment.fromHtml(captionValue || '', 'figcaption'); figure.add(caption); } + else if (alignValue !== undefined) { + if (el.attributes['class'] === undefined) { + el.attributes['class'] = ''; + } + el.attributes['class'] += 'align-' + alignValue; + } return figure || el; } @@ -147,9 +156,8 @@ CKEDITOR.on('instanceCreated', function (event) { if (typeof returnValues.hasCaption === 'number') { returnValues.hasCaption = !!returnValues.hasCaption; } - // Use the original save callback if the image has neither a caption - // nor alignment. - if (returnValues.hasCaption === false && returnValues.attributes.data_align === null) { + // Use the original save callback if the image has no caption. + if (returnValues.hasCaption === false) { widgetDefinition._insertSaveCallback.apply(this, arguments); return; } diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php index 0054d5e8a8b..6b6da18916f 100644 --- a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php +++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php @@ -45,7 +45,7 @@ class Internal extends CKEditorPluginBase { 'customConfig' => '', // Don't load CKEditor's config.js file. 'pasteFromWordPromptCleanup' => TRUE, 'resize_dir' => 'vertical', - 'justifyClasses' => array('align-left', 'align-center', 'align-right', 'align-justify'), + 'justifyClasses' => array('text-align-left', 'text-align-center', 'text-align-right', 'text-align-justify'), ); // Add the allowedContent setting, which ensures CKEditor only allows tags diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php index 66a384fa6b0..4f59069f20b 100644 --- a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php +++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php @@ -351,7 +351,7 @@ class CKEditorTest extends DrupalUnitTestBase { 'customConfig' => '', 'pasteFromWordPromptCleanup' => TRUE, 'resize_dir' => 'vertical', - 'justifyClasses' => array('align-left', 'align-center', 'align-right', 'align-justify'), + 'justifyClasses' => array('text-align-left', 'text-align-center', 'text-align-right', 'text-align-justify'), ); } 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 c19d0be147a..004cd658e2b 100644 --- a/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterCaption.php +++ b/core/modules/filter/lib/Drupal/filter/Plugin/Filter/FilterCaption.php @@ -57,9 +57,16 @@ class FilterCaption extends FilterBase { } } - // If neither attribute has a value after validation, then don't - // transform the HTML. - if ($caption === NULL && $align === NULL) { + // Don't transform the HTML if there isn't a caption after validation. + if ($caption === NULL) { + // If there is a valid alignment, then transform the data-align + // attribute to a corresponding alignment class. + if ($align !== NULL) { + $classes = $node->getAttribute('class'); + $classes = (strlen($classes) > 0) ? explode(' ', $classes) : array(); + $classes[] = 'align-' . $align; + $node->setAttribute('class', implode(' ', $classes)); + } continue; } diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php index fb31a495987..853734692c5 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php @@ -93,13 +93,13 @@ class FilterUnitTest extends DrupalUnitTestBase { // Only data-align attribute: all 3 allowed values. $input = ''; - $expected = '
'; + $expected = ''; $this->assertIdentical($expected, $test($input)); $input = ''; - $expected = '
'; + $expected = ''; $this->assertIdentical($expected, $test($input)); $input = ''; - $expected = '
'; + $expected = ''; $this->assertIdentical($expected, $test($input)); // Only data-align attribute: a disallowed value. @@ -112,7 +112,14 @@ class FilterUnitTest extends DrupalUnitTestBase { $expected = ''; $this->assertIdentical($expected, $test($input)); - // Both data-caption and data-align attributes. + // Both data-caption and data-align attributes: all 3 allowed values for the + // data-align attribute. + $input = ''; + $expected = '
Loquacious llama!
'; + $this->assertIdentical($expected, $test($input)); + $input = ''; + $expected = '
Loquacious llama!
'; + $this->assertIdentical($expected, $test($input)); $input = ''; $expected = '
Loquacious llama!
'; $this->assertIdentical($expected, $test($input)); diff --git a/core/modules/filter/templates/filter-caption.html.twig b/core/modules/filter/templates/filter-caption.html.twig index 532fb37f6ea..2f9d33115f8 100644 --- a/core/modules/filter/templates/filter-caption.html.twig +++ b/core/modules/filter/templates/filter-caption.html.twig @@ -5,14 +5,12 @@ * Available variables * - string node: The complete HTML tag whose contents are being captioned. * - string tag: The name of the HTML tag whose contents are being captioned. - * - string|NULL caption: (optional) The caption text, or NULL. + * - string caption: The caption text. * - string|NULL align: (optional) The alignment: 'left', 'center', 'right' or * NULL. */ #}
{{ node }} -{% if caption %} -
{{ caption }}
-{% endif %} +
{{ caption }}
diff --git a/core/modules/system/css/system.module.css b/core/modules/system/css/system.module.css index ef4cfae1ef9..331d3e90925 100644 --- a/core/modules/system/css/system.module.css +++ b/core/modules/system/css/system.module.css @@ -335,17 +335,32 @@ tr .ajax-progress-throbber .throbber { } /** - * Content display classes. + * Text alignment classes. */ -.align-left { +.text-align-left { text-align: left; } -.align-right { +.text-align-right { text-align: right; } -.align-center { +.text-align-center { text-align: center; } -.align-justify { +.text-align-justify { text-align: justify; } + +/** + * Alignment classes (images, videos, blockquotes …). + */ +.align-left { + float: left; +} +.align-right { + float: right; +} +.align-center { + display: block; + margin-left: auto; + margin-right: auto; +}