Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions cypress/e2e/nodes/ListItem.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

/* eslint-disable import/no-named-as-default */
import ListItem from '@tiptap/extension-list-item'
import OrderedList from '@tiptap/extension-ordered-list'
import { ListItem, OrderedList } from '@tiptap/extension-list'
/* eslint-enable import/no-named-as-default */
import Markdown from './../../../src/extensions/Markdown.js'
import BulletList from './../../../src/nodes/BulletList.js'
Expand Down
36,763 changes: 9,294 additions & 27,469 deletions package-lock.json

Large diffs are not rendered by default.

69 changes: 29 additions & 40 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,46 +45,35 @@
"@nextcloud/sharing": "^0.3.0",
"@nextcloud/vue": "^8.34.0",
"@quartzy/markdown-it-mentions": "^0.2.0",
"@tiptap/core": "^2.27.1",
"@tiptap/extension-blockquote": "^2.27.1",
"@tiptap/extension-bold": "^2.27.1",
"@tiptap/extension-bullet-list": "^2.27.1",
"@tiptap/extension-character-count": "^2.27.1",
"@tiptap/extension-code": "^2.27.1",
"@tiptap/extension-code-block": "^2.27.1",
"@tiptap/extension-code-block-lowlight": "^2.27.1",
"@tiptap/extension-collaboration": "^2.27.1",
"@tiptap/extension-collaboration-cursor": "^2.26.2",
"@tiptap/extension-document": "^2.27.1",
"@tiptap/extension-drag-handle": "^2.27.1",
"@tiptap/extension-drag-handle-vue-2": "^2.27.1",
"@tiptap/extension-dropcursor": "^2.27.1",
"@tiptap/extension-gapcursor": "^2.27.1",
"@tiptap/extension-hard-break": "^2.27.1",
"@tiptap/extension-heading": "^2.27.1",
"@tiptap/extension-history": "^2.27.1",
"@tiptap/extension-horizontal-rule": "^2.27.1",
"@tiptap/extension-image": "^2.27.1",
"@tiptap/extension-italic": "^2.27.1",
"@tiptap/extension-link": "^2.27.1",
"@tiptap/extension-list-item": "^2.27.1",
"@tiptap/extension-mention": "^2.27.1",
"@tiptap/extension-ordered-list": "^2.27.1",
"@tiptap/extension-paragraph": "^2.27.1",
"@tiptap/extension-placeholder": "^2.27.1",
"@tiptap/extension-strike": "^2.27.1",
"@tiptap/extension-table": "^2.27.1",
"@tiptap/extension-table-cell": "^2.27.1",
"@tiptap/extension-table-header": "^2.27.1",
"@tiptap/extension-table-row": "^2.27.1",
"@tiptap/extension-task-item": "^2.27.1",
"@tiptap/extension-task-list": "^2.27.1",
"@tiptap/extension-text": "^2.27.1",
"@tiptap/extension-typography": "^2.27.1",
"@tiptap/extension-underline": "^2.27.1",
"@tiptap/pm": "^2.27.1",
"@tiptap/suggestion": "^2.27.1",
"@tiptap/vue-2": "^2.27.1",
"@tiptap/core": "^3.10.5",
"@tiptap/extension-blockquote": "^3.10.5",
"@tiptap/extension-bold": "^3.10.5",
"@tiptap/extension-code": "^3.10.5",
"@tiptap/extension-code-block": "^3.10.5",
"@tiptap/extension-code-block-lowlight": "^3.10.5",
"@tiptap/extension-collaboration": "^3.10.5",
"@tiptap/extension-collaboration-caret": "^3.10.5",
"@tiptap/extension-document": "^3.10.5",
"@tiptap/extension-drag-handle": "^3.10.5",
"@tiptap/extension-drag-handle-vue-2": "^3.10.5",
"@tiptap/extension-hard-break": "^3.10.5",
"@tiptap/extension-heading": "^3.10.5",
"@tiptap/extension-horizontal-rule": "^3.10.5",
"@tiptap/extension-image": "^3.10.5",
"@tiptap/extension-italic": "^3.10.5",
"@tiptap/extension-link": "^3.10.5",
"@tiptap/extension-list": "^3.10.5",
"@tiptap/extension-mention": "^3.10.5",
"@tiptap/extension-paragraph": "^3.10.5",
"@tiptap/extension-strike": "^3.10.5",
"@tiptap/extension-table": "^3.10.5",
"@tiptap/extension-text": "^3.10.5",
"@tiptap/extension-typography": "^3.10.5",
"@tiptap/extension-underline": "^3.10.5",
"@tiptap/extensions": "^3.10.5",
"@tiptap/pm": "^3.10.5",
"@tiptap/suggestion": "^3.10.5",
"@tiptap/vue-2": "^3.10.5",
"@vueuse/shared": "^11.3.0",
"debounce": "^3.0.0",
"escape-html": "^1.0.3",
Expand Down
2 changes: 1 addition & 1 deletion src/EditorFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const createRichEditor = ({
})
}

const createPlainEditor = ({ language, extensions = [] } = {}) => {
const createPlainEditor = ({ language = 'plaintext', extensions = [] } = {}) => {
return new Editor({
editorProps,
extensions: [
Expand Down
12 changes: 6 additions & 6 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ import { provideEditorWidth } from '../composables/useEditorWidth.ts'
import { provideSaveService } from '../composables/useSaveService.ts'
import { provideSyncService } from '../composables/useSyncService.ts'
import { useSyntaxHighlighting } from '../composables/useSyntaxHighlighting.ts'
import { CollaborationCursor } from '../extensions/index.js'
import { CollaborationCaret } from '../extensions/index.js'
import { exposeForDebugging, removeFromDebugging } from '../helpers/debug.js'
import { logger } from '../helpers/logger.js'
import { setInitialYjsState } from '../helpers/setInitialYjsState.js'
Expand Down Expand Up @@ -240,7 +240,7 @@ export default defineComponent({
const extensions = [
Autofocus.configure({ fileId: props.fileId }),
Collaboration.configure({ document: ydoc }),
CollaborationCursor.configure({ provider: { awareness } }),
CollaborationCaret.configure({ provider: { awareness } }),
]
const editor = isRichEditor
? createRichEditor({
Expand Down Expand Up @@ -929,7 +929,7 @@ export default defineComponent({
}

/* Give a remote user a caret */
.collaboration-cursor__caret {
.collaboration-carets__caret {
position: relative;
margin-left: -1px;
margin-right: -1px;
Expand All @@ -940,7 +940,7 @@ export default defineComponent({
}

/* Render the username above the caret */
.collaboration-cursor__label {
.collaboration-carets__label {
position: absolute;
top: -1.4em;
left: -1px;
Expand All @@ -955,11 +955,11 @@ export default defineComponent({
white-space: nowrap;
opacity: 0;

&.collaboration-cursor__label__active {
&.collaboration-carets__label__active {
opacity: 1;
}

&:not(.collaboration-cursor__label__active) {
&:not(.collaboration-carets__label__active) {
transition: opacity 0.2s 5s;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Editor/MarkdownContentEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import MainContainer from './MainContainer.vue'
import Wrapper from './Wrapper.vue'
/* eslint-disable import/no-named-as-default */
import { getCurrentUser } from '@nextcloud/auth'
import History from '@tiptap/extension-history'
import { UndoRedo } from '@tiptap/extensions'
import { provide, watch } from 'vue'
import { provideEditor } from '../../composables/useEditor.ts'
import { editorFlagsKey } from '../../composables/useEditorFlags.ts'
Expand Down Expand Up @@ -89,7 +89,7 @@ export default {
setup(props) {
const extensions = [
RichText.configure({
extensions: [History],
extensions: [UndoRedo],
}),
FocusTrap,
]
Expand Down
4 changes: 2 additions & 2 deletions src/composables/useEditorMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import type { Editor } from '@tiptap/core'
import escapeHtml from 'escape-html'
import type { AwarenessUser } from '../extensions/CollaborationCursor.ts'
import type { AwarenessUser } from '../extensions/CollaborationCaret.ts'
import Markdown from '../extensions/Markdown.js'
import markdownit from '../markdownit/index.js'
import { isUser, type Session } from '../services/SyncService'
Expand All @@ -28,7 +28,7 @@ export const useEditorMethods = (editor: Editor) => {
: `<pre>${escapeHtml(content)}</pre>`
editor
.chain()
.setContent(html, addToHistory)
.setContent(html, { emitUpdate: addToHistory })
.command(({ tr }) => {
tr.setMeta('addToHistory', addToHistory)
return true
Expand Down
4 changes: 2 additions & 2 deletions src/css/print.scss
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@
}
}

.collaboration-cursor__caret,
.collaboration-cursor__label {
.collaboration-carets__caret,
.collaboration-carets__label {
display: none;
}
}
2 changes: 1 addition & 1 deletion src/css/prosemirror.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ div.ProseMirror {
user-select: text;
font-size: var(--default-font-size);

&:not(.collaboration-cursor__caret) {
&:not(.collaboration-carets__caret) {
border: none !important;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { t } from '@nextcloud/l10n'
import { CollaborationCursor as TiptapCollaborationCursor } from '@tiptap/extension-collaboration-cursor'
import { CollaborationCaret as TiptapCollaborationCaret } from '@tiptap/extension-collaboration-caret'

export interface AwarenessUser {
color: string
Expand All @@ -14,18 +14,18 @@ export interface AwarenessUser {
/**
* @param clientId The Yjs client ID
*/
function showCursorLabel(clientId: number) {
function showCaretLabel(clientId: number) {
setTimeout(() => {
const el = document.getElementById(
`collaboration-cursor__label__${clientId}`,
`collaboration-carets__label__${clientId}`,
)
if (!el) {
return
}

el.classList.add('collaboration-cursor__label__active')
el.classList.add('collaboration-carets__label__active')
setTimeout(() => {
el?.classList.remove('collaboration-cursor__label__active')
el?.classList.remove('collaboration-carets__label__active')
}, 50)
}, 50)
}
Expand All @@ -38,26 +38,30 @@ function getTimestamp() {
}

/**
* Render the cursor decoration
* Render the caret decoration
*
* @param user the users awareness data
* @param clientId not part of the tiptap type signature but provided by y-prosemirror
*/
function render(user: AwarenessUser, clientId?: number): HTMLElement {
const cursor = document.createElement('span')
cursor.classList.add('collaboration-cursor__caret')

cursor.classList.add('collaboration-carets__caret')
cursor.setAttribute('style', `border-color: ${user.color}`)

const label = document.createElement('div')
label.classList.add('collaboration-cursor__label')
label.id = `collaboration-cursor__label__${clientId}`
label.id = `collaboration-carets__label__${clientId}`

label.classList.add('collaboration-carets__label')
label.setAttribute('style', `background-color: ${user.color}`)
const text = document.createTextNode(user.name || t('text', 'Guest'))
label.insertBefore(text, null)
cursor.insertBefore(label, null)

return cursor
}

const CollaborationCursor = TiptapCollaborationCursor.extend({
const CollaborationCaret = TiptapCollaborationCaret.extend({
addOptions() {
return {
...this.parent?.(),
Expand All @@ -74,27 +78,27 @@ const CollaborationCursor = TiptapCollaborationCursor.extend({
) => {
if (origin !== 'local') {
for (const clientId of [...added, ...updated]) {
if (clientId !== this.options.user.clientId) {
showCursorLabel(clientId)
if (clientId !== this.options.provider.awareness.clientID) {
showCaretLabel(clientId)
}
}
}
},
)
},

// Flag own cursor as active on undoable changes to the document state
// Flag own caret as active on undoable changes to the document state
onTransaction({ transaction, editor }) {
const addToHistory = transaction.getMeta('addToHistory') ?? true
const pointer = transaction.getMeta('pointer')
const updated = transaction.docChanged
if (updated && addToHistory && !pointer) {
editor.commands.updateUser({
...this.options.user,
...this.options.provider.awareness.getLocalState().user,
lastUpdate: getTimestamp(),
})
}
},
})

export default CollaborationCursor
export default CollaborationCaret
2 changes: 1 addition & 1 deletion src/extensions/PlainText.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default Extension.create({
return {
...this.parent?.(),
lowlight: undefined,
defaultLanguage: undefined,
defaultLanguage: 'plaintext',
}
},

Expand Down
6 changes: 2 additions & 4 deletions src/extensions/RichText.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ import { common, createLowlight } from 'lowlight'

/* eslint-disable import/no-named-as-default */
import Blockquote from '@tiptap/extension-blockquote'
import CharacterCount from '@tiptap/extension-character-count'
import Code from '@tiptap/extension-code'
import Document from '@tiptap/extension-document'
import Dropcursor from '@tiptap/extension-dropcursor'
import Gapcursor from '@tiptap/extension-gapcursor'
import HorizontalRule from '@tiptap/extension-horizontal-rule'
import ListItem from '@tiptap/extension-list-item'
import { ListItem } from '@tiptap/extension-list'
import Text from '@tiptap/extension-text'
import { CharacterCount, Dropcursor, Gapcursor } from '@tiptap/extensions'
import MentionSuggestion from '../components/Suggestion/Mention/suggestions.js'
import Heading from '../nodes/Heading.js'
import EmojiSuggestion from './../components/Suggestion/Emoji/suggestions.js'
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import CollaborationCursor from './CollaborationCursor.ts'
import CollaborationCaret from './CollaborationCaret.ts'
import Emoji from './Emoji.js'
import FocusTrap from './FocusTrap.js'
import KeepSyntax from './KeepSyntax.js'
Expand All @@ -14,7 +14,7 @@ import RichText from './RichText.js'
import UserColor from './UserColor.js'

export {
CollaborationCursor,
CollaborationCaret,
Emoji,
FocusTrap,
KeepSyntax,
Expand Down
3 changes: 1 addition & 2 deletions src/nodes/BulletList.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import TiptapBulletList from '@tiptap/extension-bullet-list'
import { BulletList as TiptapBulletList } from '@tiptap/extension-list'
import { listInputRule } from '../commands/index.js'

/* We want to allow for `* [ ]` as an input rule for bullet lists.
Expand All @@ -28,7 +28,6 @@ const BulletList = TiptapBulletList.extend({
bullet: {
default: '-',
rendered: false,
isRequired: true,
parseHTML: (el) => el.getAttribute('data-bullet'),
},
}
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/OrderedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import TiptapOrderedList from '@tiptap/extension-ordered-list'
import { OrderedList as TiptapOrderedList } from '@tiptap/extension-list'

const OrderedList = TiptapOrderedList.extend({
addAttributes() {
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/Table/TableCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { mergeAttributes } from '@tiptap/core'
import { TableCell } from '@tiptap/extension-table-cell'
import { TableCell } from '@tiptap/extension-table'
import { Fragment } from '@tiptap/pm/model'
import { Plugin } from '@tiptap/pm/state'

Expand Down
10 changes: 9 additions & 1 deletion src/nodes/Table/TableHeadRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ export default TableRow.extend({
},

parseHTML() {
return [{ tag: 'tr:first-of-type', priority: 80 }]
return [
{ tag: 'table thead:empty ~ tbody tr:first-of-type', priority: 80 },
{ tag: 'table thead tr:first-of-type', priority: 80 },
{
tag: 'table:not(:has(> thead:not(:empty))) tbody tr:first-of-type',
priority: 80,
},
{ tag: 'table > tr:first-of-type', priority: 80 },
]
},
})
Loading
Loading