Skip to content

Commit fede64b

Browse files
authored
Merge pull request #4780 from nextcloud/fix/editor_api
Fixes and additions to editor API
2 parents 8dc43d3 + d080153 commit fede64b

File tree

3 files changed

+80
-18
lines changed

3 files changed

+80
-18
lines changed

src/components/Editor.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@
4343
<MainContainer v-if="hasEditor">
4444
<!-- Readonly -->
4545
<div v-if="readOnly" class="text-editor--readonly-bar">
46-
<ReadonlyBar>
47-
<Status :document="document"
48-
:dirty="dirty"
49-
:sessions="filteredSessions"
50-
:sync-error="syncError"
51-
:has-connection-issue="hasConnectionIssue" />
52-
</ReadonlyBar>
46+
<slot name="readonlyBar">
47+
<ReadonlyBar>
48+
<Status :document="document"
49+
:dirty="dirty"
50+
:sessions="filteredSessions"
51+
:sync-error="syncError"
52+
:has-connection-issue="hasConnectionIssue" />
53+
</ReadonlyBar>
54+
</slot>
5355
</div>
5456
<!-- Rich Menu -->
5557
<template v-else>
@@ -660,6 +662,10 @@ export default {
660662
this.emit('delete-image-node', imageUrl)
661663
},
662664
665+
async save() {
666+
await this.$syncService.save()
667+
},
668+
663669
async close() {
664670
if (this.currentSession && this.$syncService) {
665671
try {

src/components/Editor/MarkdownContentEditor.vue

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@
2020
-->
2121

2222
<template>
23-
<Wrapper :content-loaded="true">
23+
<Wrapper :content-loaded="true"
24+
:show-outline-outside="showOutlineOutside"
25+
@outline-toggled="outlineToggled">
2426
<MainContainer>
2527
<MenuBar v-if="!readOnly" :autohide="false" />
26-
<ReadonlyBar v-else />
28+
<slot v-else name="readonlyBar">
29+
<ReadonlyBar />
30+
</slot>
2731
<ContentContainer />
2832
</MainContainer>
2933
</Wrapper>
@@ -33,7 +37,6 @@
3337
import Wrapper from './Wrapper.vue'
3438
import MainContainer from './MainContainer.vue'
3539
import MenuBar from '../Menu/MenuBar.vue'
36-
import { useOutlineActions, useOutlineStateMixin } from './Wrapper.provider.js'
3740
import { Editor } from '@tiptap/core'
3841
/* eslint-disable import/no-named-as-default */
3942
import History from '@tiptap/extension-history'
@@ -47,7 +50,7 @@ import ContentContainer from './ContentContainer.vue'
4750
export default {
4851
name: 'MarkdownContentEditor',
4952
components: { ContentContainer, ReadonlyBar, MenuBar, MainContainer, Wrapper },
50-
mixins: [useOutlineStateMixin, useOutlineActions, useLinkClickHook],
53+
mixins: [useLinkClickHook],
5154
provide() {
5255
const val = {}
5356
@@ -72,16 +75,17 @@ export default {
7275
type: Boolean,
7376
default: false,
7477
},
78+
showOutlineOutside: {
79+
type: Boolean,
80+
default: false,
81+
},
7582
},
7683
emits: ['update:content'],
7784
7885
computed: {
7986
htmlContent() {
8087
return this.renderHtml(this.content)
8188
},
82-
showOutline() {
83-
return this.$outlineState.visible
84-
},
8589
},
8690
8791
watch: {
@@ -137,6 +141,11 @@ export default {
137141
updateContent() {
138142
this.$editor.commands.setContent(this.htmlContent, true)
139143
},
144+
145+
outlineToggled(visible) {
146+
this.$emit('outline-toggled', visible)
147+
this.$parent.$emit('outline-toggled', visible)
148+
},
140149
},
141150
}
142151
</script>

src/editor.js

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class TextEditorEmbed {
4646
return this
4747
}
4848

49+
#getEditorComponent() {
50+
return this.#vm.$children[0]
51+
}
52+
4953
onLoaded(onLoadedCallback = () => {}) {
5054
this.#vm.$on('ready', () => {
5155
onLoadedCallback()
@@ -60,6 +64,13 @@ class TextEditorEmbed {
6064
return this
6165
}
6266

67+
onOutlineToggle(onOutlineToggleCallback = () => {}) {
68+
this.#vm.$on('outline-toggled', (visible) => {
69+
onOutlineToggleCallback(visible)
70+
})
71+
return this
72+
}
73+
6374
render(el) {
6475
el.innerHTML = ''
6576
const element = document.createElement('div')
@@ -77,7 +88,16 @@ class TextEditorEmbed {
7788
// Update reactive prop for MarkdownContentEditor
7889
this.#vm.$set(this.#data, 'content', content)
7990
// Call setContent for file based Editor
80-
this.#vm.$children[0]?.setContent?.(content)
91+
this.#getEditorComponent()?.setContent?.(content)
92+
return this
93+
}
94+
95+
async save() {
96+
return this.#getEditorComponent().save?.()
97+
}
98+
99+
setShowOutline(value) {
100+
this.#vm.$set(this.#data, 'showOutlineOutside', value)
81101
return this
82102
}
83103

@@ -87,11 +107,11 @@ class TextEditorEmbed {
87107
}
88108

89109
insertAtCursor(content) {
90-
this.#vm.$children[0].$editor.chain().insertContent(content).focus().run()
110+
this.#getEditorComponent().$editor.chain().insertContent(content).focus().run()
91111
}
92112

93113
focus() {
94-
this.#vm.$children[0].$editor.focus()
114+
this.#getEditorComponent().$editor.commands.focus()
95115
}
96116

97117
#registerDebug() {
@@ -113,12 +133,20 @@ window.OCA.Text.createEditor = async function({
113133
// File mode is enabled by setting the fileId, otherwise content needs to be provided
114134
fileId = undefined,
115135
filePath = undefined,
136+
shareToken = null,
116137

117138
content = '',
118139

119140
readOnly = false,
141+
autofocus = true,
142+
readonlyBar = {
143+
component: null,
144+
props: null,
145+
},
120146

147+
onLoaded = () => {},
121148
onUpdate = ({ markdown }) => {},
149+
onOutlineToggle = (visible) => {},
122150
onLinkClick = undefined,
123151
onFileInsert = undefined,
124152
onMentionSearch = undefined,
@@ -128,6 +156,7 @@ window.OCA.Text.createEditor = async function({
128156
const { default: Editor } = await import(/* webpackChunkName: "editor" */'./components/Editor.vue')
129157

130158
const data = Vue.observable({
159+
showOutlineOutside: false,
131160
readOnly,
132161
content,
133162
})
@@ -154,25 +183,43 @@ window.OCA.Text.createEditor = async function({
154183
return data
155184
},
156185
render: h => {
186+
const scopedSlots = readonlyBar?.component
187+
? {
188+
readonlyBar: () => {
189+
return h(readonlyBar.component, {
190+
props: readonlyBar.props,
191+
})
192+
},
193+
}
194+
: {}
195+
157196
return fileId
158197
? h(Editor, {
159198
props: {
160199
fileId,
200+
relativePath: filePath,
201+
shareToken,
161202
mime: 'text/markdown',
162203
active: true,
163-
relativePath: filePath,
204+
autofocus,
205+
showOutlineOutside: data.showOutlineOutside,
164206
},
207+
scopedSlots,
165208
})
166209
: h(MarkdownContentEditor, {
167210
props: {
168211
content: data.content,
169212
readOnly: data.readOnly,
213+
showOutlineOutside: data.showOutlineOutside,
170214
},
215+
scopedSlots,
171216
})
172217
},
173218
store,
174219
})
175220
return new TextEditorEmbed(vm, data)
221+
.onLoaded(onLoaded)
176222
.onUpdate(onUpdate)
223+
.onOutlineToggle(onOutlineToggle)
177224
.render(el)
178225
}

0 commit comments

Comments
 (0)