tiptapify 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -3
- package/dist/tiptapify.css +1 -1
- package/dist/tiptapify.mjs +27785 -23593
- package/dist/tiptapify.umd.js +35 -35
- package/index.d.ts +49 -0
- package/package.json +8 -6
- package/src/components/Footer.vue +48 -6
- package/src/components/MenuBubble.vue +5 -12
- package/src/components/Tiptapify.vue +41 -31
- package/src/components/Toolbar/Group.vue +13 -14
- package/src/components/Toolbar/GroupBtn.vue +34 -0
- package/src/components/Toolbar/Index.vue +28 -79
- package/src/components/Toolbar/Items.vue +77 -0
- package/src/components/Toolbar/defaultExtensionComponents.ts +32 -0
- package/src/components/Toolbar/items/format.ts +0 -13
- package/src/components/Toolbar/items/media.ts +32 -23
- package/src/components/Toolbar/items/misc.ts +1 -1
- package/src/components/Toolbar/items/style.ts +43 -2
- package/src/components/Toolbar/items.ts +8 -7
- package/src/components/editorExtensions.ts +8 -10
- package/src/extensions/components/ImageDialog.vue +142 -0
- package/src/extensions/components/LinkDialog.vue +77 -36
- package/src/extensions/components/PreviewDialog.vue +0 -1
- package/src/extensions/components/ShowSourceDialog.vue +5 -3
- package/src/extensions/components/StyleColor.vue +177 -0
- package/src/extensions/components/TableBuilder.vue +4 -5
- package/src/extensions/image.ts +31 -0
- package/src/extensions/link.ts +24 -0
- package/src/extensions/preview.ts +2 -15
- package/src/extensions/view-source.ts +0 -3
- package/src/i18n/locales/de.json +46 -20
- package/src/i18n/locales/en.json +31 -5
- package/src/i18n/locales/es.json +38 -12
- package/src/i18n/locales/fr.json +49 -23
- package/src/i18n/locales/it.json +42 -16
- package/src/i18n/locales/pl.json +46 -19
- package/src/i18n/locales/ru.json +30 -4
- package/src/i18n/locales/ua.json +30 -4
- package/src/index.ts +0 -1
- package/src/types/overridable-extensions.ts +6 -0
|
@@ -4,78 +4,82 @@ import * as mdi from '@mdi/js'
|
|
|
4
4
|
import { Editor } from "@tiptap/vue-3";
|
|
5
5
|
|
|
6
6
|
import { useI18n } from 'vue-i18n'
|
|
7
|
-
import { computed, inject, Ref, ref
|
|
7
|
+
import { computed, inject, onMounted, onUnmounted, Ref, ref } from 'vue'
|
|
8
8
|
|
|
9
9
|
import helpers from '@tiptapify/utils/helpers'
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
defineProps({
|
|
12
|
+
variantBtn: { type: String, default() { return 'elevated' }},
|
|
13
|
+
variantField: { type: String, default() { return 'solo' }}
|
|
14
|
+
})
|
|
12
15
|
|
|
13
16
|
const { ucFirst } = helpers
|
|
14
17
|
|
|
15
|
-
interface Props {
|
|
16
|
-
value?: string
|
|
17
|
-
target?: '_self' | '_blank'
|
|
18
|
-
destroy?: () => void
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
22
|
-
value: undefined,
|
|
23
|
-
target: '_blank',
|
|
24
|
-
destroy: undefined
|
|
25
|
-
})
|
|
26
|
-
|
|
27
18
|
const editor = inject('tiptapifyEditor') as Ref<Editor>
|
|
28
|
-
|
|
29
19
|
const { t } = useI18n()
|
|
30
20
|
|
|
31
21
|
const generateLinkAttrs = () => ({
|
|
32
22
|
href: '',
|
|
33
|
-
target: '_blank'
|
|
23
|
+
target: '_blank',
|
|
24
|
+
cssClass: '',
|
|
25
|
+
rel: ''
|
|
34
26
|
})
|
|
35
27
|
|
|
28
|
+
const relAttrs = ['alternate', 'author', 'bookmark', 'external', 'help', 'license', 'next', 'nofollow', 'noreferrer', 'noopener', 'prev', 'search', 'tag']
|
|
29
|
+
|
|
36
30
|
const attrs = ref(generateLinkAttrs())
|
|
37
31
|
|
|
38
32
|
const dialog = ref<boolean>(false)
|
|
39
33
|
|
|
40
34
|
const isDisabled = computed(() => {
|
|
41
|
-
const { href
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return props.value === href && props.target === target
|
|
35
|
+
const { href } = attrs.value
|
|
36
|
+
return !href
|
|
45
37
|
})
|
|
46
38
|
|
|
47
39
|
function apply() {
|
|
48
|
-
|
|
40
|
+
let { href, target, rel, cssClass } = attrs.value
|
|
41
|
+
target = target ? '_blank' : '_self'
|
|
42
|
+
rel = rel.join(' ')
|
|
49
43
|
|
|
50
44
|
if (href) {
|
|
51
|
-
editor.value.chain().focus().extendMarkRange('link').setLink({ href, target }).run()
|
|
45
|
+
editor.value.chain().focus().extendMarkRange('link').setLink({ href, target, rel, class: cssClass }).run()
|
|
52
46
|
}
|
|
47
|
+
|
|
53
48
|
close()
|
|
54
49
|
}
|
|
55
50
|
|
|
56
|
-
function
|
|
57
|
-
|
|
51
|
+
function clear() {
|
|
52
|
+
editor.value.chain().focus().extendMarkRange('link').unsetLink().run()
|
|
53
|
+
|
|
54
|
+
close()
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
function close() {
|
|
61
58
|
dialog.value = false
|
|
59
|
+
|
|
62
60
|
attrs.value = generateLinkAttrs()
|
|
61
|
+
}
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
const showLink = (event: CustomEvent) => {
|
|
64
|
+
attrs.value.href = event.detail.link?.href
|
|
65
|
+
attrs.value.target = event.detail.link?.target === '_blank'
|
|
66
|
+
attrs.value.rel = event.detail.link?.rel?.split(' ')
|
|
67
|
+
attrs.value.cssClass = event.detail.link?.class
|
|
68
|
+
|
|
69
|
+
dialog.value = true;
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
onMounted(() => {
|
|
73
|
+
window.addEventListener('tiptapify-show-link', showLink as EventListener)
|
|
74
|
+
})
|
|
69
75
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
target: props.target
|
|
73
|
-
}
|
|
76
|
+
onUnmounted(() => {
|
|
77
|
+
window.removeEventListener('tiptapify-show-link', showLink as EventListener)
|
|
74
78
|
})
|
|
75
79
|
</script>
|
|
76
80
|
|
|
77
81
|
<template>
|
|
78
|
-
<VDialog v-model="dialog" max-width="
|
|
82
|
+
<VDialog v-model="dialog" max-width="800" absolute @click:outside="close">
|
|
79
83
|
<VCard>
|
|
80
84
|
<VToolbar class="px-6" density="compact">
|
|
81
85
|
<span class="headline">{{ ucFirst(t('dialog.link.title')) }}</span>
|
|
@@ -88,13 +92,50 @@ watch(dialog, val => {
|
|
|
88
92
|
</VToolbar>
|
|
89
93
|
|
|
90
94
|
<VCardText>
|
|
91
|
-
<
|
|
95
|
+
<VRow>
|
|
96
|
+
<VCol cols="12" md="9">
|
|
97
|
+
<VTextField v-model="attrs.href" :variant="variantField" :label="ucFirst(t('dialog.link.href'))" autofocus />
|
|
98
|
+
</VCol>
|
|
99
|
+
|
|
100
|
+
<VCol cols="12" md="3">
|
|
101
|
+
<VCheckbox v-model="attrs.target" color="primary" :label="ucFirst(t('dialog.link.target'))" />
|
|
102
|
+
</VCol>
|
|
103
|
+
|
|
104
|
+
<VCol cols="12">
|
|
105
|
+
<VSelect
|
|
106
|
+
v-model="attrs.rel"
|
|
107
|
+
:items="relAttrs"
|
|
108
|
+
:label="ucFirst(t('dialog.link.rel'))"
|
|
109
|
+
:variant="variantField"
|
|
110
|
+
multiple
|
|
111
|
+
chips
|
|
112
|
+
closable-chips
|
|
113
|
+
clearable
|
|
114
|
+
/>
|
|
115
|
+
</VCol>
|
|
116
|
+
|
|
117
|
+
<VCol cols="12">
|
|
118
|
+
<VTextField v-model="attrs.cssClass" :variant="variantField" :label="ucFirst(t('dialog.link.class'))" />
|
|
119
|
+
</VCol>
|
|
120
|
+
</VRow>
|
|
92
121
|
</VCardText>
|
|
93
122
|
|
|
94
123
|
<VCardActions>
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
124
|
+
<VRow>
|
|
125
|
+
<VCol class="d-flex justify-start">
|
|
126
|
+
<VBtn color="warning" v-if="editor.isActive('link')" :variant="variantBtn" :disabled="isDisabled" @click="clear">
|
|
127
|
+
{{ ucFirst(t('dialog.clear')) }}
|
|
128
|
+
</VBtn>
|
|
129
|
+
</VCol>
|
|
130
|
+
<VCol class="d-flex justify-end">
|
|
131
|
+
<VBtn :variant="variantBtn" @click="close" class="mr-2">
|
|
132
|
+
{{ ucFirst(t('dialog.close')) }}
|
|
133
|
+
</VBtn>
|
|
134
|
+
<VBtn color="primary" :variant="variantBtn" :disabled="isDisabled" @click="apply">
|
|
135
|
+
{{ ucFirst(t('dialog.apply')) }}
|
|
136
|
+
</VBtn>
|
|
137
|
+
</VCol>
|
|
138
|
+
</VRow>
|
|
98
139
|
</VCardActions>
|
|
99
140
|
</VCard>
|
|
100
141
|
</VDialog>
|
|
@@ -7,6 +7,8 @@ import helpers from "@tiptapify/utils/helpers";
|
|
|
7
7
|
|
|
8
8
|
const props = defineProps({
|
|
9
9
|
indent: { type: Number, default: 2 },
|
|
10
|
+
variantBtn: { type: String, default: 'elevated' },
|
|
11
|
+
variantField: { type: String, default: 'solo' }
|
|
10
12
|
})
|
|
11
13
|
|
|
12
14
|
const { ucFirst } = helpers;
|
|
@@ -97,17 +99,17 @@ watch(() => formatted.value, () => {
|
|
|
97
99
|
v-model="sourceCode"
|
|
98
100
|
no-resize
|
|
99
101
|
rows="100"
|
|
100
|
-
variant="
|
|
102
|
+
:variant="variantField"
|
|
101
103
|
class="source-code-area"
|
|
102
104
|
/>
|
|
103
105
|
</VCardText>
|
|
104
106
|
|
|
105
107
|
<VCardActions>
|
|
106
108
|
<VSpacer></VSpacer>
|
|
107
|
-
<VBtn
|
|
109
|
+
<VBtn :variant="variantBtn" @click="dialog = false">
|
|
108
110
|
{{ ucFirst(t('dialog.close')) }}
|
|
109
111
|
</VBtn>
|
|
110
|
-
<VBtn color="primary" @click="saveChanges">
|
|
112
|
+
<VBtn :variant="variantBtn" color="primary" @click="saveChanges">
|
|
111
113
|
{{ ucFirst(t('dialog.apply')) }}
|
|
112
114
|
</VBtn>
|
|
113
115
|
</VCardActions>
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
|
|
3
|
+
import { Editor } from "@tiptap/vue-3";
|
|
4
|
+
import { useI18n } from 'vue-i18n'
|
|
5
|
+
|
|
6
|
+
import { computed, inject, Ref, ref } from 'vue'
|
|
7
|
+
|
|
8
|
+
const { t } = useI18n()
|
|
9
|
+
|
|
10
|
+
defineExpose({ open })
|
|
11
|
+
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
show: { type: Boolean, default: true },
|
|
14
|
+
fontColor: { type: Boolean, default: false },
|
|
15
|
+
backgroundColor: { type: Boolean, default: false },
|
|
16
|
+
color: { type: String, default: '' },
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const emit = defineEmits(['close'])
|
|
20
|
+
|
|
21
|
+
const editor = inject('tiptapifyEditor') as Ref<Editor>
|
|
22
|
+
|
|
23
|
+
const colorPicker = ref(false)
|
|
24
|
+
const customColor = ref(computed(() => props.color).value)
|
|
25
|
+
|
|
26
|
+
const colors = {
|
|
27
|
+
black: '#000',
|
|
28
|
+
darkgray: '#444',
|
|
29
|
+
gray: '#888',
|
|
30
|
+
lightgray: '#ccc',
|
|
31
|
+
white: '#fff',
|
|
32
|
+
cyan: '#00FFFF',
|
|
33
|
+
light: '#0088ff',
|
|
34
|
+
blue: '#0000ff',
|
|
35
|
+
indigo: '#4b0082',
|
|
36
|
+
purple: '#800080',
|
|
37
|
+
pink: '#ff00ff',
|
|
38
|
+
red: '#ff0000',
|
|
39
|
+
orange: '#ff9900',
|
|
40
|
+
yellow: '#ffff00',
|
|
41
|
+
green: '#00ff00',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type Color = { r: number, g: number, b: number, a?: number }
|
|
45
|
+
|
|
46
|
+
function calculateShadowColor(color: string): string {
|
|
47
|
+
const rgb: Color = hexToRgb(color)
|
|
48
|
+
|
|
49
|
+
for (const channel of Object.keys(rgb)) {
|
|
50
|
+
rgb[channel] = Math.round(rgb[channel] * .35)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return Object.values(rgb).join(', ')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function hexToRgb(hex: string): Color {
|
|
57
|
+
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
|
58
|
+
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
|
|
59
|
+
return r + r + g + g + b + b;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
63
|
+
return {
|
|
64
|
+
r: result ? parseInt(result[1], 16) : 0,
|
|
65
|
+
g: result ? parseInt(result[2], 16) : 0,
|
|
66
|
+
b: result ? parseInt(result[3], 16) : 0
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function setColor(color: string) {
|
|
71
|
+
if (props.fontColor) {
|
|
72
|
+
editor.value.chain().focus().setColor(color).run()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (props.backgroundColor) {
|
|
76
|
+
editor.value.chain().focus().setHighlight({ color }).run()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
emit('close')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function unsetColor() {
|
|
83
|
+
if (props.fontColor) {
|
|
84
|
+
editor.value.chain().focus().unsetColor().run()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (props.backgroundColor) {
|
|
88
|
+
editor.value.chain().focus().unsetHighlight().run()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
emit('close')
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function isColorActive(color: string): boolean {
|
|
95
|
+
return props.color === color
|
|
96
|
+
}
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<template>
|
|
100
|
+
<VSheet class="pa-2">
|
|
101
|
+
<div class="tiptapify-style-color-container">
|
|
102
|
+
<template v-for="colorCode in colors">
|
|
103
|
+
<div
|
|
104
|
+
class="tiptapify-style-color-item"
|
|
105
|
+
:class="isColorActive(colorCode) ? 'tiptapify-style-color-item-active' : ''"
|
|
106
|
+
@click="setColor(colorCode)"
|
|
107
|
+
>
|
|
108
|
+
<div
|
|
109
|
+
class="tiptapify-style-color-picker"
|
|
110
|
+
:style="`background-color: ${colorCode}; box-shadow: 1px 1px 4px rgb(${calculateShadowColor(colorCode)});`"
|
|
111
|
+
></div>
|
|
112
|
+
</div>
|
|
113
|
+
</template>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<VDivider class="mt-2 mb-2" />
|
|
117
|
+
|
|
118
|
+
<VMenu v-model="colorPicker" :close-on-content-click="false">
|
|
119
|
+
<template #activator="{ props: menuProps }">
|
|
120
|
+
<VBtn v-bind="menuProps" variant="flat" block>
|
|
121
|
+
<template #prepend>
|
|
122
|
+
<div
|
|
123
|
+
class="tiptapify-style-color-picker"
|
|
124
|
+
:style="`background-color: ${customColor}; box-shadow: 1px 1px 4px rgb(0, 0, 0, .35);`"
|
|
125
|
+
>
|
|
126
|
+
</div>
|
|
127
|
+
</template>
|
|
128
|
+
<template #default>
|
|
129
|
+
{{ t('style.color.custom') }}
|
|
130
|
+
</template>
|
|
131
|
+
</VBtn>
|
|
132
|
+
</template>
|
|
133
|
+
|
|
134
|
+
<VCard>
|
|
135
|
+
<VCardItem>
|
|
136
|
+
<VColorPicker v-model="customColor" elevated elevation="24" hide-inputs />
|
|
137
|
+
</VCardItem>
|
|
138
|
+
|
|
139
|
+
<VCardActions>
|
|
140
|
+
<VBtn variant="flat" color="primary" @click="setColor(customColor)">OK</VBtn>
|
|
141
|
+
<VBtn variant="flat" color="grey-400" @click="colorPicker = !colorPicker; customColor = color">Cancel</VBtn>
|
|
142
|
+
</VCardActions>
|
|
143
|
+
</VCard>
|
|
144
|
+
</VMenu>
|
|
145
|
+
|
|
146
|
+
<VDivider class="mt-2 mb-2" />
|
|
147
|
+
|
|
148
|
+
<VBtn @click="unsetColor" block variant="flat">
|
|
149
|
+
{{ t('style.color.unset') }}
|
|
150
|
+
</VBtn>
|
|
151
|
+
</VSheet>
|
|
152
|
+
</template>
|
|
153
|
+
|
|
154
|
+
<style lang="scss" scoped>
|
|
155
|
+
.tiptapify-style-color-container {
|
|
156
|
+
display: grid;
|
|
157
|
+
grid-template-columns: repeat(5, 1fr);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.tiptapify-style-color-item {
|
|
161
|
+
cursor: pointer;
|
|
162
|
+
border-radius: 8px;
|
|
163
|
+
padding: 5px;
|
|
164
|
+
transition: background-color .2s;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.tiptapify-style-color-item:hover, .tiptapify-style-color-item-active {
|
|
168
|
+
background-color: #dedede;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.tiptapify-style-color-picker {
|
|
172
|
+
width: 24px;
|
|
173
|
+
height: 24px;
|
|
174
|
+
margin: 2px;
|
|
175
|
+
border-radius: 4px;
|
|
176
|
+
}
|
|
177
|
+
</style>
|
|
@@ -13,7 +13,6 @@ const { ucFirst } = helpers
|
|
|
13
13
|
defineExpose({ open })
|
|
14
14
|
|
|
15
15
|
defineProps({
|
|
16
|
-
show: { type: Boolean, default: false },
|
|
17
16
|
maxCols: { type: Number, default: 10 },
|
|
18
17
|
maxRows: { type: Number, default: 10 },
|
|
19
18
|
})
|
|
@@ -56,7 +55,7 @@ function printSelection() {
|
|
|
56
55
|
v-model="withHeaderRow"
|
|
57
56
|
density="compact"
|
|
58
57
|
color="primary"
|
|
59
|
-
:label="ucFirst(t('
|
|
58
|
+
:label="ucFirst(t('media.tables.insertWithHeaderRow'))" hide-details
|
|
60
59
|
/>
|
|
61
60
|
|
|
62
61
|
<div v-for="rowNum in maxRows" :key="`row-${rowNum}`" class="tiptapify-insert-table-row">
|
|
@@ -74,8 +73,8 @@ function printSelection() {
|
|
|
74
73
|
|
|
75
74
|
<div class="tiptapify-table-builder-info">
|
|
76
75
|
<span>
|
|
77
|
-
{{ ucFirst(t('
|
|
78
|
-
{{ ucFirst(t('
|
|
76
|
+
{{ ucFirst(t('media.tables.rows')) }}: {{ rowHover }}
|
|
77
|
+
{{ ucFirst(t('media.tables.cols')) }}: {{ colHover }}
|
|
79
78
|
</span>
|
|
80
79
|
<span>
|
|
81
80
|
{{ printSelection() }}
|
|
@@ -111,7 +110,7 @@ $mutedColor: var(--v-theme-muted-color, #888888);
|
|
|
111
110
|
margin: 2px;
|
|
112
111
|
width: 100%;
|
|
113
112
|
height: 100%;
|
|
114
|
-
border: 1px solid #
|
|
113
|
+
border: 1px solid #bbb;
|
|
115
114
|
background: #fff;
|
|
116
115
|
border-radius: 4px;
|
|
117
116
|
filter: drop-shadow(2px 2px 4px #88888888);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core'
|
|
2
|
+
|
|
3
|
+
const name: string = 'tiptapifyImage'
|
|
4
|
+
|
|
5
|
+
declare module '@tiptap/core' {
|
|
6
|
+
interface Commands<ReturnType> {
|
|
7
|
+
tiptapifyImage: {
|
|
8
|
+
showTiptapifyImage: () => ReturnType
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const TiptapifyImage = Extension.create({
|
|
14
|
+
name,
|
|
15
|
+
|
|
16
|
+
addCommands() {
|
|
17
|
+
return {
|
|
18
|
+
showTiptapifyImage: () => ({ editor }) => {
|
|
19
|
+
const event = new CustomEvent(`tiptapify-show-${name}`, {
|
|
20
|
+
detail: {
|
|
21
|
+
image: editor.getAttributes('image')
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
window.dispatchEvent(event)
|
|
26
|
+
|
|
27
|
+
return true
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Link from "@tiptap/extension-link";
|
|
2
|
+
|
|
3
|
+
const name: string = 'link'
|
|
4
|
+
|
|
5
|
+
export const TiptapifyLink = Link.extend({
|
|
6
|
+
name,
|
|
7
|
+
|
|
8
|
+
addCommands() {
|
|
9
|
+
return {
|
|
10
|
+
...this.parent?.(),
|
|
11
|
+
showLink: () => ({ editor }) => {
|
|
12
|
+
const event = new CustomEvent(`tiptapify-show-${name}`, {
|
|
13
|
+
detail: {
|
|
14
|
+
link: editor.getAttributes('link')
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
window.dispatchEvent(event)
|
|
19
|
+
|
|
20
|
+
return true
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
})
|
|
@@ -3,34 +3,21 @@ import { Plugin, PluginKey } from '@tiptap/pm/state'
|
|
|
3
3
|
|
|
4
4
|
const name: string = 'preview'
|
|
5
5
|
|
|
6
|
-
export interface ViewSourceOptions {
|
|
7
|
-
HTMLAttributes: Record<string, any>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
6
|
declare module '@tiptap/core' {
|
|
11
7
|
interface Commands<ReturnType> {
|
|
12
8
|
preview: {
|
|
13
|
-
/**
|
|
14
|
-
* Показать исходный HTML-код
|
|
15
|
-
*/
|
|
16
9
|
showPreview: () => ReturnType
|
|
17
10
|
}
|
|
18
11
|
}
|
|
19
12
|
}
|
|
20
13
|
|
|
21
|
-
export const Preview = Extension.create
|
|
14
|
+
export const Preview = Extension.create({
|
|
22
15
|
name,
|
|
23
16
|
|
|
24
|
-
addOptions() {
|
|
25
|
-
return {
|
|
26
|
-
HTMLAttributes: {},
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
|
|
30
17
|
addCommands() {
|
|
31
18
|
return {
|
|
32
19
|
showPreview: () => ({ editor }) => {
|
|
33
|
-
const event = new CustomEvent(
|
|
20
|
+
const event = new CustomEvent(`tiptapify-show-${name}`, {
|
|
34
21
|
detail: {
|
|
35
22
|
html: editor.getHTML()
|
|
36
23
|
}
|
package/src/i18n/locales/de.json
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
+
"content": {
|
|
3
|
+
"placeholder": "schreib hier etwas..."
|
|
4
|
+
},
|
|
2
5
|
"style": {
|
|
3
6
|
"paragraph": "absatz",
|
|
4
7
|
"heading": "überschrift",
|
|
@@ -12,7 +15,13 @@
|
|
|
12
15
|
},
|
|
13
16
|
"fontFamily": "schriftart",
|
|
14
17
|
"fontSize": "schriftgröße",
|
|
15
|
-
"lineHeight": "zeilenhöhe"
|
|
18
|
+
"lineHeight": "zeilenhöhe",
|
|
19
|
+
"color": {
|
|
20
|
+
"highlight": "hervorhebungsfarbe",
|
|
21
|
+
"text": "textfarbe",
|
|
22
|
+
"unset": "farbe zurücksetzen",
|
|
23
|
+
"custom": "benutzerdefinierte farbe"
|
|
24
|
+
}
|
|
16
25
|
},
|
|
17
26
|
"format": {
|
|
18
27
|
"bold": "fett",
|
|
@@ -21,14 +30,16 @@
|
|
|
21
30
|
"underline": "unterstrichen",
|
|
22
31
|
"sup": "hochgestellt",
|
|
23
32
|
"sub": "tiefgestellt",
|
|
24
|
-
"break": "
|
|
25
|
-
"highlight": "hervorheben",
|
|
33
|
+
"break": "harter umbruch",
|
|
26
34
|
"line": "horizontale linie",
|
|
27
35
|
"blockquote": "zitat",
|
|
28
36
|
"code": "code",
|
|
29
|
-
"codeblock": "
|
|
37
|
+
"codeblock": "code block",
|
|
38
|
+
"formatClear": "formatierung löschen"
|
|
39
|
+
},
|
|
40
|
+
"media": {
|
|
30
41
|
"link": "externer link",
|
|
31
|
-
"
|
|
42
|
+
"image": "bild",
|
|
32
43
|
"tables": {
|
|
33
44
|
"table": "tabelle",
|
|
34
45
|
"insertTable": "tabelle einfügen",
|
|
@@ -36,13 +47,13 @@
|
|
|
36
47
|
"insertWithHeaderRow": "tabelle mit kopfzeile einfügen",
|
|
37
48
|
"rows": "zeilen",
|
|
38
49
|
"row": "zeile",
|
|
39
|
-
"insertRowBefore": "zeile
|
|
40
|
-
"insertRowAfter": "zeile
|
|
50
|
+
"insertRowBefore": "zeile davor einfügen",
|
|
51
|
+
"insertRowAfter": "zeile danach einfügen",
|
|
41
52
|
"deleteRow": "zeile löschen",
|
|
42
53
|
"cols": "spalten",
|
|
43
54
|
"col": "spalte",
|
|
44
|
-
"insertColBefore": "spalte
|
|
45
|
-
"insertColAfter": "spalte
|
|
55
|
+
"insertColBefore": "spalte davor einfügen",
|
|
56
|
+
"insertColAfter": "spalte danach einfügen",
|
|
46
57
|
"deleteCol": "spalte löschen",
|
|
47
58
|
"mergeCells": "zellen verbinden",
|
|
48
59
|
"splitCell": "zelle teilen"
|
|
@@ -50,37 +61,52 @@
|
|
|
50
61
|
},
|
|
51
62
|
"action": {
|
|
52
63
|
"undo": "rückgängig",
|
|
53
|
-
"redo": "
|
|
64
|
+
"redo": "wiederholen"
|
|
54
65
|
},
|
|
55
66
|
"alignment": "ausrichtung",
|
|
56
67
|
"alignments": {
|
|
57
|
-
"left": "
|
|
58
|
-
"center": "zentriert",
|
|
59
|
-
"right": "
|
|
68
|
+
"left": "links ausrichten",
|
|
69
|
+
"center": "zentriert ausrichten",
|
|
70
|
+
"right": "rechts ausrichten",
|
|
60
71
|
"justify": "blocksatz"
|
|
61
72
|
},
|
|
62
73
|
"list": "liste",
|
|
63
74
|
"lists": {
|
|
64
|
-
"bullet": "
|
|
65
|
-
"numbered": "
|
|
75
|
+
"bullet": "ungeordnete liste",
|
|
76
|
+
"numbered": "geordnete liste",
|
|
66
77
|
"task": "aufgabenliste",
|
|
67
|
-
"indent": "
|
|
68
|
-
"outdent": "
|
|
78
|
+
"indent": "listenelement einrücken",
|
|
79
|
+
"outdent": "listenelement ausrücken"
|
|
69
80
|
},
|
|
70
81
|
"dialog": {
|
|
71
|
-
"close": "schließen",
|
|
72
82
|
"apply": "anwenden",
|
|
83
|
+
"clear": "löschen",
|
|
84
|
+
"close": "schließen",
|
|
85
|
+
"image": {
|
|
86
|
+
"title": "bild hinzufügen/bearbeiten",
|
|
87
|
+
"src": "quelle",
|
|
88
|
+
"alt": "alt",
|
|
89
|
+
"width": "breite",
|
|
90
|
+
"height": "höhe"
|
|
91
|
+
},
|
|
73
92
|
"link": {
|
|
74
93
|
"title": "link hinzufügen/bearbeiten",
|
|
75
|
-
"
|
|
94
|
+
"href": "link-adresse",
|
|
95
|
+
"target": "in neuem fenster öffnen",
|
|
96
|
+
"rel": "rel",
|
|
97
|
+
"class": "css-klasse"
|
|
76
98
|
},
|
|
77
99
|
"source": {
|
|
78
100
|
"title": "quellcode anzeigen",
|
|
79
|
-
"prettify": "
|
|
101
|
+
"prettify": "verschönern"
|
|
80
102
|
}
|
|
81
103
|
},
|
|
82
104
|
"misc": {
|
|
83
105
|
"source": "quellcode anzeigen",
|
|
84
106
|
"preview": "vorschau"
|
|
107
|
+
},
|
|
108
|
+
"footer": {
|
|
109
|
+
"words": "wörter",
|
|
110
|
+
"chars": "zeichen"
|
|
85
111
|
}
|
|
86
112
|
}
|