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 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.7",
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.type)) {
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
- core.onAttachment(files);
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
- dropdownContent.appendChild(table)
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 pluginButton = plugin.event === 'border-color'
743
- ? document.createElement('input')
744
- : document.createElement('button');
745
- if (plugin.event === 'border-color') {
746
- pluginButton.type = "color"
747
- pluginButton.style.width = '30px'
748
- pluginButton.style.padding = '4px'
749
- pluginButton.oninput = (e) => {
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
- } else
753
- pluginButton.type = "button"
754
- pluginButton.className = `${options.classPrefix}${CLASSES.RESIZE_ITEM} `
755
- pluginButton.setAttribute('data-title', plugin.title)
756
- pluginButton.setAttribute('data-type', 'button')
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
- pluginSet.appendChild(pluginButton)
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