lakelib 0.1.1 → 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/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';
@@ -737,7 +737,7 @@ class Nodes {
737
737
  }
738
738
  return block;
739
739
  }
740
- // Traverses the first node and its parents until it finds a root element which has contenteditable="true" attribute..
740
+ // Traverses the first node and its parents until it finds a root element which has contenteditable="true" attribute.
741
741
  closestContainer() {
742
742
  return this.closest('div[contenteditable="true"]');
743
743
  }
@@ -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
- class Dropdown {
4064
- constructor(config) {
4065
- this.documentClickListener = (event) => {
4066
- const targetNode = new Nodes(event.target);
4067
- const titleNode = this.node.find('.lake-dropdown-title');
4068
- const menuNode = this.node.find('.lake-dropdown-menu');
4069
- if (targetNode.closest('.lake-dropdown-title').get(0) === titleNode.get(0)) {
4070
- return;
4071
- }
4072
- menuNode.hide();
4073
- document.removeEventListener('click', this.documentClickListener);
4074
- };
4075
- this.config = config;
4076
- this.root = config.root;
4077
- this.node = query(safeTemplate `
4078
- <div class="lake-dropdown lake-${config.menuType}-dropdown" name="${config.name}">
4079
- <button type="button" name="${config.name}" class="lake-dropdown-title">
4080
- <div class="lake-dropdown-${config.icon ? 'icon' : 'text'}"></div>
4081
- <div class="lake-dropdown-down-icon"></div>
4082
- </button>
4083
- </div>
4084
- `);
4085
- if (config.tabIndex !== undefined) {
4086
- const titleNode = this.node.find('.lake-dropdown-title');
4087
- titleNode.attr('tabindex', config.tabIndex.toString());
4088
- }
4089
- }
4090
- // Returns the value of the node.
4091
- static getValue(node) {
4092
- const value = node.attr('value');
4093
- if (value === '') {
4094
- return [];
4095
- }
4096
- return JSON.parse(Base64.decode(value));
4097
- }
4098
- // Updates the value of the node.
4099
- static setValue(node, value) {
4100
- node.attr('value', Base64.encode(JSON.stringify(value)));
4101
- }
4102
- static getMenuMap(menuItems) {
4103
- const menuMap = new Map();
4104
- for (const menuItem of menuItems) {
4105
- // remove HTML tags
4106
- const text = menuItem.text.replace(/<[^>]*>/g, '');
4107
- menuMap.set(menuItem.value, text);
4108
- }
4109
- return menuMap;
4110
- }
4111
- updateColorAccent(titleNode, value) {
4112
- const svgNode = titleNode.find('.lake-dropdown-icon svg').eq(1);
4113
- const lineNode = svgNode.find('line');
4114
- if (lineNode.length > 0) {
4115
- lineNode.attr('stroke', value);
4116
- }
4117
- else {
4118
- svgNode.find('path').attr('fill', value);
4119
- }
4120
- }
4121
- apppendMenuItems(menuNode) {
4122
- const config = this.config;
4123
- for (const menuItem of config.menuItems) {
4124
- const listContent = template `
4125
- <li value="${encode(menuItem.value)}">
4126
- <div class="lake-dropdown-menu-text">${menuItem.text}</div>
4127
- </li>
4128
- `;
4129
- const listNode = query(listContent);
4130
- menuNode.append(listNode);
4131
- if (config.menuType === 'color') {
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.1";
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
- function removeBox(range) {
4341
- if (range.commonAncestor.isOutside) {
4342
- return null;
4343
- }
4344
- const boxNode = range.commonAncestor.closest('lake-box');
4345
- if (boxNode.length === 0) {
4346
- return null;
4347
- }
4348
- const box = new Box(boxNode);
4349
- if (box.type === 'block') {
4350
- const paragraph = query('<p><br /></p>');
4351
- boxNode.before(paragraph);
4352
- range.shrinkAfter(paragraph);
4353
- box.unmount();
4354
- boxNode.remove();
4355
- return box;
4356
- }
4357
- range.setStartBefore(boxNode);
4358
- range.collapseToStart();
4359
- const parentNode = boxNode.parent();
4360
- box.unmount();
4361
- boxNode.remove();
4362
- if (parentNode.isEmpty) {
4363
- appendDeepest(parentNode, query('<br />'));
4364
- range.shrinkAfter(parentNode);
4365
- }
4366
- return box;
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
- // Returns the attributes of the element as an key-value object.
4370
- function getAttributes(node) {
4371
- const nativeNode = node.get(0);
4372
- const attributes = {};
4373
- if (nativeNode.hasAttributes()) {
4374
- for (const attr of nativeNode.attributes) {
4375
- attributes[attr.name] = attr.value;
4376
- }
4377
- }
4378
- return attributes;
4379
- }
4380
- function pushAncestralNodes(appliedItems, range) {
4381
- let parentNode = range.startNode;
4382
- if (parentNode.isText) {
4383
- parentNode = parentNode.parent();
4384
- }
4385
- while (parentNode.length > 0) {
4386
- if (!parentNode.isInside) {
4387
- break;
4388
- }
4389
- appliedItems.push({
4390
- node: parentNode,
4391
- name: parentNode.name,
4392
- attributes: getAttributes(parentNode),
4393
- styles: parseStyle(parentNode.attr('style')),
4394
- });
4395
- parentNode = parentNode.parent();
4396
- }
4397
- }
4398
- function pushNextNestedNodes(appliedItems, range) {
4399
- const startNode = range.startNode;
4400
- let nextNode;
4401
- if (startNode.isText && startNode.text().length === range.startOffset) {
4402
- const node = startNode.next();
4403
- if (node.length > 0 && node.isElement) {
4404
- nextNode = node;
4405
- }
4406
- }
4407
- if (startNode.isElement) {
4408
- const children = startNode.children();
4409
- if (children.length > 0) {
4410
- const node = children[range.startOffset];
4411
- if (node && node.isElement) {
4412
- nextNode = node;
4413
- }
4414
- }
4415
- }
4416
- if (nextNode) {
4417
- let child = nextNode;
4418
- while (child.length > 0) {
4419
- if (child.isElement) {
4420
- appliedItems.push({
4421
- node: child,
4422
- name: child.name,
4423
- attributes: getAttributes(child),
4424
- styles: parseStyle(child.attr('style')),
4425
- });
4426
- }
4427
- child = child.first();
4428
- }
4429
- }
4430
- }
4431
- class Selection {
4432
- constructor(container) {
4433
- const selection = window.getSelection();
4434
- // When called on an <iframe> that is not displayed (e.g., where 'display: none' is set) Firefox will return null,
4435
- // whereas other browsers will return a selection object with Selection.type set to None.
4436
- if (!selection) {
4437
- throw new Error('Selection object is null.');
4438
- }
4439
- this.selection = selection;
4440
- this.container = container;
4441
- this.range = this.getRangeFromNativeSelection();
4442
- }
4443
- // Returns the current selected range from the native selection.
4444
- getRangeFromNativeSelection() {
4445
- if (this.selection.rangeCount > 0) {
4446
- const range = this.selection.getRangeAt(0);
4447
- return new Range(range);
4448
- }
4449
- return new Range();
4450
- }
4451
- // Adds the saved range to the native selection.
4452
- addRangeToNativeSelection() {
4453
- this.selection.removeAllRanges();
4454
- this.selection.addRange(this.range.get());
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
- // Synchronizes the saved range with the range of the native selection.
4457
- syncByRange() {
4458
- const newRange = this.getRangeFromNativeSelection();
4459
- if (this.range.get() === newRange.get()) {
4460
- return;
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
- // Synchronizes the saved range with the range represented by the bookmark.
4465
- synByBookmark() {
4466
- const range = this.range;
4467
- const container = this.container;
4468
- const boxFocus = container.find('lake-box[focus]');
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
- const anchor = container.find('lake-bookmark[type="anchor"]');
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
- insertBookmark() {
4492
- return insertBookmark(this.range);
4409
+ // Updates the value of the node.
4410
+ static setValue(node, value) {
4411
+ node.attr('value', Base64.encode(JSON.stringify(value)));
4493
4412
  }
4494
- toBookmark(bookmark) {
4495
- return toBookmark(this.range, bookmark);
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
- insertNode(node) {
4498
- return insertNode(this.range, node);
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
- insertFragment(fragment) {
4501
- return insertFragment(this.range, fragment);
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
- insertContents(value) {
4504
- return insertContents(this.range, value);
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
- deleteContents() {
4507
- return deleteContents(this.range);
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
- setBlocks(value) {
4510
- return setBlocks(this.range, value);
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
- splitBlock() {
4513
- return splitBlock$1(this.range);
4610
+ unmount() {
4611
+ this.node.remove();
4612
+ document.removeEventListener('click', this.documentClickListener);
4514
4613
  }
4515
- splitMarks(removeEmptyMark) {
4516
- return splitMarks(this.range, removeEmptyMark);
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
- addMark(value) {
4519
- return addMark(this.range, value);
4623
+ const box = new Box(boxName);
4624
+ if (boxValue) {
4625
+ box.value = boxValue;
4520
4626
  }
4521
- removeMark(value) {
4522
- return removeMark(this.range, value);
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
- fixList() {
4525
- return fixList(this.range);
4636
+ // block box
4637
+ const parts = splitBlock$1(range);
4638
+ if (parts.start) {
4639
+ range.setEndAfter(parts.start);
4640
+ range.collapseToEnd();
4526
4641
  }
4527
- insertLink(value) {
4528
- return insertLink(this.range, value);
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
- class Command {
4533
- constructor(selection) {
4534
- this.commandMap = new Map();
4535
- this.event = new EventEmitter();
4536
- this.selection = selection;
4654
+ function removeBox(range) {
4655
+ if (range.commonAncestor.isOutside) {
4656
+ return null;
4537
4657
  }
4538
- add(name, commandItem) {
4539
- this.commandMap.set(name, commandItem);
4658
+ const boxNode = range.commonAncestor.closest('lake-box');
4659
+ if (boxNode.length === 0) {
4660
+ return null;
4540
4661
  }
4541
- delete(name) {
4542
- this.commandMap.delete(name);
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
- getNames() {
4545
- return Array.from(this.commandMap.keys());
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;
@@ -4901,6 +5215,7 @@ const defaultConfig = {
4901
5215
  spellcheck: false,
4902
5216
  tabIndex: 0,
4903
5217
  indentWithTab: true,
5218
+ lang: 'en-US',
4904
5219
  minChangeSize: 5,
4905
5220
  };
4906
5221
  class Editor {
@@ -5142,563 +5457,256 @@ class Editor {
5142
5457
  this.command.event.on('beforeexecute', () => this.commitUnsavedInputData());
5143
5458
  }
5144
5459
  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
- if (!this.readonly) {
5278
- this.bindFocusEvents();
5279
- this.selection.synByBookmark();
5280
- this.history.save();
5281
- Editor.plugin.loadAll(this);
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
- };
5591
-
5592
- const localeTranslations = {
5593
- 'en-US': enUS,
5594
- 'zh-CN': zhCN,
5595
- ja,
5596
- ko,
5597
- };
5598
- const locales = Object.keys(localeTranslations);
5599
- const loadedLocales = {};
5600
- const loadedFormatters = {};
5601
- const initFormatters = () => {
5602
- const formatters = {
5603
- // add your formatter functions here
5604
- };
5605
- return formatters;
5606
- };
5607
- const loadFormatters = (locale) => {
5608
- loadedFormatters[locale] = initFormatters();
5609
- };
5610
- const loadLocale = (locale) => {
5611
- if (loadedLocales[locale]) {
5612
- return;
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
+ });
5613
5472
  }
5614
- loadedLocales[locale] = localeTranslations[locale];
5615
- loadFormatters(locale);
5616
- };
5617
- const loadAllLocales = () => locales.forEach(loadLocale);
5618
- const i18nObject = (locale) => i18nObject$1(locale, loadedLocales[locale], loadedFormatters[locale]);
5619
- loadAllLocales();
5620
- const language = locales.indexOf(window.LAKE_LANGUAGE) >= 0 ? window.LAKE_LANGUAGE : 'en-US';
5621
- const locale = i18nObject(language);
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');
@@ -6991,7 +7004,6 @@ const imageBox = {
6991
7004
  };
6992
7005
 
6993
7006
  const config = {
6994
- defaultLang: 'text',
6995
7007
  comment: '#57606a',
6996
7008
  name: '#444d56',
6997
7009
  variableName: '#953800',
@@ -7086,19 +7098,22 @@ const codeBlockBox = {
7086
7098
  return;
7087
7099
  }
7088
7100
  // begin to create CodeMirror
7089
- const CodeMirror = window.CodeMirror;
7101
+ const CodeMirror = window.LakeCodeMirror;
7090
7102
  if (!CodeMirror) {
7091
7103
  codeBlockNode.addClass('lake-code-block-error');
7092
7104
  codeBlockNode.text(`
7093
- The code cannot be displayed because window.CodeMirror is not found.
7094
- Please check if the CodeMirror file is added to this page.
7105
+ The code cannot be displayed because window.LakeCodeMirror is not found.
7106
+ Please check if the "lake-codemirror" library is added to this page.
7095
7107
  `.trim());
7096
7108
  codeBlockNode.on('click', () => {
7097
7109
  editor.selection.range.selectBox(box.node);
7098
7110
  });
7099
7111
  return;
7100
7112
  }
7101
- const { EditorState, Compartment, EditorView, keymap, history, defaultKeymap, historyKeymap, indentWithTab, syntaxHighlighting, langItems, } = CodeMirror;
7113
+ const { EditorState, Compartment, EditorView, keymap, history, defaultKeymap, historyKeymap, indentWithTab, syntaxHighlighting, } = CodeMirror;
7114
+ const defaultLangItems = CodeMirror.langItems;
7115
+ const codeBlockConfig = editor.config.codeBlock;
7116
+ const langItems = defaultLangItems.filter((item) => codeBlockConfig.langList.indexOf(item.value) >= 0);
7102
7117
  // language menu items
7103
7118
  const langItemMap = new Map();
7104
7119
  for (const item of langItems) {
@@ -7128,6 +7143,7 @@ const codeBlockBox = {
7128
7143
  doc: (_a = boxValue.code) !== null && _a !== void 0 ? _a : '',
7129
7144
  extensions: [
7130
7145
  EditorState.readOnly.of(editor.readonly),
7146
+ EditorView.editable.of(!editor.readonly),
7131
7147
  history(),
7132
7148
  keymap.of([
7133
7149
  ...defaultKeymap,
@@ -7144,8 +7160,8 @@ const codeBlockBox = {
7144
7160
  root: codeBlockNode,
7145
7161
  name: 'langType',
7146
7162
  downIcon: icons.get('down'),
7147
- defaultValue: langItem ? boxValue.lang : config.defaultLang,
7148
- tooltip: locale.codeBlock.langType(),
7163
+ defaultValue: langItem ? boxValue.lang : codeBlockConfig.defaultLang,
7164
+ tooltip: editor.locale.codeBlock.langType(),
7149
7165
  width: 'auto',
7150
7166
  menuType: 'list',
7151
7167
  menuItems: langItems.map((item) => ({
@@ -7173,6 +7189,9 @@ const codeBlockBox = {
7173
7189
  };
7174
7190
 
7175
7191
  var copy = (editor) => {
7192
+ if (editor.readonly) {
7193
+ return;
7194
+ }
7176
7195
  editor.container.on('copy', event => {
7177
7196
  const range = editor.selection.range;
7178
7197
  if (range.isInsideBox) {
@@ -7197,6 +7216,9 @@ var copy = (editor) => {
7197
7216
  };
7198
7217
 
7199
7218
  var cut = (editor) => {
7219
+ if (editor.readonly) {
7220
+ return;
7221
+ }
7200
7222
  editor.container.on('cut', event => {
7201
7223
  const range = editor.selection.range;
7202
7224
  if (range.isInsideBox) {
@@ -7377,6 +7399,9 @@ function pasteFragment(editor, fragment) {
7377
7399
  editor.history.save();
7378
7400
  }
7379
7401
  var paste = (editor) => {
7402
+ if (editor.readonly) {
7403
+ return;
7404
+ }
7380
7405
  editor.container.on('paste', event => {
7381
7406
  const { requestTypes } = editor.config.image;
7382
7407
  const range = editor.selection.range;
@@ -7423,6 +7448,9 @@ var paste = (editor) => {
7423
7448
  };
7424
7449
 
7425
7450
  var undo = (editor) => {
7451
+ if (editor.readonly) {
7452
+ return;
7453
+ }
7426
7454
  editor.command.add('undo', {
7427
7455
  execute: () => {
7428
7456
  editor.history.undo();
@@ -7439,6 +7467,9 @@ var undo = (editor) => {
7439
7467
  };
7440
7468
 
7441
7469
  var redo = (editor) => {
7470
+ if (editor.readonly) {
7471
+ return;
7472
+ }
7442
7473
  editor.command.add('redo', {
7443
7474
  execute: () => {
7444
7475
  editor.history.redo();
@@ -7457,6 +7488,9 @@ var redo = (editor) => {
7457
7488
  };
7458
7489
 
7459
7490
  var selectAll = (editor) => {
7491
+ if (editor.readonly) {
7492
+ return;
7493
+ }
7460
7494
  editor.command.add('selectAll', {
7461
7495
  execute: () => {
7462
7496
  const range = editor.selection.range;
@@ -7467,6 +7501,9 @@ var selectAll = (editor) => {
7467
7501
  };
7468
7502
 
7469
7503
  var heading = (editor) => {
7504
+ if (editor.readonly) {
7505
+ return;
7506
+ }
7470
7507
  editor.command.add('heading', {
7471
7508
  selectedValues: appliedItems => {
7472
7509
  const currentItem = appliedItems.find(item => item.node.isHeading || item.name === 'p');
@@ -7482,12 +7519,13 @@ var heading = (editor) => {
7482
7519
  const typeList = [
7483
7520
  'info',
7484
7521
  'tip',
7485
- 'success',
7486
7522
  'warning',
7487
- 'error',
7488
7523
  'danger',
7489
7524
  ];
7490
7525
  var blockQuote = (editor) => {
7526
+ if (editor.readonly) {
7527
+ return;
7528
+ }
7491
7529
  editor.command.add('blockQuote', {
7492
7530
  isSelected: appliedItems => !!appliedItems.find(item => item.name === 'blockquote'),
7493
7531
  execute: (type) => {
@@ -7515,6 +7553,9 @@ function setChecklist(editor, value) {
7515
7553
  editor.selection.setBlocks(`<ul type="checklist"><li value="${value}"></li></ul>`);
7516
7554
  }
7517
7555
  var list = (editor) => {
7556
+ if (editor.readonly) {
7557
+ return;
7558
+ }
7518
7559
  editor.command.add('list', {
7519
7560
  selectedValues: appliedItems => {
7520
7561
  let currentValue;
@@ -7615,6 +7656,9 @@ const alignValueMap = {
7615
7656
  end: 'right',
7616
7657
  };
7617
7658
  var align = (editor) => {
7659
+ if (editor.readonly) {
7660
+ return;
7661
+ }
7618
7662
  editor.command.add('align', {
7619
7663
  selectedValues: appliedItems => {
7620
7664
  let currentValue;
@@ -7639,6 +7683,9 @@ var align = (editor) => {
7639
7683
  };
7640
7684
 
7641
7685
  var indent = (editor) => {
7686
+ if (editor.readonly) {
7687
+ return;
7688
+ }
7642
7689
  editor.command.add('indent', {
7643
7690
  execute: (type) => {
7644
7691
  const blocks = editor.selection.range.getBlocks();
@@ -7652,6 +7699,9 @@ var indent = (editor) => {
7652
7699
 
7653
7700
  const tagName$6 = 'strong';
7654
7701
  var bold = (editor) => {
7702
+ if (editor.readonly) {
7703
+ return;
7704
+ }
7655
7705
  editor.command.add('bold', {
7656
7706
  isDisabled: appliedItems => !!appliedItems.find(item => item.node.isHeading),
7657
7707
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName$6),
@@ -7673,6 +7723,9 @@ var bold = (editor) => {
7673
7723
 
7674
7724
  const tagName$5 = 'i';
7675
7725
  var italic = (editor) => {
7726
+ if (editor.readonly) {
7727
+ return;
7728
+ }
7676
7729
  editor.command.add('italic', {
7677
7730
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName$5),
7678
7731
  execute: () => {
@@ -7693,6 +7746,9 @@ var italic = (editor) => {
7693
7746
 
7694
7747
  const tagName$4 = 'u';
7695
7748
  var underline = (editor) => {
7749
+ if (editor.readonly) {
7750
+ return;
7751
+ }
7696
7752
  editor.command.add('underline', {
7697
7753
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName$4),
7698
7754
  execute: () => {
@@ -7713,6 +7769,9 @@ var underline = (editor) => {
7713
7769
 
7714
7770
  const tagName$3 = 's';
7715
7771
  var strikethrough = (editor) => {
7772
+ if (editor.readonly) {
7773
+ return;
7774
+ }
7716
7775
  editor.command.add('strikethrough', {
7717
7776
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName$3),
7718
7777
  execute: () => {
@@ -7733,6 +7792,9 @@ var strikethrough = (editor) => {
7733
7792
 
7734
7793
  const tagName$2 = 'sub';
7735
7794
  var subscript = (editor) => {
7795
+ if (editor.readonly) {
7796
+ return;
7797
+ }
7736
7798
  editor.command.add('subscript', {
7737
7799
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName$2),
7738
7800
  execute: () => {
@@ -7749,6 +7811,9 @@ var subscript = (editor) => {
7749
7811
 
7750
7812
  const tagName$1 = 'sup';
7751
7813
  var superscript = (editor) => {
7814
+ if (editor.readonly) {
7815
+ return;
7816
+ }
7752
7817
  editor.command.add('superscript', {
7753
7818
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName$1),
7754
7819
  execute: () => {
@@ -7765,6 +7830,9 @@ var superscript = (editor) => {
7765
7830
 
7766
7831
  const tagName = 'code';
7767
7832
  var code = (editor) => {
7833
+ if (editor.readonly) {
7834
+ return;
7835
+ }
7768
7836
  editor.command.add('code', {
7769
7837
  isSelected: appliedItems => !!appliedItems.find(item => item.name === tagName),
7770
7838
  execute: () => {
@@ -7780,6 +7848,9 @@ var code = (editor) => {
7780
7848
  };
7781
7849
 
7782
7850
  var fontFamily = (editor) => {
7851
+ if (editor.readonly) {
7852
+ return;
7853
+ }
7783
7854
  editor.command.add('fontFamily', {
7784
7855
  selectedValues: appliedItems => {
7785
7856
  for (const item of appliedItems) {
@@ -7798,6 +7869,9 @@ var fontFamily = (editor) => {
7798
7869
  };
7799
7870
 
7800
7871
  var fontSize = (editor) => {
7872
+ if (editor.readonly) {
7873
+ return;
7874
+ }
7801
7875
  editor.command.add('fontSize', {
7802
7876
  isDisabled: appliedItems => !!appliedItems.find(item => item.node.isHeading),
7803
7877
  selectedValues: appliedItems => {
@@ -7817,6 +7891,9 @@ var fontSize = (editor) => {
7817
7891
  };
7818
7892
 
7819
7893
  var fontColor = (editor) => {
7894
+ if (editor.readonly) {
7895
+ return;
7896
+ }
7820
7897
  editor.command.add('fontColor', {
7821
7898
  selectedValues: appliedItems => {
7822
7899
  for (const item of appliedItems) {
@@ -7835,6 +7912,9 @@ var fontColor = (editor) => {
7835
7912
  };
7836
7913
 
7837
7914
  var highlight = (editor) => {
7915
+ if (editor.readonly) {
7916
+ return;
7917
+ }
7838
7918
  editor.command.add('highlight', {
7839
7919
  selectedValues: appliedItems => {
7840
7920
  for (const item of appliedItems) {
@@ -7853,6 +7933,9 @@ var highlight = (editor) => {
7853
7933
  };
7854
7934
 
7855
7935
  var removeFormat = (editor) => {
7936
+ if (editor.readonly) {
7937
+ return;
7938
+ }
7856
7939
  editor.command.add('removeFormat', {
7857
7940
  execute: () => {
7858
7941
  editor.selection.removeMark();
@@ -7863,6 +7946,9 @@ var removeFormat = (editor) => {
7863
7946
 
7864
7947
  const formatPainterClassName = 'lake-format-painter';
7865
7948
  var formatPainter = (editor) => {
7949
+ if (editor.readonly) {
7950
+ return;
7951
+ }
7866
7952
  let markList = [];
7867
7953
  editor.command.add('formatPainter', {
7868
7954
  execute: () => {
@@ -7901,17 +7987,18 @@ var formatPainter = (editor) => {
7901
7987
  };
7902
7988
 
7903
7989
  class LinkPopup {
7904
- constructor(root) {
7990
+ constructor(config) {
7905
7991
  this.linkNode = null;
7906
7992
  this.event = new EventEmitter();
7907
- this.root = root;
7993
+ this.root = config.root;
7994
+ this.locale = config.locale || i18nObject('en-US');
7908
7995
  this.container = query(safeTemplate `
7909
7996
  <div class="lake-link-popup">
7910
- <div class="lake-row">${locale.link.url()}</div>
7997
+ <div class="lake-row">${this.locale.link.url()}</div>
7911
7998
  <div class="lake-row lake-url-row">
7912
7999
  <input type="text" name="url" />
7913
8000
  </div>
7914
- <div class="lake-row">${locale.link.title()}</div>
8001
+ <div class="lake-row">${this.locale.link.title()}</div>
7915
8002
  <div class="lake-row">
7916
8003
  <input type="text" name="title" />
7917
8004
  </div>
@@ -7946,7 +8033,7 @@ class LinkPopup {
7946
8033
  root: this.container.find('.lake-url-row'),
7947
8034
  name: 'copy',
7948
8035
  icon: icons.get('copy'),
7949
- tooltip: locale.link.copy(),
8036
+ tooltip: this.locale.link.copy(),
7950
8037
  onClick: () => {
7951
8038
  if (!this.linkNode) {
7952
8039
  return;
@@ -7988,7 +8075,7 @@ class LinkPopup {
7988
8075
  root: this.container.find('.lake-url-row'),
7989
8076
  name: 'open',
7990
8077
  icon: icons.get('open'),
7991
- tooltip: locale.link.open(),
8078
+ tooltip: this.locale.link.open(),
7992
8079
  onClick: () => {
7993
8080
  if (!this.linkNode) {
7994
8081
  return;
@@ -8005,7 +8092,7 @@ class LinkPopup {
8005
8092
  root: this.container.find('.lake-button-row'),
8006
8093
  name: 'save',
8007
8094
  icon: icons.get('check'),
8008
- text: locale.link.save(),
8095
+ text: this.locale.link.save(),
8009
8096
  onClick: () => {
8010
8097
  if (!this.linkNode) {
8011
8098
  return;
@@ -8024,7 +8111,7 @@ class LinkPopup {
8024
8111
  root: this.container.find('.lake-button-row'),
8025
8112
  name: 'unlink',
8026
8113
  icon: icons.get('unlink'),
8027
- text: locale.link.unlink(),
8114
+ text: this.locale.link.unlink(),
8028
8115
  onClick: () => {
8029
8116
  if (!this.linkNode) {
8030
8117
  return;
@@ -8127,7 +8214,13 @@ class LinkPopup {
8127
8214
  }
8128
8215
 
8129
8216
  var link = (editor) => {
8130
- const popup = new LinkPopup(editor.popupContainer);
8217
+ if (editor.readonly) {
8218
+ return;
8219
+ }
8220
+ const popup = new LinkPopup({
8221
+ root: editor.popupContainer,
8222
+ locale: editor.locale,
8223
+ });
8131
8224
  popup.event.on('save', node => {
8132
8225
  const range = editor.selection.range;
8133
8226
  range.setStartAfter(node);
@@ -8167,7 +8260,7 @@ var link = (editor) => {
8167
8260
  });
8168
8261
  editor.command.add('link', {
8169
8262
  execute: () => {
8170
- const linkNode = editor.selection.insertLink(`<a href="">${locale.link.newLink()}</a>`);
8263
+ const linkNode = editor.selection.insertLink(`<a href="">${editor.locale.link.newLink()}</a>`);
8171
8264
  if (!linkNode) {
8172
8265
  return;
8173
8266
  }
@@ -8178,6 +8271,9 @@ var link = (editor) => {
8178
8271
  };
8179
8272
 
8180
8273
  var hr = (editor) => {
8274
+ if (editor.readonly) {
8275
+ return;
8276
+ }
8181
8277
  editor.event.on('beforepaste', (nativeFragment) => {
8182
8278
  const fragment = new Fragment(nativeFragment);
8183
8279
  fragment.find('hr').each(nativeNode => {
@@ -8199,6 +8295,9 @@ var image = (editor) => {
8199
8295
  requestMethod: 'POST',
8200
8296
  requestTypes: ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml'],
8201
8297
  });
8298
+ if (editor.readonly) {
8299
+ return;
8300
+ }
8202
8301
  editor.event.on('beforepaste', (nativeFragment) => {
8203
8302
  const fragment = new Fragment(nativeFragment);
8204
8303
  fragment.find('img').each(nativeNode => {
@@ -8225,8 +8324,35 @@ var image = (editor) => {
8225
8324
  });
8226
8325
  };
8227
8326
 
8327
+ const langList = [
8328
+ 'text',
8329
+ 'c',
8330
+ 'csharp',
8331
+ 'cpp',
8332
+ 'css',
8333
+ 'go',
8334
+ 'html',
8335
+ 'java',
8336
+ 'javascript',
8337
+ 'json',
8338
+ 'markdown',
8339
+ 'php',
8340
+ 'python',
8341
+ 'rust',
8342
+ 'sql',
8343
+ 'typescript',
8344
+ 'xml',
8345
+ 'yaml',
8346
+ ];
8228
8347
  var codeBlock = (editor) => {
8229
- if (!window.CodeMirror) {
8348
+ if (!window.LakeCodeMirror) {
8349
+ return;
8350
+ }
8351
+ editor.setPluginConfig('codeBlock', {
8352
+ langList,
8353
+ defaultLang: 'text',
8354
+ });
8355
+ if (editor.readonly) {
8230
8356
  return;
8231
8357
  }
8232
8358
  editor.command.add('codeBlock', {
@@ -8247,6 +8373,12 @@ const headingTypeMap = new Map([
8247
8373
  ['#####', 'h5'],
8248
8374
  ['######', 'h6'],
8249
8375
  ]);
8376
+ const shortLangTypeMap = new Map([
8377
+ ['js', 'javascript'],
8378
+ ['ts', 'typescript'],
8379
+ ['md', 'markdown'],
8380
+ ['htm', 'html'],
8381
+ ]);
8250
8382
  const markItemList = [
8251
8383
  {
8252
8384
  re: /\*\*(.+?)\*\*$/,
@@ -8365,6 +8497,7 @@ const blockItemListForEnterKey = [
8365
8497
  {
8366
8498
  re: /^`+([a-z]*)$/i,
8367
8499
  getParameters: (results) => {
8500
+ var _a;
8368
8501
  if (!results[1]) {
8369
8502
  return [
8370
8503
  'codeBlock',
@@ -8373,7 +8506,7 @@ const blockItemListForEnterKey = [
8373
8506
  return [
8374
8507
  'codeBlock',
8375
8508
  {
8376
- lang: results[1],
8509
+ lang: (_a = shortLangTypeMap.get(results[1])) !== null && _a !== void 0 ? _a : results[1],
8377
8510
  },
8378
8511
  ];
8379
8512
  },
@@ -8505,6 +8638,9 @@ function enterKeyExecutesBlockCommand(editor, block) {
8505
8638
  return false;
8506
8639
  }
8507
8640
  var markdown = (editor) => {
8641
+ if (editor.readonly) {
8642
+ return;
8643
+ }
8508
8644
  editor.keystroke.setKeydown('space', event => {
8509
8645
  const selection = editor.selection;
8510
8646
  const range = selection.range;
@@ -8609,6 +8745,9 @@ function addBlockOrSplitBlockForBox(editor) {
8609
8745
  }
8610
8746
  }
8611
8747
  var enterKey = (editor) => {
8748
+ if (editor.readonly) {
8749
+ return;
8750
+ }
8612
8751
  editor.keystroke.setKeydown('enter', event => {
8613
8752
  const range = editor.selection.range;
8614
8753
  if (range.isInsideBox) {
@@ -8692,6 +8831,9 @@ function addBlockOrLineBreakForBox(editor) {
8692
8831
  }
8693
8832
  }
8694
8833
  var shiftEnterKey = (editor) => {
8834
+ if (editor.readonly) {
8835
+ return;
8836
+ }
8695
8837
  editor.keystroke.setKeydown('shift+enter', event => {
8696
8838
  const range = editor.selection.range;
8697
8839
  if (range.isInsideBox) {
@@ -8754,6 +8896,9 @@ function mergeWithPreviousBlock(editor, block) {
8754
8896
  editor.selection.fixList();
8755
8897
  }
8756
8898
  var backspaceKey = (editor) => {
8899
+ if (editor.readonly) {
8900
+ return;
8901
+ }
8757
8902
  editor.keystroke.setKeydown('backspace', event => {
8758
8903
  const range = editor.selection.range;
8759
8904
  if (range.isInsideBox) {
@@ -8871,6 +9016,9 @@ function mergeWithNextBlock(editor, block) {
8871
9016
  editor.selection.fixList();
8872
9017
  }
8873
9018
  var deleteKey = (editor) => {
9019
+ if (editor.readonly) {
9020
+ return;
9021
+ }
8874
9022
  editor.keystroke.setKeydown('delete', event => {
8875
9023
  const range = editor.selection.range;
8876
9024
  if (range.isInsideBox) {
@@ -8949,6 +9097,9 @@ var deleteKey = (editor) => {
8949
9097
  };
8950
9098
 
8951
9099
  var tabKey = (editor) => {
9100
+ if (editor.readonly) {
9101
+ return;
9102
+ }
8952
9103
  editor.keystroke.setKeydown('tab', event => {
8953
9104
  if (editor.config.indentWithTab === false) {
8954
9105
  return;
@@ -8967,6 +9118,9 @@ var tabKey = (editor) => {
8967
9118
  };
8968
9119
 
8969
9120
  var arrowKeys = (editor) => {
9121
+ if (editor.readonly) {
9122
+ return;
9123
+ }
8970
9124
  editor.keystroke.setKeydown('arrow-left', event => {
8971
9125
  const range = editor.selection.range;
8972
9126
  if (range.isInsideBox) {
@@ -9088,6 +9242,9 @@ var arrowKeys = (editor) => {
9088
9242
  };
9089
9243
 
9090
9244
  var escapeKey = (editor) => {
9245
+ if (editor.readonly) {
9246
+ return;
9247
+ }
9091
9248
  editor.keystroke.setKeydown('escape', event => {
9092
9249
  const selection = editor.selection;
9093
9250
  const range = selection.range;