From c991e1f01773c3a32792ee486df0ecceb4779cf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 31 Jul 2019 10:10:40 +0200 Subject: [PATCH] add focus extension --- examples/Components/Routes/Focus/index.vue | 97 +++++++++++++++++++ examples/Components/Subnavigation/index.vue | 3 + examples/main.js | 7 ++ .../tiptap-extensions/src/extensions/Focus.js | 53 ++++++++++ packages/tiptap-extensions/src/index.js | 1 + 5 files changed, 161 insertions(+) create mode 100644 examples/Components/Routes/Focus/index.vue create mode 100644 packages/tiptap-extensions/src/extensions/Focus.js diff --git a/examples/Components/Routes/Focus/index.vue b/examples/Components/Routes/Focus/index.vue new file mode 100644 index 00000000..2cacb82d --- /dev/null +++ b/examples/Components/Routes/Focus/index.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/examples/Components/Subnavigation/index.vue b/examples/Components/Subnavigation/index.vue index 35a023e9..f1a05f92 100644 --- a/examples/Components/Subnavigation/index.vue +++ b/examples/Components/Subnavigation/index.vue @@ -48,6 +48,9 @@ Placeholder + + Focus + Collaboration diff --git a/examples/main.js b/examples/main.js index 3702cad6..8ee8e3e7 100644 --- a/examples/main.js +++ b/examples/main.js @@ -123,6 +123,13 @@ const routes = [ githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Placeholder', }, }, + { + path: '/focus', + component: () => import('Components/Routes/Focus'), + meta: { + githubUrl: 'https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Focus', + }, + }, { path: '/collaboration', component: () => import('Components/Routes/Collaboration'), diff --git a/packages/tiptap-extensions/src/extensions/Focus.js b/packages/tiptap-extensions/src/extensions/Focus.js new file mode 100644 index 00000000..5f78a011 --- /dev/null +++ b/packages/tiptap-extensions/src/extensions/Focus.js @@ -0,0 +1,53 @@ +import { Extension, Plugin } from 'tiptap' +import { DecorationSet, Decoration } from 'prosemirror-view' + +export default class Focus extends Extension { + + get name() { + return 'focus' + } + + get defaultOptions() { + return { + className: 'has-focus', + nested: false, + } + } + + get plugins() { + return [ + new Plugin({ + props: { + decorations: ({ doc, plugins, selection }) => { + const editablePlugin = plugins.find(plugin => plugin.key.startsWith('editable$')) + const editable = editablePlugin.props.editable() + const active = editable && this.options.className + const { focused } = this.editor + const { anchor } = selection + const decorations = [] + + if (!active || !focused) { + return false + } + + doc.descendants((node, pos) => { + const hasAnchor = anchor >= pos && anchor <= (pos + node.nodeSize) + + if (hasAnchor && !node.isText) { + const decoration = Decoration.node(pos, pos + node.nodeSize, { + class: this.options.className, + }) + decorations.push(decoration) + } + + return this.options.nested + }) + + return DecorationSet.create(doc, decorations) + }, + }, + }), + ] + } + +} diff --git a/packages/tiptap-extensions/src/index.js b/packages/tiptap-extensions/src/index.js index 3165bccb..557f008a 100644 --- a/packages/tiptap-extensions/src/index.js +++ b/packages/tiptap-extensions/src/index.js @@ -24,6 +24,7 @@ export { default as Strike } from './marks/Strike' export { default as Underline } from './marks/Underline' export { default as Collaboration } from './extensions/Collaboration' +export { default as Focus } from './extensions/Focus' export { default as History } from './extensions/History' export { default as Placeholder } from './extensions/Placeholder' export { default as Search } from './extensions/Search'