roosterjs 9.10.0 → 9.11.2

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/dist/rooster.js CHANGED
@@ -2427,8 +2427,16 @@ function setModelIndentation(model, indentation, length, context) {
2427
2427
  }
2428
2428
  else if (block.levels.length == 1 || !isMultilevelSelection(model, block, parent)) {
2429
2429
  if (isIndent) {
2430
- var lastLevel = block.levels[block.levels.length - 1];
2431
- var newLevel = (0, roosterjs_content_model_dom_1.createListLevel)((lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.listType) || 'UL', lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.format);
2430
+ var threadIdx = thread.indexOf(block);
2431
+ var previousItem = thread[threadIdx - 1];
2432
+ var nextItem = thread[threadIdx + 1];
2433
+ var levelLength = block.levels.length;
2434
+ var lastLevel = block.levels[levelLength - 1];
2435
+ var newLevel = (0, roosterjs_content_model_dom_1.createListLevel)((lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.listType) || 'UL', lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.format, previousItem && previousItem.levels.length > levelLength
2436
+ ? previousItem.levels[levelLength].dataset
2437
+ : nextItem && nextItem.levels.length > levelLength
2438
+ ? nextItem.levels[levelLength].dataset
2439
+ : undefined);
2432
2440
  (0, roosterjs_content_model_dom_1.updateListMetadata)(newLevel, function (metadata) {
2433
2441
  metadata = metadata || {};
2434
2442
  metadata.applyListStyleFromLevel = true;
@@ -2603,6 +2611,7 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
2603
2611
  * @internal
2604
2612
  */
2605
2613
  function clearModelFormat(model, blocksToClear, segmentsToClear, tablesToClear) {
2614
+ var pendingStructureChange = false;
2606
2615
  (0, roosterjs_content_model_dom_1.iterateSelections)(model, function (path, tableContext, block, segments) {
2607
2616
  if (segments) {
2608
2617
  if ((block === null || block === void 0 ? void 0 : block.blockType) == 'Paragraph') {
@@ -2634,14 +2643,14 @@ function clearModelFormat(model, blocksToClear, segmentsToClear, tablesToClear)
2634
2643
  isOnlySelectionMarkerSelected(blocksToClear[0][1]) &&
2635
2644
  blocksToClear.length == 1) {
2636
2645
  segmentsToClear.splice.apply(segmentsToClear, (0, tslib_1.__spreadArray)([0, segmentsToClear.length], (0, tslib_1.__read)((0, adjustWordSelection_1.adjustWordSelection)(model, marker)), false));
2637
- clearListFormat(blocksToClear[0][0]);
2646
+ pendingStructureChange = clearListFormat(blocksToClear[0][0]) || pendingStructureChange;
2638
2647
  }
2639
2648
  else if (blocksToClear.length > 1 || blocksToClear.some(function (x) { return isWholeBlockSelected(x[1]); })) {
2640
2649
  // 2. If a full block or multiple blocks are selected, clear block format
2641
2650
  for (var i = blocksToClear.length - 1; i >= 0; i--) {
2642
2651
  var _a = (0, tslib_1.__read)(blocksToClear[i], 2), path = _a[0], block = _a[1];
2643
2652
  clearBlockFormat(path, block);
2644
- clearListFormat(path);
2653
+ pendingStructureChange = clearListFormat(path) || pendingStructureChange;
2645
2654
  clearContainerFormat(path, block);
2646
2655
  }
2647
2656
  }
@@ -2649,6 +2658,7 @@ function clearModelFormat(model, blocksToClear, segmentsToClear, tablesToClear)
2649
2658
  clearSegmentsFormat(segmentsToClear, model.format);
2650
2659
  // 4. Clear format for table if any
2651
2660
  createTablesFormat(tablesToClear);
2661
+ return pendingStructureChange;
2652
2662
  }
2653
2663
  exports.clearModelFormat = clearModelFormat;
2654
2664
  function createTablesFormat(tablesToClear) {
@@ -2708,6 +2718,10 @@ function clearListFormat(path) {
2708
2718
  var listItem = path[(0, roosterjs_content_model_dom_1.getClosestAncestorBlockGroupIndex)(path, ['ListItem'], ['TableCell'])];
2709
2719
  if (listItem) {
2710
2720
  (0, roosterjs_content_model_dom_1.mutateBlock)(listItem).levels = [];
2721
+ return true;
2722
+ }
2723
+ else {
2724
+ return false;
2711
2725
  }
2712
2726
  }
2713
2727
  function clearBlockFormat(path, block) {
@@ -4930,6 +4944,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
4930
4944
  exports.clearFormat = void 0;
4931
4945
  var clearModelFormat_1 = __webpack_require__(/*! ../../modelApi/common/clearModelFormat */ "./packages/roosterjs-content-model-api/lib/modelApi/common/clearModelFormat.ts");
4932
4946
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
4947
+ var MAX_TRY = 3;
4933
4948
  /**
4934
4949
  * Clear format of selection
4935
4950
  * @param editor The editor to clear format from
@@ -4937,12 +4952,22 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
4937
4952
  function clearFormat(editor) {
4938
4953
  editor.focus();
4939
4954
  editor.formatContentModel(function (model) {
4940
- var blocksToClear = [];
4941
- var segmentsToClear = [];
4942
- var tablesToClear = [];
4943
- (0, clearModelFormat_1.clearModelFormat)(model, blocksToClear, segmentsToClear, tablesToClear);
4944
- (0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
4945
- return (blocksToClear.length > 0 || segmentsToClear.length > 0 || tablesToClear.length > 0);
4955
+ var changed = false;
4956
+ var needtoRun = true;
4957
+ var triedTimes = 0;
4958
+ while (needtoRun && triedTimes++ < MAX_TRY) {
4959
+ var blocksToClear = [];
4960
+ var segmentsToClear = [];
4961
+ var tablesToClear = [];
4962
+ needtoRun = (0, clearModelFormat_1.clearModelFormat)(model, blocksToClear, segmentsToClear, tablesToClear);
4963
+ (0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
4964
+ changed =
4965
+ changed ||
4966
+ blocksToClear.length > 0 ||
4967
+ segmentsToClear.length > 0 ||
4968
+ tablesToClear.length > 0;
4969
+ }
4970
+ return changed;
4946
4971
  }, {
4947
4972
  apiName: 'clearFormat',
4948
4973
  });
@@ -10372,8 +10397,8 @@ var DomIndexerImpl = /** @class */ (function () {
10372
10397
  };
10373
10398
  DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset) {
10374
10399
  var _a;
10375
- var _b;
10376
- var _c = textNode.__roosterjsContentModel, paragraph = _c.paragraph, segments = _c.segments;
10400
+ var _b, _c;
10401
+ var _d = textNode.__roosterjsContentModel, paragraph = _d.paragraph, segments = _d.segments;
10377
10402
  var first = segments[0];
10378
10403
  var last = segments[segments.length - 1];
10379
10404
  var selectable;
@@ -10395,6 +10420,14 @@ var DomIndexerImpl = /** @class */ (function () {
10395
10420
  if (endOffset === undefined) {
10396
10421
  var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(first.format);
10397
10422
  newSegments.push(marker);
10423
+ if (startOffset < ((_b = textNode.nodeValue) !== null && _b !== void 0 ? _b : '').length) {
10424
+ if (first.link) {
10425
+ (0, roosterjs_content_model_dom_1.addLink)(marker, first.link);
10426
+ }
10427
+ if (first.code) {
10428
+ (0, roosterjs_content_model_dom_1.addCode)(marker, first.code);
10429
+ }
10430
+ }
10398
10431
  selectable = marker;
10399
10432
  endOffset = startOffset;
10400
10433
  }
@@ -10436,7 +10469,7 @@ var DomIndexerImpl = /** @class */ (function () {
10436
10469
  var isBefore = wrapper.previousSibling == delimiter;
10437
10470
  var isAfter = wrapper.nextSibling == delimiter;
10438
10471
  if (index >= 0 && delimiter && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(delimiter) && (isBefore || isAfter)) {
10439
- var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_b = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _b !== void 0 ? _b : first).format);
10472
+ var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_c = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _c !== void 0 ? _c : first).format);
10440
10473
  paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);
10441
10474
  selectable = marker;
10442
10475
  }
@@ -10849,10 +10882,12 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
10849
10882
  exports.createCopyPastePlugin = exports.preprocessTable = exports.onNodeCreated = exports.adjustSelectionForCopyCut = void 0;
10850
10883
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
10851
10884
  var addRangeToSelection_1 = __webpack_require__(/*! ../../coreApi/setDOMSelection/addRangeToSelection */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/addRangeToSelection.ts");
10852
- var deleteEmptyList_1 = __webpack_require__(/*! ./deleteEmptyList */ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/deleteEmptyList.ts");
10885
+ var adjustImageSelectionOnSafari_1 = __webpack_require__(/*! ./utils/adjustImageSelectionOnSafari */ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.ts");
10886
+ var deleteEmptyList_1 = __webpack_require__(/*! ./utils/deleteEmptyList */ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts");
10853
10887
  var pasteCopyBlockEntityParser_1 = __webpack_require__(/*! ../../override/pasteCopyBlockEntityParser */ "./packages/roosterjs-content-model-core/lib/override/pasteCopyBlockEntityParser.ts");
10854
10888
  var paste_1 = __webpack_require__(/*! ../../command/paste/paste */ "./packages/roosterjs-content-model-core/lib/command/paste/paste.ts");
10855
10889
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
10890
+ var TEMP_DIV_ID = 'roosterJS_copyCutTempDiv';
10856
10891
  /**
10857
10892
  * Copy and paste plugin for handling onCopy and onPaste event
10858
10893
  */
@@ -10939,6 +10974,7 @@ var CopyPastePlugin = /** @class */ (function () {
10939
10974
  }
10940
10975
  var doc = this.editor.getDocument();
10941
10976
  var selection = this.editor.getDOMSelection();
10977
+ (0, adjustImageSelectionOnSafari_1.adjustImageSelectionOnSafari)(this.editor, selection);
10942
10978
  if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
10943
10979
  var pasteModel = this.editor.getContentModelCopy('disconnected');
10944
10980
  if (selection.type === 'table') {
@@ -11015,6 +11051,7 @@ var CopyPastePlugin = /** @class */ (function () {
11015
11051
  div.style.color = 'black';
11016
11052
  div.childNodes.forEach(function (node) { return div.removeChild(node); });
11017
11053
  div.style.display = '';
11054
+ div.id = TEMP_DIV_ID;
11018
11055
  div.focus();
11019
11056
  return div;
11020
11057
  };
@@ -11116,10 +11153,41 @@ exports.createCopyPastePlugin = createCopyPastePlugin;
11116
11153
 
11117
11154
  /***/ }),
11118
11155
 
11119
- /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/deleteEmptyList.ts":
11120
- /*!*******************************************************************************************!*\
11121
- !*** ./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/deleteEmptyList.ts ***!
11122
- \*******************************************************************************************/
11156
+ /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.ts":
11157
+ /*!**************************************************************************************************************!*\
11158
+ !*** ./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.ts ***!
11159
+ \**************************************************************************************************************/
11160
+ /***/ ((__unused_webpack_module, exports) => {
11161
+
11162
+ "use strict";
11163
+
11164
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
11165
+ exports.adjustImageSelectionOnSafari = void 0;
11166
+ /**
11167
+ * @internal
11168
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
11169
+ */
11170
+ function adjustImageSelectionOnSafari(editor, selection) {
11171
+ if (editor.getEnvironment().isSafari && (selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
11172
+ var range = new Range();
11173
+ range.setStartBefore(selection.image);
11174
+ range.setEndAfter(selection.image);
11175
+ editor.setDOMSelection({
11176
+ range: range,
11177
+ type: 'range',
11178
+ isReverted: false,
11179
+ });
11180
+ }
11181
+ }
11182
+ exports.adjustImageSelectionOnSafari = adjustImageSelectionOnSafari;
11183
+
11184
+
11185
+ /***/ }),
11186
+
11187
+ /***/ "./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts":
11188
+ /*!*************************************************************************************************!*\
11189
+ !*** ./packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts ***!
11190
+ \*************************************************************************************************/
11123
11191
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11124
11192
 
11125
11193
  "use strict";
@@ -14152,6 +14220,12 @@ var DOMHelperImpl = /** @class */ (function () {
14152
14220
  var paddingRight = (0, roosterjs_content_model_dom_1.parseValueWithUnit)(style === null || style === void 0 ? void 0 : style.paddingRight);
14153
14221
  return this.contentDiv.clientWidth - (paddingLeft + paddingRight);
14154
14222
  };
14223
+ /**
14224
+ * Get a deep cloned root element
14225
+ */
14226
+ DOMHelperImpl.prototype.getClonedRoot = function () {
14227
+ return this.contentDiv.cloneNode(true /*deep*/);
14228
+ };
14155
14229
  return DOMHelperImpl;
14156
14230
  }());
14157
14231
  /**
@@ -15692,18 +15766,27 @@ exports.blockProcessor = blockProcessor;
15692
15766
 
15693
15767
  Object.defineProperty(exports, "__esModule", ({ value: true }));
15694
15768
  exports.brProcessor = void 0;
15769
+ var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
15695
15770
  var addSegment_1 = __webpack_require__(/*! ../../modelApi/common/addSegment */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/addSegment.ts");
15696
15771
  var createBr_1 = __webpack_require__(/*! ../../modelApi/creators/createBr */ "./packages/roosterjs-content-model-dom/lib/modelApi/creators/createBr.ts");
15772
+ var getRegularSelectionOffsets_1 = __webpack_require__(/*! ../utils/getRegularSelectionOffsets */ "./packages/roosterjs-content-model-dom/lib/domToModel/utils/getRegularSelectionOffsets.ts");
15697
15773
  /**
15698
15774
  * @internal
15699
15775
  */
15700
15776
  var brProcessor = function (group, element, context) {
15701
15777
  var _a;
15702
15778
  var br = (0, createBr_1.createBr)(context.segmentFormat);
15779
+ var _b = (0, tslib_1.__read)((0, getRegularSelectionOffsets_1.getRegularSelectionOffsets)(context, element), 2), start = _b[0], end = _b[1];
15780
+ if (start >= 0) {
15781
+ context.isInSelection = true;
15782
+ }
15703
15783
  if (context.isInSelection) {
15704
15784
  br.isSelected = true;
15705
15785
  }
15706
15786
  var paragraph = (0, addSegment_1.addSegment)(group, br, context.blockFormat);
15787
+ if (end >= 0) {
15788
+ context.isInSelection = false;
15789
+ }
15707
15790
  (_a = context.domIndexer) === null || _a === void 0 ? void 0 : _a.onSegment(element, paragraph, [br]);
15708
15791
  };
15709
15792
  exports.brProcessor = brProcessor;
@@ -20905,8 +20988,6 @@ function isSegmentEmpty(segment) {
20905
20988
  switch (segment.segmentType) {
20906
20989
  case 'Text':
20907
20990
  return !segment.text;
20908
- case 'Image':
20909
- return !segment.src;
20910
20991
  default:
20911
20992
  return false;
20912
20993
  }
@@ -21120,6 +21201,7 @@ function normalizeParagraph(paragraph) {
21120
21201
  (0, mutate_1.mutateBlock)(paragraph).segments.pop();
21121
21202
  }
21122
21203
  }
21204
+ normalizeParagraphStyle(paragraph);
21123
21205
  }
21124
21206
  if (!(0, isWhiteSpacePreserved_1.isWhiteSpacePreserved)(paragraph.format.whiteSpace)) {
21125
21207
  (0, normalizeSegment_1.normalizeAllSegments)(paragraph);
@@ -21129,6 +21211,13 @@ function normalizeParagraph(paragraph) {
21129
21211
  moveUpSegmentFormat(paragraph);
21130
21212
  }
21131
21213
  exports.normalizeParagraph = normalizeParagraph;
21214
+ function normalizeParagraphStyle(paragraph) {
21215
+ // New paragraph should not have white-space style
21216
+ if (paragraph.format.whiteSpace &&
21217
+ paragraph.segments.every(function (seg) { return seg.segmentType == 'Br' || seg.segmentType == 'SelectionMarker'; })) {
21218
+ delete (0, mutate_1.mutateBlock)(paragraph).format.whiteSpace;
21219
+ }
21220
+ }
21132
21221
  function removeEmptySegments(block) {
21133
21222
  for (var j = block.segments.length - 1; j >= 0; j--) {
21134
21223
  if ((0, isEmpty_1.isSegmentEmpty)(block.segments[j])) {
@@ -22948,15 +23037,16 @@ var KeysOfSegmentFormat = (0, getObjectKeys_1.getObjectKeys)(EmptySegmentFormat_
22948
23037
  function mergeModel(target, source, context, options) {
22949
23038
  var _a;
22950
23039
  var insertPosition = (_a = options === null || options === void 0 ? void 0 : options.insertPosition) !== null && _a !== void 0 ? _a : (0, deleteSelection_1.deleteSelection)(target, [], context).insertPoint;
22951
- if (options === null || options === void 0 ? void 0 : options.addParagraphAfterMergedContent) {
22952
- var _b = insertPosition || {}, paragraph = _b.paragraph, marker = _b.marker;
23040
+ var _b = options || {}, addParagraphAfterMergedContent = _b.addParagraphAfterMergedContent, mergeFormat = _b.mergeFormat, mergeTable = _b.mergeTable;
23041
+ if (addParagraphAfterMergedContent && !mergeTable) {
23042
+ var _c = insertPosition || {}, paragraph = _c.paragraph, marker = _c.marker;
22953
23043
  var newPara = (0, createParagraph_1.createParagraph)(false /* isImplicit */, paragraph === null || paragraph === void 0 ? void 0 : paragraph.format, marker === null || marker === void 0 ? void 0 : marker.format);
22954
23044
  (0, addBlock_1.addBlock)(source, newPara);
22955
23045
  }
22956
23046
  if (insertPosition) {
22957
- if ((options === null || options === void 0 ? void 0 : options.mergeFormat) && options.mergeFormat != 'none') {
23047
+ if (mergeFormat && mergeFormat != 'none') {
22958
23048
  var newFormat = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (target.format || {})), insertPosition.marker.format);
22959
- applyDefaultFormat(source, newFormat, options === null || options === void 0 ? void 0 : options.mergeFormat);
23049
+ applyDefaultFormat(source, newFormat, mergeFormat);
22960
23050
  }
22961
23051
  for (var i = 0; i < source.blocks.length; i++) {
22962
23052
  var block = source.blocks[i];
@@ -22972,8 +23062,8 @@ function mergeModel(target, source, context, options) {
22972
23062
  context === null || context === void 0 ? void 0 : context.newEntities.push(block);
22973
23063
  break;
22974
23064
  case 'Table':
22975
- if (source.blocks.length == 1 && (options === null || options === void 0 ? void 0 : options.mergeTable)) {
22976
- mergeTable(insertPosition, block, source);
23065
+ if (source.blocks.length == 1 && mergeTable) {
23066
+ mergeTables(insertPosition, block, source);
22977
23067
  }
22978
23068
  else {
22979
23069
  insertBlock(insertPosition, block);
@@ -23043,7 +23133,7 @@ function mergeParagraph(markerPosition, newPara, mergeToCurrentParagraph, contex
23043
23133
  newParagraph.format = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, newParagraph.format), newPara.format);
23044
23134
  }
23045
23135
  }
23046
- function mergeTable(markerPosition, newTable, source) {
23136
+ function mergeTables(markerPosition, newTable, source) {
23047
23137
  var _a, _b;
23048
23138
  var tableContext = markerPosition.tableContext, marker = markerPosition.marker;
23049
23139
  if (tableContext && source.blocks.length == 1 && source.blocks[0] == newTable) {
@@ -26541,11 +26631,13 @@ var AutoFormatPlugin = /** @class */ (function () {
26541
26631
  * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:
26542
26632
  * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.
26543
26633
  * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.
26544
- * - autoLink: A boolean that enables or disables automatic hyperlink creation when pasting or typing content. Defaults to false.
26545
- * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
26546
26634
  * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.
26547
26635
  * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.
26548
26636
  * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.
26637
+ * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.
26638
+ * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
26639
+ * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
26640
+ * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
26549
26641
  */
26550
26642
  function AutoFormatPlugin(options) {
26551
26643
  if (options === void 0) { options = DefaultOptions; }
@@ -26611,7 +26703,7 @@ var AutoFormatPlugin = /** @class */ (function () {
26611
26703
  apiName: '',
26612
26704
  };
26613
26705
  (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, paragraph, _markerFormat, context) {
26614
- var _a = _this.options, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering, autoLink = _a.autoLink, autoHyphen = _a.autoHyphen, autoFraction = _a.autoFraction, autoOrdinals = _a.autoOrdinals;
26706
+ var _a = _this.options, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering, autoLink = _a.autoLink, autoHyphen = _a.autoHyphen, autoFraction = _a.autoFraction, autoOrdinals = _a.autoOrdinals, autoMailto = _a.autoMailto, autoTel = _a.autoTel;
26615
26707
  var shouldHyphen = false;
26616
26708
  var shouldLink = false;
26617
26709
  var shouldList = false;
@@ -26620,8 +26712,12 @@ var AutoFormatPlugin = /** @class */ (function () {
26620
26712
  if (autoBullet || autoNumbering) {
26621
26713
  shouldList = (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, autoBullet, autoNumbering);
26622
26714
  }
26623
- if (autoLink) {
26624
- shouldLink = (0, createLinkAfterSpace_1.createLinkAfterSpace)(previousSegment, paragraph, context);
26715
+ if (autoLink || autoTel || autoMailto) {
26716
+ shouldLink = (0, createLinkAfterSpace_1.createLinkAfterSpace)(previousSegment, paragraph, context, {
26717
+ autoLink: autoLink,
26718
+ autoTel: autoTel,
26719
+ autoMailto: autoMailto,
26720
+ });
26625
26721
  }
26626
26722
  if (autoHyphen) {
26627
26723
  shouldHyphen = (0, transformHyphen_1.transformHyphen)(previousSegment, paragraph, context);
@@ -26657,9 +26753,13 @@ var AutoFormatPlugin = /** @class */ (function () {
26657
26753
  }
26658
26754
  };
26659
26755
  AutoFormatPlugin.prototype.handleContentChangedEvent = function (editor, event) {
26660
- var autoLink = this.options.autoLink;
26661
- if (event.source == 'Paste' && autoLink) {
26662
- (0, createLink_1.createLink)(editor);
26756
+ var _a = this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto;
26757
+ if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {
26758
+ (0, createLink_1.createLink)(editor, {
26759
+ autoLink: autoLink,
26760
+ autoTel: autoTel,
26761
+ autoMailto: autoMailto,
26762
+ });
26663
26763
  }
26664
26764
  };
26665
26765
  return AutoFormatPlugin;
@@ -26736,10 +26836,11 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
26736
26836
  exports.createLink = void 0;
26737
26837
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
26738
26838
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26839
+ var getLinkUrl_1 = __webpack_require__(/*! ./getLinkUrl */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts");
26739
26840
  /**
26740
26841
  * @internal
26741
26842
  */
26742
- function createLink(editor) {
26843
+ function createLink(editor, autoLinkOptions) {
26743
26844
  var anchorNode = null;
26744
26845
  var links = [];
26745
26846
  (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (_model, linkSegment, _paragraph) {
@@ -26747,11 +26848,11 @@ function createLink(editor) {
26747
26848
  links.push(linkSegment.link);
26748
26849
  return true;
26749
26850
  }
26750
- var linkData = null;
26751
- if (!linkSegment.link && (linkData = (0, roosterjs_content_model_api_1.matchLink)(linkSegment.text))) {
26851
+ var linkUrl = undefined;
26852
+ if (!linkSegment.link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(linkSegment.text, autoLinkOptions))) {
26752
26853
  (0, roosterjs_content_model_dom_1.addLink)(linkSegment, {
26753
26854
  format: {
26754
- href: linkData.normalizedUrl,
26855
+ href: linkUrl,
26755
26856
  underline: true,
26756
26857
  },
26757
26858
  dataset: {},
@@ -26787,19 +26888,20 @@ exports.createLink = createLink;
26787
26888
 
26788
26889
  Object.defineProperty(exports, "__esModule", ({ value: true }));
26789
26890
  exports.createLinkAfterSpace = void 0;
26891
+ var getLinkUrl_1 = __webpack_require__(/*! ./getLinkUrl */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts");
26790
26892
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26791
26893
  /**
26792
26894
  * @internal
26793
26895
  */
26794
- function createLinkAfterSpace(previousSegment, paragraph, context) {
26896
+ function createLinkAfterSpace(previousSegment, paragraph, context, autoLinkOptions) {
26795
26897
  var link = previousSegment.text.split(' ').pop();
26796
26898
  var url = link === null || link === void 0 ? void 0 : link.trim();
26797
- var linkData = null;
26798
- if (url && link && (linkData = (0, roosterjs_content_model_api_1.matchLink)(url))) {
26899
+ var linkUrl = undefined;
26900
+ if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
26799
26901
  var linkSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - link.trimLeft().length, previousSegment.text.trimRight().length);
26800
26902
  linkSegment.link = {
26801
26903
  format: {
26802
- href: linkData.normalizedUrl,
26904
+ href: linkUrl,
26803
26905
  underline: true,
26804
26906
  },
26805
26907
  dataset: {},
@@ -26812,6 +26914,42 @@ function createLinkAfterSpace(previousSegment, paragraph, context) {
26812
26914
  exports.createLinkAfterSpace = createLinkAfterSpace;
26813
26915
 
26814
26916
 
26917
+ /***/ }),
26918
+
26919
+ /***/ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts":
26920
+ /*!************************************************************************************!*\
26921
+ !*** ./packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts ***!
26922
+ \************************************************************************************/
26923
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
26924
+
26925
+ "use strict";
26926
+
26927
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
26928
+ exports.getLinkUrl = void 0;
26929
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26930
+ var COMMON_REGEX = "[s]*[a-zA-Z0-9+][s]*";
26931
+ var TELEPHONE_REGEX = "(T|t)el:" + COMMON_REGEX;
26932
+ var MAILTO_REGEX = "(M|m)ailto:" + COMMON_REGEX;
26933
+ /**
26934
+ * @internal
26935
+ */
26936
+ function getLinkUrl(text, autoLinkOptions) {
26937
+ var _a;
26938
+ var autoLink = autoLinkOptions.autoLink, autoMailto = autoLinkOptions.autoMailto, autoTel = autoLinkOptions.autoTel;
26939
+ var linkMatch = autoLink ? (_a = (0, roosterjs_content_model_api_1.matchLink)(text)) === null || _a === void 0 ? void 0 : _a.normalizedUrl : undefined;
26940
+ var telMatch = autoTel ? matchTel(text) : undefined;
26941
+ var mailtoMatch = autoMailto ? matchMailTo(text) : undefined;
26942
+ return linkMatch || telMatch || mailtoMatch;
26943
+ }
26944
+ exports.getLinkUrl = getLinkUrl;
26945
+ function matchTel(text) {
26946
+ return text.match(TELEPHONE_REGEX) ? text.toLocaleLowerCase() : undefined;
26947
+ }
26948
+ function matchMailTo(text) {
26949
+ return text.match(MAILTO_REGEX) ? text.toLocaleLowerCase() : undefined;
26950
+ }
26951
+
26952
+
26815
26953
  /***/ }),
26816
26954
 
26817
26955
  /***/ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/unlink.ts":
@@ -27563,7 +27701,7 @@ var EditPlugin = /** @class */ (function () {
27563
27701
  EditPlugin.prototype.initialize = function (editor) {
27564
27702
  var _this = this;
27565
27703
  this.editor = editor;
27566
- this.handleNormalEnter = this.editor.isExperimentalFeatureEnabled('PersistCache');
27704
+ this.handleNormalEnter = this.editor.isExperimentalFeatureEnabled('HandleEnterKey');
27567
27705
  if (editor.getEnvironment().isAndroid) {
27568
27706
  this.disposer = this.editor.attachDomEvent({
27569
27707
  beforeinput: {
@@ -28458,9 +28596,9 @@ function canDeleteAfter(rawEvent, range) {
28458
28596
  Object.defineProperty(exports, "__esModule", ({ value: true }));
28459
28597
  exports.keyboardEnter = void 0;
28460
28598
  var deleteEmptyQuote_1 = __webpack_require__(/*! ./deleteSteps/deleteEmptyQuote */ "./packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteEmptyQuote.ts");
28461
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
28462
28599
  var handleEnterOnList_1 = __webpack_require__(/*! ./inputSteps/handleEnterOnList */ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts");
28463
28600
  var handleEnterOnParagraph_1 = __webpack_require__(/*! ./inputSteps/handleEnterOnParagraph */ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnParagraph.ts");
28601
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
28464
28602
  /**
28465
28603
  * @internal
28466
28604
  */
@@ -28494,6 +28632,7 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
28494
28632
  }, {
28495
28633
  rawEvent: rawEvent,
28496
28634
  scrollCaretIntoView: true,
28635
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
28497
28636
  });
28498
28637
  }
28499
28638
  exports.keyboardEnter = keyboardEnter;
@@ -28537,6 +28676,7 @@ function keyboardInput(editor, rawEvent) {
28537
28676
  }, {
28538
28677
  scrollCaretIntoView: true,
28539
28678
  rawEvent: rawEvent,
28679
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
28540
28680
  });
28541
28681
  return true;
28542
28682
  }
@@ -28567,12 +28707,12 @@ function shouldInputWithContentModel(selection, rawEvent) {
28567
28707
 
28568
28708
  Object.defineProperty(exports, "__esModule", ({ value: true }));
28569
28709
  exports.keyboardTab = void 0;
28570
- var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
28571
28710
  var handleTabOnList_1 = __webpack_require__(/*! ./tabUtils/handleTabOnList */ "./packages/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnList.ts");
28572
28711
  var handleTabOnParagraph_1 = __webpack_require__(/*! ./tabUtils/handleTabOnParagraph */ "./packages/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnParagraph.ts");
28573
28712
  var handleTabOnTable_1 = __webpack_require__(/*! ./tabUtils/handleTabOnTable */ "./packages/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnTable.ts");
28574
28713
  var handleTabOnTableCell_1 = __webpack_require__(/*! ./tabUtils/handleTabOnTableCell */ "./packages/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnTableCell.ts");
28575
28714
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
28715
+ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
28576
28716
  /**
28577
28717
  * @internal
28578
28718
  */
@@ -28591,6 +28731,7 @@ function keyboardTab(editor, rawEvent) {
28591
28731
  return (0, handleTabOnTable_1.handleTabOnTable)(model, rawEvent);
28592
28732
  }, {
28593
28733
  apiName: 'handleTabKey',
28734
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
28594
28735
  });
28595
28736
  return true;
28596
28737
  }
@@ -29344,6 +29485,8 @@ var DefaultOptions = {
29344
29485
  };
29345
29486
  var MouseRightButton = 2;
29346
29487
  var DRAG_ID = '_dragging';
29488
+ var IMAGE_EDIT_CLASS = 'imageEdit';
29489
+ var IMAGE_EDIT_CLASS_CARET = 'imageEditCaretColor';
29347
29490
  /**
29348
29491
  * ImageEdit plugin handles the following image editing features:
29349
29492
  * - Resize image
@@ -29495,14 +29638,22 @@ var ImageEditPlugin = /** @class */ (function () {
29495
29638
  };
29496
29639
  ImageEditPlugin.prototype.keyDownHandler = function (editor, event) {
29497
29640
  if (this.isEditing) {
29498
- if (event.rawEvent.key === 'Escape') {
29499
- this.removeImageWrapper();
29641
+ if (event.rawEvent.key === 'Escape' ||
29642
+ event.rawEvent.key === 'Delete' ||
29643
+ event.rawEvent.key === 'Backspace') {
29644
+ if (event.rawEvent.key === 'Escape') {
29645
+ this.removeImageWrapper();
29646
+ }
29647
+ this.cleanInfo();
29500
29648
  }
29501
29649
  else {
29502
29650
  this.applyFormatWithContentModel(editor, this.isCropMode, true /** should selectImage */, false /* isApiOperation */);
29503
29651
  }
29504
29652
  }
29505
29653
  };
29654
+ /**
29655
+ * EXPOSED FOR TESTING PURPOSE ONLY
29656
+ */
29506
29657
  ImageEditPlugin.prototype.applyFormatWithContentModel = function (editor, isCropMode, shouldSelectImage, isApiOperation) {
29507
29658
  var _this = this;
29508
29659
  var editingImageModel;
@@ -29529,6 +29680,15 @@ var ImageEditPlugin = /** @class */ (function () {
29529
29680
  image.isSelected = shouldSelectImage;
29530
29681
  image.isSelectedAsImageSelection = shouldSelectImage;
29531
29682
  delete image.dataset.isEditing;
29683
+ if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'range' && !selection.range.collapsed) {
29684
+ var selectedParagraphs = (0, roosterjs_content_model_dom_1.getSelectedParagraphs)(model, true);
29685
+ var isImageInRange = selectedParagraphs.some(function (paragraph) {
29686
+ return paragraph.segments.includes(image);
29687
+ });
29688
+ if (isImageInRange) {
29689
+ image.isSelected = true;
29690
+ }
29691
+ }
29532
29692
  });
29533
29693
  if (shouldSelectImage) {
29534
29694
  (0, normalizeImageSelection_1.normalizeImageSelection)(previousSelectedImage);
@@ -29589,9 +29749,10 @@ var ImageEditPlugin = /** @class */ (function () {
29589
29749
  this.rotators = rotators;
29590
29750
  this.croppers = croppers;
29591
29751
  this.zoomScale = editor.getDOMHelper().calculateZoomScale();
29592
- editor.setEditorStyle('imageEdit', "outline-style:none!important;", [
29752
+ editor.setEditorStyle(IMAGE_EDIT_CLASS, "outline-style:none!important;", [
29593
29753
  "span:has(>img" + (0, roosterjs_content_model_dom_1.getSafeIdSelector)(this.selectedImage.id) + ")",
29594
29754
  ]);
29755
+ editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, "caret-color: transparent;");
29595
29756
  };
29596
29757
  ImageEditPlugin.prototype.startRotateAndResize = function (editor, image) {
29597
29758
  var _this = this;
@@ -29599,6 +29760,7 @@ var ImageEditPlugin = /** @class */ (function () {
29599
29760
  if (this.imageEditInfo) {
29600
29761
  this.startEditing(editor, image, ['resize', 'rotate']);
29601
29762
  if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {
29763
+ var isMobileOrTable = !!editor.getEnvironment().isMobileOrTablet;
29602
29764
  this.dndHelpers = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.ResizeHandle, resizerContext_1.Resizer, function () {
29603
29765
  if (_this.imageEditInfo &&
29604
29766
  _this.selectedImage &&
@@ -29607,7 +29769,7 @@ var ImageEditPlugin = /** @class */ (function () {
29607
29769
  (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, _this.resizers);
29608
29770
  _this.wasImageResized = true;
29609
29771
  }
29610
- }, this.zoomScale)), false), (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.RotateHandle, rotatorContext_1.Rotator, function () {
29772
+ }, this.zoomScale, isMobileOrTable)), false), (0, tslib_1.__read)((0, getDropAndDragHelpers_1.getDropAndDragHelpers)(this.wrapper, this.imageEditInfo, this.options, ImageEditElementClass_1.ImageEditElementClass.RotateHandle, rotatorContext_1.Rotator, function () {
29611
29773
  var _a;
29612
29774
  if (_this.imageEditInfo &&
29613
29775
  _this.selectedImage &&
@@ -29616,7 +29778,7 @@ var ImageEditPlugin = /** @class */ (function () {
29616
29778
  (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper);
29617
29779
  _this.updateRotateHandleState(editor, _this.selectedImage, _this.wrapper, _this.rotators, (_a = _this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad);
29618
29780
  }
29619
- }, this.zoomScale)), false);
29781
+ }, this.zoomScale, isMobileOrTable)), false);
29620
29782
  (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, this.resizers);
29621
29783
  this.updateRotateHandleState(editor, this.selectedImage, this.wrapper, this.rotators, (_a = this.imageEditInfo) === null || _a === void 0 ? void 0 : _a.angleRad);
29622
29784
  }
@@ -29656,7 +29818,7 @@ var ImageEditPlugin = /** @class */ (function () {
29656
29818
  (0, updateWrapper_1.updateWrapper)(_this.imageEditInfo, _this.options, _this.selectedImage, _this.clonedImage, _this.wrapper, undefined, _this.croppers);
29657
29819
  _this.isCropMode = true;
29658
29820
  }
29659
- }, this.zoomScale)), false);
29821
+ }, this.zoomScale, !!editor.getEnvironment().isMobileOrTablet)), false);
29660
29822
  (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper, undefined, this.croppers);
29661
29823
  }
29662
29824
  }
@@ -29682,9 +29844,13 @@ var ImageEditPlugin = /** @class */ (function () {
29682
29844
  (0, updateWrapper_1.updateWrapper)(this.imageEditInfo, this.options, this.selectedImage, this.clonedImage, this.wrapper);
29683
29845
  this.applyFormatWithContentModel(editor, false /* isCrop */, true /* shouldSelect*/, true /* isApiOperation */);
29684
29846
  };
29847
+ /**
29848
+ * Exported for testing purpose only
29849
+ */
29685
29850
  ImageEditPlugin.prototype.cleanInfo = function () {
29686
- var _a;
29687
- (_a = this.editor) === null || _a === void 0 ? void 0 : _a.setEditorStyle('imageEdit', null);
29851
+ var _a, _b;
29852
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.setEditorStyle(IMAGE_EDIT_CLASS, null);
29853
+ (_b = this.editor) === null || _b === void 0 ? void 0 : _b.setEditorStyle(IMAGE_EDIT_CLASS_CARET, null);
29688
29854
  this.selectedImage = null;
29689
29855
  this.shadowSpan = null;
29690
29856
  this.wrapper = null;
@@ -30660,8 +30826,8 @@ function findEditingImage(group, imageId) {
30660
30826
  var segment = block.segments[j];
30661
30827
  switch (segment.segmentType) {
30662
30828
  case 'Image':
30663
- if ((segment.dataset.isEditing && !imageId) ||
30664
- segment.format.id == imageId) {
30829
+ if ((imageId && segment.format.id == imageId) ||
30830
+ segment.dataset.isEditing) {
30665
30831
  return {
30666
30832
  paragraph: block,
30667
30833
  image: segment,
@@ -30855,7 +31021,7 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
30855
31021
  /**
30856
31022
  * @internal
30857
31023
  */
30858
- function getDropAndDragHelpers(wrapper, editInfo, options, elementClass, helper, updateWrapper, zoomScale) {
31024
+ function getDropAndDragHelpers(wrapper, editInfo, options, elementClass, helper, updateWrapper, zoomScale, useTouch) {
30859
31025
  return getEditElements(wrapper, elementClass).map(function (element) {
30860
31026
  return new DragAndDropHelper_1.DragAndDropHelper(element, {
30861
31027
  editInfo: editInfo,
@@ -30863,7 +31029,7 @@ function getDropAndDragHelpers(wrapper, editInfo, options, elementClass, helper,
30863
31029
  elementClass: elementClass,
30864
31030
  x: element.dataset.x,
30865
31031
  y: element.dataset.y,
30866
- }, updateWrapper, helper, zoomScale);
31032
+ }, updateWrapper, helper, zoomScale, useTouch);
30867
31033
  });
30868
31034
  }
30869
31035
  exports.getDropAndDragHelpers = getDropAndDragHelpers;