summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/content_editor/extensions/external_keydown_handler.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/content_editor/extensions/external_keydown_handler.js')
-rw-r--r--app/assets/javascripts/content_editor/extensions/external_keydown_handler.js38
1 files changed, 38 insertions, 0 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/external_keydown_handler.js b/app/assets/javascripts/content_editor/extensions/external_keydown_handler.js
new file mode 100644
index 00000000000..e940614083e
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/external_keydown_handler.js
@@ -0,0 +1,38 @@
+import { Extension } from '@tiptap/core';
+import { Plugin, PluginKey } from 'prosemirror-state';
+import { KEYDOWN_EVENT } from '../constants';
+
+/**
+ * This extension bubbles up the keydown event, captured by ProseMirror in the
+ * contenteditale element, to the presentation layer implemented in vue.
+ *
+ * The purpose of this mechanism is allowing clients of the
+ * content editor to attach keyboard shortcuts for behavior outside
+ * of the Content Editor’s boundaries, i.e. submitting a form to save changes.
+ */
+export default Extension.create({
+ name: 'keyboardShortcut',
+ addOptions() {
+ return {
+ eventHub: null,
+ };
+ },
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ key: new PluginKey('keyboardShortcut'),
+ props: {
+ handleKeyDown: (_, event) => {
+ const {
+ options: { eventHub },
+ } = this;
+
+ eventHub.$emit(KEYDOWN_EVENT, event);
+
+ return false;
+ },
+ },
+ }),
+ ];
+ },
+});