autumnnote 1.0.8 → 1.1.0
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 +401 -628
- package/dist/autumnnote.css +169 -0
- package/dist/autumnnote.es.js +3669 -179
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +3668 -178
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +3 -2
- package/src/js/Context.js +18 -2
- package/src/js/core/func.js +5 -5
- package/src/js/i18n/de.js +320 -0
- package/src/js/i18n/en.js +328 -0
- package/src/js/i18n/es.js +320 -0
- package/src/js/i18n/fr.js +321 -0
- package/src/js/i18n/index.js +59 -0
- package/src/js/i18n/ja.js +321 -0
- package/src/js/i18n/ko.js +320 -0
- package/src/js/i18n/vi.js +321 -0
- package/src/js/i18n/zh.js +321 -0
- package/src/js/index.js +2 -1
- package/src/js/module/AutoSaveRestore.js +126 -0
- package/src/js/module/BubbleToolbar.js +243 -0
- package/src/js/module/CodeTooltip.js +12 -9
- package/src/js/module/ContextMenu.js +41 -37
- package/src/js/module/EmojiDialog.js +8 -7
- package/src/js/module/FindReplace.js +14 -13
- package/src/js/module/IconDialog.js +14 -13
- package/src/js/module/ImageDialog.js +17 -16
- package/src/js/module/ImageTooltip.js +13 -12
- package/src/js/module/LinkDialog.js +10 -9
- package/src/js/module/LinkTooltip.js +6 -5
- package/src/js/module/MarkdownShortcuts.js +253 -0
- package/src/js/module/Mention.js +337 -0
- package/src/js/module/ShortcutsDialog.js +5 -4
- package/src/js/module/Statusbar.js +6 -5
- package/src/js/module/TableTooltip.js +22 -19
- package/src/js/module/Toolbar.js +21 -15
- package/src/js/module/VideoDialog.js +10 -9
- package/src/js/module/VideoTooltip.js +12 -11
- package/src/js/settings.js +23 -0
- package/src/styles/autumnnote.scss +191 -0
- package/types/index.d.ts +114 -1
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zh.js - 简体中文 (Simplified Chinese) locale
|
|
3
|
+
* 仅包含与 en.js 不同的键值。
|
|
4
|
+
* resolveLocale 会将本文件与 en.js 进行深度合并。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** @type {Partial<import('../../../types/index.js').AsnLocale>} */
|
|
8
|
+
export const zh = {
|
|
9
|
+
toolbar: {
|
|
10
|
+
bold: '粗体 (Ctrl+B)',
|
|
11
|
+
italic: '斜体 (Ctrl+I)',
|
|
12
|
+
underline: '下划线 (Ctrl+U)',
|
|
13
|
+
strikethrough: '删除线',
|
|
14
|
+
superscript: '上标',
|
|
15
|
+
subscript: '下标',
|
|
16
|
+
alignLeft: '左对齐',
|
|
17
|
+
alignCenter: '居中',
|
|
18
|
+
alignRight: '右对齐',
|
|
19
|
+
alignJustify: '两端对齐',
|
|
20
|
+
ul: '无序列表',
|
|
21
|
+
ol: '有序列表',
|
|
22
|
+
checklist: '待办列表',
|
|
23
|
+
indent: '增加缩进',
|
|
24
|
+
outdent: '减少缩进',
|
|
25
|
+
undo: '撤销 (Ctrl+Z)',
|
|
26
|
+
redo: '重做 (Ctrl+Y)',
|
|
27
|
+
hr: '水平分割线',
|
|
28
|
+
link: '插入链接',
|
|
29
|
+
image: '插入图片',
|
|
30
|
+
video: '插入视频',
|
|
31
|
+
emoji: '插入表情',
|
|
32
|
+
icon: '插入 FA 图标',
|
|
33
|
+
table: '插入表格',
|
|
34
|
+
fontSize: '字号',
|
|
35
|
+
fontSizePlaceholder: '大小',
|
|
36
|
+
removeFormat: '清除格式',
|
|
37
|
+
direction: '切换文字方向 (LTR / RTL)',
|
|
38
|
+
fontFamily: '字体',
|
|
39
|
+
paragraphStyle: '段落样式',
|
|
40
|
+
paragraphStylePlaceholder: '样式',
|
|
41
|
+
lineHeight: '行高',
|
|
42
|
+
lineHeightPlaceholder: '\u2195 行距',
|
|
43
|
+
codeview: '查看 HTML 源码',
|
|
44
|
+
fullscreen: '全屏',
|
|
45
|
+
shortcuts: '键盘快捷键 (Ctrl+Shift+/)',
|
|
46
|
+
find: '搜索 (Ctrl+F)',
|
|
47
|
+
findReplace: '查找和替换 (Ctrl+H)',
|
|
48
|
+
inlineCode: '行内代码 (Ctrl+`)',
|
|
49
|
+
print: '打印',
|
|
50
|
+
foreColor: '文字颜色',
|
|
51
|
+
backColor: '高亮颜色',
|
|
52
|
+
chooseTextColor: '选择文字颜色',
|
|
53
|
+
chooseHighlightColor: '选择高亮颜色',
|
|
54
|
+
customColor: '自定义颜色',
|
|
55
|
+
insertTableLabel: '插入表格',
|
|
56
|
+
paragraphItems: {
|
|
57
|
+
p: '正文',
|
|
58
|
+
blockquote: '引用',
|
|
59
|
+
pre: '代码',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
linkDialog: {
|
|
64
|
+
ariaLabel: '插入链接',
|
|
65
|
+
title: '插入链接',
|
|
66
|
+
url: '链接地址',
|
|
67
|
+
urlPlaceholder: 'https://',
|
|
68
|
+
displayText: '显示文字',
|
|
69
|
+
textPlaceholder: '链接文字',
|
|
70
|
+
openInNewTab: '在新标签页中打开',
|
|
71
|
+
insertBtn: '插入',
|
|
72
|
+
cancelBtn: '取消',
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
imageDialog: {
|
|
76
|
+
ariaLabel: '插入图片',
|
|
77
|
+
title: '插入图片',
|
|
78
|
+
imageUrl: '图片地址',
|
|
79
|
+
urlPlaceholder: 'https://example.com/image.png',
|
|
80
|
+
altText: '替代文字',
|
|
81
|
+
altPlaceholder: '图片描述',
|
|
82
|
+
alignment: '对齐方式',
|
|
83
|
+
alignNone: '无',
|
|
84
|
+
alignLeft: '左',
|
|
85
|
+
alignCenter: '居中',
|
|
86
|
+
alignRight: '右',
|
|
87
|
+
uploadLabel: '或上传文件',
|
|
88
|
+
insertBtn: '插入',
|
|
89
|
+
cancelBtn: '取消',
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
videoDialog: {
|
|
93
|
+
ariaLabel: '插入视频',
|
|
94
|
+
title: '插入视频',
|
|
95
|
+
videoUrl: '视频地址',
|
|
96
|
+
urlPlaceholder: 'YouTube、Vimeo 或直接 .mp4 链接',
|
|
97
|
+
widthLabel: '宽度 (px)',
|
|
98
|
+
widthPlaceholder: '560',
|
|
99
|
+
insertBtn: '插入',
|
|
100
|
+
cancelBtn: '取消',
|
|
101
|
+
detected: (type) => `已识别: ${type}`,
|
|
102
|
+
unknownFormat: '未知格式 \u2014 将尝试直接嵌入视频',
|
|
103
|
+
invalidUrl: 'URL 无效 \u2014 请输入有效的视频链接。',
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
emojiDialog: {
|
|
107
|
+
ariaLabel: '插入表情',
|
|
108
|
+
title: '插入表情',
|
|
109
|
+
searchPlaceholder: '搜索表情\u2026',
|
|
110
|
+
all: '全部',
|
|
111
|
+
cancelBtn: '取消',
|
|
112
|
+
close: '关闭',
|
|
113
|
+
categories: {
|
|
114
|
+
smileys: '笑脸',
|
|
115
|
+
people: '人物',
|
|
116
|
+
animals: '动物',
|
|
117
|
+
food: '食物',
|
|
118
|
+
travel: '旅行',
|
|
119
|
+
objects: '物品',
|
|
120
|
+
symbols: '符号',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
iconDialog: {
|
|
125
|
+
ariaLabel: '插入 FA 图标',
|
|
126
|
+
title: '插入 FA 图标',
|
|
127
|
+
searchPlaceholder: '搜索图标\u2026',
|
|
128
|
+
all: '全部',
|
|
129
|
+
style: '样式',
|
|
130
|
+
size: '大小',
|
|
131
|
+
color: '颜色',
|
|
132
|
+
useColor: ' 使用颜色',
|
|
133
|
+
selectHint: '请选择一个图标',
|
|
134
|
+
insertBtn: '插入 FA 图标',
|
|
135
|
+
cancelBtn: '取消',
|
|
136
|
+
close: '关闭',
|
|
137
|
+
categories: {
|
|
138
|
+
popular: '热门',
|
|
139
|
+
interface: '界面',
|
|
140
|
+
navigation: '导航',
|
|
141
|
+
media: '媒体',
|
|
142
|
+
communication: '通讯',
|
|
143
|
+
files: '文件',
|
|
144
|
+
people: '人物',
|
|
145
|
+
objects: '物品',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
findReplace: {
|
|
150
|
+
findTitle: '搜索',
|
|
151
|
+
findReplaceTitle: '查找和替换',
|
|
152
|
+
findPlaceholder: '查找\u2026',
|
|
153
|
+
searchAriaLabel: '搜索文字',
|
|
154
|
+
caseSensitive: '\u00a0区分大小写',
|
|
155
|
+
prevBtn: '\u2190 上一个',
|
|
156
|
+
nextBtn: '下一个 \u2192',
|
|
157
|
+
replacePlaceholder: '替换为\u2026',
|
|
158
|
+
replaceAriaLabel: '替换为',
|
|
159
|
+
replaceBtn: '替换',
|
|
160
|
+
replaceAllBtn: '全部替换',
|
|
161
|
+
close: '\u00d7',
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
shortcutsDialog: {
|
|
165
|
+
title: '键盘快捷键',
|
|
166
|
+
ariaLabel: '键盘快捷键',
|
|
167
|
+
close: '关闭',
|
|
168
|
+
shortcuts: [
|
|
169
|
+
{
|
|
170
|
+
category: '文字格式',
|
|
171
|
+
items: [
|
|
172
|
+
{ keys: 'Ctrl + B', action: '粗体' },
|
|
173
|
+
{ keys: 'Ctrl + I', action: '斜体' },
|
|
174
|
+
{ keys: 'Ctrl + U', action: '下划线' },
|
|
175
|
+
{ keys: 'Ctrl + K', action: '插入 / 编辑链接' },
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
category: '历史记录',
|
|
180
|
+
items: [
|
|
181
|
+
{ keys: 'Ctrl + Z', action: '撤销' },
|
|
182
|
+
{ keys: 'Ctrl + Y / Ctrl + Shift + Z', action: '重做' },
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
category: '选择与导航',
|
|
187
|
+
items: [
|
|
188
|
+
{ keys: 'Ctrl + A', action: '全选' },
|
|
189
|
+
{ keys: 'Tab', action: '增加缩进 / 插入空格' },
|
|
190
|
+
{ keys: 'Shift + Tab', action: '减少缩进' },
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
category: '剪贴板',
|
|
195
|
+
items: [
|
|
196
|
+
{ keys: 'Ctrl + Shift + V', action: '粘贴为纯文本' },
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
category: '查找和替换',
|
|
201
|
+
items: [
|
|
202
|
+
{ keys: 'Ctrl + F', action: '在文档中搜索' },
|
|
203
|
+
{ keys: 'Ctrl + H', action: '查找和替换' },
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
category: '编辑器',
|
|
208
|
+
items: [
|
|
209
|
+
{ keys: 'Ctrl + Shift + /', action: '显示快捷键对话框' },
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
contextMenu: {
|
|
216
|
+
cut: '剪切',
|
|
217
|
+
copy: '复制',
|
|
218
|
+
paste: '粘贴',
|
|
219
|
+
bold: '粗体',
|
|
220
|
+
italic: '斜体',
|
|
221
|
+
underline: '下划线',
|
|
222
|
+
textColor: '文字颜色',
|
|
223
|
+
highlightColor: '高亮颜色',
|
|
224
|
+
copyFormat: '复制格式',
|
|
225
|
+
pasteFormat: '粘贴格式',
|
|
226
|
+
removeFormat: '清除格式',
|
|
227
|
+
link: '插入链接',
|
|
228
|
+
image: '插入图片',
|
|
229
|
+
video: '插入视频',
|
|
230
|
+
table: '插入表格',
|
|
231
|
+
back: '返回',
|
|
232
|
+
noHighlight: '无高亮',
|
|
233
|
+
customColor: '自定义颜色',
|
|
234
|
+
customColorLabel: '自定义\u2026',
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
statusbar: {
|
|
238
|
+
resizeHandle: '拖动以调整大小',
|
|
239
|
+
words: (n) => `字数: ${n}`,
|
|
240
|
+
wordsLimit: (n, max) => `字数: ${n}/${max}`,
|
|
241
|
+
chars: (n) => `字符数: ${n}`,
|
|
242
|
+
charsLimit: (n, max) => `字符数: ${n}/${max}`,
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
tooltips: {
|
|
246
|
+
link: {
|
|
247
|
+
ariaLabel: '链接操作',
|
|
248
|
+
openLink: '打开链接',
|
|
249
|
+
copyUrl: '复制 URL',
|
|
250
|
+
editLink: '编辑链接',
|
|
251
|
+
removeLink: '删除链接',
|
|
252
|
+
},
|
|
253
|
+
image: {
|
|
254
|
+
ariaLabel: '图片操作',
|
|
255
|
+
label: '图片',
|
|
256
|
+
floatLeft: '左浮动',
|
|
257
|
+
noFloat: '不浮动',
|
|
258
|
+
alignCenter: '居中对齐',
|
|
259
|
+
floatRight: '右浮动',
|
|
260
|
+
originalSize: '原始尺寸',
|
|
261
|
+
rotateLeft: '向左旋转',
|
|
262
|
+
rotateRight: '向右旋转',
|
|
263
|
+
cropImage: '裁剪图片',
|
|
264
|
+
addCaption: '添加 / 编辑说明',
|
|
265
|
+
deleteImage: '删除图片',
|
|
266
|
+
},
|
|
267
|
+
code: {
|
|
268
|
+
ariaLabel: '代码块操作',
|
|
269
|
+
label: '代码',
|
|
270
|
+
syntaxLanguage: '语法语言',
|
|
271
|
+
syntaxAriaLabel: '语法语言',
|
|
272
|
+
copyCode: '复制代码',
|
|
273
|
+
toggleWordWrap: '切换自动换行',
|
|
274
|
+
enableWordWrap: '启用自动换行',
|
|
275
|
+
disableWordWrap: '禁用自动换行',
|
|
276
|
+
convertToParagraph: '转换为段落',
|
|
277
|
+
deleteCodeBlock: '删除代码块',
|
|
278
|
+
},
|
|
279
|
+
table: {
|
|
280
|
+
ariaLabel: '表格操作',
|
|
281
|
+
label: '表格',
|
|
282
|
+
selectCells: '选择单元格',
|
|
283
|
+
addRowAbove: '在上方插入行',
|
|
284
|
+
addRowBelow: '在下方插入行',
|
|
285
|
+
deleteRow: '删除行',
|
|
286
|
+
addColumnLeft: '在左侧插入列',
|
|
287
|
+
addColumnRight: '在右侧插入列',
|
|
288
|
+
deleteColumn: '删除列',
|
|
289
|
+
mergeCells: '合并单元格',
|
|
290
|
+
unmergeCells: '拆分单元格',
|
|
291
|
+
columnWidth: '列宽',
|
|
292
|
+
rowHeight: '行高',
|
|
293
|
+
tableBorderWidth: '表格边框宽度',
|
|
294
|
+
deleteTable: '删除表格',
|
|
295
|
+
columnWidthPx: '列宽 (px)',
|
|
296
|
+
rowHeightPx: '行高 (px)',
|
|
297
|
+
tableBorderWidthPx: '表格边框宽度 (px)',
|
|
298
|
+
cancelBtn: '取消',
|
|
299
|
+
applyBtn: '应用',
|
|
300
|
+
},
|
|
301
|
+
video: {
|
|
302
|
+
ariaLabel: '视频操作',
|
|
303
|
+
label: '视频',
|
|
304
|
+
floatLeft: '左浮动',
|
|
305
|
+
noFloat: '不浮动',
|
|
306
|
+
alignCenter: '居中对齐',
|
|
307
|
+
floatRight: '右浮动',
|
|
308
|
+
originalSize: '原始尺寸',
|
|
309
|
+
previewVideo: '预览视频',
|
|
310
|
+
exitPreview: '退出预览',
|
|
311
|
+
deleteVideo: '删除视频',
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
|
|
315
|
+
errors: {
|
|
316
|
+
imageFormat: (type) =>
|
|
317
|
+
`格式 "${type}" 不支持在浏览器中显示。请转换为 JPEG、PNG 或 WebP。`,
|
|
318
|
+
imageSize: (maxSize) =>
|
|
319
|
+
`图片文件过大。最大允许大小为 ${maxSize} MB。`,
|
|
320
|
+
},
|
|
321
|
+
};
|
package/src/js/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export * from './core/lists.js';
|
|
|
27
27
|
export * from './core/env.js';
|
|
28
28
|
export * from './core/sanitise.js';
|
|
29
29
|
export * from './module/Buttons.js';
|
|
30
|
+
export { locales, resolveLocale } from './i18n/index.js';
|
|
30
31
|
|
|
31
32
|
// ---------------------------------------------------------------------------
|
|
32
33
|
// Main factory
|
|
@@ -99,7 +100,7 @@ const AutumnNote = {
|
|
|
99
100
|
registerModule(name, ModuleClass) { _customModules.set(name, ModuleClass); },
|
|
100
101
|
|
|
101
102
|
/** Library version */
|
|
102
|
-
version: '1.0.
|
|
103
|
+
version: '1.0.9',
|
|
103
104
|
};
|
|
104
105
|
|
|
105
106
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AutoSaveRestore.js — Detects a previously auto-saved draft and offers the
|
|
3
|
+
* user a banner to restore or discard it.
|
|
4
|
+
*
|
|
5
|
+
* Activated when both `autoSave` and `autoSaveRestore` options are true.
|
|
6
|
+
* On initialize it checks localStorage for a draft that is within the
|
|
7
|
+
* `autoSaveRestoreTimeout` day window. If one is found a dismissible banner
|
|
8
|
+
* is prepended to the editor container.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export class AutoSaveRestore {
|
|
12
|
+
/** @param {import('../Context.js').Context} context */
|
|
13
|
+
constructor(context) {
|
|
14
|
+
this.context = context;
|
|
15
|
+
this.options = context.options;
|
|
16
|
+
|
|
17
|
+
/** @type {HTMLElement|null} */
|
|
18
|
+
this._banner = null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
initialize() {
|
|
22
|
+
if (!this.options.autoSave || !this.options.autoSaveRestore) return this;
|
|
23
|
+
|
|
24
|
+
const key = this.options.autoSaveKey;
|
|
25
|
+
const metaKey = key + ':asrmeta';
|
|
26
|
+
|
|
27
|
+
let saved;
|
|
28
|
+
let meta;
|
|
29
|
+
try {
|
|
30
|
+
saved = localStorage.getItem(key);
|
|
31
|
+
meta = JSON.parse(localStorage.getItem(metaKey) || '{}');
|
|
32
|
+
} catch (_) {
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!saved) return this;
|
|
37
|
+
|
|
38
|
+
const timeout = this.options.autoSaveRestoreTimeout;
|
|
39
|
+
if (timeout > 0) {
|
|
40
|
+
const ageMs = Date.now() - (meta.savedAt || 0);
|
|
41
|
+
if (ageMs > timeout * 86400000) {
|
|
42
|
+
try { localStorage.removeItem(key); localStorage.removeItem(metaKey); } catch (_) {}
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
this._showBanner(saved, meta);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
destroy() {
|
|
52
|
+
this._removeBanner();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Internal
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
_showBanner(draftHtml, meta) {
|
|
60
|
+
const locale = this.context.locale;
|
|
61
|
+
const t = locale.autoSaveRestore || {};
|
|
62
|
+
const label = t.found || 'Draft found. Restore?';
|
|
63
|
+
const restoreLabel = t.restore || 'Restore';
|
|
64
|
+
const discardLabel = t.discard || 'Discard';
|
|
65
|
+
|
|
66
|
+
const banner = document.createElement('div');
|
|
67
|
+
banner.className = 'an-asr-banner';
|
|
68
|
+
banner.setAttribute('role', 'alert');
|
|
69
|
+
|
|
70
|
+
const msg = document.createElement('span');
|
|
71
|
+
msg.className = 'an-asr-msg';
|
|
72
|
+
if (meta.savedAt) {
|
|
73
|
+
const d = new Date(meta.savedAt);
|
|
74
|
+
const formatted = d.toLocaleString();
|
|
75
|
+
msg.textContent = (t.foundAt || 'Draft from {date}. Restore?').replace('{date}', formatted);
|
|
76
|
+
} else {
|
|
77
|
+
msg.textContent = label;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const restoreBtn = document.createElement('button');
|
|
81
|
+
restoreBtn.type = 'button';
|
|
82
|
+
restoreBtn.className = 'an-btn an-asr-btn-restore';
|
|
83
|
+
restoreBtn.textContent = restoreLabel;
|
|
84
|
+
restoreBtn.addEventListener('click', () => this._restore(draftHtml));
|
|
85
|
+
|
|
86
|
+
const discardBtn = document.createElement('button');
|
|
87
|
+
discardBtn.type = 'button';
|
|
88
|
+
discardBtn.className = 'an-btn an-asr-btn-discard';
|
|
89
|
+
discardBtn.textContent = discardLabel;
|
|
90
|
+
discardBtn.addEventListener('click', () => this._discard());
|
|
91
|
+
|
|
92
|
+
banner.appendChild(msg);
|
|
93
|
+
banner.appendChild(restoreBtn);
|
|
94
|
+
banner.appendChild(discardBtn);
|
|
95
|
+
|
|
96
|
+
this._banner = banner;
|
|
97
|
+
const container = this.context.layoutInfo.container;
|
|
98
|
+
container.insertBefore(banner, container.firstChild);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_restore(draftHtml) {
|
|
102
|
+
this.context.setHTML(draftHtml);
|
|
103
|
+
this.context.clearHistory();
|
|
104
|
+
this._removeBanner();
|
|
105
|
+
|
|
106
|
+
if (typeof this.options.onAutoSaveRestore === 'function') {
|
|
107
|
+
this.options.onAutoSaveRestore(draftHtml, this.context);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
_discard() {
|
|
112
|
+
const key = this.options.autoSaveKey;
|
|
113
|
+
try {
|
|
114
|
+
localStorage.removeItem(key);
|
|
115
|
+
localStorage.removeItem(key + ':asrmeta');
|
|
116
|
+
} catch (_) {}
|
|
117
|
+
this._removeBanner();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
_removeBanner() {
|
|
121
|
+
if (this._banner && this._banner.parentNode) {
|
|
122
|
+
this._banner.parentNode.removeChild(this._banner);
|
|
123
|
+
}
|
|
124
|
+
this._banner = null;
|
|
125
|
+
}
|
|
126
|
+
}
|