@syncfusion/ej2-richtexteditor 19.3.43 → 19.3.47

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.
Files changed (67) hide show
  1. package/CHANGELOG.md +44 -2
  2. package/dist/ej2-richtexteditor.umd.min.js +2 -2
  3. package/dist/ej2-richtexteditor.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-richtexteditor.es2015.js +199 -80
  5. package/dist/es6/ej2-richtexteditor.es2015.js.map +1 -1
  6. package/dist/es6/ej2-richtexteditor.es5.js +195 -80
  7. package/dist/es6/ej2-richtexteditor.es5.js.map +1 -1
  8. package/dist/global/ej2-richtexteditor.min.js +2 -2
  9. package/dist/global/ej2-richtexteditor.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +12 -12
  12. package/src/common/constant.d.ts +8 -8
  13. package/src/common/constant.js +8 -8
  14. package/src/editor-manager/base/editor-manager.js +1 -1
  15. package/src/editor-manager/plugin/clearformat.d.ts +1 -0
  16. package/src/editor-manager/plugin/clearformat.js +1 -0
  17. package/src/editor-manager/plugin/image.js +12 -17
  18. package/src/editor-manager/plugin/inserthtml.js +16 -6
  19. package/src/editor-manager/plugin/lists.js +0 -1
  20. package/src/editor-manager/plugin/ms-word-clean-up.js +1 -0
  21. package/src/editor-manager/plugin/selection-commands.d.ts +1 -0
  22. package/src/editor-manager/plugin/selection-commands.js +52 -2
  23. package/src/editor-manager/plugin/table.js +3 -3
  24. package/src/editor-manager/plugin/toolbar-status.js +3 -3
  25. package/src/rich-text-editor/actions/enter-key.js +4 -16
  26. package/src/rich-text-editor/actions/html-editor.d.ts +1 -0
  27. package/src/rich-text-editor/actions/html-editor.js +31 -1
  28. package/src/rich-text-editor/actions/quick-toolbar.js +5 -2
  29. package/src/rich-text-editor/actions/xhtml-validation.d.ts +1 -0
  30. package/src/rich-text-editor/actions/xhtml-validation.js +5 -3
  31. package/src/rich-text-editor/base/rich-text-editor-model.d.ts +6 -6
  32. package/src/rich-text-editor/base/util.d.ts +1 -0
  33. package/src/rich-text-editor/base/util.js +1 -0
  34. package/src/rich-text-editor/renderer/image-module.d.ts +2 -0
  35. package/src/rich-text-editor/renderer/image-module.js +39 -12
  36. package/src/rich-text-editor/renderer/link-module.js +5 -3
  37. package/src/rich-text-editor/renderer/table-module.js +10 -3
  38. package/src/rich-text-editor/renderer/toolbar-renderer.d.ts +0 -1
  39. package/src/rich-text-editor/renderer/toolbar-renderer.js +1 -1
  40. package/styles/bootstrap-dark.css +1 -1
  41. package/styles/bootstrap.css +1 -1
  42. package/styles/bootstrap4.css +1 -1
  43. package/styles/bootstrap5-dark.css +1 -1
  44. package/styles/bootstrap5.css +1 -1
  45. package/styles/fabric-dark.css +1 -1
  46. package/styles/fabric.css +1 -1
  47. package/styles/highcontrast-light.css +1 -1
  48. package/styles/highcontrast.css +1 -1
  49. package/styles/material-dark.css +1 -1
  50. package/styles/material.css +1 -1
  51. package/styles/rich-text-editor/_tailwind-definition.scss +1 -1
  52. package/styles/rich-text-editor/_theme.scss +1 -1
  53. package/styles/rich-text-editor/bootstrap-dark.css +1 -1
  54. package/styles/rich-text-editor/bootstrap.css +1 -1
  55. package/styles/rich-text-editor/bootstrap4.css +1 -1
  56. package/styles/rich-text-editor/bootstrap5-dark.css +1 -1
  57. package/styles/rich-text-editor/bootstrap5.css +1 -1
  58. package/styles/rich-text-editor/fabric-dark.css +1 -1
  59. package/styles/rich-text-editor/fabric.css +1 -1
  60. package/styles/rich-text-editor/highcontrast-light.css +1 -1
  61. package/styles/rich-text-editor/highcontrast.css +1 -1
  62. package/styles/rich-text-editor/material-dark.css +1 -1
  63. package/styles/rich-text-editor/material.css +1 -1
  64. package/styles/rich-text-editor/tailwind-dark.css +1 -1
  65. package/styles/rich-text-editor/tailwind.css +1 -1
  66. package/styles/tailwind-dark.css +1 -1
  67. package/styles/tailwind.css +1 -1
@@ -2513,6 +2513,7 @@ function getEditValue(value, rteObj) {
2513
2513
  }
2514
2514
  /**
2515
2515
  * @param {string} value - specifies the value
2516
+ * @param {IRichTextEditor} rteObj - specifies the rich text editor instance.
2516
2517
  * @returns {string} - returns the string
2517
2518
  * @hidden
2518
2519
  */
@@ -2858,7 +2859,6 @@ class ToolbarRenderer {
2858
2859
  * renderListDropDown method
2859
2860
  *
2860
2861
  * @param {IDropDownModel} args - specifies the the arguments.
2861
- * @param {string} item - specifies the string value
2862
2862
  * @returns {void}
2863
2863
  * @hidden
2864
2864
  * @deprecated
@@ -3145,6 +3145,7 @@ class ToolbarRenderer {
3145
3145
  enablePersistence: this.parent.enablePersistence,
3146
3146
  enableRtl: this.parent.enableRtl,
3147
3147
  inline: true,
3148
+ value: '#fff',
3148
3149
  created: () => {
3149
3150
  const value = (item === 'backgroundcolor') ? proxy.parent.backgroundColor.default : proxy.parent.fontColor.default;
3150
3151
  colorPicker.setProperties({ value: value });
@@ -5760,7 +5761,10 @@ class QuickToolbar {
5760
5761
  else {
5761
5762
  const closestAnchor = closest(target, 'a');
5762
5763
  target = closestAnchor ? closestAnchor : target;
5763
- if (target.tagName !== 'IMG' && target.tagName !== 'A' && (!closest(target, 'td,th') || !range.collapsed)) {
5764
+ const startNode = this.parent.getRange().startContainer.parentElement;
5765
+ const endNode = this.parent.getRange().endContainer.parentElement;
5766
+ if ((isNullOrUndefined(closest(startNode, 'A')) || isNullOrUndefined(closest(endNode, 'A'))) && (!closest(target, 'td,th') || !range.collapsed) &&
5767
+ (target.tagName !== 'IMG' || this.parent.getRange().startOffset !== this.parent.getRange().endOffset)) {
5764
5768
  if (this.parent.inlineMode.onSelection && range.collapsed) {
5765
5769
  return;
5766
5770
  }
@@ -6728,16 +6732,16 @@ const MS_WORD_CLEANUP_PLUGIN = 'ms_word_cleanup_plugin';
6728
6732
  */
6729
6733
  const MS_WORD_CLEANUP = 'ms_word_cleanup';
6730
6734
  /**
6731
- * ActionBegin event callback
6732
- *
6733
- * @hidden
6734
- */
6735
+ * ActionBegin event callback
6736
+ *
6737
+ * @hidden
6738
+ */
6735
6739
  const ON_BEGIN = 'onBegin';
6736
6740
  /**
6737
- * Callback for spacelist action
6738
- *
6739
- * @hidden
6740
- */
6741
+ * Callback for spacelist action
6742
+ *
6743
+ * @hidden
6744
+ */
6741
6745
  const SPACE_ACTION = 'actionBegin';
6742
6746
 
6743
6747
  /**
@@ -10482,7 +10486,6 @@ class Lists {
10482
10486
  }
10483
10487
  }
10484
10488
  }
10485
- // eslint-disable-next-line
10486
10489
  enterList(e) {
10487
10490
  const range = this.parent.nodeSelection.getRange(this.parent.currentDocument);
10488
10491
  const startNode = range.startContainer.nodeName === 'LI' ? range.startContainer :
@@ -11832,6 +11835,11 @@ class InsertHtml {
11832
11835
  const nodeSelection = new NodeSelection();
11833
11836
  const nodeCutter = new NodeCutter();
11834
11837
  let range = nodeSelection.getRange(docElement);
11838
+ if (range.startContainer === editNode && range.startContainer === range.endContainer && range.startOffset === 0 &&
11839
+ range.startOffset === range.endOffset && editNode.textContent.length === 0 && editNode.children[0].tagName === 'P') {
11840
+ nodeSelection.setSelectionText(docElement, range.startContainer.children[0], range.startContainer.children[0], 0, 0);
11841
+ range = nodeSelection.getRange(docElement);
11842
+ }
11835
11843
  const isCursor = range.startOffset === range.endOffset && range.startOffset === 0 &&
11836
11844
  range.startContainer === range.endContainer;
11837
11845
  const isCollapsed = range.collapsed;
@@ -12143,15 +12151,20 @@ class InsertHtml {
12143
12151
  blockNode = range.endContainer;
12144
12152
  range.setEnd(blockNode, range.endContainer.textContent.length);
12145
12153
  }
12146
- if (!isNullOrUndefined(blockNode) && editNode === blockNode &&
12147
- range.startContainer === editNode && range.endContainer === editNode) {
12148
- blockNode = editNode.firstElementChild;
12149
- range.setStart(editNode.firstElementChild, editNode.firstElementChild.textContent.length);
12150
- range.setEnd(editNode.firstElementChild, editNode.firstElementChild.textContent.length);
12151
- }
12152
12154
  if (blockNode.nodeName === 'BODY' && range.startContainer === range.endContainer && range.startContainer.nodeType === 1) {
12153
12155
  blockNode = range.startContainer;
12154
12156
  }
12157
+ if (blockNode.closest('LI') && node && node.firstElementChild &&
12158
+ ((node).firstElementChild.tagName === 'OL' || node.firstElementChild.tagName === 'UL')) {
12159
+ let liNode;
12160
+ while (node.firstElementChild.lastElementChild && node.firstElementChild.lastElementChild.tagName === 'LI') {
12161
+ liNode = node.firstElementChild.lastElementChild;
12162
+ liNode.style.removeProperty('margin-left');
12163
+ liNode.style.removeProperty('margin-top');
12164
+ liNode.style.removeProperty('margin-bottom');
12165
+ node.firstElementChild.insertAdjacentElement('afterend', liNode);
12166
+ }
12167
+ }
12155
12168
  if (blockNode.nodeName === 'TD' || blockNode.nodeName === 'TH') {
12156
12169
  const tempSpan = createElement('span', { className: 'tempSpan' });
12157
12170
  range.insertNode(tempSpan);
@@ -12784,7 +12797,7 @@ class ImageCommand {
12784
12797
  * @deprecated
12785
12798
  */
12786
12799
  imageCommand(e) {
12787
- switch (e.value.toString().toLocaleLowerCase()) {
12800
+ switch (e.value.toString().toLowerCase()) {
12788
12801
  case 'image':
12789
12802
  case 'replace':
12790
12803
  this.createImage(e);
@@ -12860,21 +12873,8 @@ class ImageCommand {
12860
12873
  const selectedNode = this.parent.nodeSelection.getSelectedNodes(this.parent.currentDocument)[0];
12861
12874
  const imgElm = (e.value === 'Replace' || isReplaced) ? e.item.selectParent[0] :
12862
12875
  (Browser.isIE ? selectedNode.previousSibling : selectedNode.previousElementSibling);
12863
- let preventLoadCall = false;
12864
12876
  imgElm.addEventListener('load', () => {
12865
- if (e.value === 'Replace' || isReplaced) {
12866
- if (!preventLoadCall) {
12867
- e.callBack({
12868
- requestType: 'Images',
12869
- editorMode: 'HTML',
12870
- event: e.event,
12871
- range: this.parent.nodeSelection.getRange(this.parent.currentDocument),
12872
- elements: [imgElm]
12873
- });
12874
- preventLoadCall = true;
12875
- }
12876
- }
12877
- else {
12877
+ if (e.value !== 'Replace' || !isReplaced) {
12878
12878
  e.callBack({
12879
12879
  requestType: 'Images',
12880
12880
  editorMode: 'HTML',
@@ -13004,10 +13004,18 @@ class ImageCommand {
13004
13004
  const selectNode = e.item.selectNode[0];
13005
13005
  selectNode.style.height = '';
13006
13006
  selectNode.style.width = '';
13007
- e.item.width !== 'auto' ? selectNode.style.width = formatUnit(e.item.width) :
13007
+ if (e.item.width !== 'auto') {
13008
+ selectNode.style.width = formatUnit(e.item.width);
13009
+ }
13010
+ else {
13008
13011
  selectNode.removeAttribute('width');
13009
- e.item.height !== 'auto' ? selectNode.style.height = formatUnit(e.item.height) :
13012
+ }
13013
+ if (e.item.height !== 'auto') {
13014
+ selectNode.style.height = formatUnit(e.item.height);
13015
+ }
13016
+ else {
13010
13017
  selectNode.removeAttribute('height');
13018
+ }
13011
13019
  this.callBack(e);
13012
13020
  }
13013
13021
  imageCaption(e) {
@@ -13333,10 +13341,10 @@ class TableCommand {
13333
13341
  const colIndex = Array.prototype.slice.call(curRow.querySelectorAll(':scope > td, :scope > th')).indexOf(selectedCell);
13334
13342
  const previousWidth = parseInt(e.item.width, 10) / (curRow.querySelectorAll(':scope > td, :scope > th').length);
13335
13343
  const currentWidth = parseInt(e.item.width, 10) / (curRow.querySelectorAll(':scope > td, :scope > th').length + 1);
13336
- let currentTabElm = closest(curRow, 'table');
13337
- let thTdElm = closest(curRow, 'table').querySelectorAll('th,td');
13344
+ const currentTabElm = closest(curRow, 'table');
13345
+ const thTdElm = closest(curRow, 'table').querySelectorAll('th,td');
13338
13346
  for (let i = 0; i < thTdElm.length; i++) {
13339
- thTdElm[i].dataset.oldWidth = (thTdElm[i].offsetWidth / currentTabElm.offsetWidth * 100) + "%";
13347
+ thTdElm[i].dataset.oldWidth = (thTdElm[i].offsetWidth / currentTabElm.offsetWidth * 100) + '%';
13340
13348
  }
13341
13349
  for (let i = 0; i < allRows.length; i++) {
13342
13350
  curCell = allRows[i].querySelectorAll(':scope > td, :scope > th')[colIndex];
@@ -13349,11 +13357,11 @@ class TableCommand {
13349
13357
  // eslint-disable-next-line
13350
13358
  (e.item.subCommand === 'InsertColumnLeft') ? curCell.parentElement.insertBefore(colTemplate, curCell) :
13351
13359
  this.insertAfter(colTemplate, curCell);
13352
- colTemplate.style.width = currentWidth.toFixed(4) + "%";
13360
+ colTemplate.style.width = currentWidth.toFixed(4) + '%';
13353
13361
  delete colTemplate.dataset.oldWidth;
13354
13362
  }
13355
13363
  for (let i = 0; i < thTdElm.length; i++) {
13356
- thTdElm[i].style.width = (Number(thTdElm[i].dataset.oldWidth.split('%')[0]) * currentWidth / previousWidth).toFixed(4) + "%";
13364
+ thTdElm[i].style.width = (Number(thTdElm[i].dataset.oldWidth.split('%')[0]) * currentWidth / previousWidth).toFixed(4) + '%';
13357
13365
  delete thTdElm[i].dataset.oldWidth;
13358
13366
  }
13359
13367
  e.item.selection.setSelectionText(this.parent.currentDocument, selectedCell, selectedCell, 0, 0);
@@ -14282,6 +14290,7 @@ class SelectionCommands {
14282
14290
  * @param {Document} docElement - specifies the document
14283
14291
  * @param {string} format - specifies the string value
14284
14292
  * @param {Node} endNode - specifies the end node
14293
+ * @param {string} enterAction - specifies the enter key action
14285
14294
  * @param {string} value - specifies the string value
14286
14295
  * @param {string} selector - specifies the string
14287
14296
  * @returns {void}
@@ -14296,7 +14305,6 @@ class SelectionCommands {
14296
14305
  if (format === 'backgroundcolor' && value === '') {
14297
14306
  value = 'transparent';
14298
14307
  }
14299
- let preventRestore = false;
14300
14308
  let domSelection = new NodeSelection();
14301
14309
  const domNode = new DOMNode(endNode, docElement);
14302
14310
  const nodeCutter = new NodeCutter();
@@ -14308,6 +14316,7 @@ class SelectionCommands {
14308
14316
  let isCollapsed = false;
14309
14317
  let isFormat = false;
14310
14318
  let isCursor = false;
14319
+ let preventRestore = false;
14311
14320
  const isFontStyle = (['fontcolor', 'fontname', 'fontsize', 'backgroundcolor'].indexOf(format) > -1);
14312
14321
  if (range.collapsed) {
14313
14322
  if (nodes.length > 0) {
@@ -14331,6 +14340,9 @@ class SelectionCommands {
14331
14340
  else {
14332
14341
  domSelection.endOffset = domSelection.startOffset = 1;
14333
14342
  }
14343
+ if (cursorNode.nodeName === 'BR' && cursorNode.parentNode.textContent.length === 0) {
14344
+ preventRestore = true;
14345
+ }
14334
14346
  }
14335
14347
  }
14336
14348
  isCursor = range.collapsed;
@@ -14378,7 +14390,52 @@ class SelectionCommands {
14378
14390
  let cursorNode = null;
14379
14391
  if (cursorFormat) {
14380
14392
  cursorNode = cursorNodes[0];
14381
- InsertMethods.unwrap(cursorFormat);
14393
+ if (cursorFormat.firstChild.textContent.charCodeAt(0) === 8203) {
14394
+ const regEx = new RegExp(String.fromCharCode(8203), 'g');
14395
+ let emptySpaceNode;
14396
+ if (cursorFormat.firstChild === cursorNode) {
14397
+ cursorNode.textContent = cursorNode.textContent.replace(regEx, '');
14398
+ emptySpaceNode = cursorNode;
14399
+
14400
+ }
14401
+ else {
14402
+ cursorFormat.firstChild.textContent = cursorFormat.firstChild.textContent.replace(regEx, '');
14403
+ emptySpaceNode = cursorFormat.firstChild;
14404
+ }
14405
+ let pointer;
14406
+ if (emptySpaceNode.textContent.length === 0) {
14407
+ if (!isNullOrUndefined(emptySpaceNode.previousSibling)) {
14408
+ cursorNode = emptySpaceNode.previousSibling;
14409
+ pointer = emptySpaceNode.textContent.length - 1;
14410
+ domSelection.setCursorPoint(docElement, emptySpaceNode, pointer);
14411
+ }
14412
+ else if (!isNullOrUndefined(emptySpaceNode.parentElement) && emptySpaceNode.parentElement.textContent.length === 0) {
14413
+ let brElem = document.createElement('BR');
14414
+ emptySpaceNode.parentElement.appendChild(brElem);
14415
+ detach(emptySpaceNode);
14416
+ cursorNode = brElem;
14417
+ domSelection.setCursorPoint(docElement, cursorNode.parentElement, 0);
14418
+ }
14419
+ }
14420
+ }
14421
+ if ((['fontcolor', 'fontname', 'fontsize', 'backgroundcolor'].indexOf(format) > -1)) {
14422
+ if (format === 'fontcolor') {
14423
+ cursorFormat.style.color = value;
14424
+ }
14425
+ else if (format === 'fontname') {
14426
+ cursorFormat.style.fontFamily = value;
14427
+ }
14428
+ else if (format === 'fontsize') {
14429
+ cursorFormat.style.fontSize = value;
14430
+ }
14431
+ else {
14432
+ cursorFormat.style.backgroundColor = value;
14433
+ }
14434
+ cursorNode = cursorFormat;
14435
+ }
14436
+ else {
14437
+ InsertMethods.unwrap(cursorFormat);
14438
+ }
14382
14439
  }
14383
14440
  else {
14384
14441
  if (cursorNodes.length > 1 && range.startOffset > 0 && (cursorNodes[0].firstElementChild &&
@@ -14813,6 +14870,7 @@ class ClearFormat$1 {
14813
14870
  *
14814
14871
  * @param {Document} docElement - specifies the document element.
14815
14872
  * @param {Node} endNode - specifies the end node
14873
+ * @param {string} enterAction - specifies the enter key action
14816
14874
  * @param {string} selector - specifies the string value
14817
14875
  * @returns {void}
14818
14876
  * @hidden
@@ -15394,6 +15452,7 @@ class MsWordPaste {
15394
15452
  const imgSrc = [];
15395
15453
  const base64Src = [];
15396
15454
  const imgName = [];
15455
+ // eslint-disable-next-line
15397
15456
  const linkRegex = new RegExp(/([^\S]|^)(((https?\:\/\/)|(www\.))(\S+))/gi);
15398
15457
  if (imgElem.length > 0) {
15399
15458
  for (let i = 0; i < imgElem.length; i++) {
@@ -16048,7 +16107,7 @@ class EditorManager {
16048
16107
  */
16049
16108
  /* eslint-enable */
16050
16109
  execCommand(command, value, event, callBack, text, exeValue, selector, enterAction) {
16051
- switch (command.toLocaleLowerCase()) {
16110
+ switch (command.toLowerCase()) {
16052
16111
  case 'lists':
16053
16112
  this.observer.notify(LIST_TYPE, { subCommand: value, event: event, callBack: callBack,
16054
16113
  selector: selector, item: exeValue, enterAction: enterAction });
@@ -16214,8 +16273,8 @@ class ToolbarStatus {
16214
16273
  const range = nodeSelection.getRange(docElement);
16215
16274
  for (let index = 0; index < nodes.length; index++) {
16216
16275
  while (nodes[index].nodeType === 3 && range.startContainer.nodeType === 3 && nodes[index].parentNode &&
16217
- nodes[index].parentNode.lastElementChild && nodes[index].parentNode.lastElementChild.nodeName !== "BR" &&
16218
- this.getImmediateBlockNode(nodes[index].parentNode, targetNode).textContent.replace(/\u200B/g, '').length === 0 &&
16276
+ nodes[index].parentNode.lastElementChild && nodes[index].parentNode.lastElementChild.nodeName !== 'BR' &&
16277
+ (this.getImmediateBlockNode(nodes[index].parentNode)).textContent.replace(/\u200B/g, '').length === 0 &&
16219
16278
  range.startContainer.textContent.replace(/\u200B/g, '').length === 0 &&
16220
16279
  nodeSelection.get(docElement).toString().replace(/\u200B/g, '').length === 0) {
16221
16280
  nodes[index] = nodes[index].parentNode.lastElementChild.firstChild;
@@ -16291,7 +16350,7 @@ class ToolbarStatus {
16291
16350
  }
16292
16351
  return nodeCollection;
16293
16352
  }
16294
- static getImmediateBlockNode(node, editNode) {
16353
+ static getImmediateBlockNode(node) {
16295
16354
  do {
16296
16355
  node = node.parentNode;
16297
16356
  } while (node && BLOCK_TAGS.indexOf(node.nodeName.toLocaleLowerCase()) < 0);
@@ -16845,22 +16904,24 @@ class XhtmlValidation {
16845
16904
  this.ImageTags();
16846
16905
  this.removeTags();
16847
16906
  this.RemoveUnsupported();
16848
- this.currentElement.innerHTML = this.selfEncloseValidation(this.currentElement.innerHTML, this.currentElement.innerText === "\n" ? this.currentElement.innerText.length : this.currentElement.innerText.trim().length);
16907
+ this.currentElement.innerHTML = this.selfEncloseValidation(this.currentElement.innerHTML, this.currentElement.innerText === '\n' ?
16908
+ this.currentElement.innerText.length : this.currentElement.innerText.trim().length);
16849
16909
  this.parent.setProperties({ value: this.currentElement.innerHTML }, true);
16850
16910
  }
16851
16911
  }
16852
16912
  /**
16853
16913
  * @param {string} currentValue - specifies the string value.
16914
+ * @param {number} valueLength - specifies the length of the current value.
16854
16915
  * @returns {void}
16855
16916
  * @deprecated
16856
16917
  */
16857
16918
  selfEncloseValidation(currentValue, valueLength) {
16858
16919
  if (valueLength === 0 && currentValue.indexOf('table') < 0 && currentValue.indexOf('img') < 0) {
16859
- let arrayValue = currentValue.split('&nbsp;');
16860
- arrayValue[arrayValue.length - 1] = "&#8203;" + arrayValue[arrayValue.length - 1];
16920
+ const arrayValue = currentValue.split('&nbsp;');
16921
+ arrayValue[arrayValue.length - 1] = '&#8203;' + arrayValue[arrayValue.length - 1];
16861
16922
  currentValue = arrayValue.join('');
16862
16923
  }
16863
- currentValue = currentValue.replace(/<br>/g, '<br/>').replace(/<hr>/g, '<hr/>').replace(/&nbsp;/gi, ' ').replace(/ /g, ' ');
16924
+ currentValue = currentValue.replace(/<br>/g, '<br/>').replace(/<hr>/g, '<hr/>').replace(/ /g, ' ');
16864
16925
  let valueTemp;
16865
16926
  const valueDupe = [];
16866
16927
  let valueOriginal = [];
@@ -17035,6 +17096,7 @@ class HtmlEditor {
17035
17096
  this.parent.on(initialLoad, this.instantiateRenderer, this);
17036
17097
  this.parent.on(htmlToolbarClick, this.onToolbarClick, this);
17037
17098
  this.parent.on(keyDown, this.onKeyDown, this);
17099
+ this.parent.on(keyUp, this.onKeyUp, this);
17038
17100
  this.parent.on(renderColorPicker, this.renderColorPicker, this);
17039
17101
  this.parent.on(initialEnd, this.render, this);
17040
17102
  this.parent.on(modelChanged, this.onPropertyChanged, this);
@@ -17069,9 +17131,33 @@ class HtmlEditor {
17069
17131
  this.saveSelection.restore();
17070
17132
  }
17071
17133
  }
17134
+ onKeyUp(e) {
17135
+ let args = e.args;
17136
+ const restrictKeys = [8, 9, 13, 16, 17, 18, 20, 27, 37, 38, 39, 40, 44, 45, 46, 91,
17137
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123];
17138
+ const range = this.parent.getRange();
17139
+ const regEx = new RegExp(String.fromCharCode(8203), 'g');
17140
+ let pointer;
17141
+ if (restrictKeys.indexOf(args.keyCode) < 0 && !args.shiftKey && !args.ctrlKey && !args.altKey) {
17142
+ if (range.startContainer.textContent.charCodeAt(0) === 8203) {
17143
+ pointer = range.startOffset - 1;
17144
+ range.startContainer.textContent = range.startContainer.textContent.replace(regEx, '');
17145
+ this.parent.formatter.editorManager.nodeSelection.setCursorPoint(this.parent.contentModule.getDocument(), range.startContainer, pointer);
17146
+ }
17147
+ if (!isNullOrUndefined(range.startContainer.previousSibling) && !isNullOrUndefined(range.startContainer.previousSibling.parentElement) &&
17148
+ range.startContainer.parentElement === range.startContainer.previousSibling.parentElement && range.startContainer.previousSibling.textContent.charCodeAt(0) === 8203) {
17149
+ range.startContainer.previousSibling.textContent = range.startContainer.previousSibling.textContent.replace(regEx, '');
17150
+ }
17151
+ if (range.endContainer.textContent.charCodeAt(range.endOffset) === 8203) {
17152
+ pointer = range.startOffset;
17153
+ range.endContainer.textContent = range.endContainer.textContent.replace(regEx, '');
17154
+ this.parent.formatter.editorManager.nodeSelection.setCursorPoint(this.parent.contentModule.getDocument(), range.startContainer, pointer);
17155
+ }
17156
+ }
17157
+ }
17072
17158
  onKeyDown(e) {
17073
17159
  let currentRange;
17074
- let args = e.args;
17160
+ const args = e.args;
17075
17161
  if (Browser.info.name === 'chrome') {
17076
17162
  currentRange = this.parent.getRange();
17077
17163
  this.backSpaceCleanup(e, currentRange);
@@ -17278,7 +17364,12 @@ class HtmlEditor {
17278
17364
  while (this.deleteOldRangeElement.firstChild) {
17279
17365
  this.deleteRangeElement.appendChild(this.deleteOldRangeElement.childNodes[0]);
17280
17366
  }
17281
- !isLiElement ? detach(this.deleteOldRangeElement) : detach(this.deleteOldRangeElement.parentElement);
17367
+ if (!isLiElement) {
17368
+ detach(this.deleteOldRangeElement);
17369
+ }
17370
+ else {
17371
+ detach(this.deleteOldRangeElement.parentElement);
17372
+ }
17282
17373
  this.deleteRangeElement.normalize();
17283
17374
  }
17284
17375
  else {
@@ -19305,7 +19396,8 @@ class Link {
19305
19396
  this.contentModule = this.rendererFactory.getRenderer(RenderType.Content);
19306
19397
  const isPopupOpen = this.quickToolObj.linkQTBar.element.classList.contains('e-rte-pop');
19307
19398
  if (target.nodeName === 'A' && (target.childNodes.length > 0 && target.childNodes[0].nodeName !== 'IMG') &&
19308
- e.args.target.nodeName !== 'IMG') {
19399
+ e.args.target.nodeName !== 'IMG' &&
19400
+ !isNullOrUndefined(closest(this.parent.getRange().startContainer.parentElement, 'A')) && !isNullOrUndefined(closest(this.parent.getRange().endContainer.parentElement, 'A'))) {
19309
19401
  if (isPopupOpen) {
19310
19402
  return;
19311
19403
  }
@@ -19565,7 +19657,8 @@ class Link {
19565
19657
  else {
19566
19658
  argsValue = this.args;
19567
19659
  }
19568
- this.selfLink.parent.formatter.process(this.selfLink.parent, argsValue, (!isNullOrUndefined(this.args) && this.args.originalEvent), value);
19660
+ this.selfLink.parent.formatter.process(this.selfLink.parent, argsValue, (!isNullOrUndefined(this.args) &&
19661
+ this.args.originalEvent), value);
19569
19662
  this.selfLink.parent.contentModule.getEditPanel().focus();
19570
19663
  }
19571
19664
  isUrl(url) {
@@ -19982,7 +20075,7 @@ class Image {
19982
20075
  if (width > height) {
19983
20076
  img.style.minWidth = '20px';
19984
20077
  if (this.parent.insertImageSettings.resizeByPercent) {
19985
- if (parseInt('' + img.getBoundingClientRect().width + '') !== 0 && parseInt('' + width + '') !== 0) {
20078
+ if (parseInt('' + img.getBoundingClientRect().width + '', 10) !== 0 && parseInt('' + width + '', 10) !== 0) {
19986
20079
  const percentageValue = this.pixToPerc((width / height * expectedY), (img.previousElementSibling || img.parentElement));
19987
20080
  img.style.width = Math.min(Math.round((percentageValue / img.getBoundingClientRect().width) * expectedX * 100) / 100, 100) + '%';
19988
20081
  }
@@ -20008,7 +20101,7 @@ class Image {
20008
20101
  }
20009
20102
  else if (height > width) {
20010
20103
  if (this.parent.insertImageSettings.resizeByPercent) {
20011
- if (parseInt('' + img.getBoundingClientRect().width + '') !== 0 && parseInt('' + width + '') !== 0) {
20104
+ if (parseInt('' + img.getBoundingClientRect().width + '', 10) !== 0 && parseInt('' + width + '', 10) !== 0) {
20012
20105
  img.style.width = Math.min(Math.round((width / img.getBoundingClientRect().width) * expectedX * 100) / 100, 100) + '%';
20013
20106
  }
20014
20107
  else {
@@ -20479,7 +20572,7 @@ class Image {
20479
20572
  const target = args.target;
20480
20573
  this.contentModule = this.rendererFactory.getRenderer(RenderType.Content);
20481
20574
  const isPopupOpen = this.quickToolObj.imageQTBar.element.classList.contains('e-rte-pop');
20482
- if (target.nodeName === 'IMG' && this.parent.quickToolbarModule) {
20575
+ if (target.nodeName === 'IMG' && this.parent.quickToolbarModule && this.parent.getRange().startOffset === this.parent.getRange().endOffset) {
20483
20576
  if (isPopupOpen) {
20484
20577
  return;
20485
20578
  }
@@ -20716,13 +20809,34 @@ class Image {
20716
20809
  }
20717
20810
  }
20718
20811
  imageRemovePost(src) {
20812
+ const proxy = this;
20813
+ let absoluteUrl = '';
20814
+ if (src.indexOf('http://') > -1 || src.indexOf('https://') > -1) {
20815
+ absoluteUrl = src;
20816
+ }
20817
+ else {
20818
+ absoluteUrl = new URL(src, document.baseURI).href;
20819
+ }
20820
+ this.removingImgName = absoluteUrl.replace(/^.*[\\\/]/, '');
20821
+ const xhr = new XMLHttpRequest();
20822
+ xhr.addEventListener("readystatechange", function () {
20823
+ if (this.readyState == 4 && this.status == 200) {
20824
+ proxy.triggerPost(this.response);
20825
+ }
20826
+ });
20827
+ xhr.open('GET', absoluteUrl);
20828
+ xhr.responseType = 'blob';
20829
+ xhr.send();
20830
+ }
20831
+ triggerPost(response) {
20719
20832
  const removeUrl = this.parent.insertImageSettings.removeUrl;
20720
20833
  if (isNullOrUndefined(removeUrl) || removeUrl === '') {
20721
20834
  return;
20722
20835
  }
20836
+ const file = new File([response], this.removingImgName);
20723
20837
  const ajax = new Ajax(removeUrl, 'POST', true, null);
20724
20838
  const formData = new FormData();
20725
- formData.append(name, src);
20839
+ formData.append('UploadFiles', file);
20726
20840
  ajax.send(formData);
20727
20841
  }
20728
20842
  caption(e) {
@@ -20960,9 +21074,15 @@ class Image {
20960
21074
  (this.parent.getToolbarElement() && this.parent.getToolbarElement().contains(e.target) &&
20961
21075
  !closest(target, '#' + this.parent.getID() + '_toolbar_Image') &&
20962
21076
  !target.querySelector('#' + this.parent.getID() + '_toolbar_Image')))) {
20963
- this.dialogObj.hide({ returnValue: true });
20964
- this.parent.isBlur = true;
20965
- dispatchEvent(this.parent.element, 'focusout');
21077
+ /* eslint-disable */
21078
+ if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) {
21079
+ }
21080
+ else {
21081
+ this.dialogObj.hide({ returnValue: true });
21082
+ this.parent.isBlur = true;
21083
+ dispatchEvent(this.parent.element, 'focusout');
21084
+ }
21085
+ /* eslint-enable */
20966
21086
  }
20967
21087
  if (e.target.tagName !== 'IMG' && this.imgResizeDiv && !(this.quickToolObj &&
20968
21088
  this.quickToolObj.imageQTBar && this.quickToolObj.imageQTBar.element.contains(e.target)) &&
@@ -21064,11 +21184,11 @@ class Image {
21064
21184
  const imgWidth = this.i10n.getConstant('imageWidth');
21065
21185
  const imgSizeWrap = this.parent.createElement('div', { className: 'e-img-sizewrap' });
21066
21186
  const widthVal = isNullOrUndefined(this.changedWidthValue) && (selectNode.style.width.toString() === 'auto' ||
21067
- selectNode.style.width !== "") ? selectNode.style.width : !isNullOrUndefined(this.changedWidthValue) ?
21068
- this.changedWidthValue : (parseInt(selectNode.getClientRects()[0].width.toString())).toString();
21187
+ selectNode.style.width !== '') ? selectNode.style.width : !isNullOrUndefined(this.changedWidthValue) ?
21188
+ this.changedWidthValue : (parseInt(selectNode.getClientRects()[0].width.toString(), 10)).toString();
21069
21189
  const heightVal = isNullOrUndefined(this.changedHeightValue) && (selectNode.style.height.toString() === 'auto' ||
21070
- selectNode.style.height !== "") ? selectNode.style.height : !isNullOrUndefined(this.changedHeightValue) ?
21071
- this.changedHeightValue : (parseInt(selectNode.getClientRects()[0].height.toString())).toString();
21190
+ selectNode.style.height !== '') ? selectNode.style.height : !isNullOrUndefined(this.changedHeightValue) ?
21191
+ this.changedHeightValue : (parseInt(selectNode.getClientRects()[0].height.toString(), 10)).toString();
21072
21192
  this.changedWidthValue = null;
21073
21193
  this.changedHeightValue = null;
21074
21194
  const content = '<div class="e-rte-label"><label>' + imgWidth +
@@ -21107,7 +21227,7 @@ class Image {
21107
21227
  return value;
21108
21228
  }
21109
21229
  else {
21110
- return "auto";
21230
+ return 'auto';
21111
21231
  }
21112
21232
  }
21113
21233
  insertSize(e) {
@@ -22299,8 +22419,12 @@ class Table {
22299
22419
  if (args.args && args.args.item.cssClass) {
22300
22420
  const classList = args.args.item.cssClass.split(' ');
22301
22421
  for (let i = 0; i < classList.length; i++) {
22302
- (table.classList.contains(classList[i])) ? table.classList.remove(classList[i]) :
22422
+ if (table.classList.contains(classList[i])) {
22423
+ table.classList.remove(classList[i]);
22424
+ }
22425
+ else {
22303
22426
  table.classList.add(classList[i]);
22427
+ }
22304
22428
  }
22305
22429
  }
22306
22430
  this.parent.formatter.saveData();
@@ -22456,7 +22580,9 @@ class Table {
22456
22580
  }
22457
22581
  const range = this.parent.formatter.editorManager.nodeSelection.getRange(this.contentModule.getDocument());
22458
22582
  const closestTable = closest(target, 'table');
22459
- if (target && target.nodeName !== 'A' && target.nodeName !== 'IMG' && (target.nodeName === 'TD' || target.nodeName === 'TH' ||
22583
+ const startNode = this.parent.getRange().startContainer.parentElement;
22584
+ const endNode = this.parent.getRange().endContainer.parentElement;
22585
+ if (target && target.nodeName !== 'A' && target.nodeName !== 'IMG' && startNode === endNode && (target.nodeName === 'TD' || target.nodeName === 'TH' ||
22460
22586
  target.nodeName === 'TABLE' || (closestTable && this.parent.contentModule.getEditPanel().contains(closestTable)))
22461
22587
  && !(range.startContainer.nodeType === 3 && !range.collapsed)) {
22462
22588
  const range = this.parent.formatter.editorManager.nodeSelection.getRange(this.contentModule.getDocument());
@@ -22543,7 +22669,6 @@ class Table {
22543
22669
  tdNode : target;
22544
22670
  removeClass(this.contentModule.getEditPanel().querySelectorAll('table td, table th'), CLS_TABLE_SEL);
22545
22671
  if (target && (target.tagName === 'TD' || target.tagName === 'TH')) {
22546
- target.removeAttribute('class');
22547
22672
  addClass([target], CLS_TABLE_SEL);
22548
22673
  this.activeCell = target;
22549
22674
  this.curTable = (this.curTable) ? this.curTable : closest(target, 'table');
@@ -22642,6 +22767,7 @@ class Table {
22642
22767
  top: 0,
22643
22768
  left: 0
22644
22769
  };
22770
+ // eslint-disable-next-line
22645
22771
  const offset = elem.getBoundingClientRect();
22646
22772
  const doc = elem.ownerDocument;
22647
22773
  let offsetParent = elem.offsetParent || doc.documentElement;
@@ -22654,6 +22780,7 @@ class Table {
22654
22780
  offsetParent = closest(offsetParent, '.e-rte-content');
22655
22781
  }
22656
22782
  if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
22783
+ // eslint-disable-next-line
22657
22784
  parentOffset = offsetParent.getBoundingClientRect();
22658
22785
  }
22659
22786
  return {
@@ -23944,9 +24071,9 @@ class EnterKeyAction {
23944
24071
  this.getRangeNode();
23945
24072
  }
23946
24073
  }
23947
- if (this.range.startContainer === this.range.endContainer && this.range.startOffset === 0 &&
23948
- this.range.startOffset == this.range.endOffset && this.range.startContainer === this.parent.inputElement) {
23949
- this.parent.formatter.editorManager.nodeSelection.setCursorPoint(this.parent.contentModule.getDocument(), this.range.startContainer.childNodes[this.range.startOffset], this.range.startOffset);
24074
+ if (this.range.startContainer === this.range.endContainer &&
24075
+ this.range.startOffset === this.range.endOffset && this.range.startContainer === this.parent.inputElement) {
24076
+ this.parent.formatter.editorManager.nodeSelection.setCursorPoint(this.parent.contentModule.getDocument(), this.range.startContainer.childNodes[this.range.startOffset], 0);
23950
24077
  this.getRangeNode();
23951
24078
  }
23952
24079
  if (this.parent.enterKey === 'P' || this.parent.enterKey === 'DIV' ||
@@ -24022,7 +24149,7 @@ class EnterKeyAction {
24022
24149
  }
24023
24150
  this.parent.formatter.editorManager.domNode.insertAfter(insertElm, newElem);
24024
24151
  detach(newElem);
24025
- this.parent.formatter.editorManager.nodeSelection.setCursorPoint(this.parent.contentModule.getDocument(), insertElm, insertElm.textContent.length >= 0 ? 0 : 1);
24152
+ this.parent.formatter.editorManager.nodeSelection.setCursorPoint(this.parent.contentModule.getDocument(), this.parent.formatter.editorManager.domNode.isBlockNode(this.startNode) ? insertElm : this.startNode, 0);
24026
24153
  }
24027
24154
  }
24028
24155
  e.args.preventDefault();
@@ -24062,11 +24189,9 @@ class EnterKeyAction {
24062
24189
  }
24063
24190
  else {
24064
24191
  let newElem;
24065
- let focusElem;
24066
24192
  const outerBRElem = this.parent.createElement('br');
24067
24193
  if (this.range.startOffset === 0 && this.range.endOffset === 0 &&
24068
24194
  !isNullOrUndefined(currentParent.previousSibling) && currentParent.previousSibling.nodeName === 'BR') {
24069
- focusElem = this.range.startContainer;
24070
24195
  newElem = this.parent.formatter.editorManager.nodeCutter.SplitNode(this.range, currentParent, false).cloneNode(true);
24071
24196
  this.parent.formatter.editorManager.domNode.insertAfter(outerBRElem, currentParent);
24072
24197
  this.insertFocusContent();
@@ -24109,12 +24234,6 @@ class EnterKeyAction {
24109
24234
  }
24110
24235
  e.args.preventDefault();
24111
24236
  }
24112
- if (this.range.startContainer.nodeName === '#text') {
24113
- this.range.startContainer.parentElement.scrollIntoView(false);
24114
- }
24115
- else {
24116
- this.range.startContainer.scrollIntoView(false);
24117
- }
24118
24237
  this.parent.trigger(actionComplete, { requestType: shiftKey ? 'ShiftEnterAction' : 'EnterAction', args: e.args });
24119
24238
  }
24120
24239
  });