@syncfusion/ej2-richtexteditor 20.4.52 → 21.1.35

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 (140) hide show
  1. package/CHANGELOG.md +32 -2
  2. package/dist/ej2-richtexteditor.min.js +2 -2
  3. package/dist/ej2-richtexteditor.umd.min.js +2 -2
  4. package/dist/ej2-richtexteditor.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-richtexteditor.es2015.js +1623 -639
  6. package/dist/es6/ej2-richtexteditor.es2015.js.map +1 -1
  7. package/dist/es6/ej2-richtexteditor.es5.js +1638 -646
  8. package/dist/es6/ej2-richtexteditor.es5.js.map +1 -1
  9. package/dist/global/ej2-richtexteditor.min.js +2 -2
  10. package/dist/global/ej2-richtexteditor.min.js.map +1 -1
  11. package/dist/global/index.d.ts +1 -1
  12. package/package.json +13 -13
  13. package/src/common/config.js +3 -1
  14. package/src/common/constant.d.ts +6 -0
  15. package/src/common/constant.js +6 -0
  16. package/src/common/util.d.ts +2 -1
  17. package/src/common/util.js +15 -6
  18. package/src/editor-manager/base/editor-manager.d.ts +2 -0
  19. package/src/editor-manager/base/editor-manager.js +6 -1
  20. package/src/editor-manager/base/enum.d.ts +14 -0
  21. package/src/editor-manager/base/interface.d.ts +34 -0
  22. package/src/editor-manager/plugin/clearformat.js +13 -4
  23. package/src/editor-manager/plugin/format-painter-actions.d.ts +63 -0
  24. package/src/editor-manager/plugin/format-painter-actions.js +474 -0
  25. package/src/editor-manager/plugin/image.js +0 -1
  26. package/src/editor-manager/plugin/inserthtml-exec.js +1 -1
  27. package/src/editor-manager/plugin/inserthtml.d.ts +1 -1
  28. package/src/editor-manager/plugin/inserthtml.js +18 -10
  29. package/src/editor-manager/plugin/isformatted.js +1 -0
  30. package/src/editor-manager/plugin/link.js +0 -1
  31. package/src/editor-manager/plugin/lists.js +1 -1
  32. package/src/editor-manager/plugin/ms-word-clean-up.js +57 -19
  33. package/src/editor-manager/plugin/selection-commands.d.ts +4 -1
  34. package/src/editor-manager/plugin/selection-commands.js +70 -9
  35. package/src/editor-manager/plugin/video.js +2 -0
  36. package/src/editor-manager/plugin.d.ts +1 -0
  37. package/src/editor-manager/plugin.js +1 -0
  38. package/src/global.js +1 -1
  39. package/src/rich-text-editor/actions/base-quick-toolbar.d.ts +1 -0
  40. package/src/rich-text-editor/actions/base-quick-toolbar.js +21 -1
  41. package/src/rich-text-editor/actions/base-toolbar.js +33 -10
  42. package/src/rich-text-editor/actions/enter-key.js +23 -16
  43. package/src/rich-text-editor/actions/format-painter.d.ts +24 -0
  44. package/src/rich-text-editor/actions/format-painter.js +142 -0
  45. package/src/rich-text-editor/actions/full-screen.js +0 -1
  46. package/src/rich-text-editor/actions/html-editor.d.ts +1 -0
  47. package/src/rich-text-editor/actions/html-editor.js +117 -97
  48. package/src/rich-text-editor/actions/paste-clean-up.js +2 -2
  49. package/src/rich-text-editor/actions/quick-toolbar.js +8 -1
  50. package/src/rich-text-editor/actions/toolbar.js +10 -0
  51. package/src/rich-text-editor/actions.d.ts +1 -0
  52. package/src/rich-text-editor/actions.js +1 -0
  53. package/src/rich-text-editor/base/constant.d.ts +10 -0
  54. package/src/rich-text-editor/base/constant.js +10 -0
  55. package/src/rich-text-editor/base/enum.d.ts +4 -0
  56. package/src/rich-text-editor/base/interface.d.ts +30 -3
  57. package/src/rich-text-editor/base/interface.js +12 -0
  58. package/src/rich-text-editor/base/rich-text-editor-model.d.ts +30 -4
  59. package/src/rich-text-editor/base/rich-text-editor.d.ts +35 -5
  60. package/src/rich-text-editor/base/rich-text-editor.js +46 -10
  61. package/src/rich-text-editor/base/util.js +2 -0
  62. package/src/rich-text-editor/formatter/formatter.js +22 -13
  63. package/src/rich-text-editor/formatter/html-formatter.d.ts +5 -3
  64. package/src/rich-text-editor/formatter/html-formatter.js +7 -5
  65. package/src/rich-text-editor/models/default-locale.js +4 -2
  66. package/src/rich-text-editor/models/items.d.ts +3 -0
  67. package/src/rich-text-editor/models/items.js +32 -0
  68. package/src/rich-text-editor/models/toolbar-settings-model.d.ts +29 -1
  69. package/src/rich-text-editor/models/toolbar-settings.d.ts +24 -1
  70. package/src/rich-text-editor/models/toolbar-settings.js +20 -0
  71. package/src/rich-text-editor/renderer/audio-module.js +6 -3
  72. package/src/rich-text-editor/renderer/image-module.js +11 -6
  73. package/src/rich-text-editor/renderer/link-module.js +2 -1
  74. package/src/rich-text-editor/renderer/table-module.js +18 -6
  75. package/src/rich-text-editor/renderer/toolbar-renderer.js +10 -1
  76. package/src/rich-text-editor/renderer/video-module.js +8 -5
  77. package/src/rich-text-editor/renderer/view-source.js +1 -1
  78. package/styles/bootstrap-dark.css +31 -1
  79. package/styles/bootstrap.css +31 -1
  80. package/styles/bootstrap4.css +31 -1
  81. package/styles/bootstrap5-dark.css +32 -2
  82. package/styles/bootstrap5.css +32 -2
  83. package/styles/fabric-dark.css +31 -1
  84. package/styles/fabric.css +31 -1
  85. package/styles/fluent-dark.css +34 -4
  86. package/styles/fluent.css +34 -4
  87. package/styles/highcontrast-light.css +31 -1
  88. package/styles/highcontrast.css +31 -1
  89. package/styles/material-dark.css +31 -1
  90. package/styles/material.css +31 -1
  91. package/styles/rich-text-editor/_bootstrap-dark-definition.scss +25 -1
  92. package/styles/rich-text-editor/_bootstrap-definition.scss +25 -1
  93. package/styles/rich-text-editor/_bootstrap4-definition.scss +25 -1
  94. package/styles/rich-text-editor/_bootstrap5-definition.scss +28 -5
  95. package/styles/rich-text-editor/_fabric-dark-definition.scss +25 -1
  96. package/styles/rich-text-editor/_fabric-definition.scss +25 -1
  97. package/styles/rich-text-editor/_fluent-definition.scss +30 -7
  98. package/styles/rich-text-editor/_fusionnew-definition.scss +26 -3
  99. package/styles/rich-text-editor/_highcontrast-definition.scss +25 -1
  100. package/styles/rich-text-editor/_highcontrast-light-definition.scss +25 -1
  101. package/styles/rich-text-editor/_layout.scss +47 -15
  102. package/styles/rich-text-editor/_material-dark-definition.scss +26 -1
  103. package/styles/rich-text-editor/_material-definition.scss +25 -1
  104. package/styles/rich-text-editor/_tailwind-definition.scss +28 -5
  105. package/styles/rich-text-editor/_theme.scss +54 -6
  106. package/styles/rich-text-editor/bootstrap-dark.css +31 -1
  107. package/styles/rich-text-editor/bootstrap.css +31 -1
  108. package/styles/rich-text-editor/bootstrap4.css +31 -1
  109. package/styles/rich-text-editor/bootstrap5-dark.css +32 -2
  110. package/styles/rich-text-editor/bootstrap5.css +32 -2
  111. package/styles/rich-text-editor/fabric-dark.css +31 -1
  112. package/styles/rich-text-editor/fabric.css +31 -1
  113. package/styles/rich-text-editor/fluent-dark.css +34 -4
  114. package/styles/rich-text-editor/fluent.css +34 -4
  115. package/styles/rich-text-editor/highcontrast-light.css +31 -1
  116. package/styles/rich-text-editor/highcontrast.css +31 -1
  117. package/styles/rich-text-editor/icons/_bootstrap-dark.scss +8 -0
  118. package/styles/rich-text-editor/icons/_bootstrap.scss +8 -0
  119. package/styles/rich-text-editor/icons/_bootstrap4.scss +8 -0
  120. package/styles/rich-text-editor/icons/_bootstrap5.scss +8 -0
  121. package/styles/rich-text-editor/icons/_fabric-dark.scss +8 -0
  122. package/styles/rich-text-editor/icons/_fabric.scss +8 -0
  123. package/styles/rich-text-editor/icons/_fluent.scss +8 -0
  124. package/styles/rich-text-editor/icons/_fusionnew.scss +8 -0
  125. package/styles/rich-text-editor/icons/_highcontrast-light.scss +8 -0
  126. package/styles/rich-text-editor/icons/_highcontrast.scss +8 -0
  127. package/styles/rich-text-editor/icons/_material-dark.scss +8 -0
  128. package/styles/rich-text-editor/icons/_material.scss +8 -0
  129. package/styles/rich-text-editor/icons/_material3.scss +8 -0
  130. package/styles/rich-text-editor/icons/_tailwind.scss +8 -0
  131. package/styles/rich-text-editor/material-dark.css +31 -1
  132. package/styles/rich-text-editor/material.css +31 -1
  133. package/styles/rich-text-editor/tailwind-dark.css +31 -1
  134. package/styles/rich-text-editor/tailwind.css +31 -1
  135. package/styles/tailwind-dark.css +31 -1
  136. package/styles/tailwind.css +31 -1
  137. package/GitLeaksReport.json +0 -1
  138. package/gitleaks-ci/gitleaks +0 -0
  139. package/gitleaks-ci.tar.gz +0 -0
  140. package/styles/rich-text-editor/_material3-definition.scss +0 -196
@@ -76,7 +76,7 @@ var MsWordPaste = /** @class */ (function () {
76
76
  if (pattern4.test(tempHTMLContent)) {
77
77
  this.addTableBorderClass(elm);
78
78
  }
79
- // Removing the margin for list items
79
+ // Removing the margin for list items
80
80
  var liChildren = elm.querySelectorAll('li');
81
81
  if (liChildren.length > 0) {
82
82
  for (var i = 0; i < liChildren.length; i++) {
@@ -374,6 +374,29 @@ var MsWordPaste = /** @class */ (function () {
374
374
  }
375
375
  fromClass = false;
376
376
  }
377
+ var listClass = ['MsoListParagraphCxSpFirst', 'MsoListParagraphCxSpMiddle', 'MsoListParagraphCxSpLast'];
378
+ for (var i = 0; i < listClass.length; i++) {
379
+ if (keys.indexOf('li.' + listClass[i]) > -1) {
380
+ var olULElems = elm.querySelectorAll('ol.' + listClass[i] + ', ul.' + listClass[i]);
381
+ for (var j = 0; j < olULElems.length; j++) {
382
+ var styleProperty = olULElems[j].getAttribute('style');
383
+ if (!isNOU(styleProperty) && styleProperty.trim() !== '' && olULElems[j].style.marginLeft !== '') {
384
+ var valueSplit = values[keys.indexOf('li.' + listClass[i])].split(';');
385
+ for (var k = 0; k < valueSplit.length; k++) {
386
+ if ('margin-left'.indexOf(valueSplit[k].split(':')[0]) >= 0) {
387
+ if (!isNOU(valueSplit[k].split(':')[1]) &&
388
+ valueSplit[k].split(':')[1].indexOf('in') >= 0 &&
389
+ olULElems[j].style.marginLeft.indexOf('in') >= 0) {
390
+ var classStyle = parseFloat(valueSplit[k].split(':')[1].split('in')[0]);
391
+ var inlineStyle = parseFloat(olULElems[j].style.marginLeft.split('in')[0]);
392
+ olULElems[j].style.marginLeft = (inlineStyle - classStyle) + 'in';
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ }
399
+ }
377
400
  }
378
401
  };
379
402
  MsWordPaste.prototype.filterStyles = function (elm, wordPasteStyleConfig) {
@@ -495,22 +518,29 @@ var MsWordPaste = /** @class */ (function () {
495
518
  var type = void 0;
496
519
  var listStyleType = void 0;
497
520
  var startAttr = void 0;
521
+ var styleMarginLeft = void 0;
498
522
  if (!isNOU(this.listContents[0])) {
499
523
  type = this.listContents[0].trim().length > 1 ? 'ol' : 'ul';
500
524
  listStyleType = this.getlistStyleType(this.listContents[0], type);
501
- if (type === 'ol' && listNodes[i - 1] === null) {
525
+ if (type === 'ol' && (i === 0 || listNodes[i - 1] === null)) {
502
526
  var startString = this.listContents[0].split('.')[0];
503
- var listTypes = ['A', 'a', 'I', 'i', 'α', '1'];
527
+ var listTypes = ['A', 'a', 'I', 'i', 'α', '1', '1-']; // Add '1-' for rare list type.
504
528
  if (listTypes.indexOf(startString) === -1) {
505
529
  if (listStyleType === 'decimal') {
506
530
  // Bug in getlistStyleType() list style stype is returned as decimal for nested list with start attribute
507
- if (!isNaN(parseInt(startString))) {
508
- startAttr = parseInt(startString);
531
+ if (!isNaN(parseInt(startString, 10))) {
532
+ startAttr = parseInt(startString, 10);
509
533
  }
510
534
  }
511
- else if (listStyleType === 'upper-alpha' || listStyleType === 'lower-alpha') {
512
- startAttr = parseInt(startString.toLowerCase()) - 96;
535
+ else if (listStyleType === 'upper-alpha') {
536
+ startAttr = (startString.split('.')[0].charCodeAt(0) - 64);
513
537
  }
538
+ else if (listStyleType === 'lower-alpha') {
539
+ startAttr = (startString.split('.')[0].charCodeAt(0) - 96);
540
+ }
541
+ }
542
+ if (listNodes[i].style.marginLeft !== '') {
543
+ styleMarginLeft = listNodes[i].style.marginLeft;
514
544
  }
515
545
  }
516
546
  var tempNode = [];
@@ -529,7 +559,7 @@ var MsWordPaste = /** @class */ (function () {
529
559
  }
530
560
  }
531
561
  collection.push({ listType: type, content: tempNode, nestedLevel: level, class: currentClassName,
532
- listStyle: currentListStyle, listStyleTypeName: listStyleType, start: startAttr });
562
+ listStyle: currentListStyle, listStyleTypeName: listStyleType, start: startAttr, styleMarginLeft: styleMarginLeft });
533
563
  }
534
564
  }
535
565
  stNode = listNodes.shift();
@@ -555,23 +585,30 @@ var MsWordPaste = /** @class */ (function () {
555
585
  };
556
586
  MsWordPaste.prototype.getlistStyleType = function (listContent, type) {
557
587
  var currentListClass;
588
+ var upperRomanNumber = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX',
589
+ 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'];
590
+ var lowerRomanNumber = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix',
591
+ 'x', 'xi', 'xii', 'xiii', 'xiv', 'xv', 'xvi', 'xvii', 'xviii', 'xix', 'xx'];
592
+ var lowerGreekNumber = ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ',
593
+ 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'];
558
594
  if (type === 'ol') {
559
- switch (listContent.split('.')[0]) {
560
- case 'A':
561
- currentListClass = 'upper-alpha';
562
- break;
563
- case 'a':
564
- currentListClass = 'lower-alpha';
565
- break;
566
- case 'I':
595
+ var charCode = listContent.split('.')[0].charCodeAt(0);
596
+ switch (true) {
597
+ case upperRomanNumber.indexOf(listContent.split('.')[0]) > -1:
567
598
  currentListClass = 'upper-roman';
568
599
  break;
569
- case 'i':
600
+ case lowerRomanNumber.indexOf(listContent.split('.')[0]) > -1:
570
601
  currentListClass = 'lower-roman';
571
602
  break;
572
- case 'α':
603
+ case lowerGreekNumber.indexOf(listContent.split('.')[0]) > -1:
573
604
  currentListClass = 'lower-greek';
574
605
  break;
606
+ case (charCode > 64 && charCode < 91):
607
+ currentListClass = 'upper-alpha';
608
+ break;
609
+ case (charCode > 96 && charCode < 123):
610
+ currentListClass = 'lower-alpha';
611
+ break;
575
612
  default:
576
613
  currentListClass = 'decimal';
577
614
  break;
@@ -603,11 +640,12 @@ var MsWordPaste = /** @class */ (function () {
603
640
  var pElement = createElement('p');
604
641
  pElement.innerHTML = collection[index].content.join(' ');
605
642
  if ((collection[index].nestedLevel === 1) && listCount === 0 && collection[index].content) {
606
- root.appendChild(temp = createElement(collection[index].listType));
643
+ root.appendChild(temp = createElement(collection[index].listType, { className: collection[index].class }));
607
644
  prevList = createElement('li');
608
645
  prevList.appendChild(pElement);
609
646
  temp.appendChild(prevList);
610
647
  temp.setAttribute('level', collection[index].nestedLevel.toString());
648
+ temp.style.marginLeft = collection[index].styleMarginLeft;
611
649
  temp.style.listStyleType = collection[index].listStyleTypeName;
612
650
  }
613
651
  else if (collection[index].nestedLevel === pLevel) {
@@ -1,3 +1,4 @@
1
+ import { FormatPainterValue } from '../plugin';
1
2
  export declare class SelectionCommands {
2
3
  static enterAction: string;
3
4
  /**
@@ -9,11 +10,12 @@ export declare class SelectionCommands {
9
10
  * @param {string} enterAction - specifies the enter key action
10
11
  * @param {string} value - specifies the string value
11
12
  * @param {string} selector - specifies the string
13
+ * @param {FormatPainterValue} painterValues specifies the element created and last child
12
14
  * @returns {void}
13
15
  * @hidden
14
16
 
15
17
  */
16
- static applyFormat(docElement: Document, format: string, endNode: Node, enterAction: string, value?: string, selector?: string): void;
18
+ static applyFormat(docElement: Document, format: string, endNode: Node, enterAction: string, value?: string, selector?: string, painterValues?: FormatPainterValue): void;
17
19
  private static insertCursorNode;
18
20
  private static getCursorFormat;
19
21
  private static removeFormat;
@@ -24,4 +26,5 @@ export declare class SelectionCommands {
24
26
  private static applySelection;
25
27
  private static GetFormatNode;
26
28
  private static updateStyles;
29
+ private static insertFormatPainterElem;
27
30
  }
@@ -20,15 +20,16 @@ var SelectionCommands = /** @class */ (function () {
20
20
  * @param {string} enterAction - specifies the enter key action
21
21
  * @param {string} value - specifies the string value
22
22
  * @param {string} selector - specifies the string
23
+ * @param {FormatPainterValue} painterValues specifies the element created and last child
23
24
  * @returns {void}
24
25
  * @hidden
25
26
 
26
27
  */
27
- SelectionCommands.applyFormat = function (docElement, format, endNode, enterAction, value, selector) {
28
+ SelectionCommands.applyFormat = function (docElement, format, endNode, enterAction, value, selector, painterValues) {
28
29
  this.enterAction = enterAction;
29
30
  var validFormats = ['bold', 'italic', 'underline', 'strikethrough', 'superscript',
30
31
  'subscript', 'uppercase', 'lowercase', 'fontcolor', 'fontname', 'fontsize', 'backgroundcolor'];
31
- if (validFormats.indexOf(format) > -1) {
32
+ if (validFormats.indexOf(format) > -1 || value === 'formatPainter') {
32
33
  if (format === 'backgroundcolor' && value === '') {
33
34
  value = 'transparent';
34
35
  }
@@ -104,8 +105,10 @@ var SelectionCommands = /** @class */ (function () {
104
105
  if (formatNode !== null && (!isFormat || isFontStyle)) {
105
106
  nodes[index] = this.removeFormat(nodes, index, formatNode, isCursor, isFormat, isFontStyle, range, nodeCutter, format, value, domSelection, endNode, domNode);
106
107
  }
107
- else if (range.startContainer.parentElement !== endNode || (range.commonAncestorContainer === endNode || nodes.length === 1)) {
108
- nodes[index] = this.insertFormat(docElement, nodes, index, formatNode, isCursor, isFormat, isFontStyle, range, nodeCutter, format, value, domNode, endNode);
108
+ else if (range.startContainer.parentElement !== endNode ||
109
+ (range.commonAncestorContainer !== endNode && range.startContainer.parentElement === endNode)
110
+ || (range.commonAncestorContainer === endNode || nodes.length === 1)) {
111
+ nodes[index] = this.insertFormat(docElement, nodes, index, formatNode, isCursor, isFormat, isFontStyle, range, nodeCutter, format, value, painterValues, domNode, endNode);
109
112
  }
110
113
  domSelection = this.applySelection(nodes, domSelection, nodeCutter, index, isCollapsed);
111
114
  }
@@ -401,7 +404,7 @@ var SelectionCommands = /** @class */ (function () {
401
404
  }
402
405
  return nodes[index];
403
406
  };
404
- SelectionCommands.insertFormat = function (docElement, nodes, index, formatNode, isCursor, isFormat, isFontStyle, range, nodeCutter, format, value, domNode, endNode) {
407
+ SelectionCommands.insertFormat = function (docElement, nodes, index, formatNode, isCursor, isFormat, isFontStyle, range, nodeCutter, format, value, painterValues, domNode, endNode) {
405
408
  var rootElementNode;
406
409
  if (!isCursor) {
407
410
  if ((formatNode === null && isFormat) || isFontStyle) {
@@ -428,11 +431,11 @@ var SelectionCommands = /** @class */ (function () {
428
431
  }
429
432
  else if (!(isFontStyle === true && value === '')) {
430
433
  var element = this.GetFormatNode(format, value);
431
- if (format === 'fontsize' || format === 'fontcolor' || format === 'fontname' || format === 'backgroundcolor') {
434
+ if (value === 'formatPainter' || format === 'fontsize' || format === 'fontcolor' || format === 'fontname' || format === 'backgroundcolor') {
432
435
  if (format !== 'fontname' && format !== 'backgroundcolor') {
433
436
  var liElement = nodes[index].parentElement;
434
437
  var parentElement = nodes[index].parentElement;
435
- while (!isNOU(parentElement) && parentElement.tagName.toLowerCase() !== 'li' && parentElement !== endNode) {
438
+ while (!isNOU(parentElement) && parentElement.tagName.toLowerCase() !== 'li') {
436
439
  parentElement = parentElement.parentElement;
437
440
  liElement = parentElement;
438
441
  }
@@ -447,7 +450,7 @@ var SelectionCommands = /** @class */ (function () {
447
450
  }
448
451
  }
449
452
  }
450
- if (rootElementNode && rootElementNode.nodeType !== 3) {
453
+ if (rootElementNode && rootElementNode.nodeType !== 3 && rootElementNode.nodeName !== 'A') {
451
454
  var save = new NodeSelection();
452
455
  save.save(range, docElement);
453
456
  domNode.setMarker(save);
@@ -467,7 +470,12 @@ var SelectionCommands = /** @class */ (function () {
467
470
  domNode.saveMarker(save, null);
468
471
  }
469
472
  else {
470
- nodes[index] = this.applyStyles(nodes, index, element);
473
+ if (value === 'formatPainter') {
474
+ return this.insertFormatPainterElem(nodes, index, range, nodeCutter, painterValues, domNode);
475
+ }
476
+ else {
477
+ nodes[index] = this.applyStyles(nodes, index, element);
478
+ }
471
479
  }
472
480
  if (format === 'fontsize') {
473
481
  var bg = closest(nodes[index].parentElement, 'span[style*=' + 'background-color' + ']');
@@ -598,6 +606,59 @@ var SelectionCommands = /** @class */ (function () {
598
606
  ele.setAttribute('style', styles);
599
607
  }
600
608
  };
609
+ // Below function is used to insert the element created by the format painter plugin.
610
+ SelectionCommands.insertFormatPainterElem = function (nodes, index, range, nodeCutter, painterValues, domNode) {
611
+ var parent = nodes[index].parentElement;
612
+ if (!domNode.isBlockNode(parent)) {
613
+ // The below code is used to remove the already present inline style from the text node.
614
+ while (parent.textContent.trim() === parent.parentElement.textContent.trim() && !domNode.isBlockNode(parent.parentElement)) {
615
+ parent = parent.parentElement;
616
+ }
617
+ if (parent.textContent.trim() !== nodes[index].textContent.trim()) {
618
+ nodeCutter.SplitNode(range, parent, true);
619
+ var childELemList = nodes[index].parentElement.childNodes;
620
+ for (var i = 0; i < childELemList.length; i++) {
621
+ if (childELemList[i].textContent.trim() === nodes[i].textContent.trim()) {
622
+ parent.parentNode.insertBefore(childELemList[i], parent);
623
+ break;
624
+ }
625
+ }
626
+ var blockChildNodes = parent.parentElement.childNodes;
627
+ for (var k = 0; k < blockChildNodes.length; k++) {
628
+ if (blockChildNodes[k].textContent.trim() === '' || blockChildNodes[k].textContent.length === 0) {
629
+ detach(blockChildNodes[k]);
630
+ }
631
+ }
632
+ }
633
+ else {
634
+ InsertMethods.unwrap(parent);
635
+ }
636
+ }
637
+ var elem = painterValues.element;
638
+ if (!isNOU(elem)) {
639
+ // Step 1: Cloning the element that is created by format painter.
640
+ // Step 2: Finding the last child of the nested elememt using the paintervalues.lastchild nodename
641
+ // Step 3: Assigning the nodes[index] text content to the last child element.
642
+ // Step 4: Wrapping the cloned element with the nodes[index]
643
+ var clonedElement = elem.cloneNode(true);
644
+ var elemList = clonedElement.querySelectorAll(painterValues.lastChild.nodeName);
645
+ var lastElement = void 0;
646
+ if (elemList.length > 0) {
647
+ lastElement = elemList[elemList.length - 1];
648
+ }
649
+ else {
650
+ if (!isNOU(clonedElement) && clonedElement.nodeName === painterValues.lastChild.nodeName) {
651
+ lastElement = clonedElement;
652
+ }
653
+ }
654
+ lastElement.textContent = nodes[index].textContent;
655
+ var lastChild = lastElement.childNodes[0];
656
+ nodes[index] = InsertMethods.Wrap(nodes[index], clonedElement);
657
+ nodes[index].textContent = '';
658
+ nodes[index] = lastChild;
659
+ }
660
+ return nodes[index];
661
+ };
601
662
  SelectionCommands.enterAction = 'P';
602
663
  return SelectionCommands;
603
664
  }());
@@ -161,6 +161,8 @@ var VideoCommand = /** @class */ (function () {
161
161
  : (Browser.isIE ? selectedNode : !e.item.isEmbedUrl ? selectedNode.lastElementChild : selectedNode.querySelector('iframe'));
162
162
  videoElm_1.addEventListener(videoElm_1.tagName !== 'IFRAME' ? 'loadeddata' : 'load', function () {
163
163
  if (e.value !== 'VideoReplace' || !isReplaced) {
164
+ if (e.item.isEmbedUrl && videoElm_1)
165
+ videoElm_1.classList.add('e-rte-embed-url');
164
166
  e.callBack({
165
167
  requestType: 'Videos',
166
168
  editorMode: 'HTML',
@@ -23,3 +23,4 @@ export * from './plugin/clearformat-exec';
23
23
  export * from './plugin/undo';
24
24
  export * from './plugin/table';
25
25
  export * from './plugin/toolbar-status';
26
+ export * from './plugin/format-painter-actions';
@@ -23,3 +23,4 @@ export * from './plugin/clearformat-exec';
23
23
  export * from './plugin/undo';
24
24
  export * from './plugin/table';
25
25
  export * from './plugin/toolbar-status';
26
+ export * from './plugin/format-painter-actions';
package/src/global.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import * as index from './index';
2
- index.RichTextEditor.Inject(index.Toolbar, index.Link, index.Image, index.Audio, index.Video, index.Count, index.QuickToolbar, index.HtmlEditor, index.MarkdownEditor, index.Table, index.PasteCleanup, index.Resize, index.FileManager);
2
+ index.RichTextEditor.Inject(index.Toolbar, index.Link, index.Image, index.Audio, index.Video, index.Count, index.QuickToolbar, index.HtmlEditor, index.MarkdownEditor, index.Table, index.PasteCleanup, index.Resize, index.FileManager, index.FormatPainter);
3
3
  export * from './index';
@@ -21,6 +21,7 @@ export declare class BaseQuickToolbar {
21
21
  private popupRenderer;
22
22
  toolbarElement: HTMLElement;
23
23
  private renderFactory;
24
+ private tooltip;
24
25
  constructor(parent?: IRichTextEditor, locator?: ServiceLocator);
25
26
  private appendPopupContent;
26
27
  /**
@@ -1,6 +1,6 @@
1
1
  import { detach, getUniqueID, append, closest, selectAll, select, isNullOrUndefined as isNOU } from '@syncfusion/ej2-base';
2
2
  import { addClass, removeClass, Browser, isNullOrUndefined, setStyleAttribute } from '@syncfusion/ej2-base';
3
- import { isCollide } from '@syncfusion/ej2-popups';
3
+ import { isCollide, Tooltip } from '@syncfusion/ej2-popups';
4
4
  import * as events from '../base/constant';
5
5
  import * as classes from '../base/classes';
6
6
  import { RenderType } from '../base/enum';
@@ -69,6 +69,8 @@ var BaseQuickToolbar = /** @class */ (function () {
69
69
  var x;
70
70
  var y;
71
71
  var imgWrapper = closest(e.target, '.e-img-caption');
72
+ var isAligned = (e.target.classList.contains('e-imginline') ||
73
+ e.target.classList.contains('e-imgbreak')) ? false : true;
72
74
  var target = !isNOU(imgWrapper) ? imgWrapper : e.target;
73
75
  addClass([this.toolbarElement], [classes.CLS_RM_WHITE_SPACE]);
74
76
  var targetOffsetTop = target.offsetTop;
@@ -82,6 +84,7 @@ var BaseQuickToolbar = /** @class */ (function () {
82
84
  else {
83
85
  y = e.y;
84
86
  }
87
+ target = isAligned ? e.target : target;
85
88
  if (target.offsetWidth > e.popWidth) {
86
89
  x = (target.offsetWidth / 2) - (e.popWidth / 2) + e.parentData.left + target.offsetLeft;
87
90
  }
@@ -213,6 +216,13 @@ var BaseQuickToolbar = /** @class */ (function () {
213
216
  _this.parent.enableToolbarItem(['Undo', 'Redo']);
214
217
  }
215
218
  append([_this.element], document.body);
219
+ if (_this.parent.showTooltip) {
220
+ _this.tooltip = new Tooltip({
221
+ target: '#' + _this.element.id + ' [title]',
222
+ showTipPointer: true
223
+ });
224
+ _this.tooltip.appendTo(_this.element);
225
+ }
216
226
  _this.popupObj.position.X = x + 20;
217
227
  _this.popupObj.position.Y = y + 20;
218
228
  _this.popupObj.dataBind();
@@ -279,6 +289,16 @@ var BaseQuickToolbar = /** @class */ (function () {
279
289
  if (Browser.isDevice && !isIDevice()) {
280
290
  removeClass([this.parent.getToolbar()], [classes.CLS_HIDE]);
281
291
  }
292
+ if (!isNullOrUndefined(document.querySelector('.e-tooltip-wrap'))) {
293
+ if (!isNullOrUndefined(document.querySelector('#' + this.element.id + ' [data-tooltip-id]'))) {
294
+ var tooltipTargetEle = document.querySelector('#' + this.element.id + ' [data-tooltip-id]');
295
+ var dataContent = tooltipTargetEle.getAttribute('data-content');
296
+ tooltipTargetEle.removeAttribute('data-content');
297
+ tooltipTargetEle.setAttribute('title', dataContent);
298
+ tooltipTargetEle.removeAttribute('data-tooltip-id');
299
+ }
300
+ this.tooltip.destroy();
301
+ }
282
302
  if (!isNullOrUndefined(this.parent.getToolbar()) && !this.parent.inlineMode.enable) {
283
303
  if (isNullOrUndefined(viewSourcePanel) || viewSourcePanel.style.display === 'none') {
284
304
  this.parent.enableToolbarItem(this.parent.toolbarSettings.items);
@@ -1,9 +1,9 @@
1
1
  import { RenderType } from '../base/enum';
2
2
  import { CLS_HR_SEPARATOR } from '../base/classes';
3
3
  import * as events from '../base/constant';
4
- import { getTooltipText, toObjectLowerCase } from '../base/util';
5
- import { tools, templateItems } from '../models/items';
6
- import { isNullOrUndefined, extend } from '@syncfusion/ej2-base';
4
+ import { getTooltipText, isIDevice, toObjectLowerCase } from '../base/util';
5
+ import { tools, templateItems, windowKeys } from '../models/items';
6
+ import { isNullOrUndefined, extend, Browser } from '@syncfusion/ej2-base';
7
7
  /**
8
8
  * `Toolbar` module is used to handle Toolbar actions.
9
9
  */
@@ -107,13 +107,23 @@ var BaseToolbar = /** @class */ (function () {
107
107
  case '-':
108
108
  return { type: 'Separator', cssClass: CLS_HR_SEPARATOR };
109
109
  default:
110
- return {
111
- id: this.parent.getID() + '_' + container + '_' + this.tools[itemStr.toLocaleLowerCase()].id,
112
- prefixIcon: this.tools[itemStr.toLocaleLowerCase()].icon,
113
- tooltipText: getTooltipText(itemStr, this.locator),
114
- command: this.tools[itemStr.toLocaleLowerCase()].command,
115
- subCommand: this.tools[itemStr.toLocaleLowerCase()].subCommand
116
- };
110
+ if (this.parent.showTooltip) {
111
+ return {
112
+ id: this.parent.getID() + '_' + container + '_' + this.tools[itemStr.toLocaleLowerCase()].id,
113
+ prefixIcon: this.tools[itemStr.toLocaleLowerCase()].icon,
114
+ tooltipText: getTooltipText(itemStr, this.locator),
115
+ command: this.tools[itemStr.toLocaleLowerCase()].command,
116
+ subCommand: this.tools[itemStr.toLocaleLowerCase()].subCommand
117
+ };
118
+ }
119
+ else {
120
+ return {
121
+ id: this.parent.getID() + '_' + container + '_' + this.tools[itemStr.toLocaleLowerCase()].id,
122
+ prefixIcon: this.tools[itemStr.toLocaleLowerCase()].icon,
123
+ command: this.tools[itemStr.toLocaleLowerCase()].command,
124
+ subCommand: this.tools[itemStr.toLocaleLowerCase()].subCommand
125
+ };
126
+ }
117
127
  }
118
128
  }
119
129
  };
@@ -161,6 +171,19 @@ var BaseToolbar = /** @class */ (function () {
161
171
  var item = tbItems_1[_i];
162
172
  _loop_1(item);
163
173
  }
174
+ for (var num = 0; num < items.length; num++) {
175
+ var tooltipText = items[num].tooltipText;
176
+ var shortCutKey = void 0;
177
+ if (windowKeys["" + tooltipText]) {
178
+ shortCutKey = Browser.isDevice && isIDevice() ? windowKeys["" + tooltipText].replace('Ctrl', 'Cmd') : windowKeys["" + tooltipText];
179
+ }
180
+ else {
181
+ shortCutKey = tooltipText;
182
+ }
183
+ if (shortCutKey) {
184
+ items[num].tooltipText = (tooltipText !== shortCutKey) ? tooltipText + ' (' + shortCutKey + ')' : tooltipText;
185
+ }
186
+ }
164
187
  return items;
165
188
  };
166
189
  BaseToolbar.prototype.getToolbarOptions = function (args) {
@@ -47,7 +47,7 @@ var EnterKeyAction = /** @class */ (function () {
47
47
  isTableEnter = blockElement.tagName === 'TD' || blockElement.tagName === 'TBODY' ? false : true;
48
48
  }
49
49
  if (e.args.which === 13 && e.args.code === 'Enter') {
50
- if (isNOU(this.startNode.closest('LI,UL,OL')) && isNOU(this.endNode.closest('LI,UL,OL')) && isTableEnter &&
50
+ if (isNOU(this.startNode.closest('LI, UL, OL')) && isNOU(this.endNode.closest('LI, UL, OL')) && isTableEnter &&
51
51
  isNOU(this.startNode.closest('PRE')) && isNOU(this.endNode.closest('PRE'))) {
52
52
  var shiftKey_1 = e.args.shiftKey;
53
53
  var actionBeginArgs = {
@@ -117,13 +117,17 @@ var EnterKeyAction = /** @class */ (function () {
117
117
  }
118
118
  if (_this.range.startContainer === _this.range.endContainer &&
119
119
  _this.range.startOffset === _this.range.endOffset && _this.range.startContainer === _this.parent.inputElement) {
120
- if (!isNOU(_this.range.startContainer.childNodes[_this.range.startOffset]) &&
121
- !isNOU(_this.range.startContainer.childNodes[_this.range.startOffset].previousElementSibling) &&
122
- _this.range.startContainer.childNodes[_this.range.startOffset].previousElementSibling.nodeName === 'TABLE') {
123
- _this.parent.tableModule.removeResizeElement();
124
- }
125
120
  if (!(_this.parent.inputElement.childNodes.length === 1 && _this.parent.inputElement.childNodes[0].nodeName === 'TABLE')) {
126
- _this.parent.formatter.editorManager.nodeSelection.setCursorPoint(_this.parent.contentModule.getDocument(), _this.range.startContainer.childNodes[_this.range.startOffset], 0);
121
+ if (isNOU(_this.range.startContainer.childNodes[_this.range.startOffset])) {
122
+ var currentLastElem = _this.range.startContainer.childNodes[_this.range.startOffset - 1];
123
+ while (currentLastElem.lastChild !== null && currentLastElem.nodeName !== '#text') {
124
+ currentLastElem = currentLastElem.lastChild;
125
+ }
126
+ _this.parent.formatter.editorManager.nodeSelection.setCursorPoint(_this.parent.contentModule.getDocument(), currentLastElem, (currentLastElem.nodeName === 'BR' ? 0 : currentLastElem.textContent.length));
127
+ }
128
+ else {
129
+ _this.parent.formatter.editorManager.nodeSelection.setCursorPoint(_this.parent.contentModule.getDocument(), _this.range.startContainer.childNodes[_this.range.startOffset], 0);
130
+ }
127
131
  }
128
132
  _this.getRangeNode();
129
133
  }
@@ -148,7 +152,7 @@ var EnterKeyAction = /** @class */ (function () {
148
152
  var isFocusedFirst = false;
149
153
  if (_this.range.startOffset !== 0 && _this.range.endOffset !== 0 &&
150
154
  _this.range.startContainer === _this.range.endContainer && !(!isNOU(nearBlockNode.childNodes[0])
151
- && nearBlockNode.childNodes[0].nodeName === 'IMG' && nearBlockNode.querySelectorAll('img,audio,video').length > 0)) {
155
+ && nearBlockNode.childNodes[0].nodeName === 'IMG' && nearBlockNode.querySelectorAll('img, audio, video').length > 0)) {
152
156
  var startNodeText = _this.range.startContainer.textContent;
153
157
  var splitFirstText = startNodeText.substring(0, _this.range.startOffset);
154
158
  // eslint-disable-next-line max-len
@@ -169,8 +173,8 @@ var EnterKeyAction = /** @class */ (function () {
169
173
  (_this.range.startContainer.previousSibling.nodeName === 'IMG' || _this.range.startContainer.previousSibling.nodeName === 'BR'))) {
170
174
  var isNearBlockLengthZero = void 0;
171
175
  var newElem = void 0;
172
- if (!isNOU(_this.range.startContainer.childNodes) && _this.range.startContainer.textContent.length === 0 &&
173
- (_this.range.startContainer.querySelectorAll('img,audio,video').length > 0 ||
176
+ if (!isNOU(_this.range.startContainer.childNodes) && _this.range.startContainer.textContent.length === 0
177
+ && (_this.range.startContainer.querySelectorAll('img, audio, video').length > 0 ||
174
178
  _this.range.startContainer.nodeName === 'IMG' || _this.range.startContainer.nodeName === 'TABLE')) {
175
179
  newElem = _this.createInsertElement(shiftKey_1);
176
180
  isMediaNode = true;
@@ -179,7 +183,7 @@ var EnterKeyAction = /** @class */ (function () {
179
183
  else {
180
184
  if ((nearBlockNode.textContent.trim().length !== 0 ||
181
185
  nearBlockNode.childNodes[0].nodeName === 'IMG' ||
182
- (nearBlockNode.textContent.trim() === '' && nearBlockNode.querySelectorAll('img,audio,video').length > 0))) {
186
+ (nearBlockNode.textContent.trim() === '' && nearBlockNode.querySelectorAll('img, audio, video').length > 0))) {
183
187
  if ((_this.range.startOffset === _this.range.endOffset && _this.range.startOffset !== 0)) {
184
188
  newElem = _this.parent.formatter.editorManager.nodeCutter.SplitNode(_this.range, nearBlockNode, false).cloneNode(true);
185
189
  }
@@ -346,11 +350,13 @@ var EnterKeyAction = /** @class */ (function () {
346
350
  }
347
351
  var isLastNodeLength = _this.range.startContainer === currentParentLastChild ?
348
352
  _this.range.startContainer.textContent.length : currentParent.textContent.length;
353
+ var isImageElement = (_this.range.startContainer.nodeName === 'IMG' || (_this.range.startContainer.childNodes.length > 0
354
+ && _this.range.startContainer.childNodes[_this.range.startOffset].nodeName === 'IMG'));
349
355
  if (currentParent !== _this.parent.inputElement &&
350
356
  _this.parent.formatter.editorManager.domNode.isBlockNode(currentParent) &&
351
357
  _this.range.startOffset === _this.range.endOffset &&
352
358
  (_this.range.startOffset === isLastNodeLength ||
353
- (currentParent.textContent.trim().length === 0 && currentParent.lastChild.nodeName === 'IMG'))) {
359
+ (currentParent.textContent.trim().length === 0 && isImageElement))) {
354
360
  var focusBRElem = _this.parent.createElement('br');
355
361
  if (_this.range.startOffset === 0 && _this.range.startContainer.nodeName === 'TABLE') {
356
362
  _this.range.startContainer.parentElement.insertBefore(focusBRElem, _this.range.startContainer);
@@ -359,10 +365,11 @@ var EnterKeyAction = /** @class */ (function () {
359
365
  if (currentParentLastChild.nodeName === 'BR' && currentParent.textContent.length === 0) {
360
366
  _this.parent.formatter.editorManager.domNode.insertAfter(focusBRElem, currentParentLastChild);
361
367
  }
362
- else if (_this.range.startOffset === 0 && _this.range.endOffset === 0 &&
363
- currentParent.lastChild && currentParent.lastChild.nodeName === 'IMG') {
364
- currentParentLastChild.parentElement.insertBefore(focusBRElem, currentParentLastChild);
365
- focusBRElem = currentParentLastChild;
368
+ else if (_this.range.startOffset === 0 && _this.range.endOffset === 0 && isImageElement) {
369
+ var imageElement = _this.range.startContainer.nodeName === 'IMG' ? _this.range.startContainer :
370
+ _this.range.startContainer.childNodes[_this.range.startOffset];
371
+ currentParent.insertBefore(focusBRElem, imageElement);
372
+ focusBRElem = imageElement;
366
373
  }
367
374
  else {
368
375
  var lineBreakBRElem = _this.parent.createElement('br');
@@ -0,0 +1,24 @@
1
+ import { IRichTextEditor } from '../base/interface';
2
+ export declare class FormatPainter {
3
+ private parent;
4
+ private isSticky;
5
+ private isActive;
6
+ previousAction: string;
7
+ constructor(parent?: IRichTextEditor);
8
+ private addEventListener;
9
+ private toolbarClick;
10
+ private toolbarDoubleClick;
11
+ private onKeyDown;
12
+ private actionHandler;
13
+ private updateCursor;
14
+ private updateToolbarBtn;
15
+ private editAreaClick;
16
+ destroy(): void;
17
+ /**
18
+ * For internal use only - Get the module name.
19
+ *
20
+ * @returns {void}
21
+ * @hidden
22
+ */
23
+ private getModuleName;
24
+ }