lakelib 0.1.2 → 0.1.3
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 +20 -16
- package/dist/lake.min.js +22 -22
- package/dist/lake.min.js.map +1 -1
- package/lib/lake.css +20 -16
- package/lib/lake.js +1353 -1330
- package/lib/lake.js.map +1 -1
- package/lib/types/editor.d.ts +4 -0
- 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 +3 -2
- 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.3";
|
|
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;
|
|
@@ -4831,874 +5145,568 @@ class Keystroke {
|
|
|
4831
5145
|
break;
|
|
4832
5146
|
}
|
|
4833
5147
|
}
|
|
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
|
-
};
|
|
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
|
+
bindFocusEvents() {
|
|
5474
|
+
this.container.on('focus', () => {
|
|
5475
|
+
this.root.addClass('lake-root-focused');
|
|
5476
|
+
});
|
|
5477
|
+
this.container.on('blur', () => {
|
|
5478
|
+
this.root.removeClass('lake-root-focused');
|
|
5479
|
+
});
|
|
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.bindFocusEvents();
|
|
5599
|
+
this.selection.synByBookmark();
|
|
5600
|
+
this.history.save();
|
|
5601
|
+
}
|
|
5602
|
+
Editor.box.renderAll(this);
|
|
5603
|
+
if (this.toolbar) {
|
|
5604
|
+
this.toolbar.render(this);
|
|
5605
|
+
}
|
|
5606
|
+
if (!this.readonly) {
|
|
5607
|
+
window.addEventListener('beforeunload', this.beforeunloadListener);
|
|
5608
|
+
document.addEventListener('selectionchange', this.selectionchangeListener);
|
|
5609
|
+
document.addEventListener('click', this.clickListener);
|
|
5610
|
+
window.addEventListener('resize', this.resizeListener);
|
|
5611
|
+
this.bindInputEvents();
|
|
5612
|
+
this.bindHistoryEvents();
|
|
5613
|
+
}
|
|
5614
|
+
}
|
|
5615
|
+
// Destroys a rendered editor.
|
|
5616
|
+
unmount() {
|
|
5617
|
+
this.root.empty();
|
|
5618
|
+
this.popupContainer.remove();
|
|
5619
|
+
if (!this.readonly) {
|
|
5620
|
+
window.removeEventListener('beforeunload', this.beforeunloadListener);
|
|
5621
|
+
document.removeEventListener('selectionchange', this.selectionchangeListener);
|
|
5622
|
+
document.removeEventListener('click', this.clickListener);
|
|
5623
|
+
window.removeEventListener('resize', this.resizeListener);
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
}
|
|
5627
|
+
Editor.version = version;
|
|
5628
|
+
Editor.box = new BoxManager();
|
|
5629
|
+
Editor.plugin = new Plugin();
|
|
5622
5630
|
|
|
5623
5631
|
const headingMenuItems = [
|
|
5624
5632
|
{
|
|
5625
5633
|
value: 'h1',
|
|
5626
|
-
text: `<span style="font-weight: bold; font-size: 26px;">${locale.toolbar.heading1()}</span>`,
|
|
5634
|
+
text: locale => `<span style="font-weight: bold; font-size: 26px;">${locale.toolbar.heading1()}</span>`,
|
|
5627
5635
|
},
|
|
5628
5636
|
{
|
|
5629
5637
|
value: 'h2',
|
|
5630
|
-
text: `<span style="font-weight: bold; font-size: 24px;">${locale.toolbar.heading2()}</span>`,
|
|
5638
|
+
text: locale => `<span style="font-weight: bold; font-size: 24px;">${locale.toolbar.heading2()}</span>`,
|
|
5631
5639
|
},
|
|
5632
5640
|
{
|
|
5633
5641
|
value: 'h3',
|
|
5634
|
-
text: `<span style="font-weight: bold; font-size: 22px;">${locale.toolbar.heading3()}</span>`,
|
|
5642
|
+
text: locale => `<span style="font-weight: bold; font-size: 22px;">${locale.toolbar.heading3()}</span>`,
|
|
5635
5643
|
},
|
|
5636
5644
|
{
|
|
5637
5645
|
value: 'h4',
|
|
5638
|
-
text: `<span style="font-weight: bold; font-size: 20px;">${locale.toolbar.heading4()}</span>`,
|
|
5646
|
+
text: locale => `<span style="font-weight: bold; font-size: 20px;">${locale.toolbar.heading4()}</span>`,
|
|
5639
5647
|
},
|
|
5640
5648
|
{
|
|
5641
5649
|
value: 'h5',
|
|
5642
|
-
text: `<span style="font-weight: bold; font-size: 18px;">${locale.toolbar.heading5()}</span>`,
|
|
5650
|
+
text: locale => `<span style="font-weight: bold; font-size: 18px;">${locale.toolbar.heading5()}</span>`,
|
|
5643
5651
|
},
|
|
5644
5652
|
{
|
|
5645
5653
|
value: 'h6',
|
|
5646
|
-
text: `<span style="font-weight: bold; font-size: 16px;">${locale.toolbar.heading6()}</span>`,
|
|
5654
|
+
text: locale => `<span style="font-weight: bold; font-size: 16px;">${locale.toolbar.heading6()}</span>`,
|
|
5647
5655
|
},
|
|
5648
5656
|
{
|
|
5649
5657
|
value: 'p',
|
|
5650
|
-
text: locale.toolbar.paragraph(),
|
|
5658
|
+
text: locale => locale.toolbar.paragraph(),
|
|
5651
5659
|
},
|
|
5652
5660
|
];
|
|
5653
5661
|
const listMenuItems = [
|
|
5654
5662
|
{
|
|
5655
5663
|
icon: icons.get('numberedList'),
|
|
5656
5664
|
value: 'numbered',
|
|
5657
|
-
text: locale.toolbar.numberedList(),
|
|
5665
|
+
text: locale => locale.toolbar.numberedList(),
|
|
5658
5666
|
},
|
|
5659
5667
|
{
|
|
5660
5668
|
icon: icons.get('bulletedList'),
|
|
5661
5669
|
value: 'bulleted',
|
|
5662
|
-
text: locale.toolbar.bulletedList(),
|
|
5670
|
+
text: locale => locale.toolbar.bulletedList(),
|
|
5663
5671
|
},
|
|
5664
5672
|
{
|
|
5665
5673
|
icon: icons.get('checklist'),
|
|
5666
5674
|
value: 'checklist',
|
|
5667
|
-
text: locale.toolbar.checklist(),
|
|
5675
|
+
text: locale => locale.toolbar.checklist(),
|
|
5668
5676
|
},
|
|
5669
5677
|
];
|
|
5670
5678
|
const alignMenuItems = [
|
|
5671
5679
|
{
|
|
5672
5680
|
icon: icons.get('alignLeft'),
|
|
5673
5681
|
value: 'left',
|
|
5674
|
-
text: locale.toolbar.alignLeft(),
|
|
5682
|
+
text: locale => locale.toolbar.alignLeft(),
|
|
5675
5683
|
},
|
|
5676
5684
|
{
|
|
5677
5685
|
icon: icons.get('alignCenter'),
|
|
5678
5686
|
value: 'center',
|
|
5679
|
-
text: locale.toolbar.alignCenter(),
|
|
5687
|
+
text: locale => locale.toolbar.alignCenter(),
|
|
5680
5688
|
},
|
|
5681
5689
|
{
|
|
5682
5690
|
icon: icons.get('alignRight'),
|
|
5683
5691
|
value: 'right',
|
|
5684
|
-
text: locale.toolbar.alignRight(),
|
|
5692
|
+
text: locale => locale.toolbar.alignRight(),
|
|
5685
5693
|
},
|
|
5686
5694
|
{
|
|
5687
5695
|
icon: icons.get('alignJustify'),
|
|
5688
5696
|
value: 'justify',
|
|
5689
|
-
text: locale.toolbar.alignJustify(),
|
|
5697
|
+
text: locale => locale.toolbar.alignJustify(),
|
|
5690
5698
|
},
|
|
5691
5699
|
];
|
|
5692
5700
|
const indentMenuItems = [
|
|
5693
5701
|
{
|
|
5694
5702
|
icon: icons.get('increaseIndent'),
|
|
5695
5703
|
value: 'increase',
|
|
5696
|
-
text: locale.toolbar.increaseIndent(),
|
|
5704
|
+
text: locale => locale.toolbar.increaseIndent(),
|
|
5697
5705
|
},
|
|
5698
5706
|
{
|
|
5699
5707
|
icon: icons.get('decreaseIndent'),
|
|
5700
5708
|
value: 'decrease',
|
|
5701
|
-
text: locale.toolbar.decreaseIndent(),
|
|
5709
|
+
text: locale => locale.toolbar.decreaseIndent(),
|
|
5702
5710
|
},
|
|
5703
5711
|
];
|
|
5704
5712
|
const fontFamilyMenuItems = [
|
|
@@ -5785,32 +5793,32 @@ const moreStyleMenuItems = [
|
|
|
5785
5793
|
{
|
|
5786
5794
|
icon: icons.get('italic'),
|
|
5787
5795
|
value: 'italic',
|
|
5788
|
-
text: locale.toolbar.italic(),
|
|
5796
|
+
text: locale => locale.toolbar.italic(),
|
|
5789
5797
|
},
|
|
5790
5798
|
{
|
|
5791
5799
|
icon: icons.get('underline'),
|
|
5792
5800
|
value: 'underline',
|
|
5793
|
-
text: locale.toolbar.underline(),
|
|
5801
|
+
text: locale => locale.toolbar.underline(),
|
|
5794
5802
|
},
|
|
5795
5803
|
{
|
|
5796
5804
|
icon: icons.get('strikethrough'),
|
|
5797
5805
|
value: 'strikethrough',
|
|
5798
|
-
text: locale.toolbar.strikethrough(),
|
|
5806
|
+
text: locale => locale.toolbar.strikethrough(),
|
|
5799
5807
|
},
|
|
5800
5808
|
{
|
|
5801
5809
|
icon: icons.get('superscript'),
|
|
5802
5810
|
value: 'superscript',
|
|
5803
|
-
text: locale.toolbar.superscript(),
|
|
5811
|
+
text: locale => locale.toolbar.superscript(),
|
|
5804
5812
|
},
|
|
5805
5813
|
{
|
|
5806
5814
|
icon: icons.get('subscript'),
|
|
5807
5815
|
value: 'subscript',
|
|
5808
|
-
text: locale.toolbar.subscript(),
|
|
5816
|
+
text: locale => locale.toolbar.subscript(),
|
|
5809
5817
|
},
|
|
5810
5818
|
{
|
|
5811
5819
|
icon: icons.get('code'),
|
|
5812
5820
|
value: 'code',
|
|
5813
|
-
text: locale.toolbar.code(),
|
|
5821
|
+
text: locale => locale.toolbar.code(),
|
|
5814
5822
|
},
|
|
5815
5823
|
];
|
|
5816
5824
|
// These colors are from Ant Design (https://ant.design/docs/spec/colors)
|
|
@@ -5833,7 +5841,7 @@ const colorMenuItems = [
|
|
|
5833
5841
|
{
|
|
5834
5842
|
icon: icons.get('removeFormat'),
|
|
5835
5843
|
value: '',
|
|
5836
|
-
text: locale.toolbar.removeColor(),
|
|
5844
|
+
text: locale => locale.toolbar.removeColor(),
|
|
5837
5845
|
},
|
|
5838
5846
|
];
|
|
5839
5847
|
for (const color of colors) {
|
|
@@ -5858,7 +5866,7 @@ const toolbarItems = [
|
|
|
5858
5866
|
name: 'undo',
|
|
5859
5867
|
type: 'button',
|
|
5860
5868
|
icon: icons.get('undo'),
|
|
5861
|
-
tooltip: locale.toolbar.undo(),
|
|
5869
|
+
tooltip: locale => locale.toolbar.undo(),
|
|
5862
5870
|
onClick: (editor, value) => {
|
|
5863
5871
|
editor.command.execute(value);
|
|
5864
5872
|
},
|
|
@@ -5867,7 +5875,7 @@ const toolbarItems = [
|
|
|
5867
5875
|
name: 'redo',
|
|
5868
5876
|
type: 'button',
|
|
5869
5877
|
icon: icons.get('redo'),
|
|
5870
|
-
tooltip: locale.toolbar.redo(),
|
|
5878
|
+
tooltip: locale => locale.toolbar.redo(),
|
|
5871
5879
|
onClick: (editor, value) => {
|
|
5872
5880
|
editor.command.execute(value);
|
|
5873
5881
|
},
|
|
@@ -5876,7 +5884,7 @@ const toolbarItems = [
|
|
|
5876
5884
|
name: 'selectAll',
|
|
5877
5885
|
type: 'button',
|
|
5878
5886
|
icon: icons.get('selectAll'),
|
|
5879
|
-
tooltip: locale.toolbar.selectAll(),
|
|
5887
|
+
tooltip: locale => locale.toolbar.selectAll(),
|
|
5880
5888
|
onClick: (editor, value) => {
|
|
5881
5889
|
editor.command.execute(value);
|
|
5882
5890
|
},
|
|
@@ -5885,7 +5893,7 @@ const toolbarItems = [
|
|
|
5885
5893
|
name: 'paragraph',
|
|
5886
5894
|
type: 'button',
|
|
5887
5895
|
icon: icons.get('paragraph'),
|
|
5888
|
-
tooltip: locale.toolbar.paragraph(),
|
|
5896
|
+
tooltip: locale => locale.toolbar.paragraph(),
|
|
5889
5897
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'p'),
|
|
5890
5898
|
onClick: editor => {
|
|
5891
5899
|
editor.command.execute('heading', 'p');
|
|
@@ -5895,7 +5903,7 @@ const toolbarItems = [
|
|
|
5895
5903
|
name: 'blockQuote',
|
|
5896
5904
|
type: 'button',
|
|
5897
5905
|
icon: icons.get('blockQuote'),
|
|
5898
|
-
tooltip: locale.toolbar.blockQuote(),
|
|
5906
|
+
tooltip: locale => locale.toolbar.blockQuote(),
|
|
5899
5907
|
onClick: (editor, value) => {
|
|
5900
5908
|
editor.command.execute(value);
|
|
5901
5909
|
},
|
|
@@ -5904,7 +5912,7 @@ const toolbarItems = [
|
|
|
5904
5912
|
name: 'numberedList',
|
|
5905
5913
|
type: 'button',
|
|
5906
5914
|
icon: icons.get('numberedList'),
|
|
5907
|
-
tooltip: locale.toolbar.numberedList(),
|
|
5915
|
+
tooltip: locale => locale.toolbar.numberedList(),
|
|
5908
5916
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'ol'),
|
|
5909
5917
|
onClick: editor => {
|
|
5910
5918
|
editor.command.execute('list', 'numbered');
|
|
@@ -5914,7 +5922,7 @@ const toolbarItems = [
|
|
|
5914
5922
|
name: 'bulletedList',
|
|
5915
5923
|
type: 'button',
|
|
5916
5924
|
icon: icons.get('bulletedList'),
|
|
5917
|
-
tooltip: locale.toolbar.bulletedList(),
|
|
5925
|
+
tooltip: locale => locale.toolbar.bulletedList(),
|
|
5918
5926
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'ul' && !item.node.hasAttr('type')),
|
|
5919
5927
|
onClick: editor => {
|
|
5920
5928
|
editor.command.execute('list', 'bulleted');
|
|
@@ -5924,7 +5932,7 @@ const toolbarItems = [
|
|
|
5924
5932
|
name: 'checklist',
|
|
5925
5933
|
type: 'button',
|
|
5926
5934
|
icon: icons.get('checklist'),
|
|
5927
|
-
tooltip: locale.toolbar.checklist(),
|
|
5935
|
+
tooltip: locale => locale.toolbar.checklist(),
|
|
5928
5936
|
isSelected: appliedItems => !!appliedItems.find(item => item.name === 'ul' && item.node.attr('type') === 'checklist'),
|
|
5929
5937
|
onClick: editor => {
|
|
5930
5938
|
editor.command.execute('list', 'checklist');
|
|
@@ -5934,7 +5942,7 @@ const toolbarItems = [
|
|
|
5934
5942
|
name: 'alignLeft',
|
|
5935
5943
|
type: 'button',
|
|
5936
5944
|
icon: icons.get('alignLeft'),
|
|
5937
|
-
tooltip: locale.toolbar.alignLeft(),
|
|
5945
|
+
tooltip: locale => locale.toolbar.alignLeft(),
|
|
5938
5946
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'left'),
|
|
5939
5947
|
onClick: editor => {
|
|
5940
5948
|
editor.command.execute('align', 'left');
|
|
@@ -5944,7 +5952,7 @@ const toolbarItems = [
|
|
|
5944
5952
|
name: 'alignCenter',
|
|
5945
5953
|
type: 'button',
|
|
5946
5954
|
icon: icons.get('alignCenter'),
|
|
5947
|
-
tooltip: locale.toolbar.alignCenter(),
|
|
5955
|
+
tooltip: locale => locale.toolbar.alignCenter(),
|
|
5948
5956
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'center'),
|
|
5949
5957
|
onClick: editor => {
|
|
5950
5958
|
editor.command.execute('align', 'center');
|
|
@@ -5954,7 +5962,7 @@ const toolbarItems = [
|
|
|
5954
5962
|
name: 'alignRight',
|
|
5955
5963
|
type: 'button',
|
|
5956
5964
|
icon: icons.get('alignRight'),
|
|
5957
|
-
tooltip: locale.toolbar.alignRight(),
|
|
5965
|
+
tooltip: locale => locale.toolbar.alignRight(),
|
|
5958
5966
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'right'),
|
|
5959
5967
|
onClick: editor => {
|
|
5960
5968
|
editor.command.execute('align', 'right');
|
|
@@ -5964,7 +5972,7 @@ const toolbarItems = [
|
|
|
5964
5972
|
name: 'alignJustify',
|
|
5965
5973
|
type: 'button',
|
|
5966
5974
|
icon: icons.get('alignJustify'),
|
|
5967
|
-
tooltip: locale.toolbar.alignJustify(),
|
|
5975
|
+
tooltip: locale => locale.toolbar.alignJustify(),
|
|
5968
5976
|
isSelected: appliedItems => !!appliedItems.find(item => item.node.isBlock && item.node.css('text-align') === 'justify'),
|
|
5969
5977
|
onClick: editor => {
|
|
5970
5978
|
editor.command.execute('align', 'justify');
|
|
@@ -5974,7 +5982,7 @@ const toolbarItems = [
|
|
|
5974
5982
|
name: 'increaseIndent',
|
|
5975
5983
|
type: 'button',
|
|
5976
5984
|
icon: icons.get('increaseIndent'),
|
|
5977
|
-
tooltip: locale.toolbar.increaseIndent(),
|
|
5985
|
+
tooltip: locale => locale.toolbar.increaseIndent(),
|
|
5978
5986
|
onClick: editor => {
|
|
5979
5987
|
editor.command.execute('indent', 'increase');
|
|
5980
5988
|
},
|
|
@@ -5983,7 +5991,7 @@ const toolbarItems = [
|
|
|
5983
5991
|
name: 'decreaseIndent',
|
|
5984
5992
|
type: 'button',
|
|
5985
5993
|
icon: icons.get('decreaseIndent'),
|
|
5986
|
-
tooltip: locale.toolbar.decreaseIndent(),
|
|
5994
|
+
tooltip: locale => locale.toolbar.decreaseIndent(),
|
|
5987
5995
|
onClick: editor => {
|
|
5988
5996
|
editor.command.execute('indent', 'decrease');
|
|
5989
5997
|
},
|
|
@@ -5992,7 +6000,7 @@ const toolbarItems = [
|
|
|
5992
6000
|
name: 'bold',
|
|
5993
6001
|
type: 'button',
|
|
5994
6002
|
icon: icons.get('bold'),
|
|
5995
|
-
tooltip: locale.toolbar.bold(),
|
|
6003
|
+
tooltip: locale => locale.toolbar.bold(),
|
|
5996
6004
|
onClick: (editor, value) => {
|
|
5997
6005
|
editor.command.execute(value);
|
|
5998
6006
|
},
|
|
@@ -6001,7 +6009,7 @@ const toolbarItems = [
|
|
|
6001
6009
|
name: 'italic',
|
|
6002
6010
|
type: 'button',
|
|
6003
6011
|
icon: icons.get('italic'),
|
|
6004
|
-
tooltip: locale.toolbar.italic(),
|
|
6012
|
+
tooltip: locale => locale.toolbar.italic(),
|
|
6005
6013
|
onClick: (editor, value) => {
|
|
6006
6014
|
editor.command.execute(value);
|
|
6007
6015
|
},
|
|
@@ -6010,7 +6018,7 @@ const toolbarItems = [
|
|
|
6010
6018
|
name: 'underline',
|
|
6011
6019
|
type: 'button',
|
|
6012
6020
|
icon: icons.get('underline'),
|
|
6013
|
-
tooltip: locale.toolbar.underline(),
|
|
6021
|
+
tooltip: locale => locale.toolbar.underline(),
|
|
6014
6022
|
onClick: (editor, value) => {
|
|
6015
6023
|
editor.command.execute(value);
|
|
6016
6024
|
},
|
|
@@ -6019,7 +6027,7 @@ const toolbarItems = [
|
|
|
6019
6027
|
name: 'strikethrough',
|
|
6020
6028
|
type: 'button',
|
|
6021
6029
|
icon: icons.get('strikethrough'),
|
|
6022
|
-
tooltip: locale.toolbar.strikethrough(),
|
|
6030
|
+
tooltip: locale => locale.toolbar.strikethrough(),
|
|
6023
6031
|
onClick: (editor, value) => {
|
|
6024
6032
|
editor.command.execute(value);
|
|
6025
6033
|
},
|
|
@@ -6028,7 +6036,7 @@ const toolbarItems = [
|
|
|
6028
6036
|
name: 'superscript',
|
|
6029
6037
|
type: 'button',
|
|
6030
6038
|
icon: icons.get('superscript'),
|
|
6031
|
-
tooltip: locale.toolbar.superscript(),
|
|
6039
|
+
tooltip: locale => locale.toolbar.superscript(),
|
|
6032
6040
|
onClick: (editor, value) => {
|
|
6033
6041
|
editor.command.execute(value);
|
|
6034
6042
|
},
|
|
@@ -6037,7 +6045,7 @@ const toolbarItems = [
|
|
|
6037
6045
|
name: 'subscript',
|
|
6038
6046
|
type: 'button',
|
|
6039
6047
|
icon: icons.get('subscript'),
|
|
6040
|
-
tooltip: locale.toolbar.subscript(),
|
|
6048
|
+
tooltip: locale => locale.toolbar.subscript(),
|
|
6041
6049
|
onClick: (editor, value) => {
|
|
6042
6050
|
editor.command.execute(value);
|
|
6043
6051
|
},
|
|
@@ -6046,7 +6054,7 @@ const toolbarItems = [
|
|
|
6046
6054
|
name: 'code',
|
|
6047
6055
|
type: 'button',
|
|
6048
6056
|
icon: icons.get('code'),
|
|
6049
|
-
tooltip: locale.toolbar.code(),
|
|
6057
|
+
tooltip: locale => locale.toolbar.code(),
|
|
6050
6058
|
onClick: (editor, value) => {
|
|
6051
6059
|
editor.command.execute(value);
|
|
6052
6060
|
},
|
|
@@ -6055,7 +6063,7 @@ const toolbarItems = [
|
|
|
6055
6063
|
name: 'removeFormat',
|
|
6056
6064
|
type: 'button',
|
|
6057
6065
|
icon: icons.get('removeFormat'),
|
|
6058
|
-
tooltip: locale.toolbar.removeFormat(),
|
|
6066
|
+
tooltip: locale => locale.toolbar.removeFormat(),
|
|
6059
6067
|
onClick: (editor, value) => {
|
|
6060
6068
|
editor.command.execute(value);
|
|
6061
6069
|
},
|
|
@@ -6064,7 +6072,7 @@ const toolbarItems = [
|
|
|
6064
6072
|
name: 'formatPainter',
|
|
6065
6073
|
type: 'button',
|
|
6066
6074
|
icon: icons.get('formatPainter'),
|
|
6067
|
-
tooltip: locale.toolbar.formatPainter(),
|
|
6075
|
+
tooltip: locale => locale.toolbar.formatPainter(),
|
|
6068
6076
|
onClick: (editor, value) => {
|
|
6069
6077
|
editor.command.execute(value);
|
|
6070
6078
|
},
|
|
@@ -6073,7 +6081,7 @@ const toolbarItems = [
|
|
|
6073
6081
|
name: 'link',
|
|
6074
6082
|
type: 'button',
|
|
6075
6083
|
icon: icons.get('link'),
|
|
6076
|
-
tooltip: locale.toolbar.link(),
|
|
6084
|
+
tooltip: locale => locale.toolbar.link(),
|
|
6077
6085
|
onClick: (editor, value) => {
|
|
6078
6086
|
editor.command.execute(value);
|
|
6079
6087
|
},
|
|
@@ -6082,7 +6090,7 @@ const toolbarItems = [
|
|
|
6082
6090
|
name: 'hr',
|
|
6083
6091
|
type: 'button',
|
|
6084
6092
|
icon: icons.get('hr'),
|
|
6085
|
-
tooltip: locale.toolbar.hr(),
|
|
6093
|
+
tooltip: locale => locale.toolbar.hr(),
|
|
6086
6094
|
onClick: (editor, value) => {
|
|
6087
6095
|
editor.command.execute(value);
|
|
6088
6096
|
},
|
|
@@ -6091,7 +6099,7 @@ const toolbarItems = [
|
|
|
6091
6099
|
name: 'codeBlock',
|
|
6092
6100
|
type: 'button',
|
|
6093
6101
|
icon: icons.get('codeBlock'),
|
|
6094
|
-
tooltip: locale.toolbar.codeBlock(),
|
|
6102
|
+
tooltip: locale => locale.toolbar.codeBlock(),
|
|
6095
6103
|
onClick: (editor, value) => {
|
|
6096
6104
|
editor.command.execute(value);
|
|
6097
6105
|
},
|
|
@@ -6101,7 +6109,7 @@ const toolbarItems = [
|
|
|
6101
6109
|
type: 'dropdown',
|
|
6102
6110
|
downIcon: icons.get('down'),
|
|
6103
6111
|
defaultValue: 'p',
|
|
6104
|
-
tooltip: locale.toolbar.heading(),
|
|
6112
|
+
tooltip: locale => locale.toolbar.heading(),
|
|
6105
6113
|
width: '100px',
|
|
6106
6114
|
menuType: 'list',
|
|
6107
6115
|
menuItems: headingMenuItems,
|
|
@@ -6115,7 +6123,7 @@ const toolbarItems = [
|
|
|
6115
6123
|
downIcon: icons.get('down'),
|
|
6116
6124
|
icon: icons.get('list'),
|
|
6117
6125
|
defaultValue: '',
|
|
6118
|
-
tooltip: locale.toolbar.list(),
|
|
6126
|
+
tooltip: locale => locale.toolbar.list(),
|
|
6119
6127
|
width: 'auto',
|
|
6120
6128
|
menuType: 'list',
|
|
6121
6129
|
menuItems: listMenuItems,
|
|
@@ -6129,7 +6137,7 @@ const toolbarItems = [
|
|
|
6129
6137
|
downIcon: icons.get('down'),
|
|
6130
6138
|
icon: icons.get('alignLeft'),
|
|
6131
6139
|
defaultValue: '',
|
|
6132
|
-
tooltip: locale.toolbar.align(),
|
|
6140
|
+
tooltip: locale => locale.toolbar.align(),
|
|
6133
6141
|
width: 'auto',
|
|
6134
6142
|
menuType: 'list',
|
|
6135
6143
|
menuItems: alignMenuItems,
|
|
@@ -6143,7 +6151,7 @@ const toolbarItems = [
|
|
|
6143
6151
|
downIcon: icons.get('down'),
|
|
6144
6152
|
icon: icons.get('increaseIndent'),
|
|
6145
6153
|
defaultValue: '',
|
|
6146
|
-
tooltip: locale.toolbar.indent(),
|
|
6154
|
+
tooltip: locale => locale.toolbar.indent(),
|
|
6147
6155
|
width: 'auto',
|
|
6148
6156
|
menuType: 'list',
|
|
6149
6157
|
menuItems: indentMenuItems,
|
|
@@ -6156,7 +6164,7 @@ const toolbarItems = [
|
|
|
6156
6164
|
type: 'dropdown',
|
|
6157
6165
|
downIcon: icons.get('down'),
|
|
6158
6166
|
defaultValue: 'Segoe UI',
|
|
6159
|
-
tooltip: locale.toolbar.fontFamily(),
|
|
6167
|
+
tooltip: locale => locale.toolbar.fontFamily(),
|
|
6160
6168
|
width: '100px',
|
|
6161
6169
|
menuType: 'list',
|
|
6162
6170
|
menuItems: fontFamilyMenuItems,
|
|
@@ -6169,7 +6177,7 @@ const toolbarItems = [
|
|
|
6169
6177
|
type: 'dropdown',
|
|
6170
6178
|
downIcon: icons.get('down'),
|
|
6171
6179
|
defaultValue: '16px',
|
|
6172
|
-
tooltip: locale.toolbar.fontSize(),
|
|
6180
|
+
tooltip: locale => locale.toolbar.fontSize(),
|
|
6173
6181
|
width: '65px',
|
|
6174
6182
|
menuType: 'list',
|
|
6175
6183
|
menuItems: fontSizeMenuItems,
|
|
@@ -6182,7 +6190,7 @@ const toolbarItems = [
|
|
|
6182
6190
|
type: 'dropdown',
|
|
6183
6191
|
icon: icons.get('more'),
|
|
6184
6192
|
defaultValue: '',
|
|
6185
|
-
tooltip: locale.toolbar.moreStyle(),
|
|
6193
|
+
tooltip: locale => locale.toolbar.moreStyle(),
|
|
6186
6194
|
width: 'auto',
|
|
6187
6195
|
menuType: 'list',
|
|
6188
6196
|
menuItems: moreStyleMenuItems,
|
|
@@ -6208,7 +6216,7 @@ const toolbarItems = [
|
|
|
6208
6216
|
icon: icons.get('fontColor'),
|
|
6209
6217
|
accentIcon: icons.get('fontColorAccent'),
|
|
6210
6218
|
defaultValue: '#f5222d',
|
|
6211
|
-
tooltip: locale.toolbar.fontColor(),
|
|
6219
|
+
tooltip: locale => locale.toolbar.fontColor(),
|
|
6212
6220
|
width: 'auto',
|
|
6213
6221
|
menuType: 'color',
|
|
6214
6222
|
menuItems: colorMenuItems,
|
|
@@ -6223,7 +6231,7 @@ const toolbarItems = [
|
|
|
6223
6231
|
icon: icons.get('highlight'),
|
|
6224
6232
|
accentIcon: icons.get('highlightAccent'),
|
|
6225
6233
|
defaultValue: '#fadb14',
|
|
6226
|
-
tooltip: locale.toolbar.highlight(),
|
|
6234
|
+
tooltip: locale => locale.toolbar.highlight(),
|
|
6227
6235
|
width: 'auto',
|
|
6228
6236
|
menuType: 'color',
|
|
6229
6237
|
menuItems: colorMenuItems,
|
|
@@ -6235,7 +6243,7 @@ const toolbarItems = [
|
|
|
6235
6243
|
name: 'image',
|
|
6236
6244
|
type: 'upload',
|
|
6237
6245
|
icon: icons.get('image'),
|
|
6238
|
-
tooltip: locale.toolbar.image(),
|
|
6246
|
+
tooltip: locale => locale.toolbar.image(),
|
|
6239
6247
|
accept: 'image/*',
|
|
6240
6248
|
multiple: true,
|
|
6241
6249
|
},
|
|
@@ -6339,7 +6347,7 @@ class Toolbar {
|
|
|
6339
6347
|
root: this.container,
|
|
6340
6348
|
name: item.name,
|
|
6341
6349
|
icon: item.icon,
|
|
6342
|
-
tooltip: item.tooltip,
|
|
6350
|
+
tooltip: typeof item.tooltip === 'string' ? item.tooltip : item.tooltip(editor.locale),
|
|
6343
6351
|
tabIndex: -1,
|
|
6344
6352
|
onClick: () => {
|
|
6345
6353
|
editor.focus();
|
|
@@ -6351,6 +6359,7 @@ class Toolbar {
|
|
|
6351
6359
|
appendDropdown(editor, item) {
|
|
6352
6360
|
const dropdown = new Dropdown({
|
|
6353
6361
|
root: this.container,
|
|
6362
|
+
locale: editor.locale,
|
|
6354
6363
|
name: item.name,
|
|
6355
6364
|
icon: item.icon,
|
|
6356
6365
|
accentIcon: item.accentIcon,
|
|
@@ -6386,7 +6395,7 @@ class Toolbar {
|
|
|
6386
6395
|
root: uploadNode,
|
|
6387
6396
|
name: item.name,
|
|
6388
6397
|
icon: item.icon,
|
|
6389
|
-
tooltip: item.tooltip,
|
|
6398
|
+
tooltip: typeof item.tooltip === 'string' ? item.tooltip : item.tooltip(editor.locale),
|
|
6390
6399
|
tabIndex: -1,
|
|
6391
6400
|
onClick: () => {
|
|
6392
6401
|
editor.focus();
|
|
@@ -6491,7 +6500,7 @@ class Toolbar {
|
|
|
6491
6500
|
return;
|
|
6492
6501
|
}
|
|
6493
6502
|
if (item.type === 'dropdown') {
|
|
6494
|
-
this.allMenuMap.set(item.name, Dropdown.getMenuMap(item.menuItems));
|
|
6503
|
+
this.allMenuMap.set(item.name, Dropdown.getMenuMap(item.menuItems, editor.locale));
|
|
6495
6504
|
this.dropdownItemList.push(item);
|
|
6496
6505
|
this.appendDropdown(editor, item);
|
|
6497
6506
|
return;
|
|
@@ -6683,10 +6692,10 @@ function openFullScreen(box) {
|
|
|
6683
6692
|
arrowPrevSVG: icons.get('left'),
|
|
6684
6693
|
arrowNextSVG: icons.get('right'),
|
|
6685
6694
|
closeSVG: icons.get('close'),
|
|
6686
|
-
arrowPrevTitle: locale.image.previous(),
|
|
6687
|
-
arrowNextTitle: locale.image.next(),
|
|
6688
|
-
closeTitle: locale.image.close(),
|
|
6689
|
-
errorMsg: locale.image.loadingError(),
|
|
6695
|
+
arrowPrevTitle: editor.locale.image.previous(),
|
|
6696
|
+
arrowNextTitle: editor.locale.image.next(),
|
|
6697
|
+
closeTitle: editor.locale.image.close(),
|
|
6698
|
+
errorMsg: editor.locale.image.loadingError(),
|
|
6690
6699
|
});
|
|
6691
6700
|
lightbox.on('uiRegister', () => {
|
|
6692
6701
|
const pswp = lightbox.pswp;
|
|
@@ -6694,7 +6703,7 @@ function openFullScreen(box) {
|
|
|
6694
6703
|
name: 'zoom-out-button',
|
|
6695
6704
|
order: 8,
|
|
6696
6705
|
isButton: true,
|
|
6697
|
-
title: locale.image.zoomOut(),
|
|
6706
|
+
title: editor.locale.image.zoomOut(),
|
|
6698
6707
|
html: icons.get('zoomOut'),
|
|
6699
6708
|
onClick: () => {
|
|
6700
6709
|
const currSlide = pswp.currSlide;
|
|
@@ -6707,7 +6716,7 @@ function openFullScreen(box) {
|
|
|
6707
6716
|
name: 'zoom-in-button',
|
|
6708
6717
|
order: 9,
|
|
6709
6718
|
isButton: true,
|
|
6710
|
-
title: locale.image.zoomIn(),
|
|
6719
|
+
title: editor.locale.image.zoomIn(),
|
|
6711
6720
|
html: icons.get('zoomIn'),
|
|
6712
6721
|
onClick: () => {
|
|
6713
6722
|
const currSlide = pswp.currSlide;
|
|
@@ -6759,6 +6768,10 @@ function removeImageBox(box) {
|
|
|
6759
6768
|
// Displays error icon and filename.
|
|
6760
6769
|
function renderError(imageNode, box) {
|
|
6761
6770
|
return __awaiter(this, void 0, void 0, function* () {
|
|
6771
|
+
const editor = box.getEditor();
|
|
6772
|
+
if (!editor) {
|
|
6773
|
+
return;
|
|
6774
|
+
}
|
|
6762
6775
|
const value = box.value;
|
|
6763
6776
|
box.getContainer().css({
|
|
6764
6777
|
width: '',
|
|
@@ -6766,7 +6779,7 @@ function renderError(imageNode, box) {
|
|
|
6766
6779
|
});
|
|
6767
6780
|
const buttonGroupNode = query(safeTemplate `
|
|
6768
6781
|
<div class="lake-button-group">
|
|
6769
|
-
<button type="button" tabindex="-1" class="lake-button-remove" title="${locale.image.remove()}"></button>
|
|
6782
|
+
<button type="button" tabindex="-1" class="lake-button-remove" title="${editor.locale.image.remove()}"></button>
|
|
6770
6783
|
</div>
|
|
6771
6784
|
`);
|
|
6772
6785
|
const removeButton = buttonGroupNode.find('.lake-button-remove');
|
|
@@ -6816,7 +6829,7 @@ function renderUploading(imageNode, box) {
|
|
|
6816
6829
|
});
|
|
6817
6830
|
const buttonGroupNode = query(safeTemplate `
|
|
6818
6831
|
<div class="lake-button-group">
|
|
6819
|
-
<button type="button" tabindex="-1" class="lake-button-remove" title="${locale.image.remove()}"></button>
|
|
6832
|
+
<button type="button" tabindex="-1" class="lake-button-remove" title="${editor.locale.image.remove()}"></button>
|
|
6820
6833
|
</div>
|
|
6821
6834
|
`);
|
|
6822
6835
|
const removeButton = buttonGroupNode.find('.lake-button-remove');
|
|
@@ -6878,8 +6891,8 @@ function renderDone(imageNode, box) {
|
|
|
6878
6891
|
});
|
|
6879
6892
|
const buttonGroupNode = query(safeTemplate `
|
|
6880
6893
|
<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>
|
|
6894
|
+
<button type="button" tabindex="-1" class="lake-button-view" title="${editor.locale.image.view()}"></button>
|
|
6895
|
+
<button type="button" tabindex="-1" class="lake-button-remove" title="${editor.locale.image.remove()}"></button>
|
|
6883
6896
|
</div>
|
|
6884
6897
|
`);
|
|
6885
6898
|
const viewButton = buttonGroupNode.find('.lake-button-view');
|
|
@@ -7130,6 +7143,7 @@ const codeBlockBox = {
|
|
|
7130
7143
|
doc: (_a = boxValue.code) !== null && _a !== void 0 ? _a : '',
|
|
7131
7144
|
extensions: [
|
|
7132
7145
|
EditorState.readOnly.of(editor.readonly),
|
|
7146
|
+
EditorView.editable.of(!editor.readonly),
|
|
7133
7147
|
history(),
|
|
7134
7148
|
keymap.of([
|
|
7135
7149
|
...defaultKeymap,
|
|
@@ -7147,7 +7161,7 @@ const codeBlockBox = {
|
|
|
7147
7161
|
name: 'langType',
|
|
7148
7162
|
downIcon: icons.get('down'),
|
|
7149
7163
|
defaultValue: langItem ? boxValue.lang : codeBlockConfig.defaultLang,
|
|
7150
|
-
tooltip: locale.codeBlock.langType(),
|
|
7164
|
+
tooltip: editor.locale.codeBlock.langType(),
|
|
7151
7165
|
width: 'auto',
|
|
7152
7166
|
menuType: 'list',
|
|
7153
7167
|
menuItems: langItems.map((item) => ({
|
|
@@ -7505,9 +7519,7 @@ var heading = (editor) => {
|
|
|
7505
7519
|
const typeList = [
|
|
7506
7520
|
'info',
|
|
7507
7521
|
'tip',
|
|
7508
|
-
'success',
|
|
7509
7522
|
'warning',
|
|
7510
|
-
'error',
|
|
7511
7523
|
'danger',
|
|
7512
7524
|
];
|
|
7513
7525
|
var blockQuote = (editor) => {
|
|
@@ -7975,17 +7987,18 @@ var formatPainter = (editor) => {
|
|
|
7975
7987
|
};
|
|
7976
7988
|
|
|
7977
7989
|
class LinkPopup {
|
|
7978
|
-
constructor(
|
|
7990
|
+
constructor(config) {
|
|
7979
7991
|
this.linkNode = null;
|
|
7980
7992
|
this.event = new EventEmitter();
|
|
7981
|
-
this.root = root;
|
|
7993
|
+
this.root = config.root;
|
|
7994
|
+
this.locale = config.locale || i18nObject('en-US');
|
|
7982
7995
|
this.container = query(safeTemplate `
|
|
7983
7996
|
<div class="lake-link-popup">
|
|
7984
|
-
<div class="lake-row">${locale.link.url()}</div>
|
|
7997
|
+
<div class="lake-row">${this.locale.link.url()}</div>
|
|
7985
7998
|
<div class="lake-row lake-url-row">
|
|
7986
7999
|
<input type="text" name="url" />
|
|
7987
8000
|
</div>
|
|
7988
|
-
<div class="lake-row">${locale.link.title()}</div>
|
|
8001
|
+
<div class="lake-row">${this.locale.link.title()}</div>
|
|
7989
8002
|
<div class="lake-row">
|
|
7990
8003
|
<input type="text" name="title" />
|
|
7991
8004
|
</div>
|
|
@@ -8020,7 +8033,7 @@ class LinkPopup {
|
|
|
8020
8033
|
root: this.container.find('.lake-url-row'),
|
|
8021
8034
|
name: 'copy',
|
|
8022
8035
|
icon: icons.get('copy'),
|
|
8023
|
-
tooltip: locale.link.copy(),
|
|
8036
|
+
tooltip: this.locale.link.copy(),
|
|
8024
8037
|
onClick: () => {
|
|
8025
8038
|
if (!this.linkNode) {
|
|
8026
8039
|
return;
|
|
@@ -8062,7 +8075,7 @@ class LinkPopup {
|
|
|
8062
8075
|
root: this.container.find('.lake-url-row'),
|
|
8063
8076
|
name: 'open',
|
|
8064
8077
|
icon: icons.get('open'),
|
|
8065
|
-
tooltip: locale.link.open(),
|
|
8078
|
+
tooltip: this.locale.link.open(),
|
|
8066
8079
|
onClick: () => {
|
|
8067
8080
|
if (!this.linkNode) {
|
|
8068
8081
|
return;
|
|
@@ -8079,7 +8092,7 @@ class LinkPopup {
|
|
|
8079
8092
|
root: this.container.find('.lake-button-row'),
|
|
8080
8093
|
name: 'save',
|
|
8081
8094
|
icon: icons.get('check'),
|
|
8082
|
-
text: locale.link.save(),
|
|
8095
|
+
text: this.locale.link.save(),
|
|
8083
8096
|
onClick: () => {
|
|
8084
8097
|
if (!this.linkNode) {
|
|
8085
8098
|
return;
|
|
@@ -8098,7 +8111,7 @@ class LinkPopup {
|
|
|
8098
8111
|
root: this.container.find('.lake-button-row'),
|
|
8099
8112
|
name: 'unlink',
|
|
8100
8113
|
icon: icons.get('unlink'),
|
|
8101
|
-
text: locale.link.unlink(),
|
|
8114
|
+
text: this.locale.link.unlink(),
|
|
8102
8115
|
onClick: () => {
|
|
8103
8116
|
if (!this.linkNode) {
|
|
8104
8117
|
return;
|
|
@@ -8204,7 +8217,10 @@ var link = (editor) => {
|
|
|
8204
8217
|
if (editor.readonly) {
|
|
8205
8218
|
return;
|
|
8206
8219
|
}
|
|
8207
|
-
const popup = new LinkPopup(
|
|
8220
|
+
const popup = new LinkPopup({
|
|
8221
|
+
root: editor.popupContainer,
|
|
8222
|
+
locale: editor.locale,
|
|
8223
|
+
});
|
|
8208
8224
|
popup.event.on('save', node => {
|
|
8209
8225
|
const range = editor.selection.range;
|
|
8210
8226
|
range.setStartAfter(node);
|
|
@@ -8244,7 +8260,7 @@ var link = (editor) => {
|
|
|
8244
8260
|
});
|
|
8245
8261
|
editor.command.add('link', {
|
|
8246
8262
|
execute: () => {
|
|
8247
|
-
const linkNode = editor.selection.insertLink(`<a href="">${locale.link.newLink()}</a>`);
|
|
8263
|
+
const linkNode = editor.selection.insertLink(`<a href="">${editor.locale.link.newLink()}</a>`);
|
|
8248
8264
|
if (!linkNode) {
|
|
8249
8265
|
return;
|
|
8250
8266
|
}
|
|
@@ -8357,6 +8373,12 @@ const headingTypeMap = new Map([
|
|
|
8357
8373
|
['#####', 'h5'],
|
|
8358
8374
|
['######', 'h6'],
|
|
8359
8375
|
]);
|
|
8376
|
+
const shortLangTypeMap = new Map([
|
|
8377
|
+
['js', 'javascript'],
|
|
8378
|
+
['ts', 'typescript'],
|
|
8379
|
+
['md', 'markdown'],
|
|
8380
|
+
['htm', 'html'],
|
|
8381
|
+
]);
|
|
8360
8382
|
const markItemList = [
|
|
8361
8383
|
{
|
|
8362
8384
|
re: /\*\*(.+?)\*\*$/,
|
|
@@ -8475,6 +8497,7 @@ const blockItemListForEnterKey = [
|
|
|
8475
8497
|
{
|
|
8476
8498
|
re: /^`+([a-z]*)$/i,
|
|
8477
8499
|
getParameters: (results) => {
|
|
8500
|
+
var _a;
|
|
8478
8501
|
if (!results[1]) {
|
|
8479
8502
|
return [
|
|
8480
8503
|
'codeBlock',
|
|
@@ -8483,7 +8506,7 @@ const blockItemListForEnterKey = [
|
|
|
8483
8506
|
return [
|
|
8484
8507
|
'codeBlock',
|
|
8485
8508
|
{
|
|
8486
|
-
lang: results[1],
|
|
8509
|
+
lang: (_a = shortLangTypeMap.get(results[1])) !== null && _a !== void 0 ? _a : results[1],
|
|
8487
8510
|
},
|
|
8488
8511
|
];
|
|
8489
8512
|
},
|