Skip to content

Commit

Permalink
Use vue-richtext for rendering paragraph widget
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <jus@bitgrid.net>

Address review feedback

Signed-off-by: Julius Härtl <jus@bitgrid.net>
  • Loading branch information
juliusknorr committed Oct 11, 2022
1 parent 24c772d commit 12d6c32
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 7 deletions.
8 changes: 1 addition & 7 deletions src/extensions/RichText.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import CodeBlock from '@tiptap/extension-code-block'
import Document from '@tiptap/extension-document'
import Dropcursor from '@tiptap/extension-dropcursor'
import FrontMatter from './../nodes/FrontMatter.js'
import Paragraph from './../nodes/Paragraph.js'
import HardBreak from './HardBreak.js'
import Heading from '../nodes/Heading/index.js'
import HorizontalRule from '@tiptap/extension-horizontal-rule'
Expand All @@ -44,17 +45,10 @@ import Table from './../nodes/Table.js'
import TaskItem from './../nodes/TaskItem.js'
import TaskList from './../nodes/TaskList.js'
import Text from '@tiptap/extension-text'
import TipTapParagraph from '@tiptap/extension-paragraph'
/* eslint-enable import/no-named-as-default */

import { Strong, Italic, Strike, Link, Underline } from './../marks/index.js'

const Paragraph = TipTapParagraph.extend({
parseHTML() {
return this.parent().map(rule => Object.assign(rule, { preserveWhitespace: 'full' }))
},
})

export default Extension.create({
name: 'RichText',

Expand Down
17 changes: 17 additions & 0 deletions src/nodes/Paragraph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import TiptapParagraph from '@tiptap/extension-paragraph'
import { VueNodeViewRenderer } from '@tiptap/vue-2'
import ParagraphView from './ParagraphView.vue'

const Paragraph = TiptapParagraph.extend({

addNodeView() {
return VueNodeViewRenderer(ParagraphView)
},

parseHTML() {
return this.parent().map(rule => Object.assign(rule, { preserveWhitespace: 'full' }))
},

})

export default Paragraph
100 changes: 100 additions & 0 deletions src/nodes/ParagraphView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<!--
- @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
-
- @author Julius Härtl <jus@bitgrid.net>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->

<template>
<NodeViewWrapper class="vue-component" as="p">
<NodeViewContent class="paragraph-content" />
<ReferenceList v-if="text"
:text="text"
:limit="1"
contenteditable="false" />
</NodeViewWrapper>
</template>

<script>
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-2'
import { ReferenceList } from '@nextcloud/vue-richtext'
import debounce from 'debounce'

import '@nextcloud/vue-richtext/dist/style.css'

export default {
name: 'ParagraphView',
components: {
NodeViewWrapper,
NodeViewContent,
ReferenceList,
},
props: nodeViewProps,
data() {
return {
text: null,
}
},
watch: {
node: {
handler(newNode) {
if (!newNode?.textContent) {
this.text = ''
return
}
this.debouncedUpdateText(newNode)
},
},
},
beforeCreate() {
this.debouncedUpdateText = debounce((newNode) => {
this.text = this.getTextReference(this.node?.textContent)
}, 500)
},
created() {
this.text = this.getTextReference(this.node?.textContent)
},
beforeUnmount() {
this.debouncedUpdateText?.cancel()
},
methods: {
getTextReference(text) {
const PATTERN = /(^)(https?:\/\/)?((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)($)/ig
if ((new RegExp(PATTERN)).test(text)) {
return text
}

return null
},
},
}
</script>
<style lang="scss" scoped>
:deep(div.widgets--list a.widget-default) {
color: var(--color-main-text);
padding: 0;
text-decoration: none;
}

:deep(.widget-default--details) {
overflow:hidden;
p {
margin-bottom: 4px !important;
}
}
</style>

0 comments on commit 12d6c32

Please sign in to comment.