diff --git a/core/modules/image/js/plugins/drupalimagestyle/plugin.es6.js b/core/modules/image/js/plugins/drupalimagestyle/plugin.es6.js new file mode 100644 index 0000000000..b492dd1b78 --- /dev/null +++ b/core/modules/image/js/plugins/drupalimagestyle/plugin.es6.js @@ -0,0 +1,135 @@ +/** + * @file + * Drupal Image Style plugin. + * + * This alters the existing CKEditor image2 widget plugin, which is already + * altered by the Drupal Image plugin, to allow for the data-image-style + * attribute to be set. + * + * @ignore + */ + +(function(CKEDITOR) { + 'use strict'; + + CKEDITOR.plugins.add('drupalimagestyle', { + requires: 'drupalimage', + + beforeInit: function beforeInit(editor) { + // Override the image2 widget definition to handle the additional + // data-image-style attributes. + editor.on( + 'widgetDefinition', + function(event) { + const widgetDefinition = event.data; + if (widgetDefinition.name !== 'image') { + return; + } + // Override default features definitions for drupalimagestyle. + CKEDITOR.tools.extend( + widgetDefinition.features, + { + drupalimagestyle: { + requiredContent: 'img[data-image-style]', + }, + }, + true, + ); + + // Override requiredContent & allowedContent. + const requiredContent = widgetDefinition.requiredContent.getDefinition(); + requiredContent.attributes['data-image-style'] = ''; + widgetDefinition.requiredContent = new CKEDITOR.style( + requiredContent, + ); + widgetDefinition.allowedContent.img.attributes[ + '!data-image-style' + ] = true; + + // Decorate downcast(). + const originalDowncast = widgetDefinition.downcast; + widgetDefinition.downcast = function(element) { + let img = originalDowncast.call(this, element); + if (!img) { + img = findElementByName(element, 'img'); + } + if ( + this.data.hasOwnProperty('data-image-style') && + this.data['data-image-style'] !== '' + ) { + img.attributes['data-image-style'] = this.data[ + 'data-image-style' + ]; + } + return img; + }; + + // Decorate upcast(). + const originalUpcast = widgetDefinition.upcast; + widgetDefinition.upcast = function(element, data) { + if ( + element.name !== 'img' || + !element.attributes['data-entity-type'] || + !element.attributes['data-entity-uuid'] + ) { + return; + } + // Don't initialize on pasted fake objects. + else if (element.attributes['data-cke-realelement']) { + return; + } + + // Parse the data-image-style attribute. + data['data-image-style'] = element.attributes['data-image-style']; + + // Upcast after parsing so correct element attributes are parsed. + element = originalUpcast.call(this, element, data); + + return element; + }; + + // Protected; keys of the widget data to be sent to the Drupal dialog. + // Append to the values defined by the drupalimage plugin. + // @see core/modules/ckeditor/js/plugins/drupalimage/plugin.js + CKEDITOR.tools.extend(widgetDefinition._mapDataToDialog, { + 'data-image-style': 'data-image-style', + }); + // Low priority to ensure drupalimage's event handler runs first. + }, + null, + null, + 20, + ); + }, + }); + + /** + * Finds an element by its name. + * + * Function will check first the passed element itself and then all its + * children in DFS order. + * + * @param {CKEDITOR.htmlParser.element} element + * The element to search. + * @param {string} name + * The element name to search for. + * + * @return {?CKEDITOR.htmlParser.element} + * The found element, or null. + */ + function findElementByName(element, name) { + if (element.name === name) { + return element; + } + + let found = null; + element.forEach(function(el) { + if (el.name === name) { + found = el; + // Stop here. + return false; + } + }, CKEDITOR.NODE_ELEMENT); + return found; + } +})(CKEDITOR); diff --git a/core/modules/image/js/plugins/drupalimagestyle/plugin.js b/core/modules/image/js/plugins/drupalimagestyle/plugin.js index 8d45a3681c..525fe3bc86 100644 --- a/core/modules/image/js/plugins/drupalimagestyle/plugin.js +++ b/core/modules/image/js/plugins/drupalimagestyle/plugin.js @@ -1,43 +1,34 @@ /** - * @file - * Drupal Image Style plugin. - * - * This alters the existing CKEditor image2 widget plugin, which is already - * altered by the Drupal Image plugin, to allow for the data-image-style - * attribute to be set. - * - * @ignore - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (CKEDITOR) { - 'use strict'; CKEDITOR.plugins.add('drupalimagestyle', { requires: 'drupalimage', beforeInit: function beforeInit(editor) { - // Override the image2 widget definition to handle the additional - // data-image-style attributes. editor.on('widgetDefinition', function (event) { var widgetDefinition = event.data; if (widgetDefinition.name !== 'image') { return; } - // Override default features definitions for drupalimagestyle. + CKEDITOR.tools.extend(widgetDefinition.features, { drupalimagestyle: { requiredContent: 'img[data-image-style]' } }, true); - // Override requiredContent & allowedContent. var requiredContent = widgetDefinition.requiredContent.getDefinition(); requiredContent.attributes['data-image-style'] = ''; widgetDefinition.requiredContent = new CKEDITOR.style(requiredContent); widgetDefinition.allowedContent.img.attributes['!data-image-style'] = true; - // Decorate downcast(). var originalDowncast = widgetDefinition.downcast; widgetDefinition.downcast = function (element) { var img = originalDowncast.call(this, element); @@ -50,51 +41,28 @@ return img; }; - // Decorate upcast(). var originalUpcast = widgetDefinition.upcast; widgetDefinition.upcast = function (element, data) { if (element.name !== 'img' || !element.attributes['data-entity-type'] || !element.attributes['data-entity-uuid']) { return; - } - // Don't initialize on pasted fake objects. - else if (element.attributes['data-cke-realelement']) { - return; - } + } else if (element.attributes['data-cke-realelement']) { + return; + } - // Parse the data-image-style attribute. data['data-image-style'] = element.attributes['data-image-style']; - // Upcast after parsing so correct element attributes are parsed. element = originalUpcast.call(this, element, data); return element; }; - // Protected; keys of the widget data to be sent to the Drupal dialog. - // Append to the values defined by the drupalimage plugin. - // @see core/modules/ckeditor/js/plugins/drupalimage/plugin.js CKEDITOR.tools.extend(widgetDefinition._mapDataToDialog, { 'data-image-style': 'data-image-style' }); - // Low priority to ensure drupalimage's event handler runs first. }, null, null, 20); } }); - /** - * Finds an element by its name. - * - * Function will check first the passed element itself and then all its - * children in DFS order. - * - * @param {CKEDITOR.htmlParser.element} element - * The element to search. - * @param {string} name - * The element name to search for. - * - * @return {?CKEDITOR.htmlParser.element} - * The found element, or null. - */ function findElementByName(element, name) { if (element.name === name) { return element; @@ -104,11 +72,10 @@ element.forEach(function (el) { if (el.name === name) { found = el; - // Stop here. + return false; } }, CKEDITOR.NODE_ELEMENT); return found; } - -})(CKEDITOR); +})(CKEDITOR); \ No newline at end of file diff --git a/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php b/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php index 4d29ee1238..d3809013f5 100644 --- a/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php +++ b/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php @@ -59,7 +59,8 @@ public function testDataImageStyleElement() { $image_url = Url::fromUri('base:core/themes/bartik/screenshot.png')->toString(); $this->drupalGet('node/add/page'); - $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextContains('Create Basic page'); + $this->assertSession()->pageTextContains('Create Basic page'); $page = $this->getSession()->getPage(); // Wait for the ckeditor toolbar elements to appear (loading is done). diff --git a/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php b/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php index 5c456afa1b..ed3fb1c245 100644 --- a/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php +++ b/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php @@ -153,10 +153,7 @@ protected function setUpForm($enable_image_filter) { * Tests that style selection is hidden when filter_image_style is disabled. */ public function testDialogNoStyles() { - $form = $this->setUpForm(FALSE); - - $this->assertFalse($form['image_style']['selection']['#access']); - $this->assertFalse($form['image_style']['link']['#access']); + $this->assertArrayNotHasKey('image_style', $this->setUpForm(FALSE)); } /** diff --git a/core/profiles/demo_umami/config/install/filter.format.basic_html.yml b/core/profiles/demo_umami/config/install/filter.format.basic_html.yml index f9baa17a24..f3b1dcec79 100644 --- a/core/profiles/demo_umami/config/install/filter.format.basic_html.yml +++ b/core/profiles/demo_umami/config/install/filter.format.basic_html.yml @@ -48,3 +48,10 @@ filters: status: true weight: 0 settings: { } + filter_image_style: + id: filter_image_style + provider: image + status: true + weight: 12 + settings: + allowed_styles: { } diff --git a/core/profiles/demo_umami/config/install/filter.format.full_html.yml b/core/profiles/demo_umami/config/install/filter.format.full_html.yml index e5febb218a..dd427f4fb6 100644 --- a/core/profiles/demo_umami/config/install/filter.format.full_html.yml +++ b/core/profiles/demo_umami/config/install/filter.format.full_html.yml @@ -33,3 +33,10 @@ filters: status: true weight: 11 settings: { } + filter_image_style: + id: filter_image_style + provider: image + status: true + weight: 12 + settings: + allowed_styles: { } diff --git a/core/profiles/standard/config/install/filter.format.basic_html.yml b/core/profiles/standard/config/install/filter.format.basic_html.yml index 9f03910c38..7a30fcd000 100644 --- a/core/profiles/standard/config/install/filter.format.basic_html.yml +++ b/core/profiles/standard/config/install/filter.format.basic_html.yml @@ -1,10 +1,6 @@ langcode: en status: true dependencies: - config: - - image.style.large - - image.style.medium - - image.style.thumbnail module: - editor - image diff --git a/core/profiles/standard/config/install/filter.format.full_html.yml b/core/profiles/standard/config/install/filter.format.full_html.yml index 2c1521ca81..6c9faf9672 100644 --- a/core/profiles/standard/config/install/filter.format.full_html.yml +++ b/core/profiles/standard/config/install/filter.format.full_html.yml @@ -1,10 +1,6 @@ langcode: en status: true dependencies: - config: - - image.style.large - - image.style.medium - - image.style.thumbnail module: - editor - image