adtec-core-package 3.0.3 → 3.0.5
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/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/package.json +21 -4
- package/prebuilt/umo-editor/umo-editor.css +1 -1
- package/prebuilt/umo-editor/umo-editor.js +13739 -15052
- package/prebuilt/umo-editor/umo-editor.js.map +1 -1
- package/src/components/RichTextEditor/RichTextEditor.vue +62 -9
- package/src/components/RichTextEditor/installUmoEditorApp.ts +20 -0
- package/src/components/editor-main/src/components/index.vue +2 -1
- package/src/components/editor-main/src/components/menus/button.vue +30 -3
- package/src/components/editor-main/src/components/menus/toolbar/base/color.vue +12 -5
- package/src/components/editor-main/src/components/menus/toolbar/base/font-family.vue +6 -4
- package/src/components/editor-main/src/components/menus/toolbar/base/font-size.vue +42 -25
- package/src/components/editor-main/src/components/menus/toolbar/base/heading.vue +6 -8
- package/src/components/editor-main/src/composables/toolbarSelection.js +233 -0
- package/src/components/editor-main/src/locales/bo.json +2 -2
- package/src/components/editor-main/src/locales/en-US.json +2 -2
- package/src/components/editor-main/src/locales/it-IT.json +2 -2
- package/src/components/editor-main/src/locales/ru-RU.json +2 -2
- package/src/components/editor-main/src/locales/zh-CN.json +2 -2
- package/src/components/editor-main/src/utils/editor-scroll.js +39 -15
- package/src/components/vxeGrid/index.vue +11 -4
- package/src/stores/dictStore.ts +72 -5
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<!-- RichTextEditor:基于预编译 Umo Editor(prebuilt/umo-editor),对外 API 与原 AiEditor 封装保持一致 -->
|
|
2
2
|
<template>
|
|
3
|
-
<div
|
|
3
|
+
<div
|
|
4
|
+
ref="rootRef"
|
|
5
|
+
class="umo-rich-text-editor-root"
|
|
6
|
+
:class="{ 'umo-rich-text-editor-root--readonly': !editable }">
|
|
4
7
|
<UmoEditor
|
|
5
8
|
v-if="umoMountOptions"
|
|
6
9
|
:key="umoRuntimeKey"
|
|
@@ -36,9 +39,44 @@ export type RichTextEditorConfig = {
|
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/** 始终保留 BlockImage NodeView;只读由 document.readOnly + node-view 静态分支控制 */
|
|
39
|
-
const DISABLED_EXTENSIONS = [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
const DISABLED_EXTENSIONS = [
|
|
43
|
+
'locale', // 视图 Tab:隐藏语言设置下拉(locale 固定 zh-CN;状态栏指示器另用 CSS 隐藏)
|
|
44
|
+
'theme', // 视图 Tab:隐藏主题设置(light/dark,theme 固定 light)
|
|
45
|
+
'mermaid',
|
|
46
|
+
'diagrams',
|
|
47
|
+
// Block 菜单(+ 插入新内容):仅保留表格与图片
|
|
48
|
+
'qrcode',
|
|
49
|
+
'barcode',
|
|
50
|
+
'signature',
|
|
51
|
+
'math',
|
|
52
|
+
'echarts',
|
|
53
|
+
'print', // 开始 Tab:隐藏打印
|
|
54
|
+
// 插入 Tab:仅保留图片
|
|
55
|
+
'link',
|
|
56
|
+
'video',
|
|
57
|
+
'audio',
|
|
58
|
+
'file',
|
|
59
|
+
'text-box',
|
|
60
|
+
'details',
|
|
61
|
+
'code-block',
|
|
62
|
+
'symbol',
|
|
63
|
+
'chinese-date',
|
|
64
|
+
'emoji',
|
|
65
|
+
'tag',
|
|
66
|
+
'columns',
|
|
67
|
+
'callout',
|
|
68
|
+
'mention',
|
|
69
|
+
'option-box',
|
|
70
|
+
'hard-break',
|
|
71
|
+
'hr',
|
|
72
|
+
'bookmark',
|
|
73
|
+
'footnote',
|
|
74
|
+
'toc',
|
|
75
|
+
'template',
|
|
76
|
+
'web-page',
|
|
77
|
+
] as const
|
|
78
|
+
|
|
79
|
+
const OFFICIAL_TOOLBAR_MENUS = ['base', 'insert', 'table', 'page', 'view'] as const
|
|
42
80
|
|
|
43
81
|
const emit = defineEmits<{
|
|
44
82
|
onBlur: [payload: { html: string; text: string }]
|
|
@@ -211,7 +249,7 @@ function seedUmoLayoutStorage() {
|
|
|
211
249
|
localStorage.setItem(`umo-editor:${umoRuntimeKey.value}:layout`, JSON.stringify('web'))
|
|
212
250
|
localStorage.setItem(
|
|
213
251
|
`umo-editor:${umoRuntimeKey.value}:toolbar`,
|
|
214
|
-
JSON.stringify({ mode: '
|
|
252
|
+
JSON.stringify({ mode: 'classic', show: showToolbar }),
|
|
215
253
|
)
|
|
216
254
|
} catch {
|
|
217
255
|
// ignore quota / private mode
|
|
@@ -280,11 +318,12 @@ function buildUmoMountOptions(content: string) {
|
|
|
280
318
|
fullscreenZIndex: 2500,
|
|
281
319
|
toolbar: {
|
|
282
320
|
showSaveLabel: false,
|
|
283
|
-
defaultMode: '
|
|
321
|
+
defaultMode: 'classic',
|
|
322
|
+
// Umo schema 要求 menus 至少含 base;只读时 readOnly=true 会隐藏工具栏 UI
|
|
284
323
|
menus:
|
|
285
324
|
props.showToolbar && editableNow
|
|
286
325
|
? [...OFFICIAL_TOOLBAR_MENUS]
|
|
287
|
-
: [],
|
|
326
|
+
: (['base'] as unknown as string[]),
|
|
288
327
|
},
|
|
289
328
|
page: {
|
|
290
329
|
layouts: ['page', 'web'],
|
|
@@ -296,7 +335,7 @@ function buildUmoMountOptions(content: string) {
|
|
|
296
335
|
zh_CN: placeholder,
|
|
297
336
|
},
|
|
298
337
|
readOnly: !editableNow,
|
|
299
|
-
autofocus:
|
|
338
|
+
autofocus: false,
|
|
300
339
|
enableMarkdown: false,
|
|
301
340
|
enableSpellcheck: false,
|
|
302
341
|
autoSave: {
|
|
@@ -367,7 +406,7 @@ async function applyEditableState() {
|
|
|
367
406
|
editor.setReadOnly?.(!canEdit)
|
|
368
407
|
ensureTipTapEditable(canEdit)
|
|
369
408
|
editor.setToolbar?.({
|
|
370
|
-
mode: '
|
|
409
|
+
mode: 'classic',
|
|
371
410
|
show: props.showToolbar && canEdit,
|
|
372
411
|
})
|
|
373
412
|
const tipTap = editor.getEditor?.()?.value
|
|
@@ -647,4 +686,18 @@ onUnmounted(() => {
|
|
|
647
686
|
cursor: text;
|
|
648
687
|
min-height: 120px;
|
|
649
688
|
}
|
|
689
|
+
|
|
690
|
+
.umo-rich-text-editor-root--readonly {
|
|
691
|
+
:deep(.umo-loading),
|
|
692
|
+
:deep(.umo-loading--visible),
|
|
693
|
+
:deep(.umo-loading__overlay),
|
|
694
|
+
:deep(.umo-loading--center),
|
|
695
|
+
:deep(.umo-icon-loading) {
|
|
696
|
+
display: none !important;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
:deep(.umo-editor-content .ProseMirror) {
|
|
700
|
+
cursor: default;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
650
703
|
</style>
|
|
@@ -5,6 +5,26 @@ import { umoGlobalComponents } from '../../../prebuilt/umo-editor/umo-editor.js'
|
|
|
5
5
|
const registeredApps = new WeakSet<App>()
|
|
6
6
|
const tdesignApps = new WeakSet<App>()
|
|
7
7
|
|
|
8
|
+
/** 嵌入 Umo 的全局样式覆盖(须注入 document.head,全屏 Teleport 到 body 时组件 scoped :deep 无法命中) */
|
|
9
|
+
function injectUmoEmbedStyles() {
|
|
10
|
+
if (typeof document === 'undefined') return
|
|
11
|
+
if (document.getElementById('umo-embed-overrides')) return
|
|
12
|
+
|
|
13
|
+
const style = document.createElement('style')
|
|
14
|
+
style.id = 'umo-embed-overrides'
|
|
15
|
+
style.textContent = `
|
|
16
|
+
svg.umo-icon:not(.t-icon) {
|
|
17
|
+
fill: none;
|
|
18
|
+
}
|
|
19
|
+
.umo-status-bar-button.umo-lang-button {
|
|
20
|
+
display: none !important;
|
|
21
|
+
}
|
|
22
|
+
`
|
|
23
|
+
document.head.appendChild(style)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
injectUmoEmbedStyles()
|
|
27
|
+
|
|
8
28
|
/** 预编译 Umo 内部用 resolveComponent,须在宿主 Vue App 上注册 umoGlobalComponents */
|
|
9
29
|
export function installUmoEditorApp(app?: App | null) {
|
|
10
30
|
if (!app) return false
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
} from '../utils/history-record'
|
|
82
82
|
import { getOpitons } from '../utils/options'
|
|
83
83
|
import { getSelectionNode, getSelectionText } from '../utils/selection'
|
|
84
|
-
import { syncCacheOnEditorSelectionUpdate } from '../composables/toolbarSelection.js'
|
|
84
|
+
import { syncCacheOnEditorSelectionUpdate, bumpToolbarEditorState } from '../composables/toolbarSelection.js'
|
|
85
85
|
import { shortId } from '../utils/short-id'
|
|
86
86
|
import { getCurrentInstance } from 'vue'
|
|
87
87
|
|
|
@@ -332,6 +332,7 @@ watch(
|
|
|
332
332
|
editor.value.on('update', ({ editor }) => {
|
|
333
333
|
emits('changed', { editor })
|
|
334
334
|
contentUpdated.value = true
|
|
335
|
+
bumpToolbarEditorState()
|
|
335
336
|
})
|
|
336
337
|
editor.value.on('selectionUpdate', ({ editor }) => {
|
|
337
338
|
syncCacheOnEditorSelectionUpdate(editor)
|
|
@@ -205,6 +205,7 @@
|
|
|
205
205
|
:disabled="
|
|
206
206
|
!forceEnabled && (disabled || editor?.isEditable === false)
|
|
207
207
|
"
|
|
208
|
+
@mousedown.prevent="cacheToolbarSelection"
|
|
208
209
|
>
|
|
209
210
|
<div class="umo-button-content" @click="menuClick">
|
|
210
211
|
<slot />
|
|
@@ -341,7 +342,7 @@ import { isString } from '@tool-belt/type-predicates'
|
|
|
341
342
|
import { getShortcut } from '../../utils/shortcut'
|
|
342
343
|
|
|
343
344
|
|
|
344
|
-
import { useAttrs, inject, watch, ref } from 'vue';
|
|
345
|
+
import { useAttrs, inject, watch, ref, onBeforeUnmount } from 'vue';
|
|
345
346
|
import { onClickOutside } from '@vueuse/core';
|
|
346
347
|
const { selectVisible } = useSelect()
|
|
347
348
|
|
|
@@ -442,24 +443,50 @@ const cacheToolbarSelection = () => {
|
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
445
|
|
|
446
|
+
/** 打开下拉时同一次点击可能落在首项上(幽灵 click),短暂忽略 @change */
|
|
447
|
+
let suppressSelectChange = false
|
|
448
|
+
let suppressSelectChangeTimer = null
|
|
449
|
+
|
|
450
|
+
const clearSuppressSelectChange = () => {
|
|
451
|
+
suppressSelectChange = false
|
|
452
|
+
if (suppressSelectChangeTimer != null) {
|
|
453
|
+
clearTimeout(suppressSelectChangeTimer)
|
|
454
|
+
suppressSelectChangeTimer = null
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const scheduleSuppressSelectChange = () => {
|
|
459
|
+
clearSuppressSelectChange()
|
|
460
|
+
suppressSelectChange = true
|
|
461
|
+
suppressSelectChangeTimer = setTimeout(clearSuppressSelectChange, 250)
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
onBeforeUnmount(clearSuppressSelectChange)
|
|
465
|
+
|
|
445
466
|
const onSelectTriggerPress = () => {
|
|
446
467
|
beginSelectMenuInteraction(editor?.value)
|
|
468
|
+
scheduleSuppressSelectChange()
|
|
447
469
|
}
|
|
448
470
|
|
|
449
471
|
const selectPopupVisibleChange = (visible) => {
|
|
450
472
|
popupVisileChange(visible)
|
|
451
473
|
if (visible) {
|
|
452
474
|
beginSelectMenuInteraction(editor?.value)
|
|
475
|
+
scheduleSuppressSelectChange()
|
|
453
476
|
} else {
|
|
454
477
|
endSelectMenuInteraction()
|
|
478
|
+
clearSuppressSelectChange()
|
|
455
479
|
}
|
|
456
480
|
}
|
|
457
481
|
|
|
458
|
-
const selectMenuClick = (...
|
|
482
|
+
const selectMenuClick = (value, context, ...rest) => {
|
|
483
|
+
if (suppressSelectChange || context?.trigger === 'default') {
|
|
484
|
+
return
|
|
485
|
+
}
|
|
459
486
|
if (editor?.value?.state.selection.empty) {
|
|
460
487
|
restorePendingSelectMenuRange(editor.value)
|
|
461
488
|
}
|
|
462
|
-
menuClick(...
|
|
489
|
+
menuClick(value, context, ...rest)
|
|
463
490
|
}
|
|
464
491
|
|
|
465
492
|
const tooltipVisible = _ref(false)
|
|
@@ -28,6 +28,10 @@ import { ref as _ref } from 'vue';
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
import { inject } from 'vue';
|
|
31
|
+
import {
|
|
32
|
+
FOCUS_WITHOUT_SCROLL,
|
|
33
|
+
runPreservingScroll,
|
|
34
|
+
} from '../../../../utils/editor-scroll.js';
|
|
31
35
|
const props = defineProps({
|
|
32
36
|
text: {
|
|
33
37
|
type: String,
|
|
@@ -46,6 +50,7 @@ const emits = defineEmits(['change'])
|
|
|
46
50
|
|
|
47
51
|
const { popupVisible, togglePopup } = usePopup()
|
|
48
52
|
const editor = inject('editor')
|
|
53
|
+
const container = inject('container')
|
|
49
54
|
|
|
50
55
|
let currentColor = _ref()
|
|
51
56
|
const colorChange = (color) => {
|
|
@@ -57,11 +62,13 @@ const colorChange = (color) => {
|
|
|
57
62
|
return
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
runPreservingScroll(container, () => {
|
|
66
|
+
if (color === '') {
|
|
67
|
+
editor.value?.chain().focus(undefined, FOCUS_WITHOUT_SCROLL).unsetColor().run()
|
|
68
|
+
} else {
|
|
69
|
+
editor.value?.chain().focus(undefined, FOCUS_WITHOUT_SCROLL).setColor(color).run()
|
|
70
|
+
}
|
|
71
|
+
})
|
|
65
72
|
}
|
|
66
73
|
</script>
|
|
67
74
|
|
|
@@ -57,6 +57,10 @@
|
|
|
57
57
|
|
|
58
58
|
<script setup>
|
|
59
59
|
import { t } from '../../../../composables/i18n.js';
|
|
60
|
+
import {
|
|
61
|
+
getToolbarFontFamily,
|
|
62
|
+
toolbarEditorTick,
|
|
63
|
+
} from '../../../../composables/toolbarSelection.js';
|
|
60
64
|
|
|
61
65
|
import { useState } from '../../../../composables/state.js';
|
|
62
66
|
import { ref as _ref } from 'vue';
|
|
@@ -81,13 +85,11 @@ let autoDownloadRunning = _ref(false)
|
|
|
81
85
|
let restoringDownloadedFonts = _ref(true)
|
|
82
86
|
|
|
83
87
|
const selectedFont = computed(() => {
|
|
88
|
+
toolbarEditorTick.value
|
|
84
89
|
if (!editor.value || typeWriterIsRunning.value) {
|
|
85
90
|
return null
|
|
86
91
|
}
|
|
87
|
-
|
|
88
|
-
return null
|
|
89
|
-
}
|
|
90
|
-
return editor.value.getAttributes('textStyle').fontFamily.replace(/"/g, '')
|
|
92
|
+
return getToolbarFontFamily(editor.value)
|
|
91
93
|
})
|
|
92
94
|
|
|
93
95
|
const ensureRecentState = () => {
|
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
hide-text
|
|
7
7
|
style="width: 80px"
|
|
8
8
|
:select-options="fontSizes"
|
|
9
|
-
:select-value="
|
|
10
|
-
typeWriterIsRunning
|
|
11
|
-
? null
|
|
12
|
-
: editor?.getAttributes('textStyle').fontSize || '14px'
|
|
13
|
-
"
|
|
9
|
+
:select-value="selectFontSize"
|
|
14
10
|
v-bind="$attrs"
|
|
15
11
|
:placeholder="t('base.fontSize.text')"
|
|
16
12
|
filterable
|
|
@@ -40,10 +36,16 @@
|
|
|
40
36
|
import { t } from '../../../../composables/i18n.js';
|
|
41
37
|
import {
|
|
42
38
|
applyCachedTextSelection,
|
|
39
|
+
getToolbarFontSize,
|
|
43
40
|
refreshCachedTextSelection,
|
|
44
41
|
restorePendingSelectMenuRange,
|
|
42
|
+
toolbarEditorTick,
|
|
45
43
|
} from '../../../../composables/toolbarSelection.js';
|
|
46
|
-
import { inject } from 'vue';
|
|
44
|
+
import { computed, inject } from 'vue';
|
|
45
|
+
import {
|
|
46
|
+
FOCUS_WITHOUT_SCROLL,
|
|
47
|
+
runPreservingScroll,
|
|
48
|
+
} from '../../../../utils/editor-scroll.js';
|
|
47
49
|
|
|
48
50
|
const props = defineProps({
|
|
49
51
|
select: {
|
|
@@ -53,6 +55,7 @@ const props = defineProps({
|
|
|
53
55
|
})
|
|
54
56
|
|
|
55
57
|
const editor = inject('editor')
|
|
58
|
+
const container = inject('container')
|
|
56
59
|
const options = inject('options')
|
|
57
60
|
const typeWriterIsRunning = inject('typeWriterIsRunning')
|
|
58
61
|
|
|
@@ -60,6 +63,12 @@ const disableMenu = (name) => {
|
|
|
60
63
|
return options.value.disableExtensions.includes(name)
|
|
61
64
|
}
|
|
62
65
|
|
|
66
|
+
const selectFontSize = computed(() => {
|
|
67
|
+
toolbarEditorTick.value
|
|
68
|
+
if (typeWriterIsRunning.value) return null
|
|
69
|
+
return getToolbarFontSize(editor.value)
|
|
70
|
+
})
|
|
71
|
+
|
|
63
72
|
const fontSizes = [
|
|
64
73
|
{ label: t('base.fontSize.default'), value: '14px', order: 4 },
|
|
65
74
|
{ label: t('base.fontSize.42pt'), value: '42pt', order: 20 }, // 56
|
|
@@ -94,36 +103,44 @@ const fontSizes = [
|
|
|
94
103
|
{ label: '96', value: '96px', order: 22 },
|
|
95
104
|
]
|
|
96
105
|
|
|
97
|
-
//
|
|
106
|
+
// 设置字体大小(连续改字号时保持选区,且不触发外层页面滚动)
|
|
98
107
|
const applyFontSize = (fontSize) => {
|
|
99
108
|
const ed = editor.value
|
|
100
109
|
if (!ed) return
|
|
101
110
|
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
runPreservingScroll(container, () => {
|
|
112
|
+
const { empty, from, to } = ed.state.selection
|
|
113
|
+
let chain = ed.chain().focus(undefined, FOCUS_WITHOUT_SCROLL)
|
|
104
114
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return
|
|
112
|
-
} else {
|
|
113
|
-
const sel = ed.state.selection
|
|
114
|
-
if (!sel.empty && sel.from !== sel.to) {
|
|
115
|
-
chain = ed.chain().focus().setTextSelection({ from: sel.from, to: sel.to })
|
|
116
|
-
} else {
|
|
115
|
+
if (!empty && from !== to) {
|
|
116
|
+
chain = chain.setTextSelection({ from, to })
|
|
117
|
+
} else if (
|
|
118
|
+
!restorePendingSelectMenuRange(ed) &&
|
|
119
|
+
!applyCachedTextSelection(ed)
|
|
120
|
+
) {
|
|
117
121
|
return
|
|
122
|
+
} else {
|
|
123
|
+
const sel = ed.state.selection
|
|
124
|
+
if (!sel.empty && sel.from !== sel.to) {
|
|
125
|
+
chain = ed
|
|
126
|
+
.chain()
|
|
127
|
+
.focus(undefined, FOCUS_WITHOUT_SCROLL)
|
|
128
|
+
.setTextSelection({ from: sel.from, to: sel.to })
|
|
129
|
+
} else {
|
|
130
|
+
return
|
|
131
|
+
}
|
|
118
132
|
}
|
|
119
|
-
}
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
if (chain.setFontSize(fontSize).run()) {
|
|
135
|
+
refreshCachedTextSelection(ed)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
124
138
|
}
|
|
125
139
|
|
|
126
140
|
const setFontSize = (fontSize) => {
|
|
141
|
+
if (!fontSize) return
|
|
142
|
+
const current = getToolbarFontSize(editor.value)
|
|
143
|
+
if (current === fontSize) return
|
|
127
144
|
applyFontSize(fontSize)
|
|
128
145
|
}
|
|
129
146
|
|
|
@@ -84,8 +84,8 @@ import { inject, ref, computed } from 'vue';
|
|
|
84
84
|
import { onClickOutside } from '@vueuse/core';
|
|
85
85
|
import {
|
|
86
86
|
applyHeadingWithoutScroll,
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
FOCUS_WITHOUT_SCROLL,
|
|
88
|
+
runPreservingScroll,
|
|
89
89
|
} from '../../../../utils/editor-scroll.js';
|
|
90
90
|
const { popupVisible } = usePopup()
|
|
91
91
|
const container = inject('container')
|
|
@@ -133,16 +133,14 @@ const currentValue = computed(() => {
|
|
|
133
133
|
return ''
|
|
134
134
|
})
|
|
135
135
|
|
|
136
|
-
const FOCUS_WITHOUT_SCROLL = { scrollIntoView: false }
|
|
137
|
-
|
|
138
136
|
const setHeading = (value) => {
|
|
139
137
|
const ed = editor.value
|
|
140
138
|
if (!ed) return
|
|
141
139
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
runPreservingScroll(container, () => {
|
|
141
|
+
ed.commands.focus(undefined, FOCUS_WITHOUT_SCROLL)
|
|
142
|
+
applyHeadingWithoutScroll(ed, value)
|
|
143
|
+
})
|
|
146
144
|
popupVisible.value = false
|
|
147
145
|
}
|
|
148
146
|
|