From 732d41f6ba4f3919ceb18dbbafaa1be33c0cd2f8 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Fri, 27 May 2022 10:54:20 +0100
Subject: [PATCH] Issue #3265140 by Spokje, bnjmnm, lauriii, mstrelan, dww, Wim
 Leers, xjm, murilohp, daffie: Move QuickEditImageController from image to
 quickedit

---
 core/modules/image/image.libraries.yml        |  16 ---
 core/modules/image/image.routing.yml          |  26 -----
 core/modules/image/js/theme.es6.js            |  92 ----------------
 core/modules/image/js/theme.js                |  31 ------
 .../css/editors/image.css                     |   2 +-
 .../quickedit/css}/editors/image.theme.css    |   6 +-
 core/modules/quickedit/images/error.svg       |   4 +
 core/modules/quickedit/images/upload.svg      |   4 +
 .../js/editors/image.es6.js                   |   0
 .../{image => quickedit}/js/editors/image.js  |   0
 core/modules/quickedit/js/theme.es6.js        |  85 +++++++++++++++
 core/modules/quickedit/js/theme.js            |  23 ++++
 .../modules/quickedit/quickedit.libraries.yml |  15 +++
 core/modules/quickedit/quickedit.routing.yml  |  26 +++++
 .../Controller/QuickEditImageController.php   |   2 +-
 .../src/Plugin/InPlaceEditor/Image.php        |   4 +-
 .../QuickEditImageEditorTestTrait.php         |   2 +-
 .../QuickEditImageTest.php                    |   2 +-
 .../editors}/editors/image.css                |   2 +-
 .../editors}/editors/image.theme.css          |   2 +-
 .../stable/css/quickedit/editors/image.css    |  52 +++++++++
 .../css/quickedit}/editors/image.theme.css    |   6 +-
 core/themes/stable/stable.info.yml            |  12 +--
 .../{image => quickedit}/editors/image.css    |   2 +-
 .../css/quickedit/editors/image.theme.css     | 100 ++++++++++++++++++
 core/themes/stable9/stable9.info.yml          |  12 +--
 26 files changed, 336 insertions(+), 192 deletions(-)
 delete mode 100644 core/modules/image/js/theme.es6.js
 delete mode 100644 core/modules/image/js/theme.js
 rename core/modules/{image => quickedit}/css/editors/image.css (93%)
 rename core/{themes/stable9/css/image => modules/quickedit/css}/editors/image.theme.css (90%)
 create mode 100644 core/modules/quickedit/images/error.svg
 create mode 100644 core/modules/quickedit/images/upload.svg
 rename core/modules/{image => quickedit}/js/editors/image.es6.js (100%)
 rename core/modules/{image => quickedit}/js/editors/image.js (100%)
 rename core/modules/{image => quickedit}/src/Controller/QuickEditImageController.php (99%)
 rename core/modules/{image => quickedit}/src/Plugin/InPlaceEditor/Image.php (87%)
 rename core/themes/stable/css/{image => quickedit/editors}/editors/image.css (93%)
 rename core/themes/stable/css/{image => quickedit/editors}/editors/image.theme.css (97%)
 create mode 100644 core/themes/stable/css/quickedit/editors/image.css
 rename core/{modules/image/css => themes/stable/css/quickedit}/editors/image.theme.css (91%)
 rename core/themes/stable9/css/{image => quickedit}/editors/image.css (93%)
 create mode 100644 core/themes/stable9/css/quickedit/editors/image.theme.css

diff --git a/core/modules/image/image.libraries.yml b/core/modules/image/image.libraries.yml
index 14ea11623dfc..e9061a42e424 100644
--- a/core/modules/image/image.libraries.yml
+++ b/core/modules/image/image.libraries.yml
@@ -3,19 +3,3 @@ admin:
   css:
     theme:
       css/image.admin.css: {}
-
-quickedit.inPlaceEditor.image:
-  version: VERSION
-  js:
-    js/editors/image.js: {}
-    js/theme.js: {}
-  css:
-    component:
-      css/editors/image.css: {}
-    theme:
-      css/editors/image.theme.css: {}
-  dependencies:
-    - core/jquery
-    - core/drupal
-    - core/internal.underscore
-    - quickedit/quickedit
diff --git a/core/modules/image/image.routing.yml b/core/modules/image/image.routing.yml
index 4a0cb88a833a..ffeed861a2a9 100644
--- a/core/modules/image/image.routing.yml
+++ b/core/modules/image/image.routing.yml
@@ -71,29 +71,3 @@ image.effect_edit_form:
 
 route_callbacks:
   - '\Drupal\image\Routing\ImageStyleRoutes::routes'
-
-image.upload:
-  path: '/quickedit/image/upload/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode_id}'
-  defaults:
-    _controller: '\Drupal\image\Controller\QuickEditImageController::upload'
-  options:
-    parameters:
-      entity:
-        type: entity:{entity_type}
-  requirements:
-    _permission: 'access in-place editing'
-    _access_quickedit_entity_field: 'TRUE'
-    _method: 'POST'
-
-image.info:
-  path: '/quickedit/image/info/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode_id}'
-  defaults:
-    _controller: '\Drupal\image\Controller\QuickEditImageController::getInfo'
-  options:
-    parameters:
-      entity:
-        type: entity:{entity_type}
-  requirements:
-    _permission: 'access in-place editing'
-    _access_quickedit_entity_field: 'TRUE'
-    _method: 'GET'
diff --git a/core/modules/image/js/theme.es6.js b/core/modules/image/js/theme.es6.js
deleted file mode 100644
index f21df3213091..000000000000
--- a/core/modules/image/js/theme.es6.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file
- * Provides theme functions for image Quick Edit's client-side HTML.
- */
-
-(function (Drupal) {
-  /**
-   * Theme function for validation errors of the Image in-place editor.
-   *
-   * @param {object} settings
-   *   Settings object used to construct the markup.
-   * @param {string} settings.errors
-   *   Already escaped HTML representing error messages.
-   *
-   * @return {string}
-   *   The corresponding HTML.
-   */
-  Drupal.theme.quickeditImageErrors = function (settings) {
-    return `<div class="quickedit-image-errors">${settings.errors}</div>`;
-  };
-
-  /**
-   * Theme function for the dropzone element of the Image module's in-place
-   * editor.
-   *
-   * @param {object} settings
-   *   Settings object used to construct the markup.
-   * @param {string} settings.state
-   *   State of the upload.
-   * @param {string} settings.text
-   *   Text to display inline with the dropzone element.
-   *
-   * @return {string}
-   *   The corresponding HTML.
-   */
-  Drupal.theme.quickeditImageDropzone = function (settings) {
-    return (
-      `<div class="quickedit-image-dropzone ${settings.state}">` +
-      '  <i class="quickedit-image-icon"></i>' +
-      `  <span class="quickedit-image-text">${settings.text}</span>` +
-      '</div>'
-    );
-  };
-
-  /**
-   * Theme function for the toolbar of the Image module's in-place editor.
-   *
-   * @param {object} settings
-   *   Settings object used to construct the markup.
-   * @param {bool} settings.alt_field
-   *   Whether or not the "Alt" field is enabled for this field.
-   * @param {bool} settings.alt_field_required
-   *   Whether or not the "Alt" field is required for this field.
-   * @param {string} settings.alt
-   *   The current value for the "Alt" field.
-   * @param {bool} settings.title_field
-   *   Whether or not the "Title" field is enabled for this field.
-   * @param {bool} settings.title_field_required
-   *   Whether or not the "Title" field is required for this field.
-   * @param {string} settings.title
-   *   The current value for the "Title" field.
-   *
-   * @return {string}
-   *   The corresponding HTML.
-   */
-  Drupal.theme.quickeditImageToolbar = function (settings) {
-    let html = '<form class="quickedit-image-field-info">';
-    if (settings.alt_field) {
-      html +=
-        `<div><label for="alt" class="${
-          settings.alt_field_required ? 'required' : ''
-        }">${Drupal.t('Alternative text')}</label>` +
-        `<input type="text" placeholder="${settings.alt}" value="${
-          settings.alt
-        }" name="alt" ${settings.alt_field_required ? 'required' : ''}/>` +
-        '  </div>';
-    }
-    if (settings.title_field) {
-      html +=
-        `<div><label for="title" class="${
-          settings.title_field_required ? 'form-required' : ''
-        }">${Drupal.t('Title')}</label>` +
-        `<input type="text" placeholder="${settings.title}" value="${
-          settings.title
-        }" name="title" ${settings.title_field_required ? 'required' : ''}/>` +
-        '</div>';
-    }
-    html += '</form>';
-
-    return html;
-  };
-})(Drupal);
diff --git a/core/modules/image/js/theme.js b/core/modules/image/js/theme.js
deleted file mode 100644
index 6ae707b0ae5e..000000000000
--- a/core/modules/image/js/theme.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
-* DO NOT EDIT THIS FILE.
-* See the following change record for more information,
-* https://www.drupal.org/node/2815083
-* @preserve
-**/
-
-(function (Drupal) {
-  Drupal.theme.quickeditImageErrors = function (settings) {
-    return `<div class="quickedit-image-errors">${settings.errors}</div>`;
-  };
-
-  Drupal.theme.quickeditImageDropzone = function (settings) {
-    return `<div class="quickedit-image-dropzone ${settings.state}">` + '  <i class="quickedit-image-icon"></i>' + `  <span class="quickedit-image-text">${settings.text}</span>` + '</div>';
-  };
-
-  Drupal.theme.quickeditImageToolbar = function (settings) {
-    let html = '<form class="quickedit-image-field-info">';
-
-    if (settings.alt_field) {
-      html += `<div><label for="alt" class="${settings.alt_field_required ? 'required' : ''}">${Drupal.t('Alternative text')}</label>` + `<input type="text" placeholder="${settings.alt}" value="${settings.alt}" name="alt" ${settings.alt_field_required ? 'required' : ''}/>` + '  </div>';
-    }
-
-    if (settings.title_field) {
-      html += `<div><label for="title" class="${settings.title_field_required ? 'form-required' : ''}">${Drupal.t('Title')}</label>` + `<input type="text" placeholder="${settings.title}" value="${settings.title}" name="title" ${settings.title_field_required ? 'required' : ''}/>` + '</div>';
-    }
-
-    html += '</form>';
-    return html;
-  };
-})(Drupal);
\ No newline at end of file
diff --git a/core/modules/image/css/editors/image.css b/core/modules/quickedit/css/editors/image.css
similarity index 93%
rename from core/modules/image/css/editors/image.css
rename to core/modules/quickedit/css/editors/image.css
index f9733d283486..b6218c93f955 100644
--- a/core/modules/image/css/editors/image.css
+++ b/core/modules/quickedit/css/editors/image.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Functional styles for the Image module's in-place editor.
+ * Functional styles for the Quick Edit image in-place editor.
  */
 
 /**
diff --git a/core/themes/stable9/css/image/editors/image.theme.css b/core/modules/quickedit/css/editors/image.theme.css
similarity index 90%
rename from core/themes/stable9/css/image/editors/image.theme.css
rename to core/modules/quickedit/css/editors/image.theme.css
index 25a21ba446e6..8514266ede4e 100644
--- a/core/themes/stable9/css/image/editors/image.theme.css
+++ b/core/modules/quickedit/css/editors/image.theme.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Theme styles for the Image module's in-place editor.
+ * Theme styles for the Quick Edit image in-place editor.
  */
 
 .quickedit-image-dropzone {
@@ -22,11 +22,11 @@
 }
 
 .quickedit-image-dropzone.upload .quickedit-image-icon {
-  background-image: url("../../../../../modules/image/images/upload.svg");
+  background-image: url("../../../../../modules/quickedit/images/upload.svg");
 }
 
 .quickedit-image-dropzone.error .quickedit-image-icon {
-  background-image: url("../../../../../modules/image/images/error.svg");
+  background-image: url("../../../../../modules/quickedit/images/error.svg");
 }
 
 .quickedit-image-dropzone.loading .quickedit-image-icon {
diff --git a/core/modules/quickedit/images/error.svg b/core/modules/quickedit/images/error.svg
new file mode 100644
index 000000000000..1932ea402c5b
--- /dev/null
+++ b/core/modules/quickedit/images/error.svg
@@ -0,0 +1,4 @@
+<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+    <path d="M0 0h24v24H0z" fill="none"/>
+    <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
+</svg>
diff --git a/core/modules/quickedit/images/upload.svg b/core/modules/quickedit/images/upload.svg
new file mode 100644
index 000000000000..168bc43e6afb
--- /dev/null
+++ b/core/modules/quickedit/images/upload.svg
@@ -0,0 +1,4 @@
+<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+    <path d="M0 0h24v24H0z" fill="none"/>
+    <path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/>
+</svg>
diff --git a/core/modules/image/js/editors/image.es6.js b/core/modules/quickedit/js/editors/image.es6.js
similarity index 100%
rename from core/modules/image/js/editors/image.es6.js
rename to core/modules/quickedit/js/editors/image.es6.js
diff --git a/core/modules/image/js/editors/image.js b/core/modules/quickedit/js/editors/image.js
similarity index 100%
rename from core/modules/image/js/editors/image.js
rename to core/modules/quickedit/js/editors/image.js
diff --git a/core/modules/quickedit/js/theme.es6.js b/core/modules/quickedit/js/theme.es6.js
index dd3eb3ac3616..fd0bba7a0fd2 100644
--- a/core/modules/quickedit/js/theme.es6.js
+++ b/core/modules/quickedit/js/theme.es6.js
@@ -182,4 +182,89 @@
     html += '</div>';
     return html;
   };
+
+  /**
+   * Theme function for validation errors of the Image in-place editor.
+   *
+   * @param {object} settings
+   *   Settings object used to construct the markup.
+   * @param {string} settings.errors
+   *   Already escaped HTML representing error messages.
+   *
+   * @return {string}
+   *   The corresponding HTML.
+   */
+  Drupal.theme.quickeditImageErrors = function (settings) {
+    return `<div class="quickedit-image-errors">${settings.errors}</div>`;
+  };
+
+  /**
+   * Theme function for the dropzone element of the in-place editor.
+   *
+   * @param {object} settings
+   *   Settings object used to construct the markup.
+   * @param {string} settings.state
+   *   State of the upload.
+   * @param {string} settings.text
+   *   Text to display inline with the dropzone element.
+   *
+   * @return {string}
+   *   The corresponding HTML.
+   */
+  Drupal.theme.quickeditImageDropzone = function (settings) {
+    return (
+      `<div class="quickedit-image-dropzone ${settings.state}">` +
+      '  <i class="quickedit-image-icon"></i>' +
+      `  <span class="quickedit-image-text">${settings.text}</span>` +
+      '</div>'
+    );
+  };
+
+  /**
+   * Theme function for the toolbar of the Image module's in-place editor.
+   *
+   * @param {object} settings
+   *   Settings object used to construct the markup.
+   * @param {bool} settings.alt_field
+   *   Whether or not the "Alt" field is enabled for this field.
+   * @param {bool} settings.alt_field_required
+   *   Whether or not the "Alt" field is required for this field.
+   * @param {string} settings.alt
+   *   The current value for the "Alt" field.
+   * @param {bool} settings.title_field
+   *   Whether or not the "Title" field is enabled for this field.
+   * @param {bool} settings.title_field_required
+   *   Whether or not the "Title" field is required for this field.
+   * @param {string} settings.title
+   *   The current value for the "Title" field.
+   *
+   * @return {string}
+   *   The corresponding HTML.
+   */
+  Drupal.theme.quickeditImageToolbar = function (settings) {
+    let html = '<form class="quickedit-image-field-info">';
+    if (settings.alt_field) {
+      html +=
+        `<div><label for="alt" class="${
+          settings.alt_field_required ? 'required' : ''
+        }">${Drupal.t('Alternative text')}</label>` +
+        `<input type="text" placeholder="${settings.alt}" value="${
+          settings.alt
+        }" name="alt" ${settings.alt_field_required ? 'required' : ''}/>` +
+        '  </div>';
+    }
+    if (settings.title_field) {
+      html +=
+        `<div><label for="title" class="${
+          settings.title_field_required ? 'form-required' : ''
+        }">${Drupal.t('Title')}</label>` +
+        `<input type="text" placeholder="${settings.title}" value="${
+          settings.title
+        }" name="title" ${settings.title_field_required ? 'required' : ''}/>` +
+        '</div>';
+    }
+    html += '</form>';
+
+    return html;
+  };
 })(jQuery, Drupal);
diff --git a/core/modules/quickedit/js/theme.js b/core/modules/quickedit/js/theme.js
index 0545c680f82f..81e43d961ff6 100644
--- a/core/modules/quickedit/js/theme.js
+++ b/core/modules/quickedit/js/theme.js
@@ -87,4 +87,27 @@
     html += '</div>';
     return html;
   };
+
+  Drupal.theme.quickeditImageErrors = function (settings) {
+    return `<div class="quickedit-image-errors">${settings.errors}</div>`;
+  };
+
+  Drupal.theme.quickeditImageDropzone = function (settings) {
+    return `<div class="quickedit-image-dropzone ${settings.state}">` + '  <i class="quickedit-image-icon"></i>' + `  <span class="quickedit-image-text">${settings.text}</span>` + '</div>';
+  };
+
+  Drupal.theme.quickeditImageToolbar = function (settings) {
+    let html = '<form class="quickedit-image-field-info">';
+
+    if (settings.alt_field) {
+      html += `<div><label for="alt" class="${settings.alt_field_required ? 'required' : ''}">${Drupal.t('Alternative text')}</label>` + `<input type="text" placeholder="${settings.alt}" value="${settings.alt}" name="alt" ${settings.alt_field_required ? 'required' : ''}/>` + '  </div>';
+    }
+
+    if (settings.title_field) {
+      html += `<div><label for="title" class="${settings.title_field_required ? 'form-required' : ''}">${Drupal.t('Title')}</label>` + `<input type="text" placeholder="${settings.title}" value="${settings.title}" name="title" ${settings.title_field_required ? 'required' : ''}/>` + '</div>';
+    }
+
+    html += '</form>';
+    return html;
+  };
 })(jQuery, Drupal);
\ No newline at end of file
diff --git a/core/modules/quickedit/quickedit.libraries.yml b/core/modules/quickedit/quickedit.libraries.yml
index c7211e27dd3f..af5bcb2d7a77 100644
--- a/core/modules/quickedit/quickedit.libraries.yml
+++ b/core/modules/quickedit/quickedit.libraries.yml
@@ -54,3 +54,18 @@ quickedit.inPlaceEditor.plainText:
     js/editors/plainTextEditor.js: {}
   dependencies:
     - quickedit/quickedit
+
+quickedit.inPlaceEditor.image:
+  version: VERSION
+  js:
+    js/editors/image.js: {}
+  css:
+    component:
+      css/editors/image.css: {}
+    theme:
+      css/editors/image.theme.css: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/underscore
+    - quickedit/quickedit
diff --git a/core/modules/quickedit/quickedit.routing.yml b/core/modules/quickedit/quickedit.routing.yml
index af22056cb785..b63b8a2f1316 100644
--- a/core/modules/quickedit/quickedit.routing.yml
+++ b/core/modules/quickedit/quickedit.routing.yml
@@ -35,3 +35,29 @@ quickedit.entity_save:
     parameters:
       entity:
         type: entity:{entity_type}
+
+quickedit.image_upload:
+  path: '/quickedit/image/upload/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode_id}'
+  defaults:
+    _controller: '\Drupal\quickedit\Controller\QuickEditImageController::upload'
+  options:
+    parameters:
+      entity:
+        type: entity:{entity_type}
+  requirements:
+    _permission: 'access in-place editing'
+    _access_quickedit_entity_field: 'TRUE'
+    _method: 'POST'
+
+quickedit.image_info:
+  path: '/quickedit/image/info/{entity_type}/{entity}/{field_name}/{langcode}/{view_mode_id}'
+  defaults:
+    _controller: '\Drupal\quickedit\Controller\QuickEditImageController::getInfo'
+  options:
+    parameters:
+      entity:
+        type: entity:{entity_type}
+  requirements:
+    _permission: 'access in-place editing'
+    _access_quickedit_entity_field: 'TRUE'
+    _method: 'GET'
diff --git a/core/modules/image/src/Controller/QuickEditImageController.php b/core/modules/quickedit/src/Controller/QuickEditImageController.php
similarity index 99%
rename from core/modules/image/src/Controller/QuickEditImageController.php
rename to core/modules/quickedit/src/Controller/QuickEditImageController.php
index b3e24c17992e..21c37206c494 100644
--- a/core/modules/image/src/Controller/QuickEditImageController.php
+++ b/core/modules/quickedit/src/Controller/QuickEditImageController.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\image\Controller;
+namespace Drupal\quickedit\Controller;
 
 use Drupal\Core\Cache\CacheableJsonResponse;
 use Drupal\Core\Controller\ControllerBase;
diff --git a/core/modules/image/src/Plugin/InPlaceEditor/Image.php b/core/modules/quickedit/src/Plugin/InPlaceEditor/Image.php
similarity index 87%
rename from core/modules/image/src/Plugin/InPlaceEditor/Image.php
rename to core/modules/quickedit/src/Plugin/InPlaceEditor/Image.php
index 9cf9cd24859f..b03007f41ac4 100644
--- a/core/modules/image/src/Plugin/InPlaceEditor/Image.php
+++ b/core/modules/quickedit/src/Plugin/InPlaceEditor/Image.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\image\Plugin\InPlaceEditor;
+namespace Drupal\quickedit\Plugin\InPlaceEditor;
 
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\quickedit\Plugin\InPlaceEditorBase;
@@ -31,7 +31,7 @@ public function isCompatible(FieldItemListInterface $items) {
   public function getAttachments() {
     return [
       'library' => [
-        'image/quickedit.inPlaceEditor.image',
+        'quickedit/quickedit.inPlaceEditor.image',
       ],
     ];
   }
diff --git a/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageEditorTestTrait.php b/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageEditorTestTrait.php
index f647d88b28df..fd224e4e1d58 100644
--- a/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageEditorTestTrait.php
+++ b/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageEditorTestTrait.php
@@ -3,7 +3,7 @@
 namespace Drupal\Tests\quickedit\FunctionalJavascript;
 
 /**
- * @see \Drupal\image\Plugin\InPlaceEditor\Image
+ * @see \Drupal\quickedit\Plugin\InPlaceEditor\Image
  * @see \Drupal\Tests\quickedit\FunctionalJavascript\QuickEditJavascriptTestBase
  */
 trait QuickEditImageEditorTestTrait {
diff --git a/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageTest.php b/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageTest.php
index 7ed590965248..8db8293b9afe 100644
--- a/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageTest.php
+++ b/core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditImageTest.php
@@ -7,7 +7,7 @@
 use Drupal\Tests\TestFileCreationTrait;
 
 /**
- * @coversDefaultClass \Drupal\image\Plugin\InPlaceEditor\Image
+ * @coversDefaultClass \Drupal\quickedit\Plugin\InPlaceEditor\Image
  * @group quickedit
  */
 class QuickEditImageTest extends QuickEditJavascriptTestBase {
diff --git a/core/themes/stable/css/image/editors/image.css b/core/themes/stable/css/quickedit/editors/editors/image.css
similarity index 93%
rename from core/themes/stable/css/image/editors/image.css
rename to core/themes/stable/css/quickedit/editors/editors/image.css
index f9733d283486..b6218c93f955 100644
--- a/core/themes/stable/css/image/editors/image.css
+++ b/core/themes/stable/css/quickedit/editors/editors/image.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Functional styles for the Image module's in-place editor.
+ * Functional styles for the Quick Edit image in-place editor.
  */
 
 /**
diff --git a/core/themes/stable/css/image/editors/image.theme.css b/core/themes/stable/css/quickedit/editors/editors/image.theme.css
similarity index 97%
rename from core/themes/stable/css/image/editors/image.theme.css
rename to core/themes/stable/css/quickedit/editors/editors/image.theme.css
index eab3b947bd4f..0257a9019cd1 100644
--- a/core/themes/stable/css/image/editors/image.theme.css
+++ b/core/themes/stable/css/quickedit/editors/editors/image.theme.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Theme styles for the Image module's in-place editor.
+ * Theme styles for the Quick Edit image in-place editor.
  */
 
 .quickedit-image-dropzone {
diff --git a/core/themes/stable/css/quickedit/editors/image.css b/core/themes/stable/css/quickedit/editors/image.css
new file mode 100644
index 000000000000..9265f309dbda
--- /dev/null
+++ b/core/themes/stable/css/quickedit/editors/image.css
@@ -0,0 +1,52 @@
+/**
+ * @file
+ * Functional styles for the QuickEdit module's in-place editor.
+ */
+
+/**
+ * A minimum width/height is required so that users can drag and drop files
+ * onto small images.
+ */
+.quickedit-image-element {
+  min-width: 200px;
+  min-height: 200px;
+}
+
+.quickedit-image-dropzone {
+  position: absolute;
+  top: 0;
+  left: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+}
+
+.quickedit-image-icon {
+  display: block;
+  width: 50px;
+  height: 50px;
+  background-repeat: no-repeat;
+  background-size: cover;
+}
+
+.quickedit-image-field-info {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+}
+
+.quickedit-image-text {
+  display: block;
+}
+
+/**
+ * If we do not prevent pointer-events for child elements, our drag+drop events
+ * will not fire properly. This can lead to unintentional redirects if a file
+ * is dropped on a child element when a user intended to upload it.
+ */
+.quickedit-image-dropzone * {
+  pointer-events: none;
+}
diff --git a/core/modules/image/css/editors/image.theme.css b/core/themes/stable/css/quickedit/editors/image.theme.css
similarity index 91%
rename from core/modules/image/css/editors/image.theme.css
rename to core/themes/stable/css/quickedit/editors/image.theme.css
index 85c5f20ba364..7fd07346e801 100644
--- a/core/modules/image/css/editors/image.theme.css
+++ b/core/themes/stable/css/quickedit/editors/image.theme.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Theme styles for the Image module's in-place editor.
+ * Theme styles for the QuickEdit module's in-place editor.
  */
 
 .quickedit-image-dropzone {
@@ -22,11 +22,11 @@
 }
 
 .quickedit-image-dropzone.upload .quickedit-image-icon {
-  background-image: url("../../images/upload.svg");
+  background-image: url("../../../images/image/upload.svg");
 }
 
 .quickedit-image-dropzone.error .quickedit-image-icon {
-  background-image: url("../../images/error.svg");
+  background-image: url("../../../images/image/error.svg");
 }
 
 .quickedit-image-dropzone.loading .quickedit-image-icon {
diff --git a/core/themes/stable/stable.info.yml b/core/themes/stable/stable.info.yml
index d75e28ba5cbb..13f28498ce42 100644
--- a/core/themes/stable/stable.info.yml
+++ b/core/themes/stable/stable.info.yml
@@ -124,12 +124,6 @@ libraries-override:
     css:
       theme:
         css/image.admin.css: css/image/image.admin.css
-  image/quickedit.inPlaceEditor.image:
-    css:
-      component:
-        css/editors/image.css: css/image/editors/image.css
-      theme:
-        css/editors/image.theme.css: css/image/editors/image.theme.css
 
   language/drupal.language.admin:
     css:
@@ -194,6 +188,12 @@ libraries-override:
       theme:
         css/quickedit.theme.css: css/quickedit/quickedit.theme.css
         css/quickedit.icons.theme.css: css/quickedit/quickedit.icons.theme.css
+  quickedit/quickedit.inPlaceEditor.image:
+    css:
+      component:
+        css/editors/image.css: css/quickedit/editors/image.css
+      theme:
+        css/editors/image.theme.css: css/quickedit/editors/image.theme.css
 
   settings_tray/drupal.settings_tray:
     css:
diff --git a/core/themes/stable9/css/image/editors/image.css b/core/themes/stable9/css/quickedit/editors/image.css
similarity index 93%
rename from core/themes/stable9/css/image/editors/image.css
rename to core/themes/stable9/css/quickedit/editors/image.css
index f9733d283486..b6218c93f955 100644
--- a/core/themes/stable9/css/image/editors/image.css
+++ b/core/themes/stable9/css/quickedit/editors/image.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Functional styles for the Image module's in-place editor.
+ * Functional styles for the Quick Edit image in-place editor.
  */
 
 /**
diff --git a/core/themes/stable9/css/quickedit/editors/image.theme.css b/core/themes/stable9/css/quickedit/editors/image.theme.css
new file mode 100644
index 000000000000..8514266ede4e
--- /dev/null
+++ b/core/themes/stable9/css/quickedit/editors/image.theme.css
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * Theme styles for the Quick Edit image in-place editor.
+ */
+
+.quickedit-image-dropzone {
+  transition: background 0.2s;
+  background: rgba(116, 183, 255, 0.8);
+}
+
+.quickedit-image-icon {
+  margin: 0 0 10px 0;
+  transition: margin 0.5s;
+}
+
+.quickedit-image-dropzone.hover {
+  background: rgba(116, 183, 255, 0.9);
+}
+
+.quickedit-image-dropzone.error {
+  background: rgba(255, 52, 27, 0.81);
+}
+
+.quickedit-image-dropzone.upload .quickedit-image-icon {
+  background-image: url("../../../../../modules/quickedit/images/upload.svg");
+}
+
+.quickedit-image-dropzone.error .quickedit-image-icon {
+  background-image: url("../../../../../modules/quickedit/images/error.svg");
+}
+
+.quickedit-image-dropzone.loading .quickedit-image-icon {
+  margin: -10px 0 20px 0;
+}
+
+.quickedit-image-dropzone.loading .quickedit-image-icon::after {
+  display: block;
+  width: 60px;
+  height: 60px;
+  margin-top: -5px;
+  margin-left: -10px;
+  content: "";
+  animation-name: quickedit-image-spin;
+  animation-duration: 2s;
+  animation-timing-function: linear;
+  animation-iteration-count: infinite;
+  border-width: 5px;
+  border-style: solid;
+  border-color: white transparent transparent transparent;
+  border-radius: 35px;
+}
+
+@keyframes quickedit-image-spin {
+  0% { transform: rotate(0deg); }
+  50% { transform: rotate(180deg); }
+  100% { transform: rotate(360deg); }
+}
+
+.quickedit-image-text {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-align: center;
+  color: white;
+  font-family: "Droid sans", "Lucida Grande", sans-serif;
+  font-size: 16px;
+}
+
+.quickedit-image-field-info {
+  padding: 5px;
+  border-top: 1px solid #c5c5c5;
+  background: rgba(0, 0, 0, 0.05);
+}
+
+.quickedit-image-field-info div {
+  margin-right: 10px; /* LTR */
+}
+
+.quickedit-image-field-info div:last-child {
+  margin-right: 0; /* LTR */
+}
+
+[dir="rtl"] .quickedit-image-field-info div {
+  margin-right: 0;
+  margin-left: 10px;
+}
+
+[dir="rtl"] .quickedit-image-field-info div:last-child {
+  margin-left: 0;
+}
+
+.quickedit-image-errors .messages__wrapper {
+  margin: 0;
+  padding: 0;
+}
+
+.quickedit-image-errors .messages--error {
+  box-shadow: none;
+}
diff --git a/core/themes/stable9/stable9.info.yml b/core/themes/stable9/stable9.info.yml
index 9dc52ab3af88..32595170a159 100644
--- a/core/themes/stable9/stable9.info.yml
+++ b/core/themes/stable9/stable9.info.yml
@@ -111,12 +111,6 @@ libraries-override:
     css:
       theme:
         css/image.admin.css: css/image/image.admin.css
-  image/quickedit.inPlaceEditor.image:
-    css:
-      component:
-        css/editors/image.css: css/image/editors/image.css
-      theme:
-        css/editors/image.theme.css: css/image/editors/image.theme.css
 
   language/drupal.language.admin:
     css:
@@ -214,6 +208,12 @@ libraries-override:
       theme:
         css/quickedit.theme.css: css/quickedit/quickedit.theme.css
         css/quickedit.icons.theme.css: css/quickedit/quickedit.icons.theme.css
+  quickedit/quickedit.inPlaceEditor.image:
+    css:
+      component:
+        css/editors/image.css: css/quickedit/editors/image.css
+      theme:
+        css/editors/image.theme.css: css/quickedit/editors/image.theme.css
 
   settings_tray/drupal.settings_tray:
     css:
-- 
GitLab