diff --git a/resources/assets/javascripts/cke/studip-quote/StudipBlockQuote.js b/resources/assets/javascripts/cke/studip-quote/StudipBlockQuote.js
index f5ac256aeadcf83129b3742216600416a509c017..b1fc65d89e4ea6e1dc7e6e9138601872cdc3c58c 100644
--- a/resources/assets/javascripts/cke/studip-quote/StudipBlockQuote.js
+++ b/resources/assets/javascripts/cke/studip-quote/StudipBlockQuote.js
@@ -1,7 +1,7 @@
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import { $gettext } from '../../lib/gettext.js';
-import { icons } from 'ckeditor5/src/core';
+import { Command, icons } from 'ckeditor5/src/core';
 
 const divideIcon =
     '<svg version="1.1" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m9.3 2h2v16h-2zm-7.2987 8.423a6.5 6.5 0 0 1 6.056-6.408l0.038 0.67c-2.646 0.738-3.74 2.978-3.874 5.315h3.78c0.552 0 0.5 0.432 0.5 0.986v4.511c0 0.554-0.448 0.503-1 0.503h-5c-0.552 0-0.5-0.449-0.5-1.003zm10 0a6.5 6.5 0 0 1 6.056-6.408l0.038 0.67c-2.646 0.739-3.74 2.979-3.873 5.315h3.779c0.552 0 0.5 0.432 0.5 0.986v4.511c0 0.554-0.448 0.503-1 0.503h-5c-0.552 0-0.5-0.449-0.5-1.003z" stroke-width="1.1664"/></svg>';
@@ -13,6 +13,10 @@ export default class StudipBlockQuote extends Plugin {
     init() {
         const editor = this.editor;
 
+        editor.commands.add('insertStudipQuote', new InsertStudipQuoteCommand(editor));
+        editor.commands.add('splitStudipQuote', new SplitStudipQuoteCommand(editor));
+        editor.commands.add('removeStudipQuote', new RemoveStudipQuoteCommand(editor));
+
         editor.ui.componentFactory.add('insertBlockQuote', (locale) => {
             const view = new ButtonView(locale);
 
@@ -22,9 +26,12 @@ export default class StudipBlockQuote extends Plugin {
                 tooltip: true,
             });
 
+            const command = editor.commands.get('removeStudipQuote');
+            view.bind('isEnabled').to(command, 'isEnabled');
+
             // Callback executed once the image is clicked.
             view.on('execute', () => {
-                this.insertStudipQuote(editor);
+                editor.execute('insertStudipQuote');
             });
 
             return view;
@@ -41,9 +48,12 @@ export default class StudipBlockQuote extends Plugin {
                 withText: false,
             });
 
+            const command = editor.commands.get('removeStudipQuote');
+            view.bind('isEnabled').to(command, 'isEnabled');
+
             // Callback executed once the image is clicked.
             view.on('execute', () => {
-                this.splitStudipQuote(editor);
+                editor.execute('splitStudipQuote');
             });
 
             return view;
@@ -59,55 +69,55 @@ export default class StudipBlockQuote extends Plugin {
                 withText: false,
             });
 
+            const command = editor.commands.get('removeStudipQuote');
+            view.bind('isEnabled').to(command, 'isEnabled');
+
             // Callback executed once the image is clicked.
             view.on('execute', () => {
-                this.removeStudipQuote(editor);
+                editor.execute('removeStudipQuote');
             });
 
             return view;
         });
     }
+}
 
-    insertStudipQuote(editor) {
-        // If quoting is changed update these functions:
-        // - StudipFormat::markupQuote
-        //   lib/classes/StudipFormat.php
-        // - quotes_encode lib/visual.inc.php
-        // - STUDIP.Forum.citeEntry > quote
-        //   public/plugins_packages/core/Forum/javascript/forum.js
-        // - StudipBlockQuote > insertStudipQuote
-        //   resources/assets/javascripts/cke/studip-quote/StudipBlockQuote.js
-
+class InsertStudipQuoteCommand extends Command {
+    execute() {
         var writtenBy = $gettext('%s hat geschrieben:');
 
         const content =
             '<blockquote><div class="author">' +
             writtenBy.replace('%s', $gettext('"Name"')) +
             '</div><p>&nbsp</p></blockquote><p>&nbsp;</p>';
-        const viewFragment = editor.data.processor.toView(content);
-        const modelFragment = editor.data.toModel(viewFragment);
-        editor.model.insertContent(modelFragment);
+        const viewFragment = this.editor.data.processor.toView(content);
+        const modelFragment = this.editor.data.toModel(viewFragment);
+        this.editor.model.insertContent(modelFragment);
     }
+}
 
-    splitStudipQuote(editor) {
-        const position = editor.model.document.selection.getFirstPosition();
+class SplitStudipQuoteCommand extends Command {
+    execute() {
+        const position = this.editor.model.document.selection.getFirstPosition();
         const quote = position.findAncestor('blockQuote');
 
         if (quote !== null) {
-            editor.model.change((writer) => {
+            this.editor.model.change((writer) => {
                 const limitElement = quote.parent;
                 const split = writer.split(position, limitElement);
                 writer.insertElement('paragraph', split.position);
             });
         }
     }
+}
 
-    removeStudipQuote(editor) {
-        const position = editor.model.document.selection.getFirstPosition();
+class RemoveStudipQuoteCommand extends Command {
+    execute() {
+        const position = this.editor.model.document.selection.getFirstPosition();
         const quote = position.findAncestor('blockQuote');
 
         if (quote !== null) {
-            editor.model.change((writer) => {
+            this.editor.model.change((writer) => {
                 // Remove the top "written by" bar
                 for (var child of quote.getChildren()) {
                     if (