leksy-editor 1.0.7 → 1.0.9
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/constant.js +4 -1
- package/index.js +3 -3
- package/package.json +1 -1
- package/plugin.js +10 -4
- package/utilities.js +81 -22
package/constant.js
CHANGED
|
@@ -362,7 +362,10 @@ const TABLE_PLUGINS = [
|
|
|
362
362
|
{ icon: SVG.CELL_BORDER_FULL, title: 'Border None', event: 'cell-border-none' },
|
|
363
363
|
|
|
364
364
|
{ icon: SVG.FIXED_COLUMN_WIDTH, title: 'Fixed Column', event: 'fixed-column-width' },
|
|
365
|
-
{ icon: SVG.COLOR, title: 'Color', event: 'border-color' },
|
|
365
|
+
{ icon: SVG.COLOR, title: 'Cell Border Color', event: 'border-color' },
|
|
366
|
+
{ icon: SVG.COLOR, title: 'Cell Background Color', event: 'background-color' },
|
|
367
|
+
{ icon: SVG.COLOR, title: 'Row Background Color', event: 'row-background-color' },
|
|
368
|
+
{ icon: SVG.COLOR, title: 'Column Background Color', event: 'column-background-color' },
|
|
366
369
|
]
|
|
367
370
|
|
|
368
371
|
const EMOJI_CATEGORIES = [
|
package/index.js
CHANGED
|
@@ -144,8 +144,8 @@ class LeksyEditor {
|
|
|
144
144
|
}
|
|
145
145
|
return content
|
|
146
146
|
},
|
|
147
|
-
handleFilePicker: async (mimeType,type) => {
|
|
148
|
-
if (editorRef.handleFilePicker instanceof Function) {return await editorRef.handleFilePicker(mimeType,type)}
|
|
147
|
+
handleFilePicker: async (mimeType, type) => {
|
|
148
|
+
if (editorRef.handleFilePicker instanceof Function) { return await editorRef.handleFilePicker(mimeType, type) }
|
|
149
149
|
return null
|
|
150
150
|
|
|
151
151
|
},
|
|
@@ -583,7 +583,7 @@ class LeksyEditor {
|
|
|
583
583
|
|
|
584
584
|
if (element.tagName === "A") showAnchorPopover(e.target, e.pageX, e.pageY, options, core)
|
|
585
585
|
if (element.tagName === 'IMG') initImageResizer('image', e.target, options, core)
|
|
586
|
-
if (element.tagName === 'TD') initTableEditPlugin(e.target, options, core)
|
|
586
|
+
if (element.tagName === 'TD' || element.tagName === 'TH') initTableEditPlugin(e.target, options, core)
|
|
587
587
|
if (element.tagName === "FIGURE") initImageResizer('figure', e.target, options, core)
|
|
588
588
|
}
|
|
589
589
|
contentEditableDiv.onpaste = (e) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leksy-editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Leksy Editor is an alternative to traditional WYSIWYG editors, designed primarily for creating mail templates, blogs, and documents without any content manipulation.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
package/plugin.js
CHANGED
|
@@ -87,6 +87,7 @@ const PLUGINS = {
|
|
|
87
87
|
click: (event, core) => {
|
|
88
88
|
core.elements.editor.focus();
|
|
89
89
|
core.elements.iframeWindow.execCommand('justifyFull');
|
|
90
|
+
core.resizerHandler()
|
|
90
91
|
core.updateCaretPosition()
|
|
91
92
|
|
|
92
93
|
changeToolbarStateByName(core, 'active', ['align_justify'])
|
|
@@ -100,6 +101,7 @@ const PLUGINS = {
|
|
|
100
101
|
click: (event, core) => {
|
|
101
102
|
core.elements.editor.focus();
|
|
102
103
|
core.elements.iframeWindow.execCommand('justifyLeft');
|
|
104
|
+
core.resizerHandler()
|
|
103
105
|
core.updateCaretPosition()
|
|
104
106
|
|
|
105
107
|
changeToolbarStateByName(core, 'active', ['align_left'])
|
|
@@ -113,6 +115,7 @@ const PLUGINS = {
|
|
|
113
115
|
click: (event, core) => {
|
|
114
116
|
core.elements.editor.focus();
|
|
115
117
|
core.elements.iframeWindow.execCommand('justifyRight');
|
|
118
|
+
core.resizerHandler()
|
|
116
119
|
core.updateCaretPosition()
|
|
117
120
|
|
|
118
121
|
changeToolbarStateByName(core, 'active', ['align_right'])
|
|
@@ -126,6 +129,7 @@ const PLUGINS = {
|
|
|
126
129
|
click: (event, core) => {
|
|
127
130
|
core.elements.editor.focus();
|
|
128
131
|
core.elements.iframeWindow.execCommand('justifyCenter');
|
|
132
|
+
core.resizerHandler()
|
|
129
133
|
core.updateCaretPosition()
|
|
130
134
|
|
|
131
135
|
changeToolbarStateByName(core, 'active', ['align_center'])
|
|
@@ -643,7 +647,7 @@ const PLUGINS = {
|
|
|
643
647
|
title: 'Table',
|
|
644
648
|
icon: SVG.TABLE,
|
|
645
649
|
type: 'table',
|
|
646
|
-
create: (core, options, { rows, cols }) => {
|
|
650
|
+
create: (core, options, { rows, cols, header }) => {
|
|
647
651
|
const table = document.createElement('table');
|
|
648
652
|
table.style.borderCollapse = 'collapse';
|
|
649
653
|
table.style.width = core.elements.editor.offsetWidth - 50 + 'px';
|
|
@@ -651,7 +655,7 @@ const PLUGINS = {
|
|
|
651
655
|
for (let i = 0; i <= rows; i++) {
|
|
652
656
|
const tr = document.createElement('tr');
|
|
653
657
|
for (let j = 0; j <= cols; j++) {
|
|
654
|
-
const td = document.createElement('td');
|
|
658
|
+
const td = i === 0 && header ? document.createElement('th') : document.createElement('td');
|
|
655
659
|
td.style.border = '1px solid black';
|
|
656
660
|
td.appendChild(document.createTextNode('\u00A0')); // Non-breaking space
|
|
657
661
|
tr.appendChild(td);
|
|
@@ -899,7 +903,7 @@ const PLUGINS = {
|
|
|
899
903
|
|
|
900
904
|
fileInput.addEventListener('click', async () => {
|
|
901
905
|
let file = await core.handleFilePicker(MIMETYPE.VIDEO.split(','), 'video');
|
|
902
|
-
if (MIMETYPE.VIDEO.includes(file
|
|
906
|
+
if (file && MIMETYPE.VIDEO.includes(file?.type)) {
|
|
903
907
|
const url = await core.uploadVideo(file);
|
|
904
908
|
if (url) {
|
|
905
909
|
const a = document.createElement('a');
|
|
@@ -932,7 +936,9 @@ const PLUGINS = {
|
|
|
932
936
|
|
|
933
937
|
fileInput.addEventListener('click', async () => {
|
|
934
938
|
let files = await core.handleFilePicker(["*"], 'attachment');
|
|
935
|
-
|
|
939
|
+
if (files) {
|
|
940
|
+
core.onAttachment(files);
|
|
941
|
+
}
|
|
936
942
|
|
|
937
943
|
});
|
|
938
944
|
fileInput.click();
|
package/utilities.js
CHANGED
|
@@ -44,7 +44,7 @@ const traverseAndClean = (element, options, core) => {
|
|
|
44
44
|
attributesToRemove.forEach(attr => node.removeAttribute(attr));
|
|
45
45
|
|
|
46
46
|
// Process child nodes
|
|
47
|
-
traverseAndClean(node, options,core);
|
|
47
|
+
traverseAndClean(node, options, core);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -367,6 +367,26 @@ const makeToolbarDropdown = (_plugin, options, core) => {
|
|
|
367
367
|
} else if (_plugin.type === 'table') {
|
|
368
368
|
const totalRows = 10;
|
|
369
369
|
const totalCols = 10;
|
|
370
|
+
|
|
371
|
+
// Create wrapper for table and checkbox
|
|
372
|
+
const wrapper = document.createElement('div');
|
|
373
|
+
wrapper.className = 'toolbar-table-wrapper'
|
|
374
|
+
|
|
375
|
+
// Create header checkbox
|
|
376
|
+
const headerOption = document.createElement('label');
|
|
377
|
+
headerOption.style.display = 'block';
|
|
378
|
+
headerOption.style.marginBottom = '8px';
|
|
379
|
+
|
|
380
|
+
const checkbox = document.createElement('input');
|
|
381
|
+
checkbox.type = 'checkbox';
|
|
382
|
+
checkbox.checked = true; // Default to include header
|
|
383
|
+
checkbox.style.marginRight = '6px';
|
|
384
|
+
|
|
385
|
+
headerOption.appendChild(checkbox);
|
|
386
|
+
headerOption.appendChild(document.createTextNode('Include header row'));
|
|
387
|
+
|
|
388
|
+
wrapper.appendChild(headerOption);
|
|
389
|
+
|
|
370
390
|
const table = document.createElement('div');
|
|
371
391
|
table.className = `${options.classPrefix}${CLASSES.TOOLBAR_TABLE}`
|
|
372
392
|
|
|
@@ -397,14 +417,15 @@ const makeToolbarDropdown = (_plugin, options, core) => {
|
|
|
397
417
|
});
|
|
398
418
|
});
|
|
399
419
|
cell.addEventListener('click', () => {
|
|
400
|
-
_plugin.create(core, options, { rows: i, cols: j })
|
|
420
|
+
_plugin.create(core, options, { rows: i, cols: j, header: checkbox.checked })
|
|
401
421
|
dropdownContent.style.display = 'none'
|
|
402
422
|
});
|
|
403
423
|
|
|
404
424
|
table.appendChild(cell);
|
|
405
425
|
}
|
|
406
426
|
}
|
|
407
|
-
|
|
427
|
+
wrapper.appendChild(table);
|
|
428
|
+
dropdownContent.appendChild(wrapper);
|
|
408
429
|
}
|
|
409
430
|
|
|
410
431
|
let isSuggestionLoaded = false;
|
|
@@ -739,23 +760,39 @@ const makeEditToolbar = (options, core, { type, td, image, updateImage, updateTa
|
|
|
739
760
|
const pluginSet = document.createElement('div')
|
|
740
761
|
pluginSet.className = `${options.classPrefix}${CLASSES.RESIZE_ITEMS} `
|
|
741
762
|
TABLE_PLUGINS.forEach(plugin => {
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
763
|
+
const isColorInput =
|
|
764
|
+
plugin.event === 'border-color' ||
|
|
765
|
+
plugin.event === 'background-color' ||
|
|
766
|
+
plugin.event === 'row-background-color' ||
|
|
767
|
+
plugin.event === 'column-background-color';
|
|
768
|
+
|
|
769
|
+
if (isColorInput) {
|
|
770
|
+
const label = document.createElement('label');
|
|
771
|
+
label.className = `${options.classPrefix}${CLASSES.RESIZE_ITEM}`;
|
|
772
|
+
label.setAttribute('data-title', plugin.title);
|
|
773
|
+
label.style.display = 'inline-block';
|
|
774
|
+
label.style.cursor = 'pointer';
|
|
775
|
+
|
|
776
|
+
const pluginInput = document.createElement('input');
|
|
777
|
+
pluginInput.type = "color";
|
|
778
|
+
pluginInput.style.width = '30px';
|
|
779
|
+
pluginInput.style.padding = '4px';
|
|
780
|
+
pluginInput.style.border = 'none';
|
|
781
|
+
pluginInput.style.background = 'transparent';
|
|
782
|
+
pluginInput.style.cursor = 'pointer';
|
|
783
|
+
pluginInput.oninput = (e) => {
|
|
750
784
|
updateTable(plugin.event, e.target.value);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
label.appendChild(pluginInput);
|
|
788
|
+
pluginSet.appendChild(label);
|
|
789
|
+
} else {
|
|
790
|
+
const pluginButton = document.createElement('button');
|
|
791
|
+
pluginButton.type = "button";
|
|
792
|
+
pluginButton.className = `${options.classPrefix}${CLASSES.RESIZE_ITEM}`;
|
|
793
|
+
pluginButton.setAttribute('data-title', plugin.title);
|
|
794
|
+
pluginButton.setAttribute('data-type', 'button');
|
|
757
795
|
|
|
758
|
-
if (plugin.event !== 'border-color') {
|
|
759
796
|
pluginButton.onclick = (e) => {
|
|
760
797
|
e.preventDefault();
|
|
761
798
|
updateTable(plugin.event);
|
|
@@ -763,10 +800,11 @@ const makeEditToolbar = (options, core, { type, td, image, updateImage, updateTa
|
|
|
763
800
|
|
|
764
801
|
const pluginIcon = document.createElement('div');
|
|
765
802
|
pluginIcon.innerHTML = plugin.icon;
|
|
766
|
-
pluginButton.appendChild(pluginIcon)
|
|
803
|
+
pluginButton.appendChild(pluginIcon);
|
|
804
|
+
pluginSet.appendChild(pluginButton);
|
|
767
805
|
}
|
|
768
|
-
|
|
769
|
-
|
|
806
|
+
});
|
|
807
|
+
|
|
770
808
|
popoverContent.appendChild(pluginSet)
|
|
771
809
|
|
|
772
810
|
popoverButton.onclick = () => {
|
|
@@ -831,7 +869,7 @@ const openModal = ({ title, bodyNode, footerNode }, core, options) => {
|
|
|
831
869
|
|
|
832
870
|
const initImageResizer = (type, image, options, core) => {
|
|
833
871
|
destroyImageResizer(options, core)
|
|
834
|
-
changeAllToolbarState(core, 'disabled', ['link'])
|
|
872
|
+
changeAllToolbarState(core, 'disabled', ['link', 'align_justify', 'align_left', 'align_right', 'align_center'])
|
|
835
873
|
core.elements.editor.blur() // to remove focus from the editor
|
|
836
874
|
|
|
837
875
|
const imageClientRect = image.getBoundingClientRect();
|
|
@@ -1411,6 +1449,27 @@ const initTableEditPlugin = (td, options, core) => {
|
|
|
1411
1449
|
}
|
|
1412
1450
|
break;
|
|
1413
1451
|
}
|
|
1452
|
+
case 'background-color': {
|
|
1453
|
+
td.style.backgroundColor = value;
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1456
|
+
case 'row-background-color': {
|
|
1457
|
+
const row = td.parentElement;
|
|
1458
|
+
for (let i = 0; i < row.cells.length; i++) {
|
|
1459
|
+
row.cells[i].style.backgroundColor = value;
|
|
1460
|
+
}
|
|
1461
|
+
break;
|
|
1462
|
+
}
|
|
1463
|
+
case 'column-background-color': {
|
|
1464
|
+
for (let r = 0; r < table.rows.length; r++) {
|
|
1465
|
+
const cell = table.rows[r].cells[cellIndex];
|
|
1466
|
+
if (cell) {
|
|
1467
|
+
cell.style.backgroundColor = value;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1414
1473
|
}
|
|
1415
1474
|
}
|
|
1416
1475
|
|