roosterjs 9.11.2 → 9.12.0

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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Type definitions for roosterjs (Version 9.11.2)
1
+ // Type definitions for roosterjs (Version 9.12.0)
2
2
  // Generated by dts tool from roosterjs
3
3
  // Project: https://github.com/Microsoft/roosterjs
4
4
 
@@ -4360,6 +4360,28 @@ interface ContextMenuPluginState {
4360
4360
  contextMenuProviders: ContextMenuProvider<any>[];
4361
4361
  }
4362
4362
 
4363
+ /**
4364
+ * Options to customize the Auto link options in Auto Format Plugin
4365
+ */
4366
+ interface AutoLinkOptions {
4367
+ /**
4368
+ * When press backspace before a link, remove the hyperlink
4369
+ */
4370
+ autoUnlink?: boolean;
4371
+ /**
4372
+ * When paste or type content with a link, create hyperlink for the link
4373
+ */
4374
+ autoLink?: boolean;
4375
+ /**
4376
+ * When paste content or type content with telephone, create hyperlink for the telephone number
4377
+ */
4378
+ autoTel?: boolean;
4379
+ /**
4380
+ * When paste or type a content with mailto, create hyperlink for the content
4381
+ */
4382
+ autoMailto?: boolean;
4383
+ }
4384
+
4363
4385
  /**
4364
4386
  * Current running environment
4365
4387
  */
@@ -5334,14 +5356,16 @@ interface MergeModelOption {
5334
5356
  insertPosition?: InsertPoint;
5335
5357
  /**
5336
5358
  * Use this to decide whether to change the source model format when doing the merge.
5337
- * 'mergeAll': segment format of the insert position will be merged into the content that is merged into current model.
5359
+ * 'mergeAll': (deprecated) Use PreferSource Instead, segment format of the insert position will be merged into the content that is merged into current model.
5338
5360
  * If the source model already has some format, it will not be overwritten.
5339
5361
  * 'keepSourceEmphasisFormat': format of the insert position will be set into the content that is merged into current model.
5340
5362
  * If the source model already has emphasis format, such as, fontWeight, Italic or underline different than the default style, it will not be overwritten.
5341
5363
  * 'none' the source segment format will not be modified.
5364
+ * 'preferSource' Will merge both formatting, but source will overwrite target
5365
+ * 'preferTarget' Will merge both formatting, but target will overwrite source
5342
5366
  * @default undefined
5343
5367
  */
5344
- mergeFormat?: 'mergeAll' | 'keepSourceEmphasisFormat' | 'none';
5368
+ mergeFormat?: 'mergeAll' | 'keepSourceEmphasisFormat' | 'none' | 'preferSource' | 'preferTarget';
5345
5369
  /**
5346
5370
  * Whether to add a paragraph after the merged content.
5347
5371
  */
@@ -7182,9 +7206,10 @@ function getListStyleTypeFromString(listType: 'OL' | 'UL', bullet: string): numb
7182
7206
  /**
7183
7207
  * Get the text format of a segment, this function will return only format that is applicable to text
7184
7208
  * @param segment The segment to get format from
7209
+ * @param includingBIU When pass true, also get Bold/Italic/Underline format
7185
7210
  * @returns
7186
7211
  */
7187
- function getSegmentTextFormat(segment: ReadonlyContentModelSegment): ContentModelSegmentFormat;
7212
+ function getSegmentTextFormat(segment: ReadonlyContentModelSegment, includingBIU?: boolean): ContentModelSegmentFormat;
7188
7213
 
7189
7214
  /**
7190
7215
  * Get index of closest ancestor block group of the expected block group type. If not found, return -1
@@ -8270,6 +8295,19 @@ function setModelIndentation(model: ReadonlyContentModelDocument, indentation: '
8270
8295
  */
8271
8296
  function matchLink(url: string): LinkData | null;
8272
8297
 
8298
+ /**
8299
+ * Promote the given text segment to a hyper link when the segment text is ending with a valid link format.
8300
+ * When the whole text segment if of a link, promote the whole segment.
8301
+ * When the text segment ends with a link format, split the segment and promote the second part
8302
+ * When link is in middle of the text segment, no action.
8303
+ * This is mainly used for doing auto link when there is a link before cursor
8304
+ * @param segment The text segment to search link text from
8305
+ * @param paragraph Parent paragraph of the segment
8306
+ * @param options Options of auto link
8307
+ * @returns If a link is promoted, return this segment. Otherwise return null
8308
+ */
8309
+ function promoteLink(segment: ContentModelText, paragraph: ShallowMutableContentModelParagraph, autoLinkOptions: AutoLinkOptions): ContentModelText | null;
8310
+
8273
8311
  /**
8274
8312
  * Get announce data for list item
8275
8313
  * @param path Content model path that include the list item
@@ -8528,28 +8566,6 @@ interface AutoFormatOptions extends AutoLinkOptions {
8528
8566
  autoOrdinals?: boolean;
8529
8567
  }
8530
8568
 
8531
- /**
8532
- * Options to customize the Auto link options in Auto Format Plugin
8533
- */
8534
- interface AutoLinkOptions {
8535
- /**
8536
- * When press backspace before a link, remove the hyperlink
8537
- */
8538
- autoUnlink?: boolean;
8539
- /**
8540
- * When paste or type content with a link, create hyperlink for the link
8541
- */
8542
- autoLink?: boolean;
8543
- /**
8544
- * When paste content or type content with telephone, create hyperlink for the telephone number
8545
- */
8546
- autoTel?: boolean;
8547
- /**
8548
- * When paste or type a content with mailto, create hyperlink for the content
8549
- */
8550
- autoMailto?: boolean;
8551
- }
8552
-
8553
8569
  /**
8554
8570
  * Shortcut command for Bold
8555
8571
  * Windows: Ctrl + B
package/dist/rooster.js CHANGED
@@ -2095,7 +2095,7 @@ exports["default"] = getDarkColor;
2095
2095
 
2096
2096
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2097
2097
  exports.formatSegmentWithContentModel = exports.formatParagraphWithContentModel = exports.formatImageWithContentModel = exports.formatTableWithContentModel = exports.clearSelectedCells = exports.insertTableColumn = exports.insertTableRow = exports.insertEntity = exports.toggleCode = exports.setParagraphMargin = exports.adjustImageSelection = exports.setImageAltText = exports.adjustLinkSelection = exports.removeLink = exports.insertLink = exports.clearFormat = exports.getFormatState = exports.changeImage = exports.setImageBoxShadow = exports.setImageBorder = exports.setSpacing = exports.toggleBlockQuote = exports.setHeadingLevel = exports.setDirection = exports.setAlignment = exports.setIndentation = exports.setListStartNumber = exports.setListStyle = exports.insertImage = exports.splitTextSegment = exports.changeCapitalization = exports.applySegmentFormat = exports.changeFontSize = exports.setTextColor = exports.setFontSize = exports.setFontName = exports.setBackgroundColor = exports.toggleSuperscript = exports.toggleSubscript = exports.toggleStrikethrough = exports.toggleUnderline = exports.toggleItalic = exports.toggleBold = exports.toggleNumbering = exports.toggleBullet = exports.applyTableBorderFormat = exports.editTable = exports.setTableCellShade = exports.formatTable = exports.insertTable = void 0;
2098
- exports.getListAnnounceData = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = exports.formatTextSegmentBeforeSelectionMarker = void 0;
2098
+ exports.getListAnnounceData = exports.promoteLink = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = exports.formatTextSegmentBeforeSelectionMarker = void 0;
2099
2099
  var insertTable_1 = __webpack_require__(/*! ./publicApi/table/insertTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/insertTable.ts");
2100
2100
  Object.defineProperty(exports, "insertTable", ({ enumerable: true, get: function () { return insertTable_1.insertTable; } }));
2101
2101
  var formatTable_1 = __webpack_require__(/*! ./publicApi/table/formatTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/formatTable.ts");
@@ -2212,6 +2212,8 @@ var setModelIndentation_1 = __webpack_require__(/*! ./modelApi/block/setModelInd
2212
2212
  Object.defineProperty(exports, "setModelIndentation", ({ enumerable: true, get: function () { return setModelIndentation_1.setModelIndentation; } }));
2213
2213
  var matchLink_1 = __webpack_require__(/*! ./modelApi/link/matchLink */ "./packages/roosterjs-content-model-api/lib/modelApi/link/matchLink.ts");
2214
2214
  Object.defineProperty(exports, "matchLink", ({ enumerable: true, get: function () { return matchLink_1.matchLink; } }));
2215
+ var promoteLink_1 = __webpack_require__(/*! ./modelApi/link/promoteLink */ "./packages/roosterjs-content-model-api/lib/modelApi/link/promoteLink.ts");
2216
+ Object.defineProperty(exports, "promoteLink", ({ enumerable: true, get: function () { return promoteLink_1.promoteLink; } }));
2215
2217
  var getListAnnounceData_1 = __webpack_require__(/*! ./modelApi/list/getListAnnounceData */ "./packages/roosterjs-content-model-api/lib/modelApi/list/getListAnnounceData.ts");
2216
2218
  Object.defineProperty(exports, "getListAnnounceData", ({ enumerable: true, get: function () { return getListAnnounceData_1.getListAnnounceData; } }));
2217
2219
 
@@ -3067,6 +3069,42 @@ function applyImageBorderFormat(image, border, borderRadius) {
3067
3069
  exports.applyImageBorderFormat = applyImageBorderFormat;
3068
3070
 
3069
3071
 
3072
+ /***/ }),
3073
+
3074
+ /***/ "./packages/roosterjs-content-model-api/lib/modelApi/link/getLinkUrl.ts":
3075
+ /*!******************************************************************************!*\
3076
+ !*** ./packages/roosterjs-content-model-api/lib/modelApi/link/getLinkUrl.ts ***!
3077
+ \******************************************************************************/
3078
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
3079
+
3080
+ "use strict";
3081
+
3082
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
3083
+ exports.getLinkUrl = void 0;
3084
+ var matchLink_1 = __webpack_require__(/*! ./matchLink */ "./packages/roosterjs-content-model-api/lib/modelApi/link/matchLink.ts");
3085
+ var COMMON_REGEX = "[s]*[a-zA-Z0-9+][s]*";
3086
+ var TELEPHONE_REGEX = "(T|t)el:" + COMMON_REGEX;
3087
+ var MAILTO_REGEX = "(M|m)ailto:" + COMMON_REGEX;
3088
+ /**
3089
+ * @internal
3090
+ */
3091
+ function getLinkUrl(text, autoLinkOptions) {
3092
+ var _a;
3093
+ var _b = autoLinkOptions !== null && autoLinkOptions !== void 0 ? autoLinkOptions : {}, autoLink = _b.autoLink, autoMailto = _b.autoMailto, autoTel = _b.autoTel;
3094
+ var linkMatch = autoLink ? (_a = (0, matchLink_1.matchLink)(text)) === null || _a === void 0 ? void 0 : _a.normalizedUrl : undefined;
3095
+ var telMatch = autoTel ? matchTel(text) : undefined;
3096
+ var mailtoMatch = autoMailto ? matchMailTo(text) : undefined;
3097
+ return linkMatch || telMatch || mailtoMatch;
3098
+ }
3099
+ exports.getLinkUrl = getLinkUrl;
3100
+ function matchTel(text) {
3101
+ return text.match(TELEPHONE_REGEX) ? text.toLocaleLowerCase() : undefined;
3102
+ }
3103
+ function matchMailTo(text) {
3104
+ return text.match(MAILTO_REGEX) ? text.toLocaleLowerCase() : undefined;
3105
+ }
3106
+
3107
+
3070
3108
  /***/ }),
3071
3109
 
3072
3110
  /***/ "./packages/roosterjs-content-model-api/lib/modelApi/link/matchLink.ts":
@@ -3171,6 +3209,51 @@ function matchLink(url) {
3171
3209
  exports.matchLink = matchLink;
3172
3210
 
3173
3211
 
3212
+ /***/ }),
3213
+
3214
+ /***/ "./packages/roosterjs-content-model-api/lib/modelApi/link/promoteLink.ts":
3215
+ /*!*******************************************************************************!*\
3216
+ !*** ./packages/roosterjs-content-model-api/lib/modelApi/link/promoteLink.ts ***!
3217
+ \*******************************************************************************/
3218
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
3219
+
3220
+ "use strict";
3221
+
3222
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
3223
+ exports.promoteLink = void 0;
3224
+ var getLinkUrl_1 = __webpack_require__(/*! ./getLinkUrl */ "./packages/roosterjs-content-model-api/lib/modelApi/link/getLinkUrl.ts");
3225
+ var splitTextSegment_1 = __webpack_require__(/*! ../../publicApi/segment/splitTextSegment */ "./packages/roosterjs-content-model-api/lib/publicApi/segment/splitTextSegment.ts");
3226
+ /**
3227
+ * Promote the given text segment to a hyper link when the segment text is ending with a valid link format.
3228
+ * When the whole text segment if of a link, promote the whole segment.
3229
+ * When the text segment ends with a link format, split the segment and promote the second part
3230
+ * When link is in middle of the text segment, no action.
3231
+ * This is mainly used for doing auto link when there is a link before cursor
3232
+ * @param segment The text segment to search link text from
3233
+ * @param paragraph Parent paragraph of the segment
3234
+ * @param options Options of auto link
3235
+ * @returns If a link is promoted, return this segment. Otherwise return null
3236
+ */
3237
+ function promoteLink(segment, paragraph, autoLinkOptions) {
3238
+ var link = segment.text.split(' ').pop();
3239
+ var url = link === null || link === void 0 ? void 0 : link.trim();
3240
+ var linkUrl = undefined;
3241
+ if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
3242
+ var linkSegment = (0, splitTextSegment_1.splitTextSegment)(segment, paragraph, segment.text.length - link.trimLeft().length, segment.text.trimRight().length);
3243
+ linkSegment.link = {
3244
+ format: {
3245
+ href: linkUrl,
3246
+ underline: true,
3247
+ },
3248
+ dataset: {},
3249
+ };
3250
+ return linkSegment;
3251
+ }
3252
+ return null;
3253
+ }
3254
+ exports.promoteLink = promoteLink;
3255
+
3256
+
3174
3257
  /***/ }),
3175
3258
 
3176
3259
  /***/ "./packages/roosterjs-content-model-api/lib/modelApi/list/findListItemsInSameThread.ts":
@@ -18435,12 +18518,15 @@ var directionFormatHandler_1 = __webpack_require__(/*! ./directionFormatHandler
18435
18518
  */
18436
18519
  exports.htmlAlignFormatHandler = {
18437
18520
  parse: function (format, element, context, defaultStyle) {
18438
- directionFormatHandler_1.directionFormatHandler.parse(format, element, context, defaultStyle);
18439
- var htmlAlign = element.getAttribute('align');
18440
- if (htmlAlign) {
18441
- format.htmlAlign = (0, dir_1.calcAlign)(htmlAlign, format.direction);
18442
- delete format.textAlign;
18443
- delete context.blockFormat.textAlign;
18521
+ // When there is text-align in CSS style on the same element, we should ignore HTML align
18522
+ if (!element.style.textAlign) {
18523
+ directionFormatHandler_1.directionFormatHandler.parse(format, element, context, defaultStyle);
18524
+ var htmlAlign = element.getAttribute('align');
18525
+ if (htmlAlign) {
18526
+ format.htmlAlign = (0, dir_1.calcAlign)(htmlAlign, format.direction);
18527
+ delete format.textAlign;
18528
+ delete context.blockFormat.textAlign;
18529
+ }
18444
18530
  }
18445
18531
  },
18446
18532
  apply: function (format, element) {
@@ -22625,7 +22711,7 @@ function deleteExpandedSelection(model, formatContext) {
22625
22711
  // so we can put cursor here after delete
22626
22712
  paragraph = block_1;
22627
22713
  insertMarkerIndex = indexes[0];
22628
- markerFormat = (0, getSegmentTextFormat_1.getSegmentTextFormat)(segments[0]);
22714
+ markerFormat = (0, getSegmentTextFormat_1.getSegmentTextFormat)(segments[0], true /*includingBIU*/);
22629
22715
  context.lastParagraph = paragraph;
22630
22716
  context.lastTableContext = tableContext;
22631
22717
  segments.forEach(function (segment, i) {
@@ -22969,18 +23055,22 @@ exports.getSegmentTextFormat = void 0;
22969
23055
  /**
22970
23056
  * Get the text format of a segment, this function will return only format that is applicable to text
22971
23057
  * @param segment The segment to get format from
23058
+ * @param includingBIU When pass true, also get Bold/Italic/Underline format
22972
23059
  * @returns
22973
23060
  */
22974
- function getSegmentTextFormat(segment) {
23061
+ function getSegmentTextFormat(segment, includingBIU) {
22975
23062
  var _a;
22976
- var _b = (_a = segment === null || segment === void 0 ? void 0 : segment.format) !== null && _a !== void 0 ? _a : {}, fontFamily = _b.fontFamily, fontSize = _b.fontSize, textColor = _b.textColor, backgroundColor = _b.backgroundColor, letterSpacing = _b.letterSpacing, lineHeight = _b.lineHeight;
23063
+ var format = (_a = segment.format) !== null && _a !== void 0 ? _a : {};
22977
23064
  var textFormat = {
22978
- fontFamily: fontFamily,
22979
- fontSize: fontSize,
22980
- textColor: textColor,
22981
- backgroundColor: backgroundColor,
22982
- letterSpacing: letterSpacing,
22983
- lineHeight: lineHeight,
23065
+ fontFamily: format.fontFamily,
23066
+ fontSize: format.fontSize,
23067
+ textColor: format.textColor,
23068
+ backgroundColor: format.backgroundColor,
23069
+ letterSpacing: format.letterSpacing,
23070
+ lineHeight: format.lineHeight,
23071
+ fontWeight: includingBIU ? format.fontWeight : undefined,
23072
+ italic: includingBIU ? format.italic : undefined,
23073
+ underline: includingBIU ? format.underline : undefined,
22984
23074
  };
22985
23075
  return removeUndefinedValues(textFormat);
22986
23076
  }
@@ -23294,12 +23384,26 @@ function getSegmentFormatInLinkFormat(targetFormat) {
23294
23384
  return result;
23295
23385
  }
23296
23386
  function mergeLinkFormat(applyDefaultFormatOption, targetFormat, sourceFormat) {
23297
- return applyDefaultFormatOption == 'mergeAll'
23298
- ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, getSegmentFormatInLinkFormat(targetFormat)), sourceFormat) : (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), getSegmentFormatInLinkFormat(targetFormat)), getSemanticFormat(sourceFormat)), getHyperlinkTextColor(sourceFormat));
23387
+ switch (applyDefaultFormatOption) {
23388
+ case 'mergeAll':
23389
+ case 'preferSource':
23390
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, getSegmentFormatInLinkFormat(targetFormat)), sourceFormat);
23391
+ case 'keepSourceEmphasisFormat':
23392
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), getSegmentFormatInLinkFormat(targetFormat)), getSemanticFormat(sourceFormat)), getHyperlinkTextColor(sourceFormat));
23393
+ case 'preferTarget':
23394
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, sourceFormat), getSegmentFormatInLinkFormat(targetFormat));
23395
+ }
23299
23396
  }
23300
23397
  function mergeSegmentFormat(applyDefaultFormatOption, targetFormat, sourceFormat) {
23301
- return applyDefaultFormatOption == 'mergeAll'
23302
- ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, targetFormat), sourceFormat) : (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), targetFormat), getSemanticFormat(sourceFormat));
23398
+ switch (applyDefaultFormatOption) {
23399
+ case 'mergeAll':
23400
+ case 'preferSource':
23401
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, targetFormat), sourceFormat);
23402
+ case 'preferTarget':
23403
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, sourceFormat), targetFormat);
23404
+ case 'keepSourceEmphasisFormat':
23405
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), targetFormat), getSemanticFormat(sourceFormat));
23406
+ }
23303
23407
  }
23304
23408
  function getSemanticFormat(segmentFormat) {
23305
23409
  var result = {};
@@ -26603,7 +26707,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
26603
26707
  exports.AutoFormatPlugin = void 0;
26604
26708
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
26605
26709
  var createLink_1 = __webpack_require__(/*! ./link/createLink */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLink.ts");
26606
- var createLinkAfterSpace_1 = __webpack_require__(/*! ./link/createLinkAfterSpace */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLinkAfterSpace.ts");
26607
26710
  var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26608
26711
  var keyboardListTrigger_1 = __webpack_require__(/*! ./list/keyboardListTrigger */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/list/keyboardListTrigger.ts");
26609
26712
  var transformFraction_1 = __webpack_require__(/*! ./numbers/transformFraction */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformFraction.ts");
@@ -26713,11 +26816,14 @@ var AutoFormatPlugin = /** @class */ (function () {
26713
26816
  shouldList = (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, autoBullet, autoNumbering);
26714
26817
  }
26715
26818
  if (autoLink || autoTel || autoMailto) {
26716
- shouldLink = (0, createLinkAfterSpace_1.createLinkAfterSpace)(previousSegment, paragraph, context, {
26819
+ shouldLink = !!(0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
26717
26820
  autoLink: autoLink,
26718
26821
  autoTel: autoTel,
26719
26822
  autoMailto: autoMailto,
26720
26823
  });
26824
+ if (shouldLink) {
26825
+ context.canUndoByBackspace = true;
26826
+ }
26721
26827
  }
26722
26828
  if (autoHyphen) {
26723
26829
  shouldHyphen = (0, transformHyphen_1.transformHyphen)(previousSegment, paragraph, context);
@@ -26741,6 +26847,7 @@ var AutoFormatPlugin = /** @class */ (function () {
26741
26847
  }
26742
26848
  };
26743
26849
  AutoFormatPlugin.prototype.handleKeyDownEvent = function (editor, event) {
26850
+ var _this = this;
26744
26851
  var rawEvent = event.rawEvent;
26745
26852
  if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
26746
26853
  switch (rawEvent.key) {
@@ -26749,6 +26856,20 @@ var AutoFormatPlugin = /** @class */ (function () {
26749
26856
  (0, unlink_1.unlink)(editor, rawEvent);
26750
26857
  }
26751
26858
  break;
26859
+ case 'Tab':
26860
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, _previousSegment, paragraph, _markerFormat, context) {
26861
+ var _a = _this.options, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering;
26862
+ var shouldList = false;
26863
+ if (autoBullet || autoNumbering) {
26864
+ shouldList = (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, autoBullet, autoNumbering);
26865
+ context.canUndoByBackspace = shouldList;
26866
+ event.rawEvent.preventDefault();
26867
+ }
26868
+ return shouldList;
26869
+ }, {
26870
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
26871
+ apiName: 'autoToggleList',
26872
+ });
26752
26873
  }
26753
26874
  }
26754
26875
  };
@@ -26836,33 +26957,26 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
26836
26957
  exports.createLink = void 0;
26837
26958
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
26838
26959
  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");
26840
26960
  /**
26841
26961
  * @internal
26842
26962
  */
26843
26963
  function createLink(editor, autoLinkOptions) {
26844
26964
  var anchorNode = null;
26845
26965
  var links = [];
26846
- (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (_model, linkSegment, _paragraph) {
26847
- if (linkSegment.link) {
26848
- links.push(linkSegment.link);
26966
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (_model, segment, paragraph) {
26967
+ var promotedSegment = null;
26968
+ if (segment.link) {
26969
+ links.push(segment.link);
26849
26970
  return true;
26850
26971
  }
26851
- var linkUrl = undefined;
26852
- if (!linkSegment.link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(linkSegment.text, autoLinkOptions))) {
26853
- (0, roosterjs_content_model_dom_1.addLink)(linkSegment, {
26854
- format: {
26855
- href: linkUrl,
26856
- underline: true,
26857
- },
26858
- dataset: {},
26859
- });
26860
- if (linkSegment.link) {
26861
- links.push(linkSegment.link);
26862
- }
26972
+ else if ((promotedSegment = (0, roosterjs_content_model_api_1.promoteLink)(segment, paragraph, autoLinkOptions)) &&
26973
+ promotedSegment.link) {
26974
+ links.push(promotedSegment.link);
26863
26975
  return true;
26864
26976
  }
26865
- return false;
26977
+ else {
26978
+ return false;
26979
+ }
26866
26980
  }, {
26867
26981
  changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoLink,
26868
26982
  onNodeCreated: function (modelElement, node) {
@@ -26876,80 +26990,6 @@ function createLink(editor, autoLinkOptions) {
26876
26990
  exports.createLink = createLink;
26877
26991
 
26878
26992
 
26879
- /***/ }),
26880
-
26881
- /***/ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLinkAfterSpace.ts":
26882
- /*!**********************************************************************************************!*\
26883
- !*** ./packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLinkAfterSpace.ts ***!
26884
- \**********************************************************************************************/
26885
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
26886
-
26887
- "use strict";
26888
-
26889
- Object.defineProperty(exports, "__esModule", ({ value: true }));
26890
- exports.createLinkAfterSpace = void 0;
26891
- var getLinkUrl_1 = __webpack_require__(/*! ./getLinkUrl */ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts");
26892
- var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
26893
- /**
26894
- * @internal
26895
- */
26896
- function createLinkAfterSpace(previousSegment, paragraph, context, autoLinkOptions) {
26897
- var link = previousSegment.text.split(' ').pop();
26898
- var url = link === null || link === void 0 ? void 0 : link.trim();
26899
- var linkUrl = undefined;
26900
- if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
26901
- var linkSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - link.trimLeft().length, previousSegment.text.trimRight().length);
26902
- linkSegment.link = {
26903
- format: {
26904
- href: linkUrl,
26905
- underline: true,
26906
- },
26907
- dataset: {},
26908
- };
26909
- context.canUndoByBackspace = true;
26910
- return true;
26911
- }
26912
- return false;
26913
- }
26914
- exports.createLinkAfterSpace = createLinkAfterSpace;
26915
-
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
-
26953
26993
  /***/ }),
26954
26994
 
26955
26995
  /***/ "./packages/roosterjs-content-model-plugins/lib/autoFormat/link/unlink.ts":
@@ -27420,6 +27460,7 @@ var getOrdinal = function (value) {
27420
27460
  };
27421
27461
  return ORDINALS[value] || 'th';
27422
27462
  };
27463
+ var ORDINALS = ['st', 'nd', 'rd', 'th'];
27423
27464
  /**
27424
27465
  * The two last characters of ordinal number (st, nd, rd, th)
27425
27466
  */
@@ -27429,21 +27470,39 @@ var ORDINAL_LENGTH = 2;
27429
27470
  */ function transformOrdinals(previousSegment, paragraph, context) {
27430
27471
  var _a;
27431
27472
  var value = (_a = previousSegment.text.split(' ').pop()) === null || _a === void 0 ? void 0 : _a.trim();
27473
+ var shouldAddSuperScript = false;
27432
27474
  if (value) {
27433
- var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
27434
- var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value = 10
27435
- if (numericValue && getOrdinal(numericValue) === ordinal) {
27475
+ var isOrdinal = ORDINALS.indexOf(value) > -1;
27476
+ if (isOrdinal) {
27477
+ var index = paragraph.segments.indexOf(previousSegment);
27478
+ var numberSegment = paragraph.segments[index - 1];
27479
+ var numericValue = null;
27480
+ if (numberSegment &&
27481
+ numberSegment.segmentType == 'Text' &&
27482
+ (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&
27483
+ getOrdinal(numericValue) === value) {
27484
+ shouldAddSuperScript = true;
27485
+ }
27486
+ }
27487
+ else {
27488
+ var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
27489
+ var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =
27490
+ if (numericValue && getOrdinal(numericValue) === ordinal) {
27491
+ shouldAddSuperScript = true;
27492
+ }
27493
+ }
27494
+ if (shouldAddSuperScript) {
27436
27495
  var ordinalSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - 3, previousSegment.text.length - 1);
27437
27496
  ordinalSegment.format.superOrSubScriptSequence = 'super';
27438
27497
  context.canUndoByBackspace = true;
27439
- return true;
27440
27498
  }
27441
27499
  }
27442
- return false;
27500
+ return shouldAddSuperScript;
27443
27501
  }
27444
27502
  exports.transformOrdinals = transformOrdinals;
27445
- function getNumericValue(text) {
27446
- var number = text.substring(0, text.length - ORDINAL_LENGTH);
27503
+ function getNumericValue(text, checkFullText) {
27504
+ if (checkFullText === void 0) { checkFullText = false; }
27505
+ var number = checkFullText ? text : text.substring(0, text.length - ORDINAL_LENGTH);
27447
27506
  var isNumber = /^-?\d+$/.test(number);
27448
27507
  if (isNumber) {
27449
27508
  return parseInt(text);
@@ -27778,6 +27837,7 @@ var EditPlugin = /** @class */ (function () {
27778
27837
  };
27779
27838
  EditPlugin.prototype.handleKeyDownEvent = function (editor, event) {
27780
27839
  var rawEvent = event.rawEvent;
27840
+ var hasCtrlOrMetaKey = rawEvent.ctrlKey || rawEvent.metaKey;
27781
27841
  if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
27782
27842
  switch (rawEvent.key) {
27783
27843
  case 'Backspace':
@@ -27794,7 +27854,7 @@ var EditPlugin = /** @class */ (function () {
27794
27854
  }
27795
27855
  break;
27796
27856
  case 'Tab':
27797
- if (this.options.handleTabKey) {
27857
+ if (this.options.handleTabKey && !hasCtrlOrMetaKey) {
27798
27858
  (0, keyboardTab_1.keyboardTab)(editor, rawEvent);
27799
27859
  }
27800
27860
  break;
@@ -27804,7 +27864,9 @@ var EditPlugin = /** @class */ (function () {
27804
27864
  }
27805
27865
  break;
27806
27866
  case 'Enter':
27807
- (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter);
27867
+ if (!hasCtrlOrMetaKey) {
27868
+ (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter);
27869
+ }
27808
27870
  break;
27809
27871
  default:
27810
27872
  (0, keyboardInput_1.keyboardInput)(editor, rawEvent);
@@ -28367,6 +28429,41 @@ function shouldDeleteAllSegmentsBefore(rawEvent) {
28367
28429
  exports.shouldDeleteAllSegmentsBefore = shouldDeleteAllSegmentsBefore;
28368
28430
 
28369
28431
 
28432
+ /***/ }),
28433
+
28434
+ /***/ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleAutoLink.ts":
28435
+ /*!****************************************************************************************!*\
28436
+ !*** ./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleAutoLink.ts ***!
28437
+ \****************************************************************************************/
28438
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
28439
+
28440
+ "use strict";
28441
+
28442
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
28443
+ exports.handleAutoLink = void 0;
28444
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
28445
+ /**
28446
+ * @internal
28447
+ */
28448
+ var handleAutoLink = function (context) {
28449
+ var deleteResult = context.deleteResult, insertPoint = context.insertPoint;
28450
+ if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {
28451
+ var marker = insertPoint.marker, paragraph = insertPoint.paragraph;
28452
+ var index = paragraph.segments.indexOf(marker);
28453
+ var segBefore = index > 0 ? paragraph.segments[index - 1] : null;
28454
+ if ((segBefore === null || segBefore === void 0 ? void 0 : segBefore.segmentType) == 'Text' &&
28455
+ (0, roosterjs_content_model_api_1.promoteLink)(segBefore, paragraph, {
28456
+ autoLink: true,
28457
+ }) &&
28458
+ context.formatContext) {
28459
+ context.formatContext.canUndoByBackspace = true;
28460
+ }
28461
+ // Do not set deleteResult here since we haven't really start a new paragraph, we need other delete step to keep working on it
28462
+ }
28463
+ };
28464
+ exports.handleAutoLink = handleAutoLink;
28465
+
28466
+
28370
28467
  /***/ }),
28371
28468
 
28372
28469
  /***/ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts":
@@ -28596,6 +28693,7 @@ function canDeleteAfter(rawEvent, range) {
28596
28693
  Object.defineProperty(exports, "__esModule", ({ value: true }));
28597
28694
  exports.keyboardEnter = void 0;
28598
28695
  var deleteEmptyQuote_1 = __webpack_require__(/*! ./deleteSteps/deleteEmptyQuote */ "./packages/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteEmptyQuote.ts");
28696
+ var handleAutoLink_1 = __webpack_require__(/*! ./inputSteps/handleAutoLink */ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleAutoLink.ts");
28599
28697
  var handleEnterOnList_1 = __webpack_require__(/*! ./inputSteps/handleEnterOnList */ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts");
28600
28698
  var handleEnterOnParagraph_1 = __webpack_require__(/*! ./inputSteps/handleEnterOnParagraph */ "./packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnParagraph.ts");
28601
28699
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
@@ -28613,7 +28711,9 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
28613
28711
  // For ENTER key, although we may have deleted something, since we still need to split the line, we always treat it as not delete
28614
28712
  // so further delete steps can keep working
28615
28713
  result.deleteResult = 'notDeleted';
28616
- var steps = rawEvent.shiftKey ? [] : [handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
28714
+ var steps = rawEvent.shiftKey
28715
+ ? []
28716
+ : [handleAutoLink_1.handleAutoLink, handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
28617
28717
  if (handleNormalEnter) {
28618
28718
  steps.push(handleEnterOnParagraph_1.handleEnterOnParagraph);
28619
28719
  }