lakelib 0.1.2 → 0.1.4
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/lake.css +21 -17
- package/dist/lake.min.js +22 -22
- package/dist/lake.min.js.map +1 -1
- package/lib/lake.css +21 -17
- package/lib/lake.js +1359 -1337
- package/lib/lake.js.map +1 -1
- package/lib/types/editor.d.ts +5 -1
- package/lib/types/i18n/index.d.ts +2 -2
- package/lib/types/types/dropdown.d.ts +3 -2
- package/lib/types/types/toolbar.d.ts +5 -4
- package/lib/types/ui/dropdown.d.ts +4 -1
- package/lib/types/ui/link-popup.d.ts +8 -1
- package/package.json +1 -1
package/lib/lake.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Base64 } from 'js-base64';
|
|
2
2
|
import EventEmitter from 'eventemitter3';
|
|
3
|
+
import { i18nObject as i18nObject$1 } from 'typesafe-i18n';
|
|
3
4
|
import debounce from 'lodash/debounce';
|
|
4
5
|
import isEqual from 'lodash/isEqual';
|
|
5
6
|
import md5 from 'blueimp-md5';
|
|
6
7
|
import { createKeybindingsHandler } from 'tinykeys';
|
|
7
|
-
import { i18nObject as i18nObject$1 } from 'typesafe-i18n';
|
|
8
8
|
import 'photoswipe/style.css';
|
|
9
9
|
import PhotoSwipeLightbox from 'photoswipe/lightbox';
|
|
10
10
|
import PhotoSwipe from 'photoswipe';
|
|
@@ -2862,6 +2862,7 @@ class Box {
|
|
|
2862
2862
|
container.off('mouseleave');
|
|
2863
2863
|
container.off('click');
|
|
2864
2864
|
}
|
|
2865
|
+
// fix: should not activate box when clicking box
|
|
2865
2866
|
container.on('mousedown', event => {
|
|
2866
2867
|
event.preventDefault();
|
|
2867
2868
|
});
|
|
@@ -4060,489 +4061,802 @@ class Button {
|
|
|
4060
4061
|
}
|
|
4061
4062
|
}
|
|
4062
4063
|
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
listNode.attr('title', menuItem.text);
|
|
4133
|
-
listNode.find('.lake-dropdown-menu-text').css('background-color', menuItem.value);
|
|
4134
|
-
}
|
|
4135
|
-
if (menuItem.icon) {
|
|
4136
|
-
const menuIconNode = query('<div class="lake-dropdown-menu-icon"></div>');
|
|
4137
|
-
menuIconNode.append(menuItem.icon);
|
|
4138
|
-
listNode.prepend(menuIconNode);
|
|
4139
|
-
}
|
|
4140
|
-
const checkIcon = icons.get('check');
|
|
4141
|
-
if (checkIcon) {
|
|
4142
|
-
const checkNode = query('<div class="lake-dropdown-menu-check"></div>');
|
|
4143
|
-
checkNode.append(checkIcon);
|
|
4144
|
-
listNode.prepend(checkNode);
|
|
4145
|
-
}
|
|
4146
|
-
}
|
|
4147
|
-
}
|
|
4148
|
-
showMenu() {
|
|
4149
|
-
const config = this.config;
|
|
4150
|
-
const dropdownNode = this.node;
|
|
4151
|
-
const menuNode = dropdownNode.find('.lake-dropdown-menu');
|
|
4152
|
-
if (dropdownNode.attr('disabled')) {
|
|
4153
|
-
return;
|
|
4154
|
-
}
|
|
4155
|
-
const currentValues = Dropdown.getValue(dropdownNode);
|
|
4156
|
-
menuNode.find('.lake-dropdown-menu-check').css('visibility', 'hidden');
|
|
4157
|
-
menuNode.find('li').each(node => {
|
|
4158
|
-
const listNode = query(node);
|
|
4159
|
-
listNode.on('mouseenter', () => {
|
|
4160
|
-
if (listNode.hasClass('lake-dropdown-item-selected')) {
|
|
4161
|
-
return;
|
|
4162
|
-
}
|
|
4163
|
-
listNode.addClass('lake-dropdown-item-hovered');
|
|
4164
|
-
});
|
|
4165
|
-
listNode.on('mouseleave', () => {
|
|
4166
|
-
listNode.removeClass('lake-dropdown-item-hovered');
|
|
4167
|
-
});
|
|
4168
|
-
if (currentValues.indexOf(listNode.attr('value')) >= 0) {
|
|
4169
|
-
listNode.find('.lake-dropdown-menu-check').css('visibility', 'visible');
|
|
4170
|
-
}
|
|
4171
|
-
});
|
|
4172
|
-
menuNode.css('visibility', 'hidden');
|
|
4173
|
-
menuNode.show(config.menuType === 'color' ? 'flex' : 'block');
|
|
4174
|
-
const dropdownNativeNode = dropdownNode.get(0);
|
|
4175
|
-
const dropdownRect = dropdownNativeNode.getBoundingClientRect();
|
|
4176
|
-
if (dropdownRect.x + menuNode.width() + 50 > window.innerWidth) {
|
|
4177
|
-
menuNode.css('left', 'auto');
|
|
4178
|
-
menuNode.css('right', '0');
|
|
4179
|
-
}
|
|
4180
|
-
else {
|
|
4181
|
-
menuNode.css('left', '');
|
|
4182
|
-
menuNode.css('right', '');
|
|
4183
|
-
}
|
|
4184
|
-
menuNode.css('visibility', '');
|
|
4185
|
-
document.addEventListener('click', this.documentClickListener);
|
|
4186
|
-
}
|
|
4187
|
-
bindEvents() {
|
|
4188
|
-
const config = this.config;
|
|
4189
|
-
const dropdownNode = this.node;
|
|
4190
|
-
const titleNode = dropdownNode.find('.lake-dropdown-title');
|
|
4191
|
-
const textNode = titleNode.find('.lake-dropdown-text');
|
|
4192
|
-
const iconNode = titleNode.find('.lake-dropdown-icon');
|
|
4193
|
-
const downIconNode = titleNode.find('.lake-dropdown-down-icon');
|
|
4194
|
-
const menuNode = dropdownNode.find('.lake-dropdown-menu');
|
|
4195
|
-
if (config.menuType === 'color') {
|
|
4196
|
-
iconNode.on('mouseenter', () => {
|
|
4197
|
-
if (dropdownNode.attr('disabled')) {
|
|
4198
|
-
return;
|
|
4199
|
-
}
|
|
4200
|
-
iconNode.addClass('lake-dropdown-icon-hovered');
|
|
4201
|
-
});
|
|
4202
|
-
iconNode.on('mouseleave', () => {
|
|
4203
|
-
iconNode.removeClass('lake-dropdown-icon-hovered');
|
|
4204
|
-
});
|
|
4205
|
-
downIconNode.on('mouseenter', () => {
|
|
4206
|
-
if (dropdownNode.attr('disabled')) {
|
|
4207
|
-
return;
|
|
4208
|
-
}
|
|
4209
|
-
downIconNode.addClass('lake-dropdown-down-icon-hovered');
|
|
4210
|
-
});
|
|
4211
|
-
downIconNode.on('mouseleave', () => {
|
|
4212
|
-
downIconNode.removeClass('lake-dropdown-down-icon-hovered');
|
|
4213
|
-
});
|
|
4214
|
-
}
|
|
4215
|
-
else {
|
|
4216
|
-
titleNode.on('mouseenter', () => {
|
|
4217
|
-
if (dropdownNode.attr('disabled')) {
|
|
4218
|
-
return;
|
|
4219
|
-
}
|
|
4220
|
-
titleNode.addClass('lake-dropdown-title-hovered');
|
|
4221
|
-
});
|
|
4222
|
-
titleNode.on('mouseleave', () => {
|
|
4223
|
-
titleNode.removeClass('lake-dropdown-title-hovered');
|
|
4224
|
-
});
|
|
4225
|
-
}
|
|
4226
|
-
if (config.menuType === 'color') {
|
|
4227
|
-
iconNode.on('click', event => {
|
|
4228
|
-
event.preventDefault();
|
|
4229
|
-
if (dropdownNode.attr('disabled')) {
|
|
4230
|
-
return;
|
|
4231
|
-
}
|
|
4232
|
-
const value = dropdownNode.attr('color') || config.defaultValue;
|
|
4233
|
-
config.onSelect(value);
|
|
4234
|
-
});
|
|
4235
|
-
}
|
|
4236
|
-
const triggerNode = (config.menuType === 'color' && downIconNode) ? downIconNode : titleNode;
|
|
4237
|
-
triggerNode.on('click', event => {
|
|
4238
|
-
event.preventDefault();
|
|
4239
|
-
this.showMenu();
|
|
4240
|
-
});
|
|
4241
|
-
menuNode.on('click', event => {
|
|
4242
|
-
event.preventDefault();
|
|
4243
|
-
const listItem = query(event.target).closest('li');
|
|
4244
|
-
const value = listItem.attr('value');
|
|
4245
|
-
Dropdown.setValue(dropdownNode, [value]);
|
|
4246
|
-
if (textNode.length > 0) {
|
|
4247
|
-
textNode.text(listItem.text());
|
|
4248
|
-
}
|
|
4249
|
-
if (config.menuType === 'color' && value !== '') {
|
|
4250
|
-
dropdownNode.attr('color', value);
|
|
4251
|
-
this.updateColorAccent(titleNode, value);
|
|
4252
|
-
}
|
|
4253
|
-
config.onSelect(value);
|
|
4254
|
-
menuNode.hide();
|
|
4255
|
-
document.removeEventListener('click', this.documentClickListener);
|
|
4256
|
-
});
|
|
4257
|
-
}
|
|
4258
|
-
render() {
|
|
4259
|
-
var _a;
|
|
4260
|
-
const config = this.config;
|
|
4261
|
-
const dropdownNode = this.node;
|
|
4262
|
-
const titleNode = dropdownNode.find('.lake-dropdown-title');
|
|
4263
|
-
if (!config.downIcon) {
|
|
4264
|
-
titleNode.addClass('lake-dropdown-title-no-down');
|
|
4265
|
-
}
|
|
4266
|
-
titleNode.css('width', config.width);
|
|
4267
|
-
titleNode.attr('title', config.tooltip);
|
|
4268
|
-
const textNode = titleNode.find('.lake-dropdown-text');
|
|
4269
|
-
const iconNode = titleNode.find('.lake-dropdown-icon');
|
|
4270
|
-
if (config.icon) {
|
|
4271
|
-
iconNode.append(config.icon);
|
|
4272
|
-
}
|
|
4273
|
-
if (config.accentIcon) {
|
|
4274
|
-
iconNode.append(config.accentIcon);
|
|
4275
|
-
}
|
|
4276
|
-
const downIconNode = titleNode.find('.lake-dropdown-down-icon');
|
|
4277
|
-
if (config.downIcon) {
|
|
4278
|
-
downIconNode.append(config.downIcon);
|
|
4279
|
-
}
|
|
4280
|
-
const menuNode = query('<ul class="lake-dropdown-menu" />');
|
|
4281
|
-
menuNode.addClass(`lake-${config.menuType}-dropdown-menu`);
|
|
4282
|
-
Dropdown.setValue(dropdownNode, [config.defaultValue]);
|
|
4283
|
-
if (textNode.length > 0) {
|
|
4284
|
-
const menuMap = Dropdown.getMenuMap(config.menuItems);
|
|
4285
|
-
textNode.text((_a = menuMap.get(config.defaultValue)) !== null && _a !== void 0 ? _a : config.defaultValue);
|
|
4286
|
-
}
|
|
4287
|
-
if (config.menuType === 'color') {
|
|
4288
|
-
this.updateColorAccent(titleNode, config.defaultValue);
|
|
4289
|
-
}
|
|
4290
|
-
this.apppendMenuItems(menuNode);
|
|
4291
|
-
dropdownNode.append(titleNode);
|
|
4292
|
-
dropdownNode.append(menuNode);
|
|
4293
|
-
this.root.append(dropdownNode);
|
|
4294
|
-
this.bindEvents();
|
|
4295
|
-
}
|
|
4296
|
-
unmount() {
|
|
4297
|
-
this.node.remove();
|
|
4298
|
-
document.removeEventListener('click', this.documentClickListener);
|
|
4299
|
-
}
|
|
4300
|
-
}
|
|
4301
|
-
|
|
4302
|
-
var version = "0.1.2";
|
|
4303
|
-
|
|
4304
|
-
// Inserts a box into the specified range.
|
|
4305
|
-
function insertBox(range, boxName, boxValue) {
|
|
4306
|
-
if (range.commonAncestor.isOutside) {
|
|
4307
|
-
return null;
|
|
4308
|
-
}
|
|
4309
|
-
const box = new Box(boxName);
|
|
4310
|
-
if (boxValue) {
|
|
4311
|
-
box.value = boxValue;
|
|
4312
|
-
}
|
|
4313
|
-
const fragment = document.createDocumentFragment();
|
|
4314
|
-
fragment.appendChild(box.node.get(0));
|
|
4315
|
-
// inline box
|
|
4316
|
-
if (box.type === 'inline') {
|
|
4317
|
-
insertFragment(range, fragment);
|
|
4318
|
-
box.render();
|
|
4319
|
-
range.selectBoxEnd(box.node);
|
|
4320
|
-
return box;
|
|
4321
|
-
}
|
|
4322
|
-
// block box
|
|
4323
|
-
const parts = splitBlock$1(range);
|
|
4324
|
-
if (parts.start) {
|
|
4325
|
-
range.setEndAfter(parts.start);
|
|
4326
|
-
range.collapseToEnd();
|
|
4327
|
-
}
|
|
4328
|
-
if (parts.end && parts.end.isEmpty) {
|
|
4329
|
-
parts.end.remove();
|
|
4330
|
-
}
|
|
4331
|
-
insertFragment(range, fragment);
|
|
4332
|
-
box.render();
|
|
4333
|
-
range.selectBoxEnd(box.node);
|
|
4334
|
-
if (parts.start && parts.start.isEmpty) {
|
|
4335
|
-
parts.start.remove();
|
|
4336
|
-
}
|
|
4337
|
-
return box;
|
|
4338
|
-
}
|
|
4064
|
+
var enUS = {
|
|
4065
|
+
toolbar: {
|
|
4066
|
+
undo: `Undo (${modifierText('mod+Z')})`,
|
|
4067
|
+
redo: `Redo (${modifierText('mod+Y')})`,
|
|
4068
|
+
selectAll: `Select all (${modifierText('mod+A')})`,
|
|
4069
|
+
paragraph: 'Paragraph',
|
|
4070
|
+
blockQuote: 'Block quotation',
|
|
4071
|
+
numberedList: 'Numbered list',
|
|
4072
|
+
bulletedList: 'Bulleted list',
|
|
4073
|
+
checklist: 'Checklist',
|
|
4074
|
+
alignLeft: 'Align left',
|
|
4075
|
+
alignCenter: 'Align center',
|
|
4076
|
+
alignRight: 'Align right',
|
|
4077
|
+
alignJustify: 'Align justify',
|
|
4078
|
+
increaseIndent: 'Increase indent',
|
|
4079
|
+
decreaseIndent: 'Decrease indent',
|
|
4080
|
+
bold: `Bold (${modifierText('mod+B')})`,
|
|
4081
|
+
italic: `Italic (${modifierText('mod+I')})`,
|
|
4082
|
+
underline: `Underline (${modifierText('mod+U')})`,
|
|
4083
|
+
strikethrough: 'Strikethrough',
|
|
4084
|
+
superscript: 'Superscript',
|
|
4085
|
+
subscript: 'Subscript',
|
|
4086
|
+
code: 'Inline code',
|
|
4087
|
+
removeFormat: 'Remove format',
|
|
4088
|
+
formatPainter: 'Format painter',
|
|
4089
|
+
link: 'Link',
|
|
4090
|
+
hr: 'Horizontal line',
|
|
4091
|
+
codeBlock: 'Code block',
|
|
4092
|
+
heading: 'Heading',
|
|
4093
|
+
heading1: 'Heading 1',
|
|
4094
|
+
heading2: 'Heading 2',
|
|
4095
|
+
heading3: 'Heading 3',
|
|
4096
|
+
heading4: 'Heading 4',
|
|
4097
|
+
heading5: 'Heading 5',
|
|
4098
|
+
heading6: 'Heading 6',
|
|
4099
|
+
list: 'List',
|
|
4100
|
+
align: 'Alignment',
|
|
4101
|
+
indent: 'Indent',
|
|
4102
|
+
fontFamily: 'Font family',
|
|
4103
|
+
fontSize: 'Font size',
|
|
4104
|
+
moreStyle: 'More style',
|
|
4105
|
+
fontColor: 'Font color',
|
|
4106
|
+
highlight: 'Highlight',
|
|
4107
|
+
image: 'Image',
|
|
4108
|
+
removeColor: 'Remove color',
|
|
4109
|
+
},
|
|
4110
|
+
link: {
|
|
4111
|
+
newLink: 'New link',
|
|
4112
|
+
url: 'Link URL',
|
|
4113
|
+
title: 'Link title',
|
|
4114
|
+
copy: 'Copy link to clipboard',
|
|
4115
|
+
open: 'Open link in new tab',
|
|
4116
|
+
save: 'Save',
|
|
4117
|
+
unlink: 'Remove link',
|
|
4118
|
+
},
|
|
4119
|
+
image: {
|
|
4120
|
+
view: 'Full screen',
|
|
4121
|
+
remove: 'Delete',
|
|
4122
|
+
previous: 'Previous',
|
|
4123
|
+
next: 'Next',
|
|
4124
|
+
close: 'Close (Esc)',
|
|
4125
|
+
loadingError: 'The image cannot be loaded',
|
|
4126
|
+
zoomOut: 'Zoom out',
|
|
4127
|
+
zoomIn: 'Zoom in',
|
|
4128
|
+
},
|
|
4129
|
+
codeBlock: {
|
|
4130
|
+
langType: 'Select language',
|
|
4131
|
+
},
|
|
4132
|
+
};
|
|
4339
4133
|
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4134
|
+
var zhCN = {
|
|
4135
|
+
toolbar: {
|
|
4136
|
+
undo: `撤消 (${modifierText('mod+Z')})`,
|
|
4137
|
+
redo: `重做 (${modifierText('mod+Y')})`,
|
|
4138
|
+
selectAll: `全选 (${modifierText('mod+A')})`,
|
|
4139
|
+
paragraph: '正文',
|
|
4140
|
+
blockQuote: '引用',
|
|
4141
|
+
numberedList: '编号',
|
|
4142
|
+
bulletedList: '项目符号',
|
|
4143
|
+
checklist: '任务列表',
|
|
4144
|
+
alignLeft: '左对齐',
|
|
4145
|
+
alignCenter: '居中',
|
|
4146
|
+
alignRight: '右对齐',
|
|
4147
|
+
alignJustify: '两端对齐',
|
|
4148
|
+
increaseIndent: '增加缩进',
|
|
4149
|
+
decreaseIndent: '减少缩进',
|
|
4150
|
+
bold: `粗体 (${modifierText('mod+B')})`,
|
|
4151
|
+
italic: `斜体 (${modifierText('mod+I')})`,
|
|
4152
|
+
underline: `下划线 (${modifierText('mod+U')})`,
|
|
4153
|
+
strikethrough: '删除线',
|
|
4154
|
+
superscript: '上标',
|
|
4155
|
+
subscript: '下标',
|
|
4156
|
+
code: '行内代码',
|
|
4157
|
+
removeFormat: '清除格式',
|
|
4158
|
+
formatPainter: '格式刷',
|
|
4159
|
+
link: '链接',
|
|
4160
|
+
hr: '分割线',
|
|
4161
|
+
codeBlock: '代码块',
|
|
4162
|
+
heading: '标题',
|
|
4163
|
+
heading1: '标题 1',
|
|
4164
|
+
heading2: '标题 2',
|
|
4165
|
+
heading3: '标题 3',
|
|
4166
|
+
heading4: '标题 4',
|
|
4167
|
+
heading5: '标题 5',
|
|
4168
|
+
heading6: '标题 6',
|
|
4169
|
+
list: '列表',
|
|
4170
|
+
align: '对齐方式',
|
|
4171
|
+
indent: '缩进',
|
|
4172
|
+
fontFamily: '字体',
|
|
4173
|
+
fontSize: '文字大小',
|
|
4174
|
+
moreStyle: '更多样式',
|
|
4175
|
+
fontColor: '文字颜色',
|
|
4176
|
+
highlight: '文字背景',
|
|
4177
|
+
image: '图片',
|
|
4178
|
+
removeColor: '默认',
|
|
4179
|
+
},
|
|
4180
|
+
link: {
|
|
4181
|
+
newLink: '新链接',
|
|
4182
|
+
url: '链接 URL',
|
|
4183
|
+
title: '链接文本',
|
|
4184
|
+
copy: '复制到剪贴板',
|
|
4185
|
+
open: '打开链接',
|
|
4186
|
+
save: '确定',
|
|
4187
|
+
unlink: '取消链接',
|
|
4188
|
+
},
|
|
4189
|
+
image: {
|
|
4190
|
+
view: '查看大图',
|
|
4191
|
+
remove: '删除',
|
|
4192
|
+
previous: '上一张',
|
|
4193
|
+
next: '下一张',
|
|
4194
|
+
close: '关闭 (Esc)',
|
|
4195
|
+
loadingError: '图片加载失败',
|
|
4196
|
+
zoomOut: '缩小',
|
|
4197
|
+
zoomIn: '放大',
|
|
4198
|
+
},
|
|
4199
|
+
codeBlock: {
|
|
4200
|
+
langType: '选择代码语言',
|
|
4201
|
+
},
|
|
4202
|
+
};
|
|
4368
4203
|
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4204
|
+
var ja = {
|
|
4205
|
+
toolbar: {
|
|
4206
|
+
undo: `元に戻す (${modifierText('mod+Z')})`,
|
|
4207
|
+
redo: `やり直し (${modifierText('mod+Y')})`,
|
|
4208
|
+
selectAll: `すべて選択 (${modifierText('mod+A')})`,
|
|
4209
|
+
paragraph: 'テキスト',
|
|
4210
|
+
blockQuote: 'ブロック引用',
|
|
4211
|
+
numberedList: '番号付きリスト',
|
|
4212
|
+
bulletedList: '箇条書きリスト',
|
|
4213
|
+
checklist: 'タスクリスト',
|
|
4214
|
+
alignLeft: '左揃え',
|
|
4215
|
+
alignCenter: '中心揃え',
|
|
4216
|
+
alignRight: '右揃え',
|
|
4217
|
+
alignJustify: '左右に並べ替え',
|
|
4218
|
+
increaseIndent: 'インデントを増やす',
|
|
4219
|
+
decreaseIndent: 'インデントを減らす',
|
|
4220
|
+
bold: `太字 (${modifierText('mod+B')})`,
|
|
4221
|
+
italic: `斜体 (${modifierText('mod+I')})`,
|
|
4222
|
+
underline: `下線 (${modifierText('mod+U')})`,
|
|
4223
|
+
strikethrough: '取り消し線',
|
|
4224
|
+
superscript: '上付き文字',
|
|
4225
|
+
subscript: '下付き文字',
|
|
4226
|
+
code: 'インラインコード',
|
|
4227
|
+
removeFormat: '形式を削除',
|
|
4228
|
+
formatPainter: '形式ペインタ',
|
|
4229
|
+
link: 'リンク',
|
|
4230
|
+
hr: '区切り線',
|
|
4231
|
+
codeBlock: 'コードブロック',
|
|
4232
|
+
heading: 'タイトル',
|
|
4233
|
+
heading1: 'タイトル 1',
|
|
4234
|
+
heading2: 'タイトル 2',
|
|
4235
|
+
heading3: 'タイトル 3',
|
|
4236
|
+
heading4: 'タイトル 4',
|
|
4237
|
+
heading5: 'タイトル 5',
|
|
4238
|
+
heading6: 'タイトル 6',
|
|
4239
|
+
list: 'リスト',
|
|
4240
|
+
align: '文字揃え',
|
|
4241
|
+
indent: 'インデント',
|
|
4242
|
+
fontFamily: 'フォント',
|
|
4243
|
+
fontSize: '文字サイズ',
|
|
4244
|
+
moreStyle: 'その他のスタイル',
|
|
4245
|
+
fontColor: '文字色',
|
|
4246
|
+
highlight: '文字の背景',
|
|
4247
|
+
image: '画像',
|
|
4248
|
+
removeColor: 'デフォルト',
|
|
4249
|
+
},
|
|
4250
|
+
link: {
|
|
4251
|
+
newLink: '新しいリンク',
|
|
4252
|
+
url: 'リンク URL',
|
|
4253
|
+
title: 'リンク文字',
|
|
4254
|
+
copy: 'クリップボードにコピー',
|
|
4255
|
+
open: 'リンクを開く',
|
|
4256
|
+
save: '確認',
|
|
4257
|
+
unlink: 'リンクを削除',
|
|
4258
|
+
},
|
|
4259
|
+
image: {
|
|
4260
|
+
view: '大きな画像を見る',
|
|
4261
|
+
remove: '削除',
|
|
4262
|
+
previous: '前の画像',
|
|
4263
|
+
next: '次の画像',
|
|
4264
|
+
close: '閉じる (Esc)',
|
|
4265
|
+
loadingError: '画像を読み込めません',
|
|
4266
|
+
zoomOut: '縮小',
|
|
4267
|
+
zoomIn: '拡大',
|
|
4268
|
+
},
|
|
4269
|
+
codeBlock: {
|
|
4270
|
+
langType: 'コード言語を選択',
|
|
4271
|
+
},
|
|
4272
|
+
};
|
|
4273
|
+
|
|
4274
|
+
var ko = {
|
|
4275
|
+
toolbar: {
|
|
4276
|
+
undo: `작업취소 (${modifierText('mod+Z')})`,
|
|
4277
|
+
redo: `작업재개 (${modifierText('mod+Y')})`,
|
|
4278
|
+
selectAll: `전체 선택 (${modifierText('mod+A')})`,
|
|
4279
|
+
paragraph: '텍스트',
|
|
4280
|
+
blockQuote: '인용문',
|
|
4281
|
+
numberedList: '순서 목록',
|
|
4282
|
+
bulletedList: '비순서 목록',
|
|
4283
|
+
checklist: '체크리스트',
|
|
4284
|
+
alignLeft: '왼쪽 정렬',
|
|
4285
|
+
alignCenter: '가운데 정렬',
|
|
4286
|
+
alignRight: '오른쪽 정렬',
|
|
4287
|
+
alignJustify: '좌우로 정렬',
|
|
4288
|
+
increaseIndent: '들여쓰기 증가',
|
|
4289
|
+
decreaseIndent: '들여쓰기 줄이기',
|
|
4290
|
+
bold: `굵게 (${modifierText('mod+B')})`,
|
|
4291
|
+
italic: `기울임꼴 (${modifierText('mod+I')})`,
|
|
4292
|
+
underline: `밑줄 (${modifierText('mod+U')})`,
|
|
4293
|
+
strikethrough: '취소선',
|
|
4294
|
+
superscript: '위첨자',
|
|
4295
|
+
subscript: '아래 첨자',
|
|
4296
|
+
code: '인라인 코드',
|
|
4297
|
+
removeFormat: '형식 지우기',
|
|
4298
|
+
formatPainter: '형식 페인터',
|
|
4299
|
+
link: '링크',
|
|
4300
|
+
hr: '구분선',
|
|
4301
|
+
codeBlock: '코드 블록',
|
|
4302
|
+
heading: '제목',
|
|
4303
|
+
heading1: '제목 1',
|
|
4304
|
+
heading2: '제목 2',
|
|
4305
|
+
heading3: '제목 3',
|
|
4306
|
+
heading4: '제목 4',
|
|
4307
|
+
heading5: '제목 5',
|
|
4308
|
+
heading6: '제목 6',
|
|
4309
|
+
list: '목록',
|
|
4310
|
+
align: '정렬',
|
|
4311
|
+
indent: '들여쓰기',
|
|
4312
|
+
fontFamily: '글꼴',
|
|
4313
|
+
fontSize: '글자 크기',
|
|
4314
|
+
moreStyle: '더 많은 스타일',
|
|
4315
|
+
fontColor: '글자 색상',
|
|
4316
|
+
highlight: '글자 배경',
|
|
4317
|
+
image: '이미지',
|
|
4318
|
+
removeColor: '기본색',
|
|
4319
|
+
},
|
|
4320
|
+
link: {
|
|
4321
|
+
newLink: '새 링크',
|
|
4322
|
+
url: '링크 URL',
|
|
4323
|
+
title: '링크 텍스트',
|
|
4324
|
+
copy: '클립보드에 복사',
|
|
4325
|
+
open: '링크 열기',
|
|
4326
|
+
save: '확인',
|
|
4327
|
+
unlink: '링크 제거',
|
|
4328
|
+
},
|
|
4329
|
+
image: {
|
|
4330
|
+
view: '큰 이미지 보기',
|
|
4331
|
+
remove: '삭제',
|
|
4332
|
+
previous: '이전 이미지',
|
|
4333
|
+
next: '다음 이미지',
|
|
4334
|
+
close: '닫기 (Esc)',
|
|
4335
|
+
loadingError: '이미지를 로드할 수 없습니다',
|
|
4336
|
+
zoomOut: '축소',
|
|
4337
|
+
zoomIn: '확대',
|
|
4338
|
+
},
|
|
4339
|
+
codeBlock: {
|
|
4340
|
+
langType: '코드언어 선택',
|
|
4341
|
+
},
|
|
4342
|
+
};
|
|
4343
|
+
|
|
4344
|
+
const localeTranslations = {
|
|
4345
|
+
'en-US': enUS,
|
|
4346
|
+
'zh-CN': zhCN,
|
|
4347
|
+
ja,
|
|
4348
|
+
ko,
|
|
4349
|
+
};
|
|
4350
|
+
const locales = Object.keys(localeTranslations);
|
|
4351
|
+
const loadedLocales = {};
|
|
4352
|
+
const loadedFormatters = {};
|
|
4353
|
+
const initFormatters = () => {
|
|
4354
|
+
const formatters = {
|
|
4355
|
+
// add your formatter functions here
|
|
4356
|
+
};
|
|
4357
|
+
return formatters;
|
|
4358
|
+
};
|
|
4359
|
+
const loadFormatters = (locale) => {
|
|
4360
|
+
loadedFormatters[locale] = initFormatters();
|
|
4361
|
+
};
|
|
4362
|
+
const loadLocale = (locale) => {
|
|
4363
|
+
if (loadedLocales[locale]) {
|
|
4364
|
+
return;
|
|
4455
4365
|
}
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4366
|
+
loadedLocales[locale] = localeTranslations[locale];
|
|
4367
|
+
loadFormatters(locale);
|
|
4368
|
+
};
|
|
4369
|
+
const loadAllLocales = () => locales.forEach(loadLocale);
|
|
4370
|
+
const i18nObject = (locale) => i18nObject$1(locale, loadedLocales[locale], loadedFormatters[locale]);
|
|
4371
|
+
loadAllLocales();
|
|
4372
|
+
|
|
4373
|
+
class Dropdown {
|
|
4374
|
+
constructor(config) {
|
|
4375
|
+
this.documentClickListener = (event) => {
|
|
4376
|
+
const targetNode = new Nodes(event.target);
|
|
4377
|
+
const titleNode = this.node.find('.lake-dropdown-title');
|
|
4378
|
+
const menuNode = this.node.find('.lake-dropdown-menu');
|
|
4379
|
+
if (targetNode.closest('.lake-dropdown-title').get(0) === titleNode.get(0)) {
|
|
4380
|
+
return;
|
|
4381
|
+
}
|
|
4382
|
+
menuNode.hide();
|
|
4383
|
+
document.removeEventListener('click', this.documentClickListener);
|
|
4384
|
+
};
|
|
4385
|
+
this.config = config;
|
|
4386
|
+
this.root = config.root;
|
|
4387
|
+
this.locale = config.locale || i18nObject('en-US');
|
|
4388
|
+
this.node = query(safeTemplate `
|
|
4389
|
+
<div class="lake-dropdown lake-${config.menuType}-dropdown" name="${config.name}">
|
|
4390
|
+
<button type="button" name="${config.name}" class="lake-dropdown-title">
|
|
4391
|
+
<div class="lake-dropdown-${config.icon ? 'icon' : 'text'}"></div>
|
|
4392
|
+
<div class="lake-dropdown-down-icon"></div>
|
|
4393
|
+
</button>
|
|
4394
|
+
</div>
|
|
4395
|
+
`);
|
|
4396
|
+
if (config.tabIndex !== undefined) {
|
|
4397
|
+
const titleNode = this.node.find('.lake-dropdown-title');
|
|
4398
|
+
titleNode.attr('tabindex', config.tabIndex.toString());
|
|
4461
4399
|
}
|
|
4462
|
-
this.range = newRange;
|
|
4463
4400
|
}
|
|
4464
|
-
//
|
|
4465
|
-
|
|
4466
|
-
const
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
if (boxFocus.length > 0) {
|
|
4470
|
-
toBookmark(range, {
|
|
4471
|
-
anchor: new Nodes(),
|
|
4472
|
-
focus: boxFocus,
|
|
4473
|
-
});
|
|
4474
|
-
this.addRangeToNativeSelection();
|
|
4475
|
-
return;
|
|
4401
|
+
// Returns the value of the node.
|
|
4402
|
+
static getValue(node) {
|
|
4403
|
+
const value = node.attr('value');
|
|
4404
|
+
if (value === '') {
|
|
4405
|
+
return [];
|
|
4476
4406
|
}
|
|
4477
|
-
|
|
4478
|
-
const focus = container.find('lake-bookmark[type="focus"]');
|
|
4479
|
-
toBookmark(range, {
|
|
4480
|
-
anchor,
|
|
4481
|
-
focus,
|
|
4482
|
-
});
|
|
4483
|
-
this.addRangeToNativeSelection();
|
|
4484
|
-
}
|
|
4485
|
-
getAppliedItems() {
|
|
4486
|
-
const appliedItems = [];
|
|
4487
|
-
pushAncestralNodes(appliedItems, this.range);
|
|
4488
|
-
pushNextNestedNodes(appliedItems, this.range);
|
|
4489
|
-
return appliedItems;
|
|
4407
|
+
return JSON.parse(Base64.decode(value));
|
|
4490
4408
|
}
|
|
4491
|
-
|
|
4492
|
-
|
|
4409
|
+
// Updates the value of the node.
|
|
4410
|
+
static setValue(node, value) {
|
|
4411
|
+
node.attr('value', Base64.encode(JSON.stringify(value)));
|
|
4493
4412
|
}
|
|
4494
|
-
|
|
4495
|
-
|
|
4413
|
+
static getMenuMap(menuItems, locale) {
|
|
4414
|
+
const menuMap = new Map();
|
|
4415
|
+
for (const menuItem of menuItems) {
|
|
4416
|
+
// remove HTML tags
|
|
4417
|
+
let text = typeof menuItem.text === 'string' ? menuItem.text : menuItem.text(locale);
|
|
4418
|
+
text = text.replace(/<[^>]*>/g, '');
|
|
4419
|
+
menuMap.set(menuItem.value, text);
|
|
4420
|
+
}
|
|
4421
|
+
return menuMap;
|
|
4496
4422
|
}
|
|
4497
|
-
|
|
4498
|
-
|
|
4423
|
+
updateColorAccent(titleNode, value) {
|
|
4424
|
+
const svgNode = titleNode.find('.lake-dropdown-icon svg').eq(1);
|
|
4425
|
+
const lineNode = svgNode.find('line');
|
|
4426
|
+
if (lineNode.length > 0) {
|
|
4427
|
+
lineNode.attr('stroke', value);
|
|
4428
|
+
}
|
|
4429
|
+
else {
|
|
4430
|
+
svgNode.find('path').attr('fill', value);
|
|
4431
|
+
}
|
|
4499
4432
|
}
|
|
4500
|
-
|
|
4501
|
-
|
|
4433
|
+
apppendMenuItems(menuNode) {
|
|
4434
|
+
const config = this.config;
|
|
4435
|
+
for (const menuItem of config.menuItems) {
|
|
4436
|
+
const menuText = typeof menuItem.text === 'string' ? menuItem.text : menuItem.text(this.locale);
|
|
4437
|
+
const listContent = template `
|
|
4438
|
+
<li value="${encode(menuItem.value)}">
|
|
4439
|
+
<div class="lake-dropdown-menu-text">${menuText}</div>
|
|
4440
|
+
</li>
|
|
4441
|
+
`;
|
|
4442
|
+
const listNode = query(listContent);
|
|
4443
|
+
menuNode.append(listNode);
|
|
4444
|
+
if (config.menuType === 'color') {
|
|
4445
|
+
listNode.attr('title', menuText);
|
|
4446
|
+
listNode.find('.lake-dropdown-menu-text').css('background-color', menuItem.value);
|
|
4447
|
+
}
|
|
4448
|
+
if (menuItem.icon) {
|
|
4449
|
+
const menuIconNode = query('<div class="lake-dropdown-menu-icon"></div>');
|
|
4450
|
+
menuIconNode.append(menuItem.icon);
|
|
4451
|
+
listNode.prepend(menuIconNode);
|
|
4452
|
+
}
|
|
4453
|
+
const checkIcon = icons.get('check');
|
|
4454
|
+
if (checkIcon) {
|
|
4455
|
+
const checkNode = query('<div class="lake-dropdown-menu-check"></div>');
|
|
4456
|
+
checkNode.append(checkIcon);
|
|
4457
|
+
listNode.prepend(checkNode);
|
|
4458
|
+
}
|
|
4459
|
+
}
|
|
4502
4460
|
}
|
|
4503
|
-
|
|
4504
|
-
|
|
4461
|
+
showMenu() {
|
|
4462
|
+
const config = this.config;
|
|
4463
|
+
const dropdownNode = this.node;
|
|
4464
|
+
const menuNode = dropdownNode.find('.lake-dropdown-menu');
|
|
4465
|
+
if (dropdownNode.attr('disabled')) {
|
|
4466
|
+
return;
|
|
4467
|
+
}
|
|
4468
|
+
const currentValues = Dropdown.getValue(dropdownNode);
|
|
4469
|
+
menuNode.find('.lake-dropdown-menu-check').css('visibility', 'hidden');
|
|
4470
|
+
menuNode.find('li').each(node => {
|
|
4471
|
+
const listNode = query(node);
|
|
4472
|
+
listNode.on('mouseenter', () => {
|
|
4473
|
+
if (listNode.hasClass('lake-dropdown-item-selected')) {
|
|
4474
|
+
return;
|
|
4475
|
+
}
|
|
4476
|
+
listNode.addClass('lake-dropdown-item-hovered');
|
|
4477
|
+
});
|
|
4478
|
+
listNode.on('mouseleave', () => {
|
|
4479
|
+
listNode.removeClass('lake-dropdown-item-hovered');
|
|
4480
|
+
});
|
|
4481
|
+
if (currentValues.indexOf(listNode.attr('value')) >= 0) {
|
|
4482
|
+
listNode.find('.lake-dropdown-menu-check').css('visibility', 'visible');
|
|
4483
|
+
}
|
|
4484
|
+
});
|
|
4485
|
+
menuNode.css('visibility', 'hidden');
|
|
4486
|
+
menuNode.show(config.menuType === 'color' ? 'flex' : 'block');
|
|
4487
|
+
const dropdownNativeNode = dropdownNode.get(0);
|
|
4488
|
+
const dropdownRect = dropdownNativeNode.getBoundingClientRect();
|
|
4489
|
+
if (dropdownRect.x + menuNode.width() + 50 > window.innerWidth) {
|
|
4490
|
+
menuNode.css('left', 'auto');
|
|
4491
|
+
menuNode.css('right', '0');
|
|
4492
|
+
}
|
|
4493
|
+
else {
|
|
4494
|
+
menuNode.css('left', '');
|
|
4495
|
+
menuNode.css('right', '');
|
|
4496
|
+
}
|
|
4497
|
+
menuNode.css('visibility', '');
|
|
4498
|
+
document.addEventListener('click', this.documentClickListener);
|
|
4505
4499
|
}
|
|
4506
|
-
|
|
4507
|
-
|
|
4500
|
+
bindEvents() {
|
|
4501
|
+
const config = this.config;
|
|
4502
|
+
const dropdownNode = this.node;
|
|
4503
|
+
const titleNode = dropdownNode.find('.lake-dropdown-title');
|
|
4504
|
+
const textNode = titleNode.find('.lake-dropdown-text');
|
|
4505
|
+
const iconNode = titleNode.find('.lake-dropdown-icon');
|
|
4506
|
+
const downIconNode = titleNode.find('.lake-dropdown-down-icon');
|
|
4507
|
+
const menuNode = dropdownNode.find('.lake-dropdown-menu');
|
|
4508
|
+
if (config.menuType === 'color') {
|
|
4509
|
+
iconNode.on('mouseenter', () => {
|
|
4510
|
+
if (dropdownNode.attr('disabled')) {
|
|
4511
|
+
return;
|
|
4512
|
+
}
|
|
4513
|
+
iconNode.addClass('lake-dropdown-icon-hovered');
|
|
4514
|
+
});
|
|
4515
|
+
iconNode.on('mouseleave', () => {
|
|
4516
|
+
iconNode.removeClass('lake-dropdown-icon-hovered');
|
|
4517
|
+
});
|
|
4518
|
+
downIconNode.on('mouseenter', () => {
|
|
4519
|
+
if (dropdownNode.attr('disabled')) {
|
|
4520
|
+
return;
|
|
4521
|
+
}
|
|
4522
|
+
downIconNode.addClass('lake-dropdown-down-icon-hovered');
|
|
4523
|
+
});
|
|
4524
|
+
downIconNode.on('mouseleave', () => {
|
|
4525
|
+
downIconNode.removeClass('lake-dropdown-down-icon-hovered');
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
else {
|
|
4529
|
+
titleNode.on('mouseenter', () => {
|
|
4530
|
+
if (dropdownNode.attr('disabled')) {
|
|
4531
|
+
return;
|
|
4532
|
+
}
|
|
4533
|
+
titleNode.addClass('lake-dropdown-title-hovered');
|
|
4534
|
+
});
|
|
4535
|
+
titleNode.on('mouseleave', () => {
|
|
4536
|
+
titleNode.removeClass('lake-dropdown-title-hovered');
|
|
4537
|
+
});
|
|
4538
|
+
}
|
|
4539
|
+
if (config.menuType === 'color') {
|
|
4540
|
+
iconNode.on('click', event => {
|
|
4541
|
+
event.preventDefault();
|
|
4542
|
+
if (dropdownNode.attr('disabled')) {
|
|
4543
|
+
return;
|
|
4544
|
+
}
|
|
4545
|
+
const value = dropdownNode.attr('color') || config.defaultValue;
|
|
4546
|
+
config.onSelect(value);
|
|
4547
|
+
});
|
|
4548
|
+
}
|
|
4549
|
+
const triggerNode = (config.menuType === 'color' && downIconNode) ? downIconNode : titleNode;
|
|
4550
|
+
triggerNode.on('click', event => {
|
|
4551
|
+
event.preventDefault();
|
|
4552
|
+
this.showMenu();
|
|
4553
|
+
});
|
|
4554
|
+
menuNode.on('click', event => {
|
|
4555
|
+
event.preventDefault();
|
|
4556
|
+
const listItem = query(event.target).closest('li');
|
|
4557
|
+
const value = listItem.attr('value');
|
|
4558
|
+
Dropdown.setValue(dropdownNode, [value]);
|
|
4559
|
+
if (textNode.length > 0) {
|
|
4560
|
+
textNode.text(listItem.text());
|
|
4561
|
+
}
|
|
4562
|
+
if (config.menuType === 'color' && value !== '') {
|
|
4563
|
+
dropdownNode.attr('color', value);
|
|
4564
|
+
this.updateColorAccent(titleNode, value);
|
|
4565
|
+
}
|
|
4566
|
+
config.onSelect(value);
|
|
4567
|
+
menuNode.hide();
|
|
4568
|
+
document.removeEventListener('click', this.documentClickListener);
|
|
4569
|
+
});
|
|
4508
4570
|
}
|
|
4509
|
-
|
|
4510
|
-
|
|
4571
|
+
render() {
|
|
4572
|
+
var _a;
|
|
4573
|
+
const config = this.config;
|
|
4574
|
+
const dropdownNode = this.node;
|
|
4575
|
+
const titleNode = dropdownNode.find('.lake-dropdown-title');
|
|
4576
|
+
if (!config.downIcon) {
|
|
4577
|
+
titleNode.addClass('lake-dropdown-title-no-down');
|
|
4578
|
+
}
|
|
4579
|
+
titleNode.css('width', config.width);
|
|
4580
|
+
const tooltip = typeof config.tooltip === 'string' ? config.tooltip : config.tooltip(this.locale);
|
|
4581
|
+
titleNode.attr('title', tooltip);
|
|
4582
|
+
const textNode = titleNode.find('.lake-dropdown-text');
|
|
4583
|
+
const iconNode = titleNode.find('.lake-dropdown-icon');
|
|
4584
|
+
if (config.icon) {
|
|
4585
|
+
iconNode.append(config.icon);
|
|
4586
|
+
}
|
|
4587
|
+
if (config.accentIcon) {
|
|
4588
|
+
iconNode.append(config.accentIcon);
|
|
4589
|
+
}
|
|
4590
|
+
const downIconNode = titleNode.find('.lake-dropdown-down-icon');
|
|
4591
|
+
if (config.downIcon) {
|
|
4592
|
+
downIconNode.append(config.downIcon);
|
|
4593
|
+
}
|
|
4594
|
+
const menuNode = query('<ul class="lake-dropdown-menu" />');
|
|
4595
|
+
menuNode.addClass(`lake-${config.menuType}-dropdown-menu`);
|
|
4596
|
+
Dropdown.setValue(dropdownNode, [config.defaultValue]);
|
|
4597
|
+
if (textNode.length > 0) {
|
|
4598
|
+
const menuMap = Dropdown.getMenuMap(config.menuItems, this.locale);
|
|
4599
|
+
textNode.text((_a = menuMap.get(config.defaultValue)) !== null && _a !== void 0 ? _a : config.defaultValue);
|
|
4600
|
+
}
|
|
4601
|
+
if (config.menuType === 'color') {
|
|
4602
|
+
this.updateColorAccent(titleNode, config.defaultValue);
|
|
4603
|
+
}
|
|
4604
|
+
this.apppendMenuItems(menuNode);
|
|
4605
|
+
dropdownNode.append(titleNode);
|
|
4606
|
+
dropdownNode.append(menuNode);
|
|
4607
|
+
this.root.append(dropdownNode);
|
|
4608
|
+
this.bindEvents();
|
|
4511
4609
|
}
|
|
4512
|
-
|
|
4513
|
-
|
|
4610
|
+
unmount() {
|
|
4611
|
+
this.node.remove();
|
|
4612
|
+
document.removeEventListener('click', this.documentClickListener);
|
|
4514
4613
|
}
|
|
4515
|
-
|
|
4516
|
-
|
|
4614
|
+
}
|
|
4615
|
+
|
|
4616
|
+
var version = "0.1.4";
|
|
4617
|
+
|
|
4618
|
+
// Inserts a box into the specified range.
|
|
4619
|
+
function insertBox(range, boxName, boxValue) {
|
|
4620
|
+
if (range.commonAncestor.isOutside) {
|
|
4621
|
+
return null;
|
|
4517
4622
|
}
|
|
4518
|
-
|
|
4519
|
-
|
|
4623
|
+
const box = new Box(boxName);
|
|
4624
|
+
if (boxValue) {
|
|
4625
|
+
box.value = boxValue;
|
|
4520
4626
|
}
|
|
4521
|
-
|
|
4522
|
-
|
|
4627
|
+
const fragment = document.createDocumentFragment();
|
|
4628
|
+
fragment.appendChild(box.node.get(0));
|
|
4629
|
+
// inline box
|
|
4630
|
+
if (box.type === 'inline') {
|
|
4631
|
+
insertFragment(range, fragment);
|
|
4632
|
+
box.render();
|
|
4633
|
+
range.selectBoxEnd(box.node);
|
|
4634
|
+
return box;
|
|
4523
4635
|
}
|
|
4524
|
-
|
|
4525
|
-
|
|
4636
|
+
// block box
|
|
4637
|
+
const parts = splitBlock$1(range);
|
|
4638
|
+
if (parts.start) {
|
|
4639
|
+
range.setEndAfter(parts.start);
|
|
4640
|
+
range.collapseToEnd();
|
|
4526
4641
|
}
|
|
4527
|
-
|
|
4528
|
-
|
|
4642
|
+
if (parts.end && parts.end.isEmpty) {
|
|
4643
|
+
parts.end.remove();
|
|
4529
4644
|
}
|
|
4645
|
+
insertFragment(range, fragment);
|
|
4646
|
+
box.render();
|
|
4647
|
+
range.selectBoxEnd(box.node);
|
|
4648
|
+
if (parts.start && parts.start.isEmpty) {
|
|
4649
|
+
parts.start.remove();
|
|
4650
|
+
}
|
|
4651
|
+
return box;
|
|
4530
4652
|
}
|
|
4531
4653
|
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
this.event = new EventEmitter();
|
|
4536
|
-
this.selection = selection;
|
|
4654
|
+
function removeBox(range) {
|
|
4655
|
+
if (range.commonAncestor.isOutside) {
|
|
4656
|
+
return null;
|
|
4537
4657
|
}
|
|
4538
|
-
|
|
4539
|
-
|
|
4658
|
+
const boxNode = range.commonAncestor.closest('lake-box');
|
|
4659
|
+
if (boxNode.length === 0) {
|
|
4660
|
+
return null;
|
|
4540
4661
|
}
|
|
4541
|
-
|
|
4542
|
-
|
|
4662
|
+
const box = new Box(boxNode);
|
|
4663
|
+
if (box.type === 'block') {
|
|
4664
|
+
const paragraph = query('<p><br /></p>');
|
|
4665
|
+
boxNode.before(paragraph);
|
|
4666
|
+
range.shrinkAfter(paragraph);
|
|
4667
|
+
box.unmount();
|
|
4668
|
+
boxNode.remove();
|
|
4669
|
+
return box;
|
|
4543
4670
|
}
|
|
4544
|
-
|
|
4545
|
-
|
|
4671
|
+
range.setStartBefore(boxNode);
|
|
4672
|
+
range.collapseToStart();
|
|
4673
|
+
const parentNode = boxNode.parent();
|
|
4674
|
+
box.unmount();
|
|
4675
|
+
boxNode.remove();
|
|
4676
|
+
if (parentNode.isEmpty) {
|
|
4677
|
+
appendDeepest(parentNode, query('<br />'));
|
|
4678
|
+
range.shrinkAfter(parentNode);
|
|
4679
|
+
}
|
|
4680
|
+
return box;
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4683
|
+
// Returns the attributes of the element as an key-value object.
|
|
4684
|
+
function getAttributes(node) {
|
|
4685
|
+
const nativeNode = node.get(0);
|
|
4686
|
+
const attributes = {};
|
|
4687
|
+
if (nativeNode.hasAttributes()) {
|
|
4688
|
+
for (const attr of nativeNode.attributes) {
|
|
4689
|
+
attributes[attr.name] = attr.value;
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
return attributes;
|
|
4693
|
+
}
|
|
4694
|
+
function pushAncestralNodes(appliedItems, range) {
|
|
4695
|
+
let parentNode = range.startNode;
|
|
4696
|
+
if (parentNode.isText) {
|
|
4697
|
+
parentNode = parentNode.parent();
|
|
4698
|
+
}
|
|
4699
|
+
while (parentNode.length > 0) {
|
|
4700
|
+
if (!parentNode.isInside) {
|
|
4701
|
+
break;
|
|
4702
|
+
}
|
|
4703
|
+
appliedItems.push({
|
|
4704
|
+
node: parentNode,
|
|
4705
|
+
name: parentNode.name,
|
|
4706
|
+
attributes: getAttributes(parentNode),
|
|
4707
|
+
styles: parseStyle(parentNode.attr('style')),
|
|
4708
|
+
});
|
|
4709
|
+
parentNode = parentNode.parent();
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
function pushNextNestedNodes(appliedItems, range) {
|
|
4713
|
+
const startNode = range.startNode;
|
|
4714
|
+
let nextNode;
|
|
4715
|
+
if (startNode.isText && startNode.text().length === range.startOffset) {
|
|
4716
|
+
const node = startNode.next();
|
|
4717
|
+
if (node.length > 0 && node.isElement) {
|
|
4718
|
+
nextNode = node;
|
|
4719
|
+
}
|
|
4720
|
+
}
|
|
4721
|
+
if (startNode.isElement) {
|
|
4722
|
+
const children = startNode.children();
|
|
4723
|
+
if (children.length > 0) {
|
|
4724
|
+
const node = children[range.startOffset];
|
|
4725
|
+
if (node && node.isElement) {
|
|
4726
|
+
nextNode = node;
|
|
4727
|
+
}
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
if (nextNode) {
|
|
4731
|
+
let child = nextNode;
|
|
4732
|
+
while (child.length > 0) {
|
|
4733
|
+
if (child.isElement) {
|
|
4734
|
+
appliedItems.push({
|
|
4735
|
+
node: child,
|
|
4736
|
+
name: child.name,
|
|
4737
|
+
attributes: getAttributes(child),
|
|
4738
|
+
styles: parseStyle(child.attr('style')),
|
|
4739
|
+
});
|
|
4740
|
+
}
|
|
4741
|
+
child = child.first();
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
class Selection {
|
|
4746
|
+
constructor(container) {
|
|
4747
|
+
const selection = window.getSelection();
|
|
4748
|
+
// When called on an <iframe> that is not displayed (e.g., where 'display: none' is set) Firefox will return null,
|
|
4749
|
+
// whereas other browsers will return a selection object with Selection.type set to None.
|
|
4750
|
+
if (!selection) {
|
|
4751
|
+
throw new Error('Selection object is null.');
|
|
4752
|
+
}
|
|
4753
|
+
this.selection = selection;
|
|
4754
|
+
this.container = container;
|
|
4755
|
+
this.range = this.getRangeFromNativeSelection();
|
|
4756
|
+
}
|
|
4757
|
+
// Returns the current selected range from the native selection.
|
|
4758
|
+
getRangeFromNativeSelection() {
|
|
4759
|
+
if (this.selection.rangeCount > 0) {
|
|
4760
|
+
const range = this.selection.getRangeAt(0);
|
|
4761
|
+
return new Range(range);
|
|
4762
|
+
}
|
|
4763
|
+
return new Range();
|
|
4764
|
+
}
|
|
4765
|
+
// Adds the saved range to the native selection.
|
|
4766
|
+
addRangeToNativeSelection() {
|
|
4767
|
+
this.selection.removeAllRanges();
|
|
4768
|
+
this.selection.addRange(this.range.get());
|
|
4769
|
+
}
|
|
4770
|
+
// Synchronizes the saved range with the range of the native selection.
|
|
4771
|
+
syncByRange() {
|
|
4772
|
+
const newRange = this.getRangeFromNativeSelection();
|
|
4773
|
+
if (this.range.get() === newRange.get()) {
|
|
4774
|
+
return;
|
|
4775
|
+
}
|
|
4776
|
+
this.range = newRange;
|
|
4777
|
+
}
|
|
4778
|
+
// Synchronizes the saved range with the range represented by the bookmark.
|
|
4779
|
+
synByBookmark() {
|
|
4780
|
+
const range = this.range;
|
|
4781
|
+
const container = this.container;
|
|
4782
|
+
const boxFocus = container.find('lake-box[focus]');
|
|
4783
|
+
if (boxFocus.length > 0) {
|
|
4784
|
+
toBookmark(range, {
|
|
4785
|
+
anchor: new Nodes(),
|
|
4786
|
+
focus: boxFocus,
|
|
4787
|
+
});
|
|
4788
|
+
this.addRangeToNativeSelection();
|
|
4789
|
+
return;
|
|
4790
|
+
}
|
|
4791
|
+
const anchor = container.find('lake-bookmark[type="anchor"]');
|
|
4792
|
+
const focus = container.find('lake-bookmark[type="focus"]');
|
|
4793
|
+
toBookmark(range, {
|
|
4794
|
+
anchor,
|
|
4795
|
+
focus,
|
|
4796
|
+
});
|
|
4797
|
+
this.addRangeToNativeSelection();
|
|
4798
|
+
}
|
|
4799
|
+
getAppliedItems() {
|
|
4800
|
+
const appliedItems = [];
|
|
4801
|
+
pushAncestralNodes(appliedItems, this.range);
|
|
4802
|
+
pushNextNestedNodes(appliedItems, this.range);
|
|
4803
|
+
return appliedItems;
|
|
4804
|
+
}
|
|
4805
|
+
insertBookmark() {
|
|
4806
|
+
return insertBookmark(this.range);
|
|
4807
|
+
}
|
|
4808
|
+
toBookmark(bookmark) {
|
|
4809
|
+
return toBookmark(this.range, bookmark);
|
|
4810
|
+
}
|
|
4811
|
+
insertNode(node) {
|
|
4812
|
+
return insertNode(this.range, node);
|
|
4813
|
+
}
|
|
4814
|
+
insertFragment(fragment) {
|
|
4815
|
+
return insertFragment(this.range, fragment);
|
|
4816
|
+
}
|
|
4817
|
+
insertContents(value) {
|
|
4818
|
+
return insertContents(this.range, value);
|
|
4819
|
+
}
|
|
4820
|
+
deleteContents() {
|
|
4821
|
+
return deleteContents(this.range);
|
|
4822
|
+
}
|
|
4823
|
+
setBlocks(value) {
|
|
4824
|
+
return setBlocks(this.range, value);
|
|
4825
|
+
}
|
|
4826
|
+
splitBlock() {
|
|
4827
|
+
return splitBlock$1(this.range);
|
|
4828
|
+
}
|
|
4829
|
+
splitMarks(removeEmptyMark) {
|
|
4830
|
+
return splitMarks(this.range, removeEmptyMark);
|
|
4831
|
+
}
|
|
4832
|
+
addMark(value) {
|
|
4833
|
+
return addMark(this.range, value);
|
|
4834
|
+
}
|
|
4835
|
+
removeMark(value) {
|
|
4836
|
+
return removeMark(this.range, value);
|
|
4837
|
+
}
|
|
4838
|
+
fixList() {
|
|
4839
|
+
return fixList(this.range);
|
|
4840
|
+
}
|
|
4841
|
+
insertLink(value) {
|
|
4842
|
+
return insertLink(this.range, value);
|
|
4843
|
+
}
|
|
4844
|
+
}
|
|
4845
|
+
|
|
4846
|
+
class Command {
|
|
4847
|
+
constructor(selection) {
|
|
4848
|
+
this.commandMap = new Map();
|
|
4849
|
+
this.event = new EventEmitter();
|
|
4850
|
+
this.selection = selection;
|
|
4851
|
+
}
|
|
4852
|
+
add(name, commandItem) {
|
|
4853
|
+
this.commandMap.set(name, commandItem);
|
|
4854
|
+
}
|
|
4855
|
+
delete(name) {
|
|
4856
|
+
this.commandMap.delete(name);
|
|
4857
|
+
}
|
|
4858
|
+
getNames() {
|
|
4859
|
+
return Array.from(this.commandMap.keys());
|
|
4546
4860
|
}
|
|
4547
4861
|
has(name) {
|
|
4548
4862
|
return this.commandMap.get(name) !== undefined;
|
|
@@ -4825,880 +5139,573 @@ class Keystroke {
|
|
|
4825
5139
|
// Executes the keyup shortcuts.
|
|
4826
5140
|
keyup(type) {
|
|
4827
5141
|
type = this.normalizeType(type);
|
|
4828
|
-
for (const item of this.keyupEventList) {
|
|
4829
|
-
if (item.type === type) {
|
|
4830
|
-
if (item.listener(new Event(type)) === false) {
|
|
4831
|
-
break;
|
|
4832
|
-
}
|
|
4833
|
-
}
|
|
4834
|
-
}
|
|
4835
|
-
}
|
|
4836
|
-
}
|
|
4837
|
-
|
|
4838
|
-
class BoxManager {
|
|
4839
|
-
add(component) {
|
|
4840
|
-
boxes.set(component.name, component);
|
|
4841
|
-
}
|
|
4842
|
-
remove(name) {
|
|
4843
|
-
boxes.delete(name);
|
|
4844
|
-
}
|
|
4845
|
-
getNames() {
|
|
4846
|
-
return Array.from(boxes.keys());
|
|
4847
|
-
}
|
|
4848
|
-
getInstances(editor) {
|
|
4849
|
-
let instanceMap = boxInstances.get(editor.container.id);
|
|
4850
|
-
if (!instanceMap) {
|
|
4851
|
-
instanceMap = new Map();
|
|
4852
|
-
boxInstances.set(editor.container.id, instanceMap);
|
|
4853
|
-
return instanceMap;
|
|
4854
|
-
}
|
|
4855
|
-
return instanceMap;
|
|
4856
|
-
}
|
|
4857
|
-
rectifyInstances(editor) {
|
|
4858
|
-
const instanceMap = this.getInstances(editor);
|
|
4859
|
-
for (const box of instanceMap.values()) {
|
|
4860
|
-
if (!box.node.get(0).isConnected) {
|
|
4861
|
-
box.unmount();
|
|
4862
|
-
instanceMap.delete(box.node.id);
|
|
4863
|
-
}
|
|
4864
|
-
}
|
|
4865
|
-
}
|
|
4866
|
-
findAll(editor) {
|
|
4867
|
-
return editor.container.find('lake-box');
|
|
4868
|
-
}
|
|
4869
|
-
renderAll(editor) {
|
|
4870
|
-
this.rectifyInstances(editor);
|
|
4871
|
-
const instanceMap = this.getInstances(editor);
|
|
4872
|
-
this.findAll(editor).each(boxNativeNode => {
|
|
4873
|
-
const boxNode = new Nodes(boxNativeNode);
|
|
4874
|
-
if (instanceMap.get(boxNode.id)) {
|
|
4875
|
-
return;
|
|
4876
|
-
}
|
|
4877
|
-
const box = new Box(boxNode);
|
|
4878
|
-
box.render();
|
|
4879
|
-
instanceMap.set(box.node.id, box);
|
|
4880
|
-
});
|
|
4881
|
-
}
|
|
4882
|
-
}
|
|
4883
|
-
|
|
4884
|
-
class Plugin {
|
|
4885
|
-
constructor() {
|
|
4886
|
-
this.pluginList = [];
|
|
4887
|
-
}
|
|
4888
|
-
add(plugin) {
|
|
4889
|
-
this.pluginList.push(plugin);
|
|
4890
|
-
}
|
|
4891
|
-
loadAll(editor) {
|
|
4892
|
-
this.pluginList.forEach(plugin => {
|
|
4893
|
-
plugin(editor);
|
|
4894
|
-
});
|
|
4895
|
-
}
|
|
4896
|
-
}
|
|
4897
|
-
|
|
4898
|
-
const defaultConfig = {
|
|
4899
|
-
value: '<p><br /><focus /></p>',
|
|
4900
|
-
readonly: false,
|
|
4901
|
-
spellcheck: false,
|
|
4902
|
-
tabIndex: 0,
|
|
4903
|
-
indentWithTab: true,
|
|
4904
|
-
minChangeSize: 5,
|
|
4905
|
-
};
|
|
4906
|
-
class Editor {
|
|
4907
|
-
constructor(config) {
|
|
4908
|
-
this.unsavedInputData = '';
|
|
4909
|
-
this.stateData = {
|
|
4910
|
-
appliedItems: [],
|
|
4911
|
-
disabledNameMap: new Map(),
|
|
4912
|
-
selectedNameMap: new Map(),
|
|
4913
|
-
selectedValuesMap: new Map(),
|
|
4914
|
-
};
|
|
4915
|
-
this.isComposing = false;
|
|
4916
|
-
this.event = new EventEmitter();
|
|
4917
|
-
this.box = Editor.box;
|
|
4918
|
-
this.beforeunloadListener = () => {
|
|
4919
|
-
this.history.save();
|
|
4920
|
-
};
|
|
4921
|
-
this.selectionchangeListener = () => {
|
|
4922
|
-
this.selection.syncByRange();
|
|
4923
|
-
this.updateBoxSelectionStyle();
|
|
4924
|
-
this.emitStateChangeEvent();
|
|
4925
|
-
};
|
|
4926
|
-
this.clickListener = event => {
|
|
4927
|
-
const targetNode = new Nodes(event.target);
|
|
4928
|
-
if (targetNode.closest('.lake-popup').length > 0) {
|
|
4929
|
-
return;
|
|
4930
|
-
}
|
|
4931
|
-
this.event.emit('click', targetNode);
|
|
4932
|
-
};
|
|
4933
|
-
this.resizeListener = () => {
|
|
4934
|
-
this.event.emit('resize');
|
|
4935
|
-
};
|
|
4936
|
-
this.updateBoxSelectionStyle = debounce(() => {
|
|
4937
|
-
// The editor has been unmounted.
|
|
4938
|
-
if (this.root.first().length === 0) {
|
|
4939
|
-
return;
|
|
4940
|
-
}
|
|
4941
|
-
const range = this.selection.range;
|
|
4942
|
-
const clonedRange = range.clone();
|
|
4943
|
-
clonedRange.adaptBox();
|
|
4944
|
-
this.box.findAll(this).each(boxNode => {
|
|
4945
|
-
const box = new Box(boxNode);
|
|
4946
|
-
const boxContainer = box.getContainer();
|
|
4947
|
-
if (boxContainer.length === 0) {
|
|
4948
|
-
return;
|
|
4949
|
-
}
|
|
4950
|
-
if (range.compareBeforeNode(boxContainer) < 0 && range.compareAfterNode(boxContainer) > 0) {
|
|
4951
|
-
if (!(range.isCollapsed && range.startNode.get(0) === boxContainer.get(0) && range.startOffset === 0)) {
|
|
4952
|
-
boxContainer.removeClass('lake-box-hovered');
|
|
4953
|
-
boxContainer.removeClass('lake-box-selected');
|
|
4954
|
-
boxContainer.removeClass('lake-box-focused');
|
|
4955
|
-
boxContainer.addClass('lake-box-activated');
|
|
4956
|
-
return;
|
|
4957
|
-
}
|
|
4958
|
-
}
|
|
4959
|
-
if (clonedRange.intersectsNode(box.node)) {
|
|
4960
|
-
boxContainer.removeClass('lake-box-activated');
|
|
4961
|
-
if (range.isCollapsed) {
|
|
4962
|
-
boxContainer.removeClass('lake-box-hovered');
|
|
4963
|
-
boxContainer.removeClass('lake-box-selected');
|
|
4964
|
-
boxContainer.addClass('lake-box-focused');
|
|
4965
|
-
}
|
|
4966
|
-
else {
|
|
4967
|
-
boxContainer.removeClass('lake-box-focused');
|
|
4968
|
-
boxContainer.addClass('lake-box-selected');
|
|
4969
|
-
}
|
|
4970
|
-
return;
|
|
4971
|
-
}
|
|
4972
|
-
boxContainer.removeClass('lake-box-activated');
|
|
4973
|
-
boxContainer.removeClass('lake-box-focused');
|
|
4974
|
-
boxContainer.removeClass('lake-box-selected');
|
|
4975
|
-
});
|
|
4976
|
-
this.event.emit('boxselectionstylechange');
|
|
4977
|
-
}, 50, {
|
|
4978
|
-
leading: false,
|
|
4979
|
-
trailing: true,
|
|
4980
|
-
maxWait: 50,
|
|
4981
|
-
});
|
|
4982
|
-
this.emitStateChangeEvent = debounce(() => {
|
|
4983
|
-
const commandNames = this.command.getNames();
|
|
4984
|
-
let appliedItems = this.selection.getAppliedItems();
|
|
4985
|
-
if (appliedItems.length > 0 &&
|
|
4986
|
-
appliedItems[0].node.closestContainer().get(0) !== this.container.get(0)) {
|
|
4987
|
-
appliedItems = [];
|
|
4988
|
-
}
|
|
4989
|
-
const disabledNameMap = new Map();
|
|
4990
|
-
const selectedNameMap = new Map();
|
|
4991
|
-
const selectedValuesMap = new Map();
|
|
4992
|
-
if (appliedItems.length > 0) {
|
|
4993
|
-
for (const name of commandNames) {
|
|
4994
|
-
const commandItem = this.command.getItem(name);
|
|
4995
|
-
if (commandItem.isDisabled && commandItem.isDisabled(appliedItems)) {
|
|
4996
|
-
disabledNameMap.set(name, true);
|
|
4997
|
-
}
|
|
4998
|
-
if (commandItem.isSelected && commandItem.isSelected(appliedItems)) {
|
|
4999
|
-
selectedNameMap.set(name, true);
|
|
5000
|
-
}
|
|
5001
|
-
if (commandItem.selectedValues) {
|
|
5002
|
-
const values = commandItem.selectedValues(appliedItems);
|
|
5003
|
-
if (values.length > 0) {
|
|
5004
|
-
selectedValuesMap.set(name, values);
|
|
5005
|
-
}
|
|
5006
|
-
}
|
|
5007
|
-
}
|
|
5008
|
-
}
|
|
5009
|
-
const stateData = {
|
|
5010
|
-
appliedItems,
|
|
5011
|
-
disabledNameMap,
|
|
5012
|
-
selectedNameMap,
|
|
5013
|
-
selectedValuesMap,
|
|
5014
|
-
};
|
|
5015
|
-
if (isEqual(stateData, this.stateData)) {
|
|
5016
|
-
return;
|
|
5017
|
-
}
|
|
5018
|
-
if (this.toolbar) {
|
|
5019
|
-
this.toolbar.updateState(stateData);
|
|
5020
|
-
}
|
|
5021
|
-
this.event.emit('statechange', stateData);
|
|
5022
|
-
this.stateData = stateData;
|
|
5023
|
-
}, 100, {
|
|
5024
|
-
leading: false,
|
|
5025
|
-
trailing: true,
|
|
5026
|
-
maxWait: 100,
|
|
5027
|
-
});
|
|
5028
|
-
this.emitChangeEvent = (value) => {
|
|
5029
|
-
this.rectifyContent();
|
|
5030
|
-
this.emitStateChangeEvent();
|
|
5031
|
-
this.event.emit('change', value);
|
|
5032
|
-
};
|
|
5033
|
-
if (!config.root) {
|
|
5034
|
-
throw new Error('The root of the config must be specified.');
|
|
5035
|
-
}
|
|
5036
|
-
this.root = query(config.root);
|
|
5037
|
-
this.toolbar = config.toolbar;
|
|
5038
|
-
this.config = Object.assign({}, defaultConfig);
|
|
5039
|
-
for (const key of Object.keys(config)) {
|
|
5040
|
-
this.config[key] = config[key];
|
|
5041
|
-
}
|
|
5042
|
-
this.containerWrapper = query('<div class="lake-container-wrapper" />');
|
|
5043
|
-
this.container = query('<div class="lake-container" />');
|
|
5044
|
-
this.overlayContainer = query('<div class="lake-overlay" />');
|
|
5045
|
-
this.popupContainer = query('<div class="lake-popup lake-custom-properties" />');
|
|
5046
|
-
this.readonly = this.config.readonly;
|
|
5047
|
-
this.root.addClass('lake-custom-properties');
|
|
5048
|
-
this.container.attr({
|
|
5049
|
-
contenteditable: this.readonly ? 'false' : 'true',
|
|
5050
|
-
spellcheck: this.config.spellcheck ? 'true' : 'false',
|
|
5051
|
-
tabindex: this.config.tabIndex.toString(),
|
|
5052
|
-
});
|
|
5053
|
-
this.selection = new Selection(this.container);
|
|
5054
|
-
this.command = new Command(this.selection);
|
|
5055
|
-
this.history = new History(this.selection);
|
|
5056
|
-
this.keystroke = new Keystroke(this.container);
|
|
5057
|
-
editors.set(this.container.id, this);
|
|
5058
|
-
}
|
|
5059
|
-
inputInBoxStrip() {
|
|
5060
|
-
const selection = this.selection;
|
|
5061
|
-
const range = selection.range;
|
|
5062
|
-
const stripNode = range.startNode.closest('.lake-box-strip');
|
|
5063
|
-
const boxNode = stripNode.closest('lake-box');
|
|
5064
|
-
const box = new Box(boxNode);
|
|
5065
|
-
if (box.type === 'inline') {
|
|
5066
|
-
if (range.isBoxStart) {
|
|
5067
|
-
range.setStartBefore(boxNode);
|
|
5068
|
-
range.collapseToStart();
|
|
5069
|
-
}
|
|
5070
|
-
else {
|
|
5071
|
-
range.setStartAfter(boxNode);
|
|
5072
|
-
range.collapseToStart();
|
|
5073
|
-
}
|
|
5074
|
-
}
|
|
5075
|
-
else {
|
|
5076
|
-
const paragraph = query('<p />');
|
|
5077
|
-
if (range.isBoxStart) {
|
|
5078
|
-
boxNode.before(paragraph);
|
|
5079
|
-
}
|
|
5080
|
-
else {
|
|
5081
|
-
boxNode.after(paragraph);
|
|
5082
|
-
}
|
|
5083
|
-
range.shrinkAfter(paragraph);
|
|
5084
|
-
}
|
|
5085
|
-
const text = stripNode.text();
|
|
5086
|
-
stripNode.html('<br />');
|
|
5087
|
-
selection.insertNode(document.createTextNode(text));
|
|
5088
|
-
}
|
|
5089
|
-
bindInputEvents() {
|
|
5090
|
-
this.container.on('compositionstart', () => {
|
|
5091
|
-
this.isComposing = true;
|
|
5092
|
-
});
|
|
5093
|
-
this.container.on('compositionend', () => {
|
|
5094
|
-
this.isComposing = false;
|
|
5095
|
-
});
|
|
5096
|
-
this.container.on('beforeinput', event => {
|
|
5097
|
-
const inputEvent = event;
|
|
5098
|
-
const range = this.selection.range;
|
|
5099
|
-
if (range.isBoxStart || range.isBoxEnd) {
|
|
5100
|
-
this.commitUnsavedInputData();
|
|
5101
|
-
return;
|
|
5102
|
-
}
|
|
5103
|
-
if (inputEvent.inputType === 'insertText' ||
|
|
5104
|
-
inputEvent.inputType === 'insertCompositionText') {
|
|
5105
|
-
return;
|
|
5106
|
-
}
|
|
5107
|
-
this.commitUnsavedInputData();
|
|
5108
|
-
});
|
|
5109
|
-
this.container.on('input', event => {
|
|
5110
|
-
const inputEvent = event;
|
|
5111
|
-
// Here setTimeout is necessary because isComposing is not false after ending composition.
|
|
5112
|
-
window.setTimeout(() => {
|
|
5113
|
-
var _a;
|
|
5114
|
-
const range = this.selection.range;
|
|
5115
|
-
if (range.isInsideBox) {
|
|
5116
|
-
return;
|
|
5117
|
-
}
|
|
5118
|
-
// isComposing is false after ending composition because compositionend event has been emitted.
|
|
5119
|
-
if (this.isComposing) {
|
|
5120
|
-
this.event.emit('input', inputEvent);
|
|
5121
|
-
return;
|
|
5122
|
-
}
|
|
5123
|
-
if (range.isBoxStart || range.isBoxEnd) {
|
|
5124
|
-
this.inputInBoxStrip();
|
|
5125
|
-
this.history.save();
|
|
5126
|
-
this.event.emit('input', inputEvent);
|
|
5127
|
-
return;
|
|
5128
|
-
}
|
|
5129
|
-
if (inputEvent.inputType === 'insertText' ||
|
|
5130
|
-
inputEvent.inputType === 'insertCompositionText') {
|
|
5131
|
-
this.unsavedInputData += (_a = inputEvent.data) !== null && _a !== void 0 ? _a : '';
|
|
5132
|
-
if (this.unsavedInputData.length < this.config.minChangeSize) {
|
|
5133
|
-
this.event.emit('input', inputEvent);
|
|
5134
|
-
this.emitChangeEvent(this.getValue());
|
|
5135
|
-
return;
|
|
5136
|
-
}
|
|
5137
|
-
}
|
|
5138
|
-
this.history.save();
|
|
5139
|
-
this.event.emit('input', inputEvent);
|
|
5140
|
-
}, 0);
|
|
5141
|
-
});
|
|
5142
|
-
this.command.event.on('beforeexecute', () => this.commitUnsavedInputData());
|
|
5143
|
-
}
|
|
5144
|
-
bindHistoryEvents() {
|
|
5145
|
-
this.history.event.on('undo', value => {
|
|
5146
|
-
this.box.renderAll(this);
|
|
5147
|
-
this.emitChangeEvent(value);
|
|
5148
|
-
});
|
|
5149
|
-
this.history.event.on('redo', value => {
|
|
5150
|
-
this.box.renderAll(this);
|
|
5151
|
-
this.emitChangeEvent(value);
|
|
5152
|
-
});
|
|
5153
|
-
this.history.event.on('save', value => {
|
|
5154
|
-
this.box.rectifyInstances(this);
|
|
5155
|
-
this.emitChangeEvent(value);
|
|
5156
|
-
});
|
|
5157
|
-
}
|
|
5158
|
-
bindFocusEvents() {
|
|
5159
|
-
this.container.on('focus', () => {
|
|
5160
|
-
this.root.addClass('lake-root-focused');
|
|
5161
|
-
});
|
|
5162
|
-
this.container.on('blur', () => {
|
|
5163
|
-
this.root.removeClass('lake-root-focused');
|
|
5164
|
-
});
|
|
5165
|
-
}
|
|
5166
|
-
// Fixes wrong content, especially empty tag.
|
|
5167
|
-
rectifyContent() {
|
|
5168
|
-
let children = this.container.children();
|
|
5169
|
-
for (const child of children) {
|
|
5170
|
-
if ((child.isBlock || child.isMark) && child.html() === '') {
|
|
5171
|
-
child.remove();
|
|
5172
|
-
debug('Rectifying content: empty tag was removed');
|
|
5173
|
-
}
|
|
5174
|
-
}
|
|
5175
|
-
children = this.container.children();
|
|
5176
|
-
if (children.length === 0) {
|
|
5177
|
-
this.container.html('<p><br /></p>');
|
|
5178
|
-
this.selection.range.shrinkAfter(this.container);
|
|
5179
|
-
debug('Rectifying content: default paragraph was added');
|
|
5180
|
-
return;
|
|
5181
|
-
}
|
|
5182
|
-
if (children.length === 1) {
|
|
5183
|
-
const child = children[0];
|
|
5184
|
-
if (child.isVoid) {
|
|
5185
|
-
const paragraph = query('<p />');
|
|
5186
|
-
child.before(paragraph);
|
|
5187
|
-
paragraph.append(child);
|
|
5188
|
-
this.selection.range.shrinkAfter(paragraph);
|
|
5189
|
-
debug('Rectifying content: void element was wrapped in paragraph');
|
|
5190
|
-
}
|
|
5191
|
-
}
|
|
5192
|
-
}
|
|
5193
|
-
// Saves the input data which is unsaved.
|
|
5194
|
-
commitUnsavedInputData() {
|
|
5195
|
-
if (this.unsavedInputData.length > 0) {
|
|
5196
|
-
this.history.save(false);
|
|
5197
|
-
this.unsavedInputData = '';
|
|
5198
|
-
}
|
|
5199
|
-
}
|
|
5200
|
-
// Updates some state before custom modifications.
|
|
5201
|
-
prepareOperation() {
|
|
5202
|
-
this.commitUnsavedInputData();
|
|
5203
|
-
this.history.pause();
|
|
5204
|
-
}
|
|
5205
|
-
// Saves custom modifications to the history.
|
|
5206
|
-
commitOperation() {
|
|
5207
|
-
this.history.continue();
|
|
5208
|
-
this.history.save();
|
|
5209
|
-
}
|
|
5210
|
-
// Sets default config for a plugin.
|
|
5211
|
-
setPluginConfig(pluginName, pluginConfig) {
|
|
5212
|
-
if (!this.config[pluginName]) {
|
|
5213
|
-
this.config[pluginName] = {};
|
|
5214
|
-
}
|
|
5215
|
-
for (const key of Object.keys(pluginConfig)) {
|
|
5216
|
-
if (this.config[pluginName][key] === undefined) {
|
|
5217
|
-
this.config[pluginName][key] = pluginConfig[key];
|
|
5218
|
-
}
|
|
5219
|
-
}
|
|
5220
|
-
}
|
|
5221
|
-
// Sets focus on the editor area.
|
|
5222
|
-
focus() {
|
|
5223
|
-
this.container.focus();
|
|
5224
|
-
}
|
|
5225
|
-
// Removes focus from the editor area.
|
|
5226
|
-
blur() {
|
|
5227
|
-
this.container.blur();
|
|
5228
|
-
}
|
|
5229
|
-
// Sets the specified HTML string to the editor area.
|
|
5230
|
-
setValue(value) {
|
|
5231
|
-
value = normalizeValue(value);
|
|
5232
|
-
const htmlParser = new HTMLParser(value);
|
|
5233
|
-
const fragment = htmlParser.getFragment();
|
|
5234
|
-
this.container.empty();
|
|
5235
|
-
this.container.append(fragment);
|
|
5236
|
-
Editor.box.renderAll(this);
|
|
5237
|
-
this.selection.synByBookmark();
|
|
5238
|
-
}
|
|
5239
|
-
// Returns the contents from the editor.
|
|
5240
|
-
getValue() {
|
|
5241
|
-
const bookmark = this.selection.insertBookmark();
|
|
5242
|
-
let value = new HTMLParser(this.container).getHTML();
|
|
5243
|
-
value = denormalizeValue(value);
|
|
5244
|
-
this.selection.toBookmark(bookmark);
|
|
5245
|
-
return value;
|
|
5246
|
-
}
|
|
5247
|
-
// Inserts a box into the position of the selection.
|
|
5248
|
-
insertBox(boxName, boxValue) {
|
|
5249
|
-
const box = insertBox(this.selection.range, boxName, boxValue);
|
|
5250
|
-
if (!box) {
|
|
5251
|
-
throw new Error(`Box '${boxName}' cannot be inserted outside the editor.`);
|
|
5252
|
-
}
|
|
5253
|
-
const instanceMap = this.box.getInstances(this);
|
|
5254
|
-
instanceMap.set(box.node.id, box);
|
|
5255
|
-
return box;
|
|
5256
|
-
}
|
|
5257
|
-
// Removes the selected box.
|
|
5258
|
-
removeBox() {
|
|
5259
|
-
const box = removeBox(this.selection.range);
|
|
5260
|
-
if (box) {
|
|
5261
|
-
const instanceMap = this.box.getInstances(this);
|
|
5262
|
-
instanceMap.delete(box.node.id);
|
|
5263
|
-
}
|
|
5264
|
-
return box;
|
|
5265
|
-
}
|
|
5266
|
-
// Renders an editor area and set default value to it.
|
|
5267
|
-
render() {
|
|
5268
|
-
const value = normalizeValue(this.config.value);
|
|
5269
|
-
const htmlParser = new HTMLParser(value);
|
|
5270
|
-
const fragment = htmlParser.getFragment();
|
|
5271
|
-
this.root.empty();
|
|
5272
|
-
this.root.append(this.containerWrapper);
|
|
5273
|
-
this.containerWrapper.append(this.container);
|
|
5274
|
-
this.containerWrapper.append(this.overlayContainer);
|
|
5275
|
-
query(document.body).append(this.popupContainer);
|
|
5276
|
-
this.container.append(fragment);
|
|
5277
|
-
Editor.plugin.loadAll(this);
|
|
5278
|
-
if (!this.readonly) {
|
|
5279
|
-
this.bindFocusEvents();
|
|
5280
|
-
this.selection.synByBookmark();
|
|
5281
|
-
this.history.save();
|
|
5282
|
-
}
|
|
5283
|
-
Editor.box.renderAll(this);
|
|
5284
|
-
if (this.toolbar) {
|
|
5285
|
-
this.toolbar.render(this);
|
|
5286
|
-
}
|
|
5287
|
-
if (!this.readonly) {
|
|
5288
|
-
window.addEventListener('beforeunload', this.beforeunloadListener);
|
|
5289
|
-
document.addEventListener('selectionchange', this.selectionchangeListener);
|
|
5290
|
-
document.addEventListener('click', this.clickListener);
|
|
5291
|
-
window.addEventListener('resize', this.resizeListener);
|
|
5292
|
-
this.bindInputEvents();
|
|
5293
|
-
this.bindHistoryEvents();
|
|
5294
|
-
}
|
|
5295
|
-
}
|
|
5296
|
-
// Destroys a rendered editor.
|
|
5297
|
-
unmount() {
|
|
5298
|
-
this.root.empty();
|
|
5299
|
-
this.popupContainer.remove();
|
|
5300
|
-
if (!this.readonly) {
|
|
5301
|
-
window.removeEventListener('beforeunload', this.beforeunloadListener);
|
|
5302
|
-
document.removeEventListener('selectionchange', this.selectionchangeListener);
|
|
5303
|
-
document.removeEventListener('click', this.clickListener);
|
|
5304
|
-
window.removeEventListener('resize', this.resizeListener);
|
|
5305
|
-
}
|
|
5306
|
-
}
|
|
5307
|
-
}
|
|
5308
|
-
Editor.version = version;
|
|
5309
|
-
Editor.box = new BoxManager();
|
|
5310
|
-
Editor.plugin = new Plugin();
|
|
5311
|
-
|
|
5312
|
-
var enUS = {
|
|
5313
|
-
toolbar: {
|
|
5314
|
-
undo: `Undo (${modifierText('mod+Z')})`,
|
|
5315
|
-
redo: `Redo (${modifierText('mod+Y')})`,
|
|
5316
|
-
selectAll: `Select all (${modifierText('mod+A')})`,
|
|
5317
|
-
paragraph: 'Paragraph',
|
|
5318
|
-
blockQuote: 'Block quotation',
|
|
5319
|
-
numberedList: 'Numbered list',
|
|
5320
|
-
bulletedList: 'Bulleted list',
|
|
5321
|
-
checklist: 'Checklist',
|
|
5322
|
-
alignLeft: 'Align left',
|
|
5323
|
-
alignCenter: 'Align center',
|
|
5324
|
-
alignRight: 'Align right',
|
|
5325
|
-
alignJustify: 'Align justify',
|
|
5326
|
-
increaseIndent: 'Increase indent',
|
|
5327
|
-
decreaseIndent: 'Decrease indent',
|
|
5328
|
-
bold: `Bold (${modifierText('mod+B')})`,
|
|
5329
|
-
italic: `Italic (${modifierText('mod+I')})`,
|
|
5330
|
-
underline: `Underline (${modifierText('mod+U')})`,
|
|
5331
|
-
strikethrough: 'Strikethrough',
|
|
5332
|
-
superscript: 'Superscript',
|
|
5333
|
-
subscript: 'Subscript',
|
|
5334
|
-
code: 'Inline code',
|
|
5335
|
-
removeFormat: 'Remove format',
|
|
5336
|
-
formatPainter: 'Format painter',
|
|
5337
|
-
link: 'Link',
|
|
5338
|
-
hr: 'Horizontal line',
|
|
5339
|
-
codeBlock: 'Code block',
|
|
5340
|
-
heading: 'Heading',
|
|
5341
|
-
heading1: 'Heading 1',
|
|
5342
|
-
heading2: 'Heading 2',
|
|
5343
|
-
heading3: 'Heading 3',
|
|
5344
|
-
heading4: 'Heading 4',
|
|
5345
|
-
heading5: 'Heading 5',
|
|
5346
|
-
heading6: 'Heading 6',
|
|
5347
|
-
list: 'List',
|
|
5348
|
-
align: 'Alignment',
|
|
5349
|
-
indent: 'Indent',
|
|
5350
|
-
fontFamily: 'Font family',
|
|
5351
|
-
fontSize: 'Font size',
|
|
5352
|
-
moreStyle: 'More style',
|
|
5353
|
-
fontColor: 'Font color',
|
|
5354
|
-
highlight: 'Highlight',
|
|
5355
|
-
image: 'Image',
|
|
5356
|
-
removeColor: 'Remove color',
|
|
5357
|
-
},
|
|
5358
|
-
link: {
|
|
5359
|
-
newLink: 'New link',
|
|
5360
|
-
url: 'Link URL',
|
|
5361
|
-
title: 'Link title',
|
|
5362
|
-
copy: 'Copy link to clipboard',
|
|
5363
|
-
open: 'Open link in new tab',
|
|
5364
|
-
save: 'Save',
|
|
5365
|
-
unlink: 'Remove link',
|
|
5366
|
-
},
|
|
5367
|
-
image: {
|
|
5368
|
-
view: 'Full screen',
|
|
5369
|
-
remove: 'Delete',
|
|
5370
|
-
previous: 'Previous',
|
|
5371
|
-
next: 'Next',
|
|
5372
|
-
close: 'Close (Esc)',
|
|
5373
|
-
loadingError: 'The image cannot be loaded',
|
|
5374
|
-
zoomOut: 'Zoom out',
|
|
5375
|
-
zoomIn: 'Zoom in',
|
|
5376
|
-
},
|
|
5377
|
-
codeBlock: {
|
|
5378
|
-
langType: 'Select language',
|
|
5379
|
-
},
|
|
5380
|
-
};
|
|
5381
|
-
|
|
5382
|
-
var zhCN = {
|
|
5383
|
-
toolbar: {
|
|
5384
|
-
undo: `撤消 (${modifierText('mod+Z')})`,
|
|
5385
|
-
redo: `重做 (${modifierText('mod+Y')})`,
|
|
5386
|
-
selectAll: `全选 (${modifierText('mod+A')})`,
|
|
5387
|
-
paragraph: '正文',
|
|
5388
|
-
blockQuote: '引用',
|
|
5389
|
-
numberedList: '编号',
|
|
5390
|
-
bulletedList: '项目符号',
|
|
5391
|
-
checklist: '任务列表',
|
|
5392
|
-
alignLeft: '左对齐',
|
|
5393
|
-
alignCenter: '居中',
|
|
5394
|
-
alignRight: '右对齐',
|
|
5395
|
-
alignJustify: '两端对齐',
|
|
5396
|
-
increaseIndent: '增加缩进',
|
|
5397
|
-
decreaseIndent: '减少缩进',
|
|
5398
|
-
bold: `粗体 (${modifierText('mod+B')})`,
|
|
5399
|
-
italic: `斜体 (${modifierText('mod+I')})`,
|
|
5400
|
-
underline: `下划线 (${modifierText('mod+U')})`,
|
|
5401
|
-
strikethrough: '删除线',
|
|
5402
|
-
superscript: '上标',
|
|
5403
|
-
subscript: '下标',
|
|
5404
|
-
code: '行内代码',
|
|
5405
|
-
removeFormat: '清除格式',
|
|
5406
|
-
formatPainter: '格式刷',
|
|
5407
|
-
link: '链接',
|
|
5408
|
-
hr: '分割线',
|
|
5409
|
-
codeBlock: '代码块',
|
|
5410
|
-
heading: '标题',
|
|
5411
|
-
heading1: '标题 1',
|
|
5412
|
-
heading2: '标题 2',
|
|
5413
|
-
heading3: '标题 3',
|
|
5414
|
-
heading4: '标题 4',
|
|
5415
|
-
heading5: '标题 5',
|
|
5416
|
-
heading6: '标题 6',
|
|
5417
|
-
list: '列表',
|
|
5418
|
-
align: '对齐方式',
|
|
5419
|
-
indent: '缩进',
|
|
5420
|
-
fontFamily: '字体',
|
|
5421
|
-
fontSize: '文字大小',
|
|
5422
|
-
moreStyle: '更多样式',
|
|
5423
|
-
fontColor: '文字颜色',
|
|
5424
|
-
highlight: '文字背景',
|
|
5425
|
-
image: '图片',
|
|
5426
|
-
removeColor: '默认',
|
|
5427
|
-
},
|
|
5428
|
-
link: {
|
|
5429
|
-
newLink: '新链接',
|
|
5430
|
-
url: '链接 URL',
|
|
5431
|
-
title: '链接文本',
|
|
5432
|
-
copy: '复制到剪贴板',
|
|
5433
|
-
open: '打开链接',
|
|
5434
|
-
save: '确定',
|
|
5435
|
-
unlink: '取消链接',
|
|
5436
|
-
},
|
|
5437
|
-
image: {
|
|
5438
|
-
view: '查看大图',
|
|
5439
|
-
remove: '删除',
|
|
5440
|
-
previous: '上一张',
|
|
5441
|
-
next: '下一张',
|
|
5442
|
-
close: '关闭 (Esc)',
|
|
5443
|
-
loadingError: '图片加载失败',
|
|
5444
|
-
zoomOut: '缩小',
|
|
5445
|
-
zoomIn: '放大',
|
|
5446
|
-
},
|
|
5447
|
-
codeBlock: {
|
|
5448
|
-
langType: '选择代码语言',
|
|
5449
|
-
},
|
|
5450
|
-
};
|
|
5451
|
-
|
|
5452
|
-
var ja = {
|
|
5453
|
-
toolbar: {
|
|
5454
|
-
undo: `元に戻す (${modifierText('mod+Z')})`,
|
|
5455
|
-
redo: `やり直し (${modifierText('mod+Y')})`,
|
|
5456
|
-
selectAll: `すべて選択 (${modifierText('mod+A')})`,
|
|
5457
|
-
paragraph: 'テキスト',
|
|
5458
|
-
blockQuote: 'ブロック引用',
|
|
5459
|
-
numberedList: '番号付きリスト',
|
|
5460
|
-
bulletedList: '箇条書きリスト',
|
|
5461
|
-
checklist: 'タスクリスト',
|
|
5462
|
-
alignLeft: '左揃え',
|
|
5463
|
-
alignCenter: '中心揃え',
|
|
5464
|
-
alignRight: '右揃え',
|
|
5465
|
-
alignJustify: '左右に並べ替え',
|
|
5466
|
-
increaseIndent: 'インデントを増やす',
|
|
5467
|
-
decreaseIndent: 'インデントを減らす',
|
|
5468
|
-
bold: `太字 (${modifierText('mod+B')})`,
|
|
5469
|
-
italic: `斜体 (${modifierText('mod+I')})`,
|
|
5470
|
-
underline: `下線 (${modifierText('mod+U')})`,
|
|
5471
|
-
strikethrough: '取り消し線',
|
|
5472
|
-
superscript: '上付き文字',
|
|
5473
|
-
subscript: '下付き文字',
|
|
5474
|
-
code: 'インラインコード',
|
|
5475
|
-
removeFormat: '形式を削除',
|
|
5476
|
-
formatPainter: '形式ペインタ',
|
|
5477
|
-
link: 'リンク',
|
|
5478
|
-
hr: '区切り線',
|
|
5479
|
-
codeBlock: 'コードブロック',
|
|
5480
|
-
heading: 'タイトル',
|
|
5481
|
-
heading1: 'タイトル 1',
|
|
5482
|
-
heading2: 'タイトル 2',
|
|
5483
|
-
heading3: 'タイトル 3',
|
|
5484
|
-
heading4: 'タイトル 4',
|
|
5485
|
-
heading5: 'タイトル 5',
|
|
5486
|
-
heading6: 'タイトル 6',
|
|
5487
|
-
list: 'リスト',
|
|
5488
|
-
align: '文字揃え',
|
|
5489
|
-
indent: 'インデント',
|
|
5490
|
-
fontFamily: 'フォント',
|
|
5491
|
-
fontSize: '文字サイズ',
|
|
5492
|
-
moreStyle: 'その他のスタイル',
|
|
5493
|
-
fontColor: '文字色',
|
|
5494
|
-
highlight: '文字の背景',
|
|
5495
|
-
image: '画像',
|
|
5496
|
-
removeColor: 'デフォルト',
|
|
5497
|
-
},
|
|
5498
|
-
link: {
|
|
5499
|
-
newLink: '新しいリンク',
|
|
5500
|
-
url: 'リンク URL',
|
|
5501
|
-
title: 'リンク文字',
|
|
5502
|
-
copy: 'クリップボードにコピー',
|
|
5503
|
-
open: 'リンクを開く',
|
|
5504
|
-
save: '確認',
|
|
5505
|
-
unlink: 'リンクを削除',
|
|
5506
|
-
},
|
|
5507
|
-
image: {
|
|
5508
|
-
view: '大きな画像を見る',
|
|
5509
|
-
remove: '削除',
|
|
5510
|
-
previous: '前の画像',
|
|
5511
|
-
next: '次の画像',
|
|
5512
|
-
close: '閉じる (Esc)',
|
|
5513
|
-
loadingError: '画像を読み込めません',
|
|
5514
|
-
zoomOut: '縮小',
|
|
5515
|
-
zoomIn: '拡大',
|
|
5516
|
-
},
|
|
5517
|
-
codeBlock: {
|
|
5518
|
-
langType: 'コード言語を選択',
|
|
5519
|
-
},
|
|
5520
|
-
};
|
|
5521
|
-
|
|
5522
|
-
var ko = {
|
|
5523
|
-
toolbar: {
|
|
5524
|
-
undo: `작업취소 (${modifierText('mod+Z')})`,
|
|
5525
|
-
redo: `작업재개 (${modifierText('mod+Y')})`,
|
|
5526
|
-
selectAll: `전체 선택 (${modifierText('mod+A')})`,
|
|
5527
|
-
paragraph: '텍스트',
|
|
5528
|
-
blockQuote: '인용문',
|
|
5529
|
-
numberedList: '순서 목록',
|
|
5530
|
-
bulletedList: '비순서 목록',
|
|
5531
|
-
checklist: '체크리스트',
|
|
5532
|
-
alignLeft: '왼쪽 정렬',
|
|
5533
|
-
alignCenter: '가운데 정렬',
|
|
5534
|
-
alignRight: '오른쪽 정렬',
|
|
5535
|
-
alignJustify: '좌우로 정렬',
|
|
5536
|
-
increaseIndent: '들여쓰기 증가',
|
|
5537
|
-
decreaseIndent: '들여쓰기 줄이기',
|
|
5538
|
-
bold: `굵게 (${modifierText('mod+B')})`,
|
|
5539
|
-
italic: `기울임꼴 (${modifierText('mod+I')})`,
|
|
5540
|
-
underline: `밑줄 (${modifierText('mod+U')})`,
|
|
5541
|
-
strikethrough: '취소선',
|
|
5542
|
-
superscript: '위첨자',
|
|
5543
|
-
subscript: '아래 첨자',
|
|
5544
|
-
code: '인라인 코드',
|
|
5545
|
-
removeFormat: '형식 지우기',
|
|
5546
|
-
formatPainter: '형식 페인터',
|
|
5547
|
-
link: '링크',
|
|
5548
|
-
hr: '구분선',
|
|
5549
|
-
codeBlock: '코드 블록',
|
|
5550
|
-
heading: '제목',
|
|
5551
|
-
heading1: '제목 1',
|
|
5552
|
-
heading2: '제목 2',
|
|
5553
|
-
heading3: '제목 3',
|
|
5554
|
-
heading4: '제목 4',
|
|
5555
|
-
heading5: '제목 5',
|
|
5556
|
-
heading6: '제목 6',
|
|
5557
|
-
list: '목록',
|
|
5558
|
-
align: '정렬',
|
|
5559
|
-
indent: '들여쓰기',
|
|
5560
|
-
fontFamily: '글꼴',
|
|
5561
|
-
fontSize: '글자 크기',
|
|
5562
|
-
moreStyle: '더 많은 스타일',
|
|
5563
|
-
fontColor: '글자 색상',
|
|
5564
|
-
highlight: '글자 배경',
|
|
5565
|
-
image: '이미지',
|
|
5566
|
-
removeColor: '기본색',
|
|
5567
|
-
},
|
|
5568
|
-
link: {
|
|
5569
|
-
newLink: '새 링크',
|
|
5570
|
-
url: '링크 URL',
|
|
5571
|
-
title: '링크 텍스트',
|
|
5572
|
-
copy: '클립보드에 복사',
|
|
5573
|
-
open: '링크 열기',
|
|
5574
|
-
save: '확인',
|
|
5575
|
-
unlink: '링크 제거',
|
|
5576
|
-
},
|
|
5577
|
-
image: {
|
|
5578
|
-
view: '큰 이미지 보기',
|
|
5579
|
-
remove: '삭제',
|
|
5580
|
-
previous: '이전 이미지',
|
|
5581
|
-
next: '다음 이미지',
|
|
5582
|
-
close: '닫기 (Esc)',
|
|
5583
|
-
loadingError: '이미지를 로드할 수 없습니다',
|
|
5584
|
-
zoomOut: '축소',
|
|
5585
|
-
zoomIn: '확대',
|
|
5586
|
-
},
|
|
5587
|
-
codeBlock: {
|
|
5588
|
-
langType: '코드언어 선택',
|
|
5589
|
-
},
|
|
5590
|
-
};
|
|
5142
|
+
for (const item of this.keyupEventList) {
|
|
5143
|
+
if (item.type === type) {
|
|
5144
|
+
if (item.listener(new Event(type)) === false) {
|
|
5145
|
+
break;
|
|
5146
|
+
}
|
|
5147
|
+
}
|
|
5148
|
+
}
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5591
5151
|
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5152
|
+
class BoxManager {
|
|
5153
|
+
add(component) {
|
|
5154
|
+
boxes.set(component.name, component);
|
|
5155
|
+
}
|
|
5156
|
+
remove(name) {
|
|
5157
|
+
boxes.delete(name);
|
|
5158
|
+
}
|
|
5159
|
+
getNames() {
|
|
5160
|
+
return Array.from(boxes.keys());
|
|
5161
|
+
}
|
|
5162
|
+
getInstances(editor) {
|
|
5163
|
+
let instanceMap = boxInstances.get(editor.container.id);
|
|
5164
|
+
if (!instanceMap) {
|
|
5165
|
+
instanceMap = new Map();
|
|
5166
|
+
boxInstances.set(editor.container.id, instanceMap);
|
|
5167
|
+
return instanceMap;
|
|
5168
|
+
}
|
|
5169
|
+
return instanceMap;
|
|
5170
|
+
}
|
|
5171
|
+
rectifyInstances(editor) {
|
|
5172
|
+
const instanceMap = this.getInstances(editor);
|
|
5173
|
+
for (const box of instanceMap.values()) {
|
|
5174
|
+
if (!box.node.get(0).isConnected) {
|
|
5175
|
+
box.unmount();
|
|
5176
|
+
instanceMap.delete(box.node.id);
|
|
5177
|
+
}
|
|
5178
|
+
}
|
|
5179
|
+
}
|
|
5180
|
+
findAll(editor) {
|
|
5181
|
+
return editor.container.find('lake-box');
|
|
5182
|
+
}
|
|
5183
|
+
renderAll(editor) {
|
|
5184
|
+
this.rectifyInstances(editor);
|
|
5185
|
+
const instanceMap = this.getInstances(editor);
|
|
5186
|
+
this.findAll(editor).each(boxNativeNode => {
|
|
5187
|
+
const boxNode = new Nodes(boxNativeNode);
|
|
5188
|
+
if (instanceMap.get(boxNode.id)) {
|
|
5189
|
+
return;
|
|
5190
|
+
}
|
|
5191
|
+
const box = new Box(boxNode);
|
|
5192
|
+
box.render();
|
|
5193
|
+
instanceMap.set(box.node.id, box);
|
|
5194
|
+
});
|
|
5195
|
+
}
|
|
5196
|
+
}
|
|
5197
|
+
|
|
5198
|
+
class Plugin {
|
|
5199
|
+
constructor() {
|
|
5200
|
+
this.pluginList = [];
|
|
5201
|
+
}
|
|
5202
|
+
add(plugin) {
|
|
5203
|
+
this.pluginList.push(plugin);
|
|
5204
|
+
}
|
|
5205
|
+
loadAll(editor) {
|
|
5206
|
+
this.pluginList.forEach(plugin => {
|
|
5207
|
+
plugin(editor);
|
|
5208
|
+
});
|
|
5209
|
+
}
|
|
5210
|
+
}
|
|
5211
|
+
|
|
5212
|
+
const defaultConfig = {
|
|
5213
|
+
value: '<p><br /><focus /></p>',
|
|
5214
|
+
readonly: false,
|
|
5215
|
+
spellcheck: false,
|
|
5216
|
+
tabIndex: 0,
|
|
5217
|
+
indentWithTab: true,
|
|
5218
|
+
lang: 'en-US',
|
|
5219
|
+
minChangeSize: 5,
|
|
5609
5220
|
};
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5221
|
+
class Editor {
|
|
5222
|
+
constructor(config) {
|
|
5223
|
+
this.unsavedInputData = '';
|
|
5224
|
+
this.stateData = {
|
|
5225
|
+
appliedItems: [],
|
|
5226
|
+
disabledNameMap: new Map(),
|
|
5227
|
+
selectedNameMap: new Map(),
|
|
5228
|
+
selectedValuesMap: new Map(),
|
|
5229
|
+
};
|
|
5230
|
+
this.isComposing = false;
|
|
5231
|
+
this.event = new EventEmitter();
|
|
5232
|
+
this.box = Editor.box;
|
|
5233
|
+
this.beforeunloadListener = () => {
|
|
5234
|
+
this.history.save();
|
|
5235
|
+
};
|
|
5236
|
+
this.selectionchangeListener = () => {
|
|
5237
|
+
this.selection.syncByRange();
|
|
5238
|
+
this.updateBoxSelectionStyle();
|
|
5239
|
+
this.emitStateChangeEvent();
|
|
5240
|
+
};
|
|
5241
|
+
this.clickListener = event => {
|
|
5242
|
+
const targetNode = new Nodes(event.target);
|
|
5243
|
+
if (targetNode.closest('.lake-popup').length > 0) {
|
|
5244
|
+
return;
|
|
5245
|
+
}
|
|
5246
|
+
this.event.emit('click', targetNode);
|
|
5247
|
+
};
|
|
5248
|
+
this.resizeListener = () => {
|
|
5249
|
+
this.event.emit('resize');
|
|
5250
|
+
};
|
|
5251
|
+
this.updateBoxSelectionStyle = debounce(() => {
|
|
5252
|
+
// The editor has been unmounted.
|
|
5253
|
+
if (this.root.first().length === 0) {
|
|
5254
|
+
return;
|
|
5255
|
+
}
|
|
5256
|
+
const range = this.selection.range;
|
|
5257
|
+
const clonedRange = range.clone();
|
|
5258
|
+
clonedRange.adaptBox();
|
|
5259
|
+
this.box.findAll(this).each(boxNode => {
|
|
5260
|
+
const box = new Box(boxNode);
|
|
5261
|
+
const boxContainer = box.getContainer();
|
|
5262
|
+
if (boxContainer.length === 0) {
|
|
5263
|
+
return;
|
|
5264
|
+
}
|
|
5265
|
+
if (range.compareBeforeNode(boxContainer) < 0 && range.compareAfterNode(boxContainer) > 0) {
|
|
5266
|
+
if (!(range.isCollapsed && range.startNode.get(0) === boxContainer.get(0) && range.startOffset === 0)) {
|
|
5267
|
+
boxContainer.removeClass('lake-box-hovered');
|
|
5268
|
+
boxContainer.removeClass('lake-box-selected');
|
|
5269
|
+
boxContainer.removeClass('lake-box-focused');
|
|
5270
|
+
boxContainer.addClass('lake-box-activated');
|
|
5271
|
+
return;
|
|
5272
|
+
}
|
|
5273
|
+
}
|
|
5274
|
+
if (clonedRange.intersectsNode(box.node)) {
|
|
5275
|
+
boxContainer.removeClass('lake-box-activated');
|
|
5276
|
+
if (range.isCollapsed) {
|
|
5277
|
+
boxContainer.removeClass('lake-box-hovered');
|
|
5278
|
+
boxContainer.removeClass('lake-box-selected');
|
|
5279
|
+
boxContainer.addClass('lake-box-focused');
|
|
5280
|
+
}
|
|
5281
|
+
else {
|
|
5282
|
+
boxContainer.removeClass('lake-box-focused');
|
|
5283
|
+
boxContainer.addClass('lake-box-selected');
|
|
5284
|
+
}
|
|
5285
|
+
return;
|
|
5286
|
+
}
|
|
5287
|
+
boxContainer.removeClass('lake-box-activated');
|
|
5288
|
+
boxContainer.removeClass('lake-box-focused');
|
|
5289
|
+
boxContainer.removeClass('lake-box-selected');
|
|
5290
|
+
});
|
|
5291
|
+
this.event.emit('boxselectionstylechange');
|
|
5292
|
+
}, 50, {
|
|
5293
|
+
leading: false,
|
|
5294
|
+
trailing: true,
|
|
5295
|
+
maxWait: 50,
|
|
5296
|
+
});
|
|
5297
|
+
this.emitStateChangeEvent = debounce(() => {
|
|
5298
|
+
const commandNames = this.command.getNames();
|
|
5299
|
+
let appliedItems = this.selection.getAppliedItems();
|
|
5300
|
+
if (appliedItems.length > 0 &&
|
|
5301
|
+
appliedItems[0].node.closestContainer().get(0) !== this.container.get(0)) {
|
|
5302
|
+
appliedItems = [];
|
|
5303
|
+
}
|
|
5304
|
+
const disabledNameMap = new Map();
|
|
5305
|
+
const selectedNameMap = new Map();
|
|
5306
|
+
const selectedValuesMap = new Map();
|
|
5307
|
+
if (appliedItems.length > 0) {
|
|
5308
|
+
for (const name of commandNames) {
|
|
5309
|
+
const commandItem = this.command.getItem(name);
|
|
5310
|
+
if (commandItem.isDisabled && commandItem.isDisabled(appliedItems)) {
|
|
5311
|
+
disabledNameMap.set(name, true);
|
|
5312
|
+
}
|
|
5313
|
+
if (commandItem.isSelected && commandItem.isSelected(appliedItems)) {
|
|
5314
|
+
selectedNameMap.set(name, true);
|
|
5315
|
+
}
|
|
5316
|
+
if (commandItem.selectedValues) {
|
|
5317
|
+
const values = commandItem.selectedValues(appliedItems);
|
|
5318
|
+
if (values.length > 0) {
|
|
5319
|
+
selectedValuesMap.set(name, values);
|
|
5320
|
+
}
|
|
5321
|
+
}
|
|
5322
|
+
}
|
|
5323
|
+
}
|
|
5324
|
+
const stateData = {
|
|
5325
|
+
appliedItems,
|
|
5326
|
+
disabledNameMap,
|
|
5327
|
+
selectedNameMap,
|
|
5328
|
+
selectedValuesMap,
|
|
5329
|
+
};
|
|
5330
|
+
if (isEqual(stateData, this.stateData)) {
|
|
5331
|
+
return;
|
|
5332
|
+
}
|
|
5333
|
+
if (this.toolbar) {
|
|
5334
|
+
this.toolbar.updateState(stateData);
|
|
5335
|
+
}
|
|
5336
|
+
this.event.emit('statechange', stateData);
|
|
5337
|
+
this.stateData = stateData;
|
|
5338
|
+
}, 100, {
|
|
5339
|
+
leading: false,
|
|
5340
|
+
trailing: true,
|
|
5341
|
+
maxWait: 100,
|
|
5342
|
+
});
|
|
5343
|
+
this.emitChangeEvent = (value) => {
|
|
5344
|
+
this.rectifyContent();
|
|
5345
|
+
this.emitStateChangeEvent();
|
|
5346
|
+
this.event.emit('change', value);
|
|
5347
|
+
};
|
|
5348
|
+
if (!config.root) {
|
|
5349
|
+
throw new Error('The root of the config must be specified.');
|
|
5350
|
+
}
|
|
5351
|
+
this.root = query(config.root);
|
|
5352
|
+
this.toolbar = config.toolbar;
|
|
5353
|
+
this.config = Object.assign({}, defaultConfig);
|
|
5354
|
+
for (const key of Object.keys(config)) {
|
|
5355
|
+
this.config[key] = config[key];
|
|
5356
|
+
}
|
|
5357
|
+
this.containerWrapper = query('<div class="lake-container-wrapper" />');
|
|
5358
|
+
this.container = query('<div class="lake-container" />');
|
|
5359
|
+
this.overlayContainer = query('<div class="lake-overlay" />');
|
|
5360
|
+
this.popupContainer = query('<div class="lake-popup lake-custom-properties" />');
|
|
5361
|
+
this.readonly = this.config.readonly;
|
|
5362
|
+
this.root.addClass('lake-custom-properties');
|
|
5363
|
+
this.container.attr({
|
|
5364
|
+
contenteditable: this.readonly ? 'false' : 'true',
|
|
5365
|
+
spellcheck: this.config.spellcheck ? 'true' : 'false',
|
|
5366
|
+
tabindex: this.config.tabIndex.toString(),
|
|
5367
|
+
});
|
|
5368
|
+
this.selection = new Selection(this.container);
|
|
5369
|
+
this.command = new Command(this.selection);
|
|
5370
|
+
this.history = new History(this.selection);
|
|
5371
|
+
this.keystroke = new Keystroke(this.container);
|
|
5372
|
+
editors.set(this.container.id, this);
|
|
5373
|
+
}
|
|
5374
|
+
inputInBoxStrip() {
|
|
5375
|
+
const selection = this.selection;
|
|
5376
|
+
const range = selection.range;
|
|
5377
|
+
const stripNode = range.startNode.closest('.lake-box-strip');
|
|
5378
|
+
const boxNode = stripNode.closest('lake-box');
|
|
5379
|
+
const box = new Box(boxNode);
|
|
5380
|
+
if (box.type === 'inline') {
|
|
5381
|
+
if (range.isBoxStart) {
|
|
5382
|
+
range.setStartBefore(boxNode);
|
|
5383
|
+
range.collapseToStart();
|
|
5384
|
+
}
|
|
5385
|
+
else {
|
|
5386
|
+
range.setStartAfter(boxNode);
|
|
5387
|
+
range.collapseToStart();
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
else {
|
|
5391
|
+
const paragraph = query('<p />');
|
|
5392
|
+
if (range.isBoxStart) {
|
|
5393
|
+
boxNode.before(paragraph);
|
|
5394
|
+
}
|
|
5395
|
+
else {
|
|
5396
|
+
boxNode.after(paragraph);
|
|
5397
|
+
}
|
|
5398
|
+
range.shrinkAfter(paragraph);
|
|
5399
|
+
}
|
|
5400
|
+
const text = stripNode.text();
|
|
5401
|
+
stripNode.html('<br />');
|
|
5402
|
+
selection.insertNode(document.createTextNode(text));
|
|
5613
5403
|
}
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5404
|
+
bindInputEvents() {
|
|
5405
|
+
this.container.on('compositionstart', () => {
|
|
5406
|
+
this.isComposing = true;
|
|
5407
|
+
});
|
|
5408
|
+
this.container.on('compositionend', () => {
|
|
5409
|
+
this.isComposing = false;
|
|
5410
|
+
});
|
|
5411
|
+
this.container.on('beforeinput', event => {
|
|
5412
|
+
const inputEvent = event;
|
|
5413
|
+
const range = this.selection.range;
|
|
5414
|
+
if (range.isBoxStart || range.isBoxEnd) {
|
|
5415
|
+
this.commitUnsavedInputData();
|
|
5416
|
+
return;
|
|
5417
|
+
}
|
|
5418
|
+
if (inputEvent.inputType === 'insertText' ||
|
|
5419
|
+
inputEvent.inputType === 'insertCompositionText') {
|
|
5420
|
+
return;
|
|
5421
|
+
}
|
|
5422
|
+
this.commitUnsavedInputData();
|
|
5423
|
+
});
|
|
5424
|
+
this.container.on('input', event => {
|
|
5425
|
+
const inputEvent = event;
|
|
5426
|
+
// Here setTimeout is necessary because isComposing is not false after ending composition.
|
|
5427
|
+
window.setTimeout(() => {
|
|
5428
|
+
var _a;
|
|
5429
|
+
const range = this.selection.range;
|
|
5430
|
+
if (range.isInsideBox) {
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
5433
|
+
// isComposing is false after ending composition because compositionend event has been emitted.
|
|
5434
|
+
if (this.isComposing) {
|
|
5435
|
+
this.event.emit('input', inputEvent);
|
|
5436
|
+
return;
|
|
5437
|
+
}
|
|
5438
|
+
if (range.isBoxStart || range.isBoxEnd) {
|
|
5439
|
+
this.inputInBoxStrip();
|
|
5440
|
+
this.history.save();
|
|
5441
|
+
this.event.emit('input', inputEvent);
|
|
5442
|
+
return;
|
|
5443
|
+
}
|
|
5444
|
+
if (inputEvent.inputType === 'insertText' ||
|
|
5445
|
+
inputEvent.inputType === 'insertCompositionText') {
|
|
5446
|
+
this.unsavedInputData += (_a = inputEvent.data) !== null && _a !== void 0 ? _a : '';
|
|
5447
|
+
if (this.unsavedInputData.length < this.config.minChangeSize) {
|
|
5448
|
+
this.event.emit('input', inputEvent);
|
|
5449
|
+
this.emitChangeEvent(this.getValue());
|
|
5450
|
+
return;
|
|
5451
|
+
}
|
|
5452
|
+
}
|
|
5453
|
+
this.history.save();
|
|
5454
|
+
this.event.emit('input', inputEvent);
|
|
5455
|
+
}, 0);
|
|
5456
|
+
});
|
|
5457
|
+
this.command.event.on('beforeexecute', () => this.commitUnsavedInputData());
|
|
5458
|
+
}
|
|
5459
|
+
bindHistoryEvents() {
|
|
5460
|
+
this.history.event.on('undo', value => {
|
|
5461
|
+
this.box.renderAll(this);
|
|
5462
|
+
this.emitChangeEvent(value);
|
|
5463
|
+
});
|
|
5464
|
+
this.history.event.on('redo', value => {
|
|
5465
|
+
this.box.renderAll(this);
|
|
5466
|
+
this.emitChangeEvent(value);
|
|
5467
|
+
});
|
|
5468
|
+
this.history.event.on('save', value => {
|
|
5469
|
+
this.box.rectifyInstances(this);
|
|
5470
|
+
this.emitChangeEvent(value);
|
|
5471
|
+
});
|
|
5472
|
+
}
|
|
5473
|
+
// Returns a boolean value indicating whether the editor has focus.
|
|
5474
|
+
get hasFocus() {
|
|
5475
|
+
const activeElement = document.activeElement;
|
|
5476
|
+
if (!activeElement) {
|
|
5477
|
+
return false;
|
|
5478
|
+
}
|
|
5479
|
+
return query(activeElement).closest('.lake-container').get(0) === this.container.get(0);
|
|
5480
|
+
}
|
|
5481
|
+
// Returns translation functions by the specified lang.
|
|
5482
|
+
get locale() {
|
|
5483
|
+
return i18nObject(this.config.lang);
|
|
5484
|
+
}
|
|
5485
|
+
// Fixes wrong content, especially empty tag.
|
|
5486
|
+
rectifyContent() {
|
|
5487
|
+
let children = this.container.children();
|
|
5488
|
+
for (const child of children) {
|
|
5489
|
+
if ((child.isBlock || child.isMark) && child.html() === '') {
|
|
5490
|
+
child.remove();
|
|
5491
|
+
debug('Rectifying content: empty tag was removed');
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
children = this.container.children();
|
|
5495
|
+
if (children.length === 0) {
|
|
5496
|
+
this.container.html('<p><br /></p>');
|
|
5497
|
+
this.selection.range.shrinkAfter(this.container);
|
|
5498
|
+
debug('Rectifying content: default paragraph was added');
|
|
5499
|
+
return;
|
|
5500
|
+
}
|
|
5501
|
+
if (children.length === 1) {
|
|
5502
|
+
const child = children[0];
|
|
5503
|
+
if (child.isVoid) {
|
|
5504
|
+
const paragraph = query('<p />');
|
|
5505
|
+
child.before(paragraph);
|
|
5506
|
+
paragraph.append(child);
|
|
5507
|
+
this.selection.range.shrinkAfter(paragraph);
|
|
5508
|
+
debug('Rectifying content: void element was wrapped in paragraph');
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5511
|
+
}
|
|
5512
|
+
// Saves the input data which is unsaved.
|
|
5513
|
+
commitUnsavedInputData() {
|
|
5514
|
+
if (this.unsavedInputData.length > 0) {
|
|
5515
|
+
this.history.save(false);
|
|
5516
|
+
this.unsavedInputData = '';
|
|
5517
|
+
}
|
|
5518
|
+
}
|
|
5519
|
+
// Updates some state before custom modifications.
|
|
5520
|
+
prepareOperation() {
|
|
5521
|
+
this.commitUnsavedInputData();
|
|
5522
|
+
this.history.pause();
|
|
5523
|
+
}
|
|
5524
|
+
// Saves custom modifications to the history.
|
|
5525
|
+
commitOperation() {
|
|
5526
|
+
this.history.continue();
|
|
5527
|
+
this.history.save();
|
|
5528
|
+
}
|
|
5529
|
+
// Sets default config for a plugin.
|
|
5530
|
+
setPluginConfig(pluginName, pluginConfig) {
|
|
5531
|
+
if (!this.config[pluginName]) {
|
|
5532
|
+
this.config[pluginName] = {};
|
|
5533
|
+
}
|
|
5534
|
+
for (const key of Object.keys(pluginConfig)) {
|
|
5535
|
+
if (this.config[pluginName][key] === undefined) {
|
|
5536
|
+
this.config[pluginName][key] = pluginConfig[key];
|
|
5537
|
+
}
|
|
5538
|
+
}
|
|
5539
|
+
}
|
|
5540
|
+
// Sets focus on the editor area.
|
|
5541
|
+
focus() {
|
|
5542
|
+
this.container.focus();
|
|
5543
|
+
}
|
|
5544
|
+
// Removes focus from the editor area.
|
|
5545
|
+
blur() {
|
|
5546
|
+
this.container.blur();
|
|
5547
|
+
}
|
|
5548
|
+
// Sets the specified HTML string to the editor area.
|
|
5549
|
+
setValue(value) {
|
|
5550
|
+
value = normalizeValue(value);
|
|
5551
|
+
const htmlParser = new HTMLParser(value);
|
|
5552
|
+
const fragment = htmlParser.getFragment();
|
|
5553
|
+
this.container.empty();
|
|
5554
|
+
this.container.append(fragment);
|
|
5555
|
+
Editor.box.renderAll(this);
|
|
5556
|
+
this.selection.synByBookmark();
|
|
5557
|
+
}
|
|
5558
|
+
// Returns the contents from the editor.
|
|
5559
|
+
getValue() {
|
|
5560
|
+
const bookmark = this.selection.insertBookmark();
|
|
5561
|
+
let value = new HTMLParser(this.container).getHTML();
|
|
5562
|
+
value = denormalizeValue(value);
|
|
5563
|
+
this.selection.toBookmark(bookmark);
|
|
5564
|
+
return value;
|
|
5565
|
+
}
|
|
5566
|
+
// Inserts a box into the position of the selection.
|
|
5567
|
+
insertBox(boxName, boxValue) {
|
|
5568
|
+
const box = insertBox(this.selection.range, boxName, boxValue);
|
|
5569
|
+
if (!box) {
|
|
5570
|
+
throw new Error(`Box '${boxName}' cannot be inserted outside the editor.`);
|
|
5571
|
+
}
|
|
5572
|
+
const instanceMap = this.box.getInstances(this);
|
|
5573
|
+
instanceMap.set(box.node.id, box);
|
|
5574
|
+
return box;
|
|
5575
|
+
}
|
|
5576
|
+
// Removes the selected box.
|
|
5577
|
+
removeBox() {
|
|
5578
|
+
const box = removeBox(this.selection.range);
|
|
5579
|
+
if (box) {
|
|
5580
|
+
const instanceMap = this.box.getInstances(this);
|
|
5581
|
+
instanceMap.delete(box.node.id);
|
|
5582
|
+
}
|
|
5583
|
+
return box;
|
|
5584
|
+
}
|
|
5585
|
+
// Renders an editor area and set default value to it.
|
|
5586
|
+
render() {
|
|
5587
|
+
const value = normalizeValue(this.config.value);
|
|
5588
|
+
const htmlParser = new HTMLParser(value);
|
|
5589
|
+
const fragment = htmlParser.getFragment();
|
|
5590
|
+
this.root.empty();
|
|
5591
|
+
this.root.append(this.containerWrapper);
|
|
5592
|
+
this.containerWrapper.append(this.container);
|
|
5593
|
+
this.containerWrapper.append(this.overlayContainer);
|
|
5594
|
+
query(document.body).append(this.popupContainer);
|
|
5595
|
+
this.container.append(fragment);
|
|
5596
|
+
Editor.plugin.loadAll(this);
|
|
5597
|
+
if (!this.readonly) {
|
|
5598
|
+
this.selection.synByBookmark();
|
|
5599
|
+
this.history.save();
|
|
5600
|
+
}
|
|
5601
|
+
Editor.box.renderAll(this);
|
|
5602
|
+
if (this.toolbar) {
|
|
5603
|
+
this.toolbar.render(this);
|
|
5604
|
+
}
|
|
5605
|
+
if (!this.readonly) {
|
|
5606
|
+
window.addEventListener('beforeunload', this.beforeunloadListener);
|
|
5607
|
+
document.addEventListener('selectionchange', this.selectionchangeListener);
|
|
5608
|
+
document.addEventListener('click', this.clickListener);
|
|
5609
|
+
window.addEventListener('resize', this.resizeListener);
|
|
5610
|
+
this.bindInputEvents();
|
|
5611
|
+
this.bindHistoryEvents();
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
// Destroys a rendered editor.
|
|
5615
|
+
unmount() {
|
|
5616
|
+
this.root.empty();
|
|
5617
|
+
this.popupContainer.remove();
|
|
5618
|
+
if (!this.readonly) {
|
|
5619
|
+
window.removeEventListener('beforeunload', this.beforeunloadListener);
|
|
5620
|
+
document.removeEventListener('selectionchange', this.selectionchangeListener);
|
|
5621
|
+
document.removeEventListener('click', this.clickListener);
|
|
5622
|
+
window.removeEventListener('resize', this.resizeListener);
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
Editor.version = version;
|
|
5627
|
+
Editor.box = new BoxManager();
|
|
5628
|
+
Editor.plugin = new Plugin();
|
|
5622
5629
|
|
|
5623
5630
|
const headingMenuItems = [
|
|
5624
5631
|
{
|
|
5625
5632
|
value: 'h1',
|
|
5626
|
-
text: `<span style="font-weight: bold; font-size: 26px;">${locale.toolbar.heading1()}</span>`,
|
|
5633
|
+
text: locale => `<span style="font-weight: bold; font-size: 26px;">${locale.toolbar.heading1()}</span>`,
|
|
5627
5634
|
},
|
|
5628
5635
|
{
|
|
5629
5636
|
value: 'h2',
|
|
5630
|
-
text: `<span style="font-weight: bold; font-size: 24px;">${locale.toolbar.heading2()}</span>`,
|
|
5637
|
+
text: locale => `<span style="font-weight: bold; font-size: 24px;">${locale.toolbar.heading2()}</span>`,
|
|
5631
5638
|
},
|
|
5632
5639
|
{
|
|
5633
5640
|
value: 'h3',
|
|
5634
|
-
text: `<span style="font-weight: bold; font-size: 22px;">${locale.toolbar.heading3()}</span>`,
|
|
5641
|
+
text: locale => `<span style="font-weight: bold; font-size: 22px;">${locale.toolbar.heading3()}</span>`,
|
|
5635
5642
|
},
|
|
5636
5643
|
{
|
|
5637
5644
|
value: 'h4',
|
|
5638
|
-
text: `<span style="font-weight: bold; font-size: 20px;">${locale.toolbar.heading4()}</span>`,
|
|
5645
|
+
text: locale => `<span style="font-weight: bold; font-size: 20px;">${locale.toolbar.heading4()}</span>`,
|
|
5639
5646
|
},
|
|
5640
5647
|
{
|
|
5641
5648
|
value: 'h5',
|
|
5642
|
-
text: `<span style="font-weight: bold; font-size: 18px;">${locale.toolbar.heading5()}</span>`,
|
|
5649
|
+
text: locale => `<span style="font-weight: bold; font-size: 18px;">${locale.toolbar.heading5()}</span>`,
|
|
5643
5650
|
},
|
|
5644
5651
|
{
|
|
5645
5652
|
value: 'h6',
|
|
5646
|
-
text: `<span style="font-weight: bold; font-size: 16px;">${locale.toolbar.heading6()}</span>`,
|
|
5653
|
+
text: locale => `<span style="font-weight: bold; font-size: 16px;">${locale.toolbar.heading6()}</span>`,
|
|
5647
5654
|
},
|
|
5648
5655
|
{
|
|
5649
5656
|
value: 'p',
|
|
5650
|
-
text: locale.toolbar.paragraph(),
|
|
5657
|
+
text: locale => locale.toolbar.paragraph(),
|
|
5651
5658
|
},
|
|
5652
5659
|
];
|
|
5653
5660
|
const listMenuItems = [
|
|
5654
5661
|
{
|
|
5655
5662
|
icon: icons.get('numberedList'),
|
|
5656
5663
|
value: 'numbered',
|
|
5657
|
-
text: locale.toolbar.numberedList(),
|
|
5664
|
+
text: locale => locale.toolbar.numberedList(),
|
|
5658
5665
|
},
|
|
5659
5666
|
{
|
|
5660
5667
|
icon: icons.get('bulletedList'),
|
|
5661
5668
|
value: 'bulleted',
|
|
5662
|
-
text: locale.toolbar.bulletedList(),
|
|
5669
|
+
text: locale => locale.toolbar.bulletedList(),
|
|
5663
5670
|
},
|
|
5664
5671
|
{
|
|
5665
5672
|
icon: icons.get('checklist'),
|
|
5666
5673
|
value: 'checklist',
|
|
5667
|
-
text: locale.toolbar.checklist(),
|
|
5674
|
+
text: locale => locale.toolbar.checklist(),
|
|
5668
5675
|
},
|
|
5669
5676
|
];
|
|
5670
5677
|
const alignMenuItems = [
|
|
5671
5678
|
{
|
|
5672
5679
|
icon: icons.get('alignLeft'),
|
|
5673
5680
|
value: 'left',
|
|
5674
|
-
text: locale.toolbar.alignLeft(),
|
|
5681
|
+
text: locale => locale.toolbar.alignLeft(),
|
|
5675
5682
|
},
|
|
5676
5683
|
{
|
|
5677
5684
|
icon: icons.get('alignCenter'),
|
|
5678
5685
|
value: 'center',
|
|
5679
|
-
text: locale.toolbar.alignCenter(),
|
|
5686
|
+
text: locale => locale.toolbar.alignCenter(),
|
|
5680
5687
|
},
|
|
5681
5688
|
{
|
|
5682
5689
|
icon: icons.get('alignRight'),
|
|
5683
5690
|
value: 'right',
|
|
5684
|
-
text: locale.toolbar.alignRight(),
|
|
5691
|
+
text: locale => locale.toolbar.alignRight(),
|
|
5685
5692
|
},
|
|
5686
5693
|
{
|
|
5687
5694
|
icon: icons.get('alignJustify'),
|
|
5688
5695
|
value: 'justify',
|
|
5689
|
-
text: locale.toolbar.alignJustify(),
|
|
5696
|
+
text: locale => locale.toolbar.alignJustify(),
|
|
5690
5697
|
},
|
|
5691
5698
|
];
|
|
5692
5699
|
const indentMenuItems = [
|
|
5693
5700
|
{
|
|
5694
5701
|
icon: icons.get('increaseIndent'),
|
|
5695
5702
|
value: 'increase',
|
|
5696
|
-
text: locale.toolbar.increaseIndent(),
|
|
5703
|
+
text: locale => locale.toolbar.increaseIndent(),
|
|
5697
5704
|
},
|
|
5698
5705
|
{
|
|
5699
5706
|
icon: icons.get('decreaseIndent'),
|
|
5700
5707
|
value: 'decrease',
|
|
5701
|
-
text: locale.toolbar.decreaseIndent(),
|
|
5708
|
+
text: locale => locale.toolbar.decreaseIndent(),
|
|
5702
5709
|
},
|
|
5703
5710
|
];
|
|
5704
5711
|
const fontFamilyMenuItems = [
|
|
@@ -5785,32 +5792,32 @@ const moreStyleMenuItems = [
|
|
|
5785
5792
|
{
|
|
5786
5793
|
icon: icons.get('italic'),
|
|
5787
5794
|
value: 'italic',
|
|
5788
|
-
text: locale.toolbar.italic(),
|
|
5795
|
+
text: locale => locale.toolbar.italic(),
|
|
5789
5796
|
},
|
|
5790
5797
|
{
|
|
5791
5798
|
icon: icons.get('underline'),
|
|
5792
5799
|
value: 'underline',
|
|
5793
|
-
text: locale.toolbar.underline(),
|
|
5800
|
+
text: locale => locale.toolbar.underline(),
|
|
5794
5801
|
},
|
|
5795
5802
|
{
|
|
5796
5803
|
icon: icons.get('strikethrough'),
|
|
5797
5804
|
value: 'strikethrough',
|
|
5798
|
-
text: locale.toolbar.strikethrough(),
|
|
5805
|
+
text: locale => locale.toolbar.strikethrough(),
|
|
5799
5806
|
},
|
|
5800
5807
|
{
|
|
5801
5808
|
icon: icons.get('superscript'),
|
|
5802
5809
|
value: 'superscript',
|
|
5803
|
-
text: locale.toolbar.superscript(),
|
|
5810
|
+
text: locale => locale.toolbar.superscript(),
|
|
5804
5811
|
},
|
|
5805
5812
|
{
|
|
5806
5813
|
icon: icons.get('subscript'),
|
|
5807
5814
|
value: 'subscript',
|
|
5808
|
-
text: locale.toolbar.subscript(),
|
|
5815
|
+
text: locale => locale.toolbar.subscript(),
|
|
5809
5816
|
},
|
|
5810
5817
|
{
|
|
5811
5818
|
icon: icons.get('code'),
|
|
5812
5819
|
value: 'code',
|
|
5813
|
-
text: locale.toolbar.code(),
|
|
5820
|
+
text: locale => locale.toolbar.code(),
|
|
5814
5821
|
},
|
|
5815
5822
|
];
|
|
5816
5823
|
// These colors are from Ant Design (https://ant.design/docs/spec/colors)
|
|
@@ -5833,7 +5840,7 @@ const colorMenuItems = [
|
|
|
5833
5840
|
{
|
|
5834
5841
|
icon: icons.get('removeFormat'),
|
|
5835
5842
|
value: '',
|
|
5836
|
-
text: locale.toolbar.removeColor(),
|
|
5843
|
+
text: locale => locale.toolbar.removeColor(),
|
|
5837
5844
|
},
|
|
5838
5845
|
];
|
|
5839
5846
|
for (const color of colors) {
|
|
@@ -5858,7 +5865,7 @@ const toolbarItems = [
|
|
|
5858
5865
|
name: 'undo',
|
|
5859
5866
|
type: 'button',
|
|
5860
5867
|
icon: icons.get('undo'),
|
|
5861
|
-
tooltip: locale.toolbar.undo(),
|
|
5868
|
+
tooltip: locale => locale.toolbar.undo(),
|
|
5862
5869
|
onClick: (editor, value) => {
|
|
5863
5870
|
editor.command.execute(value);
|
|
5864
5871
|
},
|
|
@@ -5867,7 +5874,7 @@ const toolbarItems = [
|
|
|
5867
5874
|
name: 'redo',
|
|
5868
5875
|
type: 'button',
|
|
5869
5876
|
icon: icons.get('redo'),
|
|
5870
|
-
tooltip: locale.toolbar.redo(),
|
|
5877
|
+
tooltip: locale => locale.toolbar.redo(),
|
|
5871
5878
|
onClick: (editor, value) => {
|
|
5872
5879
|
editor.command.execute(value);
|
|
5873
5880
|
},
|
|
@@ -5876,7 +5883,7 @@ const toolbarItems = [
|
|
|
5876
5883
|
name: 'selectAll',
|
|
5877
5884
|
type: 'button',
|
|
5878
5885
|
icon: icons.get('selectAll'),
|
|
5879
|
-
tooltip: locale.toolbar.selectAll(),
|
|
5886
|
+
tooltip: locale => locale.toolbar.selectAll(),
|
|
5880
5887
|
onClick: (editor, value) => {
|
|
5881
5888
|
editor.command.execute(value);
|
|
5882
5889
|
},
|
|
@@ -5885,7 +5892,7 @@ const toolbarItems = [
|
|
|
5885
5892
|
name: 'paragraph',
|
|
5886
5893
|
type: 'button',
|
|
5887
5894
|
icon: icons.get('paragraph'),
|
|
5888
|
-
tooltip: locale.toolbar.paragraph(),
|
|
5895
|
+
tooltip: locale => locale.toolbar.paragraph(),
|
|
5889
5896
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'p'),
|
|
5890
5897
|
onClick: editor => {
|
|
5891
5898
|
editor.command.execute('heading', 'p');
|
|
@@ -5895,7 +5902,7 @@ const toolbarItems = [
|
|
|
5895
5902
|
name: 'blockQuote',
|
|
5896
5903
|
type: 'button',
|
|
5897
5904
|
icon: icons.get('blockQuote'),
|
|
5898
|
-
tooltip: locale.toolbar.blockQuote(),
|
|
5905
|
+
tooltip: locale => locale.toolbar.blockQuote(),
|
|
5899
5906
|
onClick: (editor, value) => {
|
|
5900
5907
|
editor.command.execute(value);
|
|
5901
5908
|
},
|
|
@@ -5904,7 +5911,7 @@ const toolbarItems = [
|
|
|
5904
5911
|
name: 'numberedList',
|
|
5905
5912
|
type: 'button',
|
|
5906
5913
|
icon: icons.get('numberedList'),
|
|
5907
|
-
tooltip: locale.toolbar.numberedList(),
|
|
5914
|
+
tooltip: locale => locale.toolbar.numberedList(),
|
|
5908
5915
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'ol'),
|
|
5909
5916
|
onClick: editor => {
|
|
5910
5917
|
editor.command.execute('list', 'numbered');
|
|
@@ -5914,7 +5921,7 @@ const toolbarItems = [
|
|
|
5914
5921
|
name: 'bulletedList',
|
|
5915
5922
|
type: 'button',
|
|
5916
5923
|
icon: icons.get('bulletedList'),
|
|
5917
|
-
tooltip: locale.toolbar.bulletedList(),
|
|
5924
|
+
tooltip: locale => locale.toolbar.bulletedList(),
|
|
5918
5925
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'ul' && !item.node.hasAttr('type')),
|
|
5919
5926
|
onClick: editor => {
|
|
5920
5927
|
editor.command.execute('list', 'bulleted');
|
|
@@ -5924,7 +5931,7 @@ const toolbarItems = [
|
|
|
5924
5931
|
name: 'checklist',
|
|
5925
5932
|
type: 'button',
|
|
5926
5933
|
icon: icons.get('checklist'),
|
|
5927
|
-
tooltip: locale.toolbar.checklist(),
|
|
5934
|
+
tooltip: locale => locale.toolbar.checklist(),
|
|
5928
5935
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'ul' && item.node.attr('type') === 'checklist'),
|
|
5929
5936
|
onClick: editor => {
|
|
5930
5937
|
editor.command.execute('list', 'checklist');
|
|
@@ -5934,7 +5941,7 @@ const toolbarItems = [
|
|
|
5934
5941
|
name: 'alignLeft',
|
|
5935
5942
|
type: 'button',
|
|
5936
5943
|
icon: icons.get('alignLeft'),
|
|
5937
|
-
tooltip: locale.toolbar.alignLeft(),
|
|
5944
|
+
tooltip: locale => locale.toolbar.alignLeft(),
|
|
5938
5945
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'left'),
|
|
5939
5946
|
onClick: editor => {
|
|
5940
5947
|
editor.command.execute('align', 'left');
|
|
@@ -5944,7 +5951,7 @@ const toolbarItems = [
|
|
|
5944
5951
|
name: 'alignCenter',
|
|
5945
5952
|
type: 'button',
|
|
5946
5953
|
icon: icons.get('alignCenter'),
|
|
5947
|
-
tooltip: locale.toolbar.alignCenter(),
|
|
5954
|
+
tooltip: locale => locale.toolbar.alignCenter(),
|
|
5948
5955
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'center'),
|
|
5949
5956
|
onClick: editor => {
|
|
5950
5957
|
editor.command.execute('align', 'center');
|
|
@@ -5954,7 +5961,7 @@ const toolbarItems = [
|
|
|
5954
5961
|
name: 'alignRight',
|
|
5955
5962
|
type: 'button',
|
|
5956
5963
|
icon: icons.get('alignRight'),
|
|
5957
|
-
tooltip: locale.toolbar.alignRight(),
|
|
5964
|
+
tooltip: locale => locale.toolbar.alignRight(),
|
|
5958
5965
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'right'),
|
|
5959
5966
|
onClick: editor => {
|
|
5960
5967
|
editor.command.execute('align', 'right');
|
|
@@ -5964,7 +5971,7 @@ const toolbarItems = [
|
|
|
5964
5971
|
name: 'alignJustify',
|
|
5965
5972
|
type: 'button',
|
|
5966
5973
|
icon: icons.get('alignJustify'),
|
|
5967
|
-
tooltip: locale.toolbar.alignJustify(),
|
|
5974
|
+
tooltip: locale => locale.toolbar.alignJustify(),
|
|
5968
5975
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'justify'),
|
|
5969
5976
|
onClick: editor => {
|
|
5970
5977
|
editor.command.execute('align', 'justify');
|
|
@@ -5974,7 +5981,7 @@ const toolbarItems = [
|
|
|
5974
5981
|
name: 'increaseIndent',
|
|
5975
5982
|
type: 'button',
|
|
5976
5983
|
icon: icons.get('increaseIndent'),
|
|
5977
|
-
tooltip: locale.toolbar.increaseIndent(),
|
|
5984
|
+
tooltip: locale => locale.toolbar.increaseIndent(),
|
|
5978
5985
|
onClick: editor => {
|
|
5979
5986
|
editor.command.execute('indent', 'increase');
|
|
5980
5987
|
},
|
|
@@ -5983,7 +5990,7 @@ const toolbarItems = [
|
|
|
5983
5990
|
name: 'decreaseIndent',
|
|
5984
5991
|
type: 'button',
|
|
5985
5992
|
icon: icons.get('decreaseIndent'),
|
|
5986
|
-
tooltip: locale.toolbar.decreaseIndent(),
|
|
5993
|
+
tooltip: locale => locale.toolbar.decreaseIndent(),
|
|
5987
5994
|
onClick: editor => {
|
|
5988
5995
|
editor.command.execute('indent', 'decrease');
|
|
5989
5996
|
},
|
|
@@ -5992,7 +5999,7 @@ const toolbarItems = [
|
|
|
5992
5999
|
name: 'bold',
|
|
5993
6000
|
type: 'button',
|
|
5994
6001
|
icon: icons.get('bold'),
|
|
5995
|
-
tooltip: locale.toolbar.bold(),
|
|
6002
|
+
tooltip: locale => locale.toolbar.bold(),
|
|
5996
6003
|
onClick: (editor, value) => {
|
|
5997
6004
|
editor.command.execute(value);
|
|
5998
6005
|
},
|
|
@@ -6001,7 +6008,7 @@ const toolbarItems = [
|
|
|
6001
6008
|
name: 'italic',
|
|
6002
6009
|
type: 'button',
|
|
6003
6010
|
icon: icons.get('italic'),
|
|
6004
|
-
tooltip: locale.toolbar.italic(),
|
|
6011
|
+
tooltip: locale => locale.toolbar.italic(),
|
|
6005
6012
|
onClick: (editor, value) => {
|
|
6006
6013
|
editor.command.execute(value);
|
|
6007
6014
|
},
|
|
@@ -6010,7 +6017,7 @@ const toolbarItems = [
|
|
|
6010
6017
|
name: 'underline',
|
|
6011
6018
|
type: 'button',
|
|
6012
6019
|
icon: icons.get('underline'),
|
|
6013
|
-
tooltip: locale.toolbar.underline(),
|
|
6020
|
+
tooltip: locale => locale.toolbar.underline(),
|
|
6014
6021
|
onClick: (editor, value) => {
|
|
6015
6022
|
editor.command.execute(value);
|
|
6016
6023
|
},
|
|
@@ -6019,7 +6026,7 @@ const toolbarItems = [
|
|
|
6019
6026
|
name: 'strikethrough',
|
|
6020
6027
|
type: 'button',
|
|
6021
6028
|
icon: icons.get('strikethrough'),
|
|
6022
|
-
tooltip: locale.toolbar.strikethrough(),
|
|
6029
|
+
tooltip: locale => locale.toolbar.strikethrough(),
|
|
6023
6030
|
onClick: (editor, value) => {
|
|
6024
6031
|
editor.command.execute(value);
|
|
6025
6032
|
},
|
|
@@ -6028,7 +6035,7 @@ const toolbarItems = [
|
|
|
6028
6035
|
name: 'superscript',
|
|
6029
6036
|
type: 'button',
|
|
6030
6037
|
icon: icons.get('superscript'),
|
|
6031
|
-
tooltip: locale.toolbar.superscript(),
|
|
6038
|
+
tooltip: locale => locale.toolbar.superscript(),
|
|
6032
6039
|
onClick: (editor, value) => {
|
|
6033
6040
|
editor.command.execute(value);
|
|
6034
6041
|
},
|
|
@@ -6037,7 +6044,7 @@ const toolbarItems = [
|
|
|
6037
6044
|
name: 'subscript',
|
|
6038
6045
|
type: 'button',
|
|
6039
6046
|
icon: icons.get('subscript'),
|
|
6040
|
-
tooltip: locale.toolbar.subscript(),
|
|
6047
|
+
tooltip: locale => locale.toolbar.subscript(),
|
|
6041
6048
|
onClick: (editor, value) => {
|
|
6042
6049
|
editor.command.execute(value);
|
|
6043
6050
|
},
|
|
@@ -6046,7 +6053,7 @@ const toolbarItems = [
|
|
|
6046
6053
|
name: 'code',
|
|
6047
6054
|
type: 'button',
|
|
6048
6055
|
icon: icons.get('code'),
|
|
6049
|
-
tooltip: locale.toolbar.code(),
|
|
6056
|
+
tooltip: locale => locale.toolbar.code(),
|
|
6050
6057
|
onClick: (editor, value) => {
|
|
6051
6058
|
editor.command.execute(value);
|
|
6052
6059
|
},
|
|
@@ -6055,7 +6062,7 @@ const toolbarItems = [
|
|
|
6055
6062
|
name: 'removeFormat',
|
|
6056
6063
|
type: 'button',
|
|
6057
6064
|
icon: icons.get('removeFormat'),
|
|
6058
|
-
tooltip: locale.toolbar.removeFormat(),
|
|
6065
|
+
tooltip: locale => locale.toolbar.removeFormat(),
|
|
6059
6066
|
onClick: (editor, value) => {
|
|
6060
6067
|
editor.command.execute(value);
|
|
6061
6068
|
},
|
|
@@ -6064,7 +6071,7 @@ const toolbarItems = [
|
|
|
6064
6071
|
name: 'formatPainter',
|
|
6065
6072
|
type: 'button',
|
|
6066
6073
|
icon: icons.get('formatPainter'),
|
|
6067
|
-
tooltip: locale.toolbar.formatPainter(),
|
|
6074
|
+
tooltip: locale => locale.toolbar.formatPainter(),
|
|
6068
6075
|
onClick: (editor, value) => {
|
|
6069
6076
|
editor.command.execute(value);
|
|
6070
6077
|
},
|
|
@@ -6073,7 +6080,7 @@ const toolbarItems = [
|
|
|
6073
6080
|
name: 'link',
|
|
6074
6081
|
type: 'button',
|
|
6075
6082
|
icon: icons.get('link'),
|
|
6076
|
-
tooltip: locale.toolbar.link(),
|
|
6083
|
+
tooltip: locale => locale.toolbar.link(),
|
|
6077
6084
|
onClick: (editor, value) => {
|
|
6078
6085
|
editor.command.execute(value);
|
|
6079
6086
|
},
|
|
@@ -6082,7 +6089,7 @@ const toolbarItems = [
|
|
|
6082
6089
|
name: 'hr',
|
|
6083
6090
|
type: 'button',
|
|
6084
6091
|
icon: icons.get('hr'),
|
|
6085
|
-
tooltip: locale.toolbar.hr(),
|
|
6092
|
+
tooltip: locale => locale.toolbar.hr(),
|
|
6086
6093
|
onClick: (editor, value) => {
|
|
6087
6094
|
editor.command.execute(value);
|
|
6088
6095
|
},
|
|
@@ -6091,7 +6098,7 @@ const toolbarItems = [
|
|
|
6091
6098
|
name: 'codeBlock',
|
|
6092
6099
|
type: 'button',
|
|
6093
6100
|
icon: icons.get('codeBlock'),
|
|
6094
|
-
tooltip: locale.toolbar.codeBlock(),
|
|
6101
|
+
tooltip: locale => locale.toolbar.codeBlock(),
|
|
6095
6102
|
onClick: (editor, value) => {
|
|
6096
6103
|
editor.command.execute(value);
|
|
6097
6104
|
},
|
|
@@ -6101,7 +6108,7 @@ const toolbarItems = [
|
|
|
6101
6108
|
type: 'dropdown',
|
|
6102
6109
|
downIcon: icons.get('down'),
|
|
6103
6110
|
defaultValue: 'p',
|
|
6104
|
-
tooltip: locale.toolbar.heading(),
|
|
6111
|
+
tooltip: locale => locale.toolbar.heading(),
|
|
6105
6112
|
width: '100px',
|
|
6106
6113
|
menuType: 'list',
|
|
6107
6114
|
menuItems: headingMenuItems,
|
|
@@ -6115,7 +6122,7 @@ const toolbarItems = [
|
|
|
6115
6122
|
downIcon: icons.get('down'),
|
|
6116
6123
|
icon: icons.get('list'),
|
|
6117
6124
|
defaultValue: '',
|
|
6118
|
-
tooltip: locale.toolbar.list(),
|
|
6125
|
+
tooltip: locale => locale.toolbar.list(),
|
|
6119
6126
|
width: 'auto',
|
|
6120
6127
|
menuType: 'list',
|
|
6121
6128
|
menuItems: listMenuItems,
|
|
@@ -6129,7 +6136,7 @@ const toolbarItems = [
|
|
|
6129
6136
|
downIcon: icons.get('down'),
|
|
6130
6137
|
icon: icons.get('alignLeft'),
|
|
6131
6138
|
defaultValue: '',
|
|
6132
|
-
tooltip: locale.toolbar.align(),
|
|
6139
|
+
tooltip: locale => locale.toolbar.align(),
|
|
6133
6140
|
width: 'auto',
|
|
6134
6141
|
menuType: 'list',
|
|
6135
6142
|
menuItems: alignMenuItems,
|
|
@@ -6143,7 +6150,7 @@ const toolbarItems = [
|
|
|
6143
6150
|
downIcon: icons.get('down'),
|
|
6144
6151
|
icon: icons.get('increaseIndent'),
|
|
6145
6152
|
defaultValue: '',
|
|
6146
|
-
tooltip: locale.toolbar.indent(),
|
|
6153
|
+
tooltip: locale => locale.toolbar.indent(),
|
|
6147
6154
|
width: 'auto',
|
|
6148
6155
|
menuType: 'list',
|
|
6149
6156
|
menuItems: indentMenuItems,
|
|
@@ -6156,7 +6163,7 @@ const toolbarItems = [
|
|
|
6156
6163
|
type: 'dropdown',
|
|
6157
6164
|
downIcon: icons.get('down'),
|
|
6158
6165
|
defaultValue: 'Segoe UI',
|
|
6159
|
-
tooltip: locale.toolbar.fontFamily(),
|
|
6166
|
+
tooltip: locale => locale.toolbar.fontFamily(),
|
|
6160
6167
|
width: '100px',
|
|
6161
6168
|
menuType: 'list',
|
|
6162
6169
|
menuItems: fontFamilyMenuItems,
|
|
@@ -6169,7 +6176,7 @@ const toolbarItems = [
|
|
|
6169
6176
|
type: 'dropdown',
|
|
6170
6177
|
downIcon: icons.get('down'),
|
|
6171
6178
|
defaultValue: '16px',
|
|
6172
|
-
tooltip: locale.toolbar.fontSize(),
|
|
6179
|
+
tooltip: locale => locale.toolbar.fontSize(),
|
|
6173
6180
|
width: '65px',
|
|
6174
6181
|
menuType: 'list',
|
|
6175
6182
|
menuItems: fontSizeMenuItems,
|
|
@@ -6182,7 +6189,7 @@ const toolbarItems = [
|
|
|
6182
6189
|
type: 'dropdown',
|
|
6183
6190
|
icon: icons.get('more'),
|
|
6184
6191
|
defaultValue: '',
|
|
6185
|
-
tooltip: locale.toolbar.moreStyle(),
|
|
6192
|
+
tooltip: locale => locale.toolbar.moreStyle(),
|
|
6186
6193
|
width: 'auto',
|
|
6187
6194
|
menuType: 'list',
|
|
6188
6195
|
menuItems: moreStyleMenuItems,
|
|
@@ -6208,7 +6215,7 @@ const toolbarItems = [
|
|
|
6208
6215
|
icon: icons.get('fontColor'),
|
|
6209
6216
|
accentIcon: icons.get('fontColorAccent'),
|
|
6210
6217
|
defaultValue: '#f5222d',
|
|
6211
|
-
tooltip: locale.toolbar.fontColor(),
|
|
6218
|
+
tooltip: locale => locale.toolbar.fontColor(),
|
|
6212
6219
|
width: 'auto',
|
|
6213
6220
|
menuType: 'color',
|
|
6214
6221
|
menuItems: colorMenuItems,
|
|
@@ -6223,7 +6230,7 @@ const toolbarItems = [
|
|
|
6223
6230
|
icon: icons.get('highlight'),
|
|
6224
6231
|
accentIcon: icons.get('highlightAccent'),
|
|
6225
6232
|
defaultValue: '#fadb14',
|
|
6226
|
-
tooltip: locale.toolbar.highlight(),
|
|
6233
|
+
tooltip: locale => locale.toolbar.highlight(),
|
|
6227
6234
|
width: 'auto',
|
|
6228
6235
|
menuType: 'color',
|
|
6229
6236
|
menuItems: colorMenuItems,
|
|
@@ -6235,7 +6242,7 @@ const toolbarItems = [
|
|
|
6235
6242
|
name: 'image',
|
|
6236
6243
|
type: 'upload',
|
|
6237
6244
|
icon: icons.get('image'),
|
|
6238
|
-
tooltip: locale.toolbar.image(),
|
|
6245
|
+
tooltip: locale => locale.toolbar.image(),
|
|
6239
6246
|
accept: 'image/*',
|
|
6240
6247
|
multiple: true,
|
|
6241
6248
|
},
|
|
@@ -6339,7 +6346,7 @@ class Toolbar {
|
|
|
6339
6346
|
root: this.container,
|
|
6340
6347
|
name: item.name,
|
|
6341
6348
|
icon: item.icon,
|
|
6342
|
-
tooltip: item.tooltip,
|
|
6349
|
+
tooltip: typeof item.tooltip === 'string' ? item.tooltip : item.tooltip(editor.locale),
|
|
6343
6350
|
tabIndex: -1,
|
|
6344
6351
|
onClick: () => {
|
|
6345
6352
|
editor.focus();
|
|
@@ -6351,6 +6358,7 @@ class Toolbar {
|
|
|
6351
6358
|
appendDropdown(editor, item) {
|
|
6352
6359
|
const dropdown = new Dropdown({
|
|
6353
6360
|
root: this.container,
|
|
6361
|
+
locale: editor.locale,
|
|
6354
6362
|
name: item.name,
|
|
6355
6363
|
icon: item.icon,
|
|
6356
6364
|
accentIcon: item.accentIcon,
|
|
@@ -6386,7 +6394,7 @@ class Toolbar {
|
|
|
6386
6394
|
root: uploadNode,
|
|
6387
6395
|
name: item.name,
|
|
6388
6396
|
icon: item.icon,
|
|
6389
|
-
tooltip: item.tooltip,
|
|
6397
|
+
tooltip: typeof item.tooltip === 'string' ? item.tooltip : item.tooltip(editor.locale),
|
|
6390
6398
|
tabIndex: -1,
|
|
6391
6399
|
onClick: () => {
|
|
6392
6400
|
editor.focus();
|
|
@@ -6491,7 +6499,7 @@ class Toolbar {
|
|
|
6491
6499
|
return;
|
|
6492
6500
|
}
|
|
6493
6501
|
if (item.type === 'dropdown') {
|
|
6494
|
-
this.allMenuMap.set(item.name, Dropdown.getMenuMap(item.menuItems));
|
|
6502
|
+
this.allMenuMap.set(item.name, Dropdown.getMenuMap(item.menuItems, editor.locale));
|
|
6495
6503
|
this.dropdownItemList.push(item);
|
|
6496
6504
|
this.appendDropdown(editor, item);
|
|
6497
6505
|
return;
|
|
@@ -6683,10 +6691,10 @@ function openFullScreen(box) {
|
|
|
6683
6691
|
arrowPrevSVG: icons.get('left'),
|
|
6684
6692
|
arrowNextSVG: icons.get('right'),
|
|
6685
6693
|
closeSVG: icons.get('close'),
|
|
6686
|
-
arrowPrevTitle: locale.image.previous(),
|
|
6687
|
-
arrowNextTitle: locale.image.next(),
|
|
6688
|
-
closeTitle: locale.image.close(),
|
|
6689
|
-
errorMsg: locale.image.loadingError(),
|
|
6694
|
+
arrowPrevTitle: editor.locale.image.previous(),
|
|
6695
|
+
arrowNextTitle: editor.locale.image.next(),
|
|
6696
|
+
closeTitle: editor.locale.image.close(),
|
|
6697
|
+
errorMsg: editor.locale.image.loadingError(),
|
|
6690
6698
|
});
|
|
6691
6699
|
lightbox.on('uiRegister', () => {
|
|
6692
6700
|
const pswp = lightbox.pswp;
|
|
@@ -6694,7 +6702,7 @@ function openFullScreen(box) {
|
|
|
6694
6702
|
name: 'zoom-out-button',
|
|
6695
6703
|
order: 8,
|
|
6696
6704
|
isButton: true,
|
|
6697
|
-
title: locale.image.zoomOut(),
|
|
6705
|
+
title: editor.locale.image.zoomOut(),
|
|
6698
6706
|
html: icons.get('zoomOut'),
|
|
6699
6707
|
onClick: () => {
|
|
6700
6708
|
const currSlide = pswp.currSlide;
|
|
@@ -6707,7 +6715,7 @@ function openFullScreen(box) {
|
|
|
6707
6715
|
name: 'zoom-in-button',
|
|
6708
6716
|
order: 9,
|
|
6709
6717
|
isButton: true,
|
|
6710
|
-
title: locale.image.zoomIn(),
|
|
6718
|
+
title: editor.locale.image.zoomIn(),
|
|
6711
6719
|
html: icons.get('zoomIn'),
|
|
6712
6720
|
onClick: () => {
|
|
6713
6721
|
const currSlide = pswp.currSlide;
|
|
@@ -6759,6 +6767,10 @@ function removeImageBox(box) {
|
|
|
6759
6767
|
// Displays error icon and filename.
|
|
6760
6768
|
function renderError(imageNode, box) {
|
|
6761
6769
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6770
|
+
const editor = box.getEditor();
|
|
6771
|
+
if (!editor) {
|
|
6772
|
+
return;
|
|
6773
|
+
}
|
|
6762
6774
|
const value = box.value;
|
|
6763
6775
|
box.getContainer().css({
|
|
6764
6776
|
width: '',
|
|
@@ -6766,7 +6778,7 @@ function renderError(imageNode, box) {
|
|
|
6766
6778
|
});
|
|
6767
6779
|
const buttonGroupNode = query(safeTemplate `
|
|
6768
6780
|
<div class="lake-button-group">
|
|
6769
|
-
<button type="button" tabindex="-1" class="lake-button-remove" title="${locale.image.remove()}"></button>
|
|
6781
|
+
<button type="button" tabindex="-1" class="lake-button-remove" title="${editor.locale.image.remove()}"></button>
|
|
6770
6782
|
</div>
|
|
6771
6783
|
`);
|
|
6772
6784
|
const removeButton = buttonGroupNode.find('.lake-button-remove');
|
|
@@ -6816,7 +6828,7 @@ function renderUploading(imageNode, box) {
|
|
|
6816
6828
|
});
|
|
6817
6829
|
const buttonGroupNode = query(safeTemplate `
|
|
6818
6830
|
<div class="lake-button-group">
|
|
6819
|
-
<button type="button" tabindex="-1" class="lake-button-remove" title="${locale.image.remove()}"></button>
|
|
6831
|
+
<button type="button" tabindex="-1" class="lake-button-remove" title="${editor.locale.image.remove()}"></button>
|
|
6820
6832
|
</div>
|
|
6821
6833
|
`);
|
|
6822
6834
|
const removeButton = buttonGroupNode.find('.lake-button-remove');
|
|
@@ -6878,8 +6890,8 @@ function renderDone(imageNode, box) {
|
|
|
6878
6890
|
});
|
|
6879
6891
|
const buttonGroupNode = query(safeTemplate `
|
|
6880
6892
|
<div class="lake-button-group">
|
|
6881
|
-
<button type="button" tabindex="-1" class="lake-button-view" title="${locale.image.view()}"></button>
|
|
6882
|
-
<button type="button" tabindex="-1" class="lake-button-remove" title="${locale.image.remove()}"></button>
|
|
6893
|
+
<button type="button" tabindex="-1" class="lake-button-view" title="${editor.locale.image.view()}"></button>
|
|
6894
|
+
<button type="button" tabindex="-1" class="lake-button-remove" title="${editor.locale.image.remove()}"></button>
|
|
6883
6895
|
</div>
|
|
6884
6896
|
`);
|
|
6885
6897
|
const viewButton = buttonGroupNode.find('.lake-button-view');
|
|
@@ -7130,6 +7142,7 @@ const codeBlockBox = {
|
|
|
7130
7142
|
doc: (_a = boxValue.code) !== null && _a !== void 0 ? _a : '',
|
|
7131
7143
|
extensions: [
|
|
7132
7144
|
EditorState.readOnly.of(editor.readonly),
|
|
7145
|
+
EditorView.editable.of(!editor.readonly),
|
|
7133
7146
|
history(),
|
|
7134
7147
|
keymap.of([
|
|
7135
7148
|
...defaultKeymap,
|
|
@@ -7147,7 +7160,7 @@ const codeBlockBox = {
|
|
|
7147
7160
|
name: 'langType',
|
|
7148
7161
|
downIcon: icons.get('down'),
|
|
7149
7162
|
defaultValue: langItem ? boxValue.lang : codeBlockConfig.defaultLang,
|
|
7150
|
-
tooltip: locale.codeBlock.langType(),
|
|
7163
|
+
tooltip: editor.locale.codeBlock.langType(),
|
|
7151
7164
|
width: 'auto',
|
|
7152
7165
|
menuType: 'list',
|
|
7153
7166
|
menuItems: langItems.map((item) => ({
|
|
@@ -7505,9 +7518,7 @@ var heading = (editor) => {
|
|
|
7505
7518
|
const typeList = [
|
|
7506
7519
|
'info',
|
|
7507
7520
|
'tip',
|
|
7508
|
-
'success',
|
|
7509
7521
|
'warning',
|
|
7510
|
-
'error',
|
|
7511
7522
|
'danger',
|
|
7512
7523
|
];
|
|
7513
7524
|
var blockQuote = (editor) => {
|
|
@@ -7975,17 +7986,18 @@ var formatPainter = (editor) => {
|
|
|
7975
7986
|
};
|
|
7976
7987
|
|
|
7977
7988
|
class LinkPopup {
|
|
7978
|
-
constructor(
|
|
7989
|
+
constructor(config) {
|
|
7979
7990
|
this.linkNode = null;
|
|
7980
7991
|
this.event = new EventEmitter();
|
|
7981
|
-
this.root = root;
|
|
7992
|
+
this.root = config.root;
|
|
7993
|
+
this.locale = config.locale || i18nObject('en-US');
|
|
7982
7994
|
this.container = query(safeTemplate `
|
|
7983
7995
|
<div class="lake-link-popup">
|
|
7984
|
-
<div class="lake-row">${locale.link.url()}</div>
|
|
7996
|
+
<div class="lake-row">${this.locale.link.url()}</div>
|
|
7985
7997
|
<div class="lake-row lake-url-row">
|
|
7986
7998
|
<input type="text" name="url" />
|
|
7987
7999
|
</div>
|
|
7988
|
-
<div class="lake-row">${locale.link.title()}</div>
|
|
8000
|
+
<div class="lake-row">${this.locale.link.title()}</div>
|
|
7989
8001
|
<div class="lake-row">
|
|
7990
8002
|
<input type="text" name="title" />
|
|
7991
8003
|
</div>
|
|
@@ -8020,7 +8032,7 @@ class LinkPopup {
|
|
|
8020
8032
|
root: this.container.find('.lake-url-row'),
|
|
8021
8033
|
name: 'copy',
|
|
8022
8034
|
icon: icons.get('copy'),
|
|
8023
|
-
tooltip: locale.link.copy(),
|
|
8035
|
+
tooltip: this.locale.link.copy(),
|
|
8024
8036
|
onClick: () => {
|
|
8025
8037
|
if (!this.linkNode) {
|
|
8026
8038
|
return;
|
|
@@ -8062,7 +8074,7 @@ class LinkPopup {
|
|
|
8062
8074
|
root: this.container.find('.lake-url-row'),
|
|
8063
8075
|
name: 'open',
|
|
8064
8076
|
icon: icons.get('open'),
|
|
8065
|
-
tooltip: locale.link.open(),
|
|
8077
|
+
tooltip: this.locale.link.open(),
|
|
8066
8078
|
onClick: () => {
|
|
8067
8079
|
if (!this.linkNode) {
|
|
8068
8080
|
return;
|
|
@@ -8079,7 +8091,7 @@ class LinkPopup {
|
|
|
8079
8091
|
root: this.container.find('.lake-button-row'),
|
|
8080
8092
|
name: 'save',
|
|
8081
8093
|
icon: icons.get('check'),
|
|
8082
|
-
text: locale.link.save(),
|
|
8094
|
+
text: this.locale.link.save(),
|
|
8083
8095
|
onClick: () => {
|
|
8084
8096
|
if (!this.linkNode) {
|
|
8085
8097
|
return;
|
|
@@ -8098,7 +8110,7 @@ class LinkPopup {
|
|
|
8098
8110
|
root: this.container.find('.lake-button-row'),
|
|
8099
8111
|
name: 'unlink',
|
|
8100
8112
|
icon: icons.get('unlink'),
|
|
8101
|
-
text: locale.link.unlink(),
|
|
8113
|
+
text: this.locale.link.unlink(),
|
|
8102
8114
|
onClick: () => {
|
|
8103
8115
|
if (!this.linkNode) {
|
|
8104
8116
|
return;
|
|
@@ -8204,7 +8216,10 @@ var link = (editor) => {
|
|
|
8204
8216
|
if (editor.readonly) {
|
|
8205
8217
|
return;
|
|
8206
8218
|
}
|
|
8207
|
-
const popup = new LinkPopup(
|
|
8219
|
+
const popup = new LinkPopup({
|
|
8220
|
+
root: editor.popupContainer,
|
|
8221
|
+
locale: editor.locale,
|
|
8222
|
+
});
|
|
8208
8223
|
popup.event.on('save', node => {
|
|
8209
8224
|
const range = editor.selection.range;
|
|
8210
8225
|
range.setStartAfter(node);
|
|
@@ -8244,7 +8259,7 @@ var link = (editor) => {
|
|
|
8244
8259
|
});
|
|
8245
8260
|
editor.command.add('link', {
|
|
8246
8261
|
execute: () => {
|
|
8247
|
-
const linkNode = editor.selection.insertLink(`<a href="">${locale.link.newLink()}</a>`);
|
|
8262
|
+
const linkNode = editor.selection.insertLink(`<a href="">${editor.locale.link.newLink()}</a>`);
|
|
8248
8263
|
if (!linkNode) {
|
|
8249
8264
|
return;
|
|
8250
8265
|
}
|
|
@@ -8357,6 +8372,12 @@ const headingTypeMap = new Map([
|
|
|
8357
8372
|
['#####', 'h5'],
|
|
8358
8373
|
['######', 'h6'],
|
|
8359
8374
|
]);
|
|
8375
|
+
const shortLangTypeMap = new Map([
|
|
8376
|
+
['js', 'javascript'],
|
|
8377
|
+
['ts', 'typescript'],
|
|
8378
|
+
['md', 'markdown'],
|
|
8379
|
+
['htm', 'html'],
|
|
8380
|
+
]);
|
|
8360
8381
|
const markItemList = [
|
|
8361
8382
|
{
|
|
8362
8383
|
re: /\*\*(.+?)\*\*$/,
|
|
@@ -8475,6 +8496,7 @@ const blockItemListForEnterKey = [
|
|
|
8475
8496
|
{
|
|
8476
8497
|
re: /^`+([a-z]*)$/i,
|
|
8477
8498
|
getParameters: (results) => {
|
|
8499
|
+
var _a;
|
|
8478
8500
|
if (!results[1]) {
|
|
8479
8501
|
return [
|
|
8480
8502
|
'codeBlock',
|
|
@@ -8483,7 +8505,7 @@ const blockItemListForEnterKey = [
|
|
|
8483
8505
|
return [
|
|
8484
8506
|
'codeBlock',
|
|
8485
8507
|
{
|
|
8486
|
-
lang: results[1],
|
|
8508
|
+
lang: (_a = shortLangTypeMap.get(results[1])) !== null && _a !== void 0 ? _a : results[1],
|
|
8487
8509
|
},
|
|
8488
8510
|
];
|
|
8489
8511
|
},
|
|
@@ -9232,7 +9254,7 @@ var escapeKey = (editor) => {
|
|
|
9232
9254
|
selection.addRangeToNativeSelection();
|
|
9233
9255
|
return;
|
|
9234
9256
|
}
|
|
9235
|
-
if (editor.
|
|
9257
|
+
if (editor.hasFocus) {
|
|
9236
9258
|
event.preventDefault();
|
|
9237
9259
|
editor.blur();
|
|
9238
9260
|
}
|