tiptapify 0.4.0 → 0.4.2
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/dist/tiptapify.css +1 -1
- package/dist/tiptapify.mjs +7593 -6318
- package/dist/tiptapify.umd.js +64 -64
- package/index.d.ts +3 -0
- package/package.json +2 -1
- package/src/components/Toolbar/actions.ts +5 -0
- package/src/components/editorExtensions.ts +2 -0
- package/src/extensions/components/actions/reset/Button.vue +108 -0
- package/src/extensions/components/actions/reset/resetChanges.test.ts +99 -0
- package/src/extensions/components/actions/reset/resetChanges.ts +78 -0
- package/src/extensions/components/media/image/imageDialog.test.ts +10 -0
- package/src/extensions/components/media/image/imageDialog.ts +6 -3
- package/src/i18n/locales/ar.json +4 -0
- package/src/i18n/locales/bg.json +4 -0
- package/src/i18n/locales/ch.json +4 -0
- package/src/i18n/locales/cz.json +4 -0
- package/src/i18n/locales/de.json +4 -0
- package/src/i18n/locales/el.json +4 -0
- package/src/i18n/locales/en.json +4 -0
- package/src/i18n/locales/es.json +4 -0
- package/src/i18n/locales/et.json +4 -0
- package/src/i18n/locales/fi.json +4 -0
- package/src/i18n/locales/fr.json +4 -0
- package/src/i18n/locales/he.json +4 -0
- package/src/i18n/locales/hi.json +4 -0
- package/src/i18n/locales/hr.json +4 -0
- package/src/i18n/locales/hu.json +4 -0
- package/src/i18n/locales/id.json +4 -0
- package/src/i18n/locales/it.json +4 -0
- package/src/i18n/locales/ja.json +4 -0
- package/src/i18n/locales/ko.json +4 -0
- package/src/i18n/locales/la.json +4 -0
- package/src/i18n/locales/lt.json +4 -0
- package/src/i18n/locales/nl.json +4 -0
- package/src/i18n/locales/no.json +4 -0
- package/src/i18n/locales/pl.json +4 -0
- package/src/i18n/locales/pt-BR.json +4 -0
- package/src/i18n/locales/pt.json +4 -0
- package/src/i18n/locales/ro.json +4 -0
- package/src/i18n/locales/ru.json +4 -0
- package/src/i18n/locales/se.json +4 -0
- package/src/i18n/locales/sk.json +4 -0
- package/src/i18n/locales/sl.json +4 -0
- package/src/i18n/locales/sr.json +4 -0
- package/src/i18n/locales/th.json +4 -0
- package/src/i18n/locales/tr.json +4 -0
- package/src/i18n/locales/uk.json +4 -0
- package/src/i18n/locales/vi.json +4 -0
- package/src/index.ts +2 -0
package/index.d.ts
CHANGED
|
@@ -360,6 +360,9 @@ export type {
|
|
|
360
360
|
|
|
361
361
|
export type { TiptapifyConfig }
|
|
362
362
|
|
|
363
|
+
/** The logic of the image dialog, for a host that replaces the dialog with its own */
|
|
364
|
+
export * as imageDialog from './src/extensions/components/media/image/imageDialog'
|
|
365
|
+
|
|
363
366
|
declare module '@vue/runtime-core' {
|
|
364
367
|
interface GlobalComponents {
|
|
365
368
|
Tiptapify: typeof Tiptapify
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiptapify",
|
|
3
3
|
"types": "./index.d.ts",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.2",
|
|
5
5
|
"description": "Tiptap3 editor with Vuetify3 menu implementation",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"scripts": {
|
|
31
31
|
"dev": "vite",
|
|
32
32
|
"build": "vite build",
|
|
33
|
+
"prepublishOnly": "pnpm test && pnpm build",
|
|
33
34
|
"lint": "eslint resources/ts --fix --ext .ts,.js,.cjs,.vue,.tsx,.jsx",
|
|
34
35
|
"test": "vitest run",
|
|
35
36
|
"test:watch": "vitest",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { default as UndoButton } from '@tiptapify/extensions/components/actions/undo/Button.vue'
|
|
2
2
|
import { default as RedoButton } from '@tiptapify/extensions/components/actions/redo/Button.vue'
|
|
3
|
+
import { default as ResetButton } from '@tiptapify/extensions/components/actions/reset/Button.vue'
|
|
3
4
|
import { markRaw } from 'vue'
|
|
4
5
|
|
|
5
6
|
export default {
|
|
@@ -13,6 +14,10 @@ export default {
|
|
|
13
14
|
{
|
|
14
15
|
name: 'redo',
|
|
15
16
|
component: markRaw(RedoButton),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'resetChanges',
|
|
20
|
+
component: markRaw(ResetButton),
|
|
16
21
|
}
|
|
17
22
|
]
|
|
18
23
|
}
|
|
@@ -27,6 +27,7 @@ import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight'
|
|
|
27
27
|
import { InvisibleCharacters } from '@tiptap/extension-invisible-characters'
|
|
28
28
|
|
|
29
29
|
import { default as Iframe } from '@tiptapify/extensions/components/media/iframe'
|
|
30
|
+
import { ResetChanges } from '@tiptapify/extensions/components/actions/reset/resetChanges'
|
|
30
31
|
import { BulletListCircle, BulletListSquare } from '@tiptapify/extensions/components/list/bullet'
|
|
31
32
|
import { ListStyle } from '@tiptapify/extensions/components/list/styles'
|
|
32
33
|
import { TiptapifyImage } from '@tiptapify/extensions/components/media/image'
|
|
@@ -149,6 +150,7 @@ export function editorExtensions (
|
|
|
149
150
|
TableKit,
|
|
150
151
|
Code,
|
|
151
152
|
UndoRedo,
|
|
153
|
+
ResetChanges,
|
|
152
154
|
Focus,
|
|
153
155
|
CodeBlockLowlight
|
|
154
156
|
.extend({
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
|
|
3
|
+
import * as mdi from '@mdi/js'
|
|
4
|
+
import { Editor } from '@tiptap/vue-3'
|
|
5
|
+
import BtnIcon from '@tiptapify/components/UI/BtnIcon.vue'
|
|
6
|
+
import TiptapifyDialog from '@tiptapify/components/UI/TiptapifyDialog.vue'
|
|
7
|
+
import Tooltip from '@tiptapify/components/UI/Tooltip.vue'
|
|
8
|
+
import { useTiptapifyConfig } from '@tiptapify/composables/useTiptapifyConfig'
|
|
9
|
+
import {
|
|
10
|
+
resetChanges,
|
|
11
|
+
resetConfirmationOff,
|
|
12
|
+
turnOffResetConfirmation,
|
|
13
|
+
} from '@tiptapify/extensions/components/actions/reset/resetChanges'
|
|
14
|
+
import { inject, Ref, ref, useTemplateRef } from 'vue'
|
|
15
|
+
|
|
16
|
+
import { ComposerTranslation } from 'vue-i18n'
|
|
17
|
+
|
|
18
|
+
const { variantBtn } = useTiptapifyConfig()
|
|
19
|
+
|
|
20
|
+
const editor = inject('tiptapifyEditor') as Ref<Editor>
|
|
21
|
+
|
|
22
|
+
const { t } = inject('tiptapifyI18n') as { t: ComposerTranslation }
|
|
23
|
+
|
|
24
|
+
const dialog = useTemplateRef('dialog')
|
|
25
|
+
const dontAskAgain = ref(false)
|
|
26
|
+
|
|
27
|
+
function requestReset() {
|
|
28
|
+
if (resetConfirmationOff()) {
|
|
29
|
+
reset()
|
|
30
|
+
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
dontAskAgain.value = false
|
|
35
|
+
dialog.value?.open()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function confirmReset() {
|
|
39
|
+
if (dontAskAgain.value) {
|
|
40
|
+
turnOffResetConfirmation()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dialog.value?.close()
|
|
44
|
+
reset()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function reset() {
|
|
48
|
+
resetChanges(editor.value)
|
|
49
|
+
editor.value.commands.focus()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<VBtn
|
|
56
|
+
:disabled="!editor.can().undo() && !editor.can().redo()"
|
|
57
|
+
size="32"
|
|
58
|
+
color=""
|
|
59
|
+
:variant="variantBtn"
|
|
60
|
+
@click="requestReset"
|
|
61
|
+
>
|
|
62
|
+
<Tooltip :label="t('action.reset_changes')" />
|
|
63
|
+
<BtnIcon :icon="`mdiSvg:${mdi.mdiRestore}`" />
|
|
64
|
+
</VBtn>
|
|
65
|
+
|
|
66
|
+
<TiptapifyDialog
|
|
67
|
+
ref="dialog"
|
|
68
|
+
module="resetChanges"
|
|
69
|
+
:title="t('action.reset_changes')"
|
|
70
|
+
:max-width="440"
|
|
71
|
+
@submit="confirmReset"
|
|
72
|
+
>
|
|
73
|
+
<template #content>
|
|
74
|
+
<VCardText>
|
|
75
|
+
<p>{{ t('action.reset_changes_confirm') }}</p>
|
|
76
|
+
<VCheckbox
|
|
77
|
+
v-model="dontAskAgain"
|
|
78
|
+
class="tiptapify-reset-changes__dont-ask"
|
|
79
|
+
:label="t('action.reset_changes_dont_ask')"
|
|
80
|
+
density="compact"
|
|
81
|
+
hide-details
|
|
82
|
+
/>
|
|
83
|
+
</VCardText>
|
|
84
|
+
</template>
|
|
85
|
+
|
|
86
|
+
<template #actions>
|
|
87
|
+
<VCardActions>
|
|
88
|
+
<div class="tiptapify-dialog-actions">
|
|
89
|
+
<div class="tiptapify-dialog-actions__start" />
|
|
90
|
+
<div class="tiptapify-dialog-actions__end">
|
|
91
|
+
<VBtn :variant="variantBtn" @click="dialog?.close()">
|
|
92
|
+
{{ t('dialog.cancel') }}
|
|
93
|
+
</VBtn>
|
|
94
|
+
<VBtn type="submit" color="error" :variant="variantBtn">
|
|
95
|
+
{{ t('action.reset') }}
|
|
96
|
+
</VBtn>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</VCardActions>
|
|
100
|
+
</template>
|
|
101
|
+
</TiptapifyDialog>
|
|
102
|
+
</template>
|
|
103
|
+
|
|
104
|
+
<style lang="scss" scoped>
|
|
105
|
+
.tiptapify-reset-changes__dont-ask {
|
|
106
|
+
margin-top: 12px;
|
|
107
|
+
}
|
|
108
|
+
</style>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { Editor } from '@tiptap/vue-3'
|
|
3
|
+
import { Document } from '@tiptap/extension-document'
|
|
4
|
+
import { Paragraph } from '@tiptap/extension-paragraph'
|
|
5
|
+
import { Text } from '@tiptap/extension-text'
|
|
6
|
+
import { UndoRedo } from '@tiptap/extensions'
|
|
7
|
+
import {
|
|
8
|
+
ResetChanges,
|
|
9
|
+
resetChanges,
|
|
10
|
+
resetConfirmationOff,
|
|
11
|
+
turnOffResetConfirmation,
|
|
12
|
+
} from '@tiptapify/extensions/components/actions/reset/resetChanges'
|
|
13
|
+
|
|
14
|
+
let editor: Editor | null = null
|
|
15
|
+
|
|
16
|
+
function createEditor(content: string, onUpdate: () => void = () => {}) {
|
|
17
|
+
editor = new Editor({
|
|
18
|
+
element: document.createElement('div'),
|
|
19
|
+
content,
|
|
20
|
+
extensions: [Document, Paragraph, Text, UndoRedo, ResetChanges],
|
|
21
|
+
onUpdate,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
return editor
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
editor?.destroy()
|
|
29
|
+
editor = null
|
|
30
|
+
vi.restoreAllMocks()
|
|
31
|
+
localStorage.clear()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('the reset confirmation', () => {
|
|
35
|
+
it('asks until the user turns it off, and remembers that', () => {
|
|
36
|
+
expect(resetConfirmationOff()).toBe(false)
|
|
37
|
+
|
|
38
|
+
turnOffResetConfirmation()
|
|
39
|
+
|
|
40
|
+
expect(resetConfirmationOff()).toBe(true)
|
|
41
|
+
expect(localStorage.getItem('tiptapify:reset-changes:confirm')).toBe('off')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('keeps asking where the storage is blocked', () => {
|
|
45
|
+
vi.spyOn(window, 'localStorage', 'get').mockImplementation(() => {
|
|
46
|
+
throw new Error('blocked')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
expect(() => turnOffResetConfirmation()).not.toThrow()
|
|
50
|
+
expect(resetConfirmationOff()).toBe(false)
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('resetChanges', () => {
|
|
55
|
+
it('returns the document to the content the editor opened with', () => {
|
|
56
|
+
const instance = createEditor('<p>Original</p>')
|
|
57
|
+
instance.commands.insertContentAt(instance.state.doc.content.size, '<p>Added</p>')
|
|
58
|
+
instance.commands.setContent('<p>Replaced</p>')
|
|
59
|
+
|
|
60
|
+
expect(resetChanges(instance)).toBe(true)
|
|
61
|
+
|
|
62
|
+
expect(instance.getHTML()).toBe('<p>Original</p>')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('empties the undo and redo history, so the reset itself cannot be undone', () => {
|
|
66
|
+
const instance = createEditor('<p>Original</p>')
|
|
67
|
+
instance.commands.insertContentAt(instance.state.doc.content.size, '<p>Added</p>')
|
|
68
|
+
instance.commands.insertContentAt(instance.state.doc.content.size, '<p>More</p>')
|
|
69
|
+
instance.commands.undo()
|
|
70
|
+
expect(instance.can().redo()).toBe(true)
|
|
71
|
+
|
|
72
|
+
resetChanges(instance)
|
|
73
|
+
|
|
74
|
+
expect(instance.can().undo()).toBe(false)
|
|
75
|
+
expect(instance.can().redo()).toBe(false)
|
|
76
|
+
|
|
77
|
+
instance.commands.insertContentAt(instance.state.doc.content.size, '<p>After</p>')
|
|
78
|
+
instance.commands.undo()
|
|
79
|
+
expect(instance.getHTML()).toBe('<p>Original</p>')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('does nothing before the first change', () => {
|
|
83
|
+
const instance = createEditor('<p>Original</p>')
|
|
84
|
+
|
|
85
|
+
expect(resetChanges(instance)).toBe(false)
|
|
86
|
+
expect(instance.getHTML()).toBe('<p>Original</p>')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('reports the reset as a content change, for the host to save', () => {
|
|
90
|
+
let updates = 0
|
|
91
|
+
const instance = createEditor('<p>Original</p>', () => updates++)
|
|
92
|
+
instance.commands.insertContentAt(instance.state.doc.content.size, '<p>Added</p>')
|
|
93
|
+
updates = 0
|
|
94
|
+
|
|
95
|
+
resetChanges(instance)
|
|
96
|
+
|
|
97
|
+
expect(updates).toBe(1)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Editor, Extension, JSONContent } from '@tiptap/core'
|
|
2
|
+
import { EditorState } from '@tiptap/pm/state'
|
|
3
|
+
|
|
4
|
+
const name = 'resetChanges'
|
|
5
|
+
|
|
6
|
+
declare module '@tiptap/core' {
|
|
7
|
+
interface Storage {
|
|
8
|
+
resetChanges: { initialContent: JSONContent | null }
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Keeps the document the editor opened with, for resetChanges to return to: the document before its first change
|
|
14
|
+
* (the create event comes later than the first changes can).
|
|
15
|
+
*/
|
|
16
|
+
export const ResetChanges = Extension.create({
|
|
17
|
+
name,
|
|
18
|
+
|
|
19
|
+
addStorage() {
|
|
20
|
+
return { initialContent: null as JSONContent | null }
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
onTransaction({ transaction }) {
|
|
24
|
+
if (this.storage.initialContent === null && transaction.docChanged) {
|
|
25
|
+
this.storage.initialContent = transaction.before.toJSON()
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const confirmKey = 'tiptapify:reset-changes:confirm'
|
|
31
|
+
|
|
32
|
+
// Storage may be blocked (private mode, sandboxed iframe): the reset then keeps asking
|
|
33
|
+
function storage(): Storage | null {
|
|
34
|
+
try {
|
|
35
|
+
return window.localStorage
|
|
36
|
+
} catch {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The user chose "Don't ask again" in the reset confirmation (kept in this browser).
|
|
43
|
+
*/
|
|
44
|
+
export function resetConfirmationOff(): boolean {
|
|
45
|
+
try {
|
|
46
|
+
return storage()?.getItem(confirmKey) === 'off'
|
|
47
|
+
} catch {
|
|
48
|
+
return false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function turnOffResetConfirmation(): void {
|
|
53
|
+
try {
|
|
54
|
+
storage()?.setItem(confirmKey, 'off')
|
|
55
|
+
} catch {
|
|
56
|
+
// The choice is not kept: the next reset asks again
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns the document to the content the editor opened with and empties the undo and redo history,
|
|
62
|
+
* so the reset itself cannot be undone.
|
|
63
|
+
*/
|
|
64
|
+
export function resetChanges(editor: Editor): boolean {
|
|
65
|
+
const initialContent = editor.storage.resetChanges?.initialContent
|
|
66
|
+
if (!initialContent) {
|
|
67
|
+
return false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
editor.commands.setContent(initialContent, { emitUpdate: true })
|
|
71
|
+
|
|
72
|
+
const { state } = editor
|
|
73
|
+
editor.view.updateState(EditorState.create({ schema: state.schema, doc: state.doc, plugins: state.plugins }))
|
|
74
|
+
// An empty transaction re-renders what reads the history, as the undo and redo buttons
|
|
75
|
+
editor.view.dispatch(editor.state.tr.setMeta('addToHistory', false))
|
|
76
|
+
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
@@ -140,6 +140,16 @@ describe('image dialog apply', () => {
|
|
|
140
140
|
expect(selectedImageAttrs(editor!.state)).toMatchObject({ src: 'https://example.com/a.png', width: 640 })
|
|
141
141
|
})
|
|
142
142
|
|
|
143
|
+
it('reads a node selection made by another copy of prosemirror-state', () => {
|
|
144
|
+
createEditor('<p>Text</p><img src="https://example.com/a.png" width="640">')
|
|
145
|
+
const { from, to } = editor!.state.selection
|
|
146
|
+
const node = editor!.state.doc.nodeAt(6)
|
|
147
|
+
const foreignSelection = { from, to, node }
|
|
148
|
+
const state = { ...editor!.state, selection: foreignSelection } as unknown as Parameters<typeof selectedImageAttrs>[0]
|
|
149
|
+
|
|
150
|
+
expect(selectedImageAttrs(state)).toMatchObject({ src: 'https://example.com/a.png', width: 640 })
|
|
151
|
+
})
|
|
152
|
+
|
|
143
153
|
it('sends the selected image to the dialog, or none to insert one', () => {
|
|
144
154
|
createEditor('<p>Text</p><img src="https://example.com/a.png">')
|
|
145
155
|
const details: Array<{ image: Record<string, unknown> | null }> = []
|
|
@@ -5,6 +5,8 @@ import { ImageAlign } from '@tiptapify/extensions/components/media/image/caption
|
|
|
5
5
|
|
|
6
6
|
export { resizeSide, toSize }
|
|
7
7
|
|
|
8
|
+
export type { ImageAlign }
|
|
9
|
+
|
|
8
10
|
export type ImageSizeMode = 'original' | 'text' | 'custom'
|
|
9
11
|
|
|
10
12
|
export type ImageSize = MediaSize
|
|
@@ -27,12 +29,13 @@ const typeName = 'image'
|
|
|
27
29
|
* The attributes of the image selected as a node, or null when no image is selected (the dialog inserts one).
|
|
28
30
|
*/
|
|
29
31
|
export function selectedImageAttrs(state: EditorState): Record<string, unknown> | null {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
// Not instanceof: a host that imports this module from the source runs another copy of prosemirror-state than the editor
|
|
33
|
+
const { node } = state.selection as Partial<NodeSelection>
|
|
34
|
+
if (node?.type.name !== typeName) {
|
|
32
35
|
return null
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
return { ...
|
|
38
|
+
return { ...node.attrs }
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/**
|
package/src/i18n/locales/ar.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "إعادة",
|
|
4
|
+
"reset": "إعادة تعيين",
|
|
5
|
+
"reset_changes": "إعادة تعيين التغييرات",
|
|
6
|
+
"reset_changes_confirm": "سيتم تجاهل جميع التغييرات منذ فتح المحرر. لا يمكن التراجع عن ذلك.",
|
|
7
|
+
"reset_changes_dont_ask": "عدم السؤال مرة أخرى",
|
|
4
8
|
"undo": "تراجع"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/bg.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Повтори",
|
|
4
|
+
"reset": "Нулирай",
|
|
5
|
+
"reset_changes": "Нулиране на промените",
|
|
6
|
+
"reset_changes_confirm": "Всички промени от отварянето на редактора ще бъдат отхвърлени. Това не може да бъде отменено.",
|
|
7
|
+
"reset_changes_dont_ask": "Не питай повече",
|
|
4
8
|
"undo": "Отмъкни"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/ch.json
CHANGED
package/src/i18n/locales/cz.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Znovu",
|
|
4
|
+
"reset": "Obnovit",
|
|
5
|
+
"reset_changes": "Zahodit změny",
|
|
6
|
+
"reset_changes_confirm": "Všechny změny od otevření editoru budou zahozeny. Tuto akci nelze vrátit zpět.",
|
|
7
|
+
"reset_changes_dont_ask": "Příště se neptat",
|
|
4
8
|
"undo": "Zpět"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/de.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Wiederholen",
|
|
4
|
+
"reset": "Zurücksetzen",
|
|
5
|
+
"reset_changes": "Änderungen zurücksetzen",
|
|
6
|
+
"reset_changes_confirm": "Alle Änderungen seit dem Öffnen des Editors werden verworfen. Dies kann nicht rückgängig gemacht werden.",
|
|
7
|
+
"reset_changes_dont_ask": "Nicht mehr fragen",
|
|
4
8
|
"undo": "Rückgängig"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/el.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Επανάληψη",
|
|
4
|
+
"reset": "Επαναφορά",
|
|
5
|
+
"reset_changes": "Επαναφορά αλλαγών",
|
|
6
|
+
"reset_changes_confirm": "Όλες οι αλλαγές από το άνοιγμα του επεξεργαστή θα απορριφθούν. Αυτό δεν μπορεί να αναιρεθεί.",
|
|
7
|
+
"reset_changes_dont_ask": "Να μην ερωτηθώ ξανά",
|
|
4
8
|
"undo": "Αναίρεση"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/en.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Redo",
|
|
4
|
+
"reset": "Reset",
|
|
5
|
+
"reset_changes": "Reset changes",
|
|
6
|
+
"reset_changes_confirm": "All changes made since the editor opened will be discarded. This cannot be undone.",
|
|
7
|
+
"reset_changes_dont_ask": "Don’t ask again",
|
|
4
8
|
"undo": "Undo"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/es.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Rehacer",
|
|
4
|
+
"reset": "Restablecer",
|
|
5
|
+
"reset_changes": "Restablecer cambios",
|
|
6
|
+
"reset_changes_confirm": "Se descartarán todos los cambios desde que se abrió el editor. Esta acción no se puede deshacer.",
|
|
7
|
+
"reset_changes_dont_ask": "No volver a preguntar",
|
|
4
8
|
"undo": "Deshacer"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/et.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Tee uuesti",
|
|
4
|
+
"reset": "Lähtesta",
|
|
5
|
+
"reset_changes": "Lähtesta muudatused",
|
|
6
|
+
"reset_changes_confirm": "Kõik muudatused alates redaktori avamisest tühistatakse. Seda ei saa tagasi võtta.",
|
|
7
|
+
"reset_changes_dont_ask": "Ära küsi enam",
|
|
4
8
|
"undo": "Tühista"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/fi.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Tee uudelleen",
|
|
4
|
+
"reset": "Palauta",
|
|
5
|
+
"reset_changes": "Palauta muutokset",
|
|
6
|
+
"reset_changes_confirm": "Kaikki muutokset editorin avaamisen jälkeen hylätään. Tätä ei voi kumota.",
|
|
7
|
+
"reset_changes_dont_ask": "Älä kysy uudelleen",
|
|
4
8
|
"undo": "Kumoa"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/fr.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Refaire",
|
|
4
|
+
"reset": "Réinitialiser",
|
|
5
|
+
"reset_changes": "Réinitialiser les modifications",
|
|
6
|
+
"reset_changes_confirm": "Toutes les modifications depuis l’ouverture de l’éditeur seront abandonnées. Cette action est irréversible.",
|
|
7
|
+
"reset_changes_dont_ask": "Ne plus demander",
|
|
4
8
|
"undo": "Annuler"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/he.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "ביצוע מחדש",
|
|
4
|
+
"reset": "איפוס",
|
|
5
|
+
"reset_changes": "איפוס שינויים",
|
|
6
|
+
"reset_changes_confirm": "כל השינויים מאז פתיחת העורך יבוטלו. לא ניתן לבטל פעולה זו.",
|
|
7
|
+
"reset_changes_dont_ask": "אל תשאל שוב",
|
|
4
8
|
"undo": "ביטול"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/hi.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "फिर से करें",
|
|
4
|
+
"reset": "रीसेट करें",
|
|
5
|
+
"reset_changes": "बदलाव रीसेट करें",
|
|
6
|
+
"reset_changes_confirm": "संपादक खुलने के बाद से किए गए सभी बदलाव हटा दिए जाएंगे। इसे पूर्ववत नहीं किया जा सकता।",
|
|
7
|
+
"reset_changes_dont_ask": "फिर से न पूछें",
|
|
4
8
|
"undo": "पूर्ववत् करें"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/hr.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Ponovno",
|
|
4
|
+
"reset": "Poništi sve",
|
|
5
|
+
"reset_changes": "Poništi promjene",
|
|
6
|
+
"reset_changes_confirm": "Sve promjene od otvaranja uređivača bit će odbačene. Ovo se ne može poništiti.",
|
|
7
|
+
"reset_changes_dont_ask": "Ne pitaj ponovno",
|
|
4
8
|
"undo": "Poništi"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/hu.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Ismétlés",
|
|
4
|
+
"reset": "Visszaállítás",
|
|
5
|
+
"reset_changes": "Változtatások visszaállítása",
|
|
6
|
+
"reset_changes_confirm": "A szerkesztő megnyitása óta végzett összes változtatás elvész. Ez nem vonható vissza.",
|
|
7
|
+
"reset_changes_dont_ask": "Ne kérdezze újra",
|
|
4
8
|
"undo": "Visszavonás"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/id.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Ulang",
|
|
4
|
+
"reset": "Atur ulang",
|
|
5
|
+
"reset_changes": "Atur ulang perubahan",
|
|
6
|
+
"reset_changes_confirm": "Semua perubahan sejak editor dibuka akan dibuang. Tindakan ini tidak dapat diurungkan.",
|
|
7
|
+
"reset_changes_dont_ask": "Jangan tanya lagi",
|
|
4
8
|
"undo": "Urungkan"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/it.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Ripeti",
|
|
4
|
+
"reset": "Ripristina",
|
|
5
|
+
"reset_changes": "Ripristina modifiche",
|
|
6
|
+
"reset_changes_confirm": "Tutte le modifiche dall’apertura dell’editor verranno annullate. L’operazione non può essere annullata.",
|
|
7
|
+
"reset_changes_dont_ask": "Non chiedere più",
|
|
4
8
|
"undo": "Annulla"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/ja.json
CHANGED
package/src/i18n/locales/ko.json
CHANGED
package/src/i18n/locales/la.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Atcelt atsaukšanu",
|
|
4
|
+
"reset": "Atiestatīt",
|
|
5
|
+
"reset_changes": "Atiestatīt izmaiņas",
|
|
6
|
+
"reset_changes_confirm": "Visas izmaiņas kopš redaktora atvēršanas tiks atmestas. To nevar atsaukt.",
|
|
7
|
+
"reset_changes_dont_ask": "Vairs nejautāt",
|
|
4
8
|
"undo": "Atsaukt"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/lt.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Pakartoti",
|
|
4
|
+
"reset": "Atkurti",
|
|
5
|
+
"reset_changes": "Atkurti pakeitimus",
|
|
6
|
+
"reset_changes_confirm": "Visi pakeitimai nuo redaktoriaus atidarymo bus atmesti. To negalima atšaukti.",
|
|
7
|
+
"reset_changes_dont_ask": "Daugiau neklausti",
|
|
4
8
|
"undo": "Atšaukti"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|
package/src/i18n/locales/nl.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"action": {
|
|
3
3
|
"redo": "Opnieuw",
|
|
4
|
+
"reset": "Herstellen",
|
|
5
|
+
"reset_changes": "Wijzigingen herstellen",
|
|
6
|
+
"reset_changes_confirm": "Alle wijzigingen sinds het openen van de editor worden verwijderd. Dit kan niet ongedaan worden gemaakt.",
|
|
7
|
+
"reset_changes_dont_ask": "Niet meer vragen",
|
|
4
8
|
"undo": "Ongedaan maken"
|
|
5
9
|
},
|
|
6
10
|
"ai": {
|