roosterjs-content-model-plugins 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.
Files changed (82) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.js +19 -2
  2. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  3. package/lib/autoFormat/interface/AutoFormatOptions.d.ts +1 -1
  4. package/lib/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  5. package/lib/autoFormat/link/createLink.d.ts +1 -2
  6. package/lib/autoFormat/link/createLink.js +10 -17
  7. package/lib/autoFormat/link/createLink.js.map +1 -1
  8. package/lib/autoFormat/numbers/transformOrdinals.js +26 -7
  9. package/lib/autoFormat/numbers/transformOrdinals.js.map +1 -1
  10. package/lib/edit/EditPlugin.js +5 -2
  11. package/lib/edit/EditPlugin.js.map +1 -1
  12. package/lib/edit/inputSteps/handleAutoLink.d.ts +5 -0
  13. package/lib/edit/inputSteps/handleAutoLink.js +25 -0
  14. package/lib/edit/inputSteps/handleAutoLink.js.map +1 -0
  15. package/lib/edit/keyboardEnter.js +4 -1
  16. package/lib/edit/keyboardEnter.js.map +1 -1
  17. package/lib/index.d.ts +0 -1
  18. package/lib/index.js.map +1 -1
  19. package/lib-amd/autoFormat/AutoFormatPlugin.js +20 -2
  20. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  21. package/lib-amd/autoFormat/interface/AutoFormatOptions.d.ts +1 -1
  22. package/lib-amd/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  23. package/lib-amd/autoFormat/link/createLink.d.ts +1 -2
  24. package/lib-amd/autoFormat/link/createLink.js +11 -17
  25. package/lib-amd/autoFormat/link/createLink.js.map +1 -1
  26. package/lib-amd/autoFormat/numbers/transformOrdinals.js +26 -7
  27. package/lib-amd/autoFormat/numbers/transformOrdinals.js.map +1 -1
  28. package/lib-amd/edit/EditPlugin.js +5 -2
  29. package/lib-amd/edit/EditPlugin.js.map +1 -1
  30. package/lib-amd/edit/inputSteps/handleAutoLink.d.ts +5 -0
  31. package/lib-amd/edit/inputSteps/handleAutoLink.js +26 -0
  32. package/lib-amd/edit/inputSteps/handleAutoLink.js.map +1 -0
  33. package/lib-amd/edit/keyboardEnter.js +4 -2
  34. package/lib-amd/edit/keyboardEnter.js.map +1 -1
  35. package/lib-amd/index.d.ts +0 -1
  36. package/lib-amd/index.js.map +1 -1
  37. package/lib-mjs/autoFormat/AutoFormatPlugin.js +20 -3
  38. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  39. package/lib-mjs/autoFormat/interface/AutoFormatOptions.d.ts +1 -1
  40. package/lib-mjs/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  41. package/lib-mjs/autoFormat/link/createLink.d.ts +1 -2
  42. package/lib-mjs/autoFormat/link/createLink.js +12 -19
  43. package/lib-mjs/autoFormat/link/createLink.js.map +1 -1
  44. package/lib-mjs/autoFormat/numbers/transformOrdinals.js +26 -7
  45. package/lib-mjs/autoFormat/numbers/transformOrdinals.js.map +1 -1
  46. package/lib-mjs/edit/EditPlugin.js +5 -2
  47. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  48. package/lib-mjs/edit/inputSteps/handleAutoLink.d.ts +5 -0
  49. package/lib-mjs/edit/inputSteps/handleAutoLink.js +21 -0
  50. package/lib-mjs/edit/inputSteps/handleAutoLink.js.map +1 -0
  51. package/lib-mjs/edit/keyboardEnter.js +4 -1
  52. package/lib-mjs/edit/keyboardEnter.js.map +1 -1
  53. package/lib-mjs/index.d.ts +0 -1
  54. package/lib-mjs/index.js.map +1 -1
  55. package/package.json +5 -5
  56. package/lib/autoFormat/interface/AutoLinkOptions.d.ts +0 -21
  57. package/lib/autoFormat/interface/AutoLinkOptions.js +0 -3
  58. package/lib/autoFormat/interface/AutoLinkOptions.js.map +0 -1
  59. package/lib/autoFormat/link/createLinkAfterSpace.d.ts +0 -6
  60. package/lib/autoFormat/link/createLinkAfterSpace.js +0 -28
  61. package/lib/autoFormat/link/createLinkAfterSpace.js.map +0 -1
  62. package/lib/autoFormat/link/getLinkUrl.d.ts +0 -5
  63. package/lib/autoFormat/link/getLinkUrl.js +0 -26
  64. package/lib/autoFormat/link/getLinkUrl.js.map +0 -1
  65. package/lib-amd/autoFormat/interface/AutoLinkOptions.d.ts +0 -21
  66. package/lib-amd/autoFormat/interface/AutoLinkOptions.js +0 -5
  67. package/lib-amd/autoFormat/interface/AutoLinkOptions.js.map +0 -1
  68. package/lib-amd/autoFormat/link/createLinkAfterSpace.d.ts +0 -6
  69. package/lib-amd/autoFormat/link/createLinkAfterSpace.js +0 -28
  70. package/lib-amd/autoFormat/link/createLinkAfterSpace.js.map +0 -1
  71. package/lib-amd/autoFormat/link/getLinkUrl.d.ts +0 -5
  72. package/lib-amd/autoFormat/link/getLinkUrl.js +0 -27
  73. package/lib-amd/autoFormat/link/getLinkUrl.js.map +0 -1
  74. package/lib-mjs/autoFormat/interface/AutoLinkOptions.d.ts +0 -21
  75. package/lib-mjs/autoFormat/interface/AutoLinkOptions.js +0 -2
  76. package/lib-mjs/autoFormat/interface/AutoLinkOptions.js.map +0 -1
  77. package/lib-mjs/autoFormat/link/createLinkAfterSpace.d.ts +0 -6
  78. package/lib-mjs/autoFormat/link/createLinkAfterSpace.js +0 -24
  79. package/lib-mjs/autoFormat/link/createLinkAfterSpace.js.map +0 -1
  80. package/lib-mjs/autoFormat/link/getLinkUrl.d.ts +0 -5
  81. package/lib-mjs/autoFormat/link/getLinkUrl.js +0 -22
  82. package/lib-mjs/autoFormat/link/getLinkUrl.js.map +0 -1
@@ -1,32 +1,25 @@
1
- import { addLink, ChangeSource } from 'roosterjs-content-model-dom';
2
- import { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';
3
- import { getLinkUrl } from './getLinkUrl';
1
+ import { ChangeSource } from 'roosterjs-content-model-dom';
2
+ import { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';
4
3
  /**
5
4
  * @internal
6
5
  */
7
6
  export function createLink(editor, autoLinkOptions) {
8
7
  var anchorNode = null;
9
8
  var links = [];
10
- formatTextSegmentBeforeSelectionMarker(editor, function (_model, linkSegment, _paragraph) {
11
- if (linkSegment.link) {
12
- links.push(linkSegment.link);
9
+ formatTextSegmentBeforeSelectionMarker(editor, function (_model, segment, paragraph) {
10
+ var promotedSegment = null;
11
+ if (segment.link) {
12
+ links.push(segment.link);
13
13
  return true;
14
14
  }
15
- var linkUrl = undefined;
16
- if (!linkSegment.link && (linkUrl = getLinkUrl(linkSegment.text, autoLinkOptions))) {
17
- addLink(linkSegment, {
18
- format: {
19
- href: linkUrl,
20
- underline: true,
21
- },
22
- dataset: {},
23
- });
24
- if (linkSegment.link) {
25
- links.push(linkSegment.link);
26
- }
15
+ else if ((promotedSegment = promoteLink(segment, paragraph, autoLinkOptions)) &&
16
+ promotedSegment.link) {
17
+ links.push(promotedSegment.link);
27
18
  return true;
28
19
  }
29
- return false;
20
+ else {
21
+ return false;
22
+ }
30
23
  }, {
31
24
  changeSource: ChangeSource.AutoLink,
32
25
  onNodeCreated: function (modelElement, node) {
@@ -1 +1 @@
1
- {"version":3,"file":"createLink.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,sCAAsC,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAe,EAAE,eAAgC;IACxE,IAAI,UAAU,GAAgB,IAAI,CAAC;IACnC,IAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,sCAAsC,CAClC,MAAM,EACN,UAAC,MAAM,EAAE,WAAW,EAAE,UAAU;QAC5B,IAAI,WAAW,CAAC,IAAI,EAAE;YAClB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC;SACf;QACD,IAAI,OAAO,GAAuB,SAAS,CAAC;QAC5C,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,EAAE;YAChF,OAAO,CAAC,WAAW,EAAE;gBACjB,MAAM,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,SAAS,EAAE,IAAI;iBAClB;gBACD,OAAO,EAAE,EAAE;aACd,CAAC,CAAC;YACH,IAAI,WAAW,CAAC,IAAI,EAAE;gBAClB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;aAChC;YACD,OAAO,IAAI,CAAC;SACf;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,EACD;QACI,YAAY,EAAE,YAAY,CAAC,QAAQ;QACnC,aAAa,EAAE,UAAC,YAAY,EAAE,IAAI;YAC9B,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,YAAgC,CAAC,IAAI,CAAC,EAAE;gBACrE,UAAU,GAAG,IAAI,CAAC;aACrB;QACL,CAAC;QACD,aAAa,EAAE,cAAM,OAAA,UAAU,EAAV,CAAU;KAClC,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { addLink, ChangeSource } from 'roosterjs-content-model-dom';\nimport { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport { getLinkUrl } from './getLinkUrl';\nimport type { AutoLinkOptions } from '../interface/AutoLinkOptions';\nimport type { ContentModelLink, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function createLink(editor: IEditor, autoLinkOptions: AutoLinkOptions) {\n let anchorNode: Node | null = null;\n const links: ContentModelLink[] = [];\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (_model, linkSegment, _paragraph) => {\n if (linkSegment.link) {\n links.push(linkSegment.link);\n return true;\n }\n let linkUrl: string | undefined = undefined;\n if (!linkSegment.link && (linkUrl = getLinkUrl(linkSegment.text, autoLinkOptions))) {\n addLink(linkSegment, {\n format: {\n href: linkUrl,\n underline: true,\n },\n dataset: {},\n });\n if (linkSegment.link) {\n links.push(linkSegment.link);\n }\n return true;\n }\n\n return false;\n },\n {\n changeSource: ChangeSource.AutoLink,\n onNodeCreated: (modelElement, node) => {\n if (!anchorNode && links.indexOf(modelElement as ContentModelLink) >= 0) {\n anchorNode = node;\n }\n },\n getChangeData: () => anchorNode,\n }\n );\n}\n"]}
1
+ {"version":3,"file":"createLink.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,sCAAsC,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAQlG;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAe,EAAE,eAAgC;IACxE,IAAI,UAAU,GAAgB,IAAI,CAAC;IACnC,IAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,sCAAsC,CAClC,MAAM,EACN,UAAC,MAAM,EAAE,OAAO,EAAE,SAAS;QACvB,IAAI,eAAe,GAA4B,IAAI,CAAC;QAEpD,IAAI,OAAO,CAAC,IAAI,EAAE;YACd,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAEzB,OAAO,IAAI,CAAC;SACf;aAAM,IACH,CAAC,eAAe,GAAG,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;YACpE,eAAe,CAAC,IAAI,EACtB;YACE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAEjC,OAAO,IAAI,CAAC;SACf;aAAM;YACH,OAAO,KAAK,CAAC;SAChB;IACL,CAAC,EACD;QACI,YAAY,EAAE,YAAY,CAAC,QAAQ;QACnC,aAAa,EAAE,UAAC,YAAY,EAAE,IAAI;YAC9B,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,YAAgC,CAAC,IAAI,CAAC,EAAE;gBACrE,UAAU,GAAG,IAAI,CAAC;aACrB;QACL,CAAC;QACD,aAAa,EAAE,cAAM,OAAA,UAAU,EAAV,CAAU;KAClC,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport type {\n ContentModelLink,\n IEditor,\n ContentModelText,\n AutoLinkOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function createLink(editor: IEditor, autoLinkOptions: AutoLinkOptions) {\n let anchorNode: Node | null = null;\n const links: ContentModelLink[] = [];\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (_model, segment, paragraph) => {\n let promotedSegment: ContentModelText | null = null;\n\n if (segment.link) {\n links.push(segment.link);\n\n return true;\n } else if (\n (promotedSegment = promoteLink(segment, paragraph, autoLinkOptions)) &&\n promotedSegment.link\n ) {\n links.push(promotedSegment.link);\n\n return true;\n } else {\n return false;\n }\n },\n {\n changeSource: ChangeSource.AutoLink,\n onNodeCreated: (modelElement, node) => {\n if (!anchorNode && links.indexOf(modelElement as ContentModelLink) >= 0) {\n anchorNode = node;\n }\n },\n getChangeData: () => anchorNode,\n }\n );\n}\n"]}
@@ -7,6 +7,7 @@ var getOrdinal = function (value) {
7
7
  };
8
8
  return ORDINALS[value] || 'th';
9
9
  };
10
+ var ORDINALS = ['st', 'nd', 'rd', 'th'];
10
11
  /**
11
12
  * The two last characters of ordinal number (st, nd, rd, th)
12
13
  */
@@ -16,20 +17,38 @@ var ORDINAL_LENGTH = 2;
16
17
  */ export function transformOrdinals(previousSegment, paragraph, context) {
17
18
  var _a;
18
19
  var value = (_a = previousSegment.text.split(' ').pop()) === null || _a === void 0 ? void 0 : _a.trim();
20
+ var shouldAddSuperScript = false;
19
21
  if (value) {
20
- var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
21
- var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value = 10
22
- if (numericValue && getOrdinal(numericValue) === ordinal) {
22
+ var isOrdinal = ORDINALS.indexOf(value) > -1;
23
+ if (isOrdinal) {
24
+ var index = paragraph.segments.indexOf(previousSegment);
25
+ var numberSegment = paragraph.segments[index - 1];
26
+ var numericValue = null;
27
+ if (numberSegment &&
28
+ numberSegment.segmentType == 'Text' &&
29
+ (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&
30
+ getOrdinal(numericValue) === value) {
31
+ shouldAddSuperScript = true;
32
+ }
33
+ }
34
+ else {
35
+ var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
36
+ var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =
37
+ if (numericValue && getOrdinal(numericValue) === ordinal) {
38
+ shouldAddSuperScript = true;
39
+ }
40
+ }
41
+ if (shouldAddSuperScript) {
23
42
  var ordinalSegment = splitTextSegment(previousSegment, paragraph, previousSegment.text.length - 3, previousSegment.text.length - 1);
24
43
  ordinalSegment.format.superOrSubScriptSequence = 'super';
25
44
  context.canUndoByBackspace = true;
26
- return true;
27
45
  }
28
46
  }
29
- return false;
47
+ return shouldAddSuperScript;
30
48
  }
31
- function getNumericValue(text) {
32
- var number = text.substring(0, text.length - ORDINAL_LENGTH);
49
+ function getNumericValue(text, checkFullText) {
50
+ if (checkFullText === void 0) { checkFullText = false; }
51
+ var number = checkFullText ? text : text.substring(0, text.length - ORDINAL_LENGTH);
33
52
  var isNumber = /^-?\d+$/.test(number);
34
53
  if (isNumber) {
35
54
  return parseInt(text);
@@ -1 +1 @@
1
- {"version":3,"file":"transformOrdinals.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformOrdinals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAO/D,IAAM,UAAU,GAAG,UAAC,KAAa;IAC7B,IAAM,QAAQ,GAA2B;QACrC,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACV,CAAC;IACF,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC,CAAC;AAEF;;GAEG;AACH,IAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;GAEG,CAAC,MAAM,UAAU,iBAAiB,CACjC,eAAiC,EACjC,SAA8C,EAC9C,OAAkC;;IAElC,IAAM,KAAK,GAAG,MAAA,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,0CAAE,IAAI,EAAE,CAAC;IAC5D,IAAI,KAAK,EAAE;QACP,IAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,sCAAsC;QACtG,IAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,wDAAwD;QACrG,IAAI,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC,KAAK,OAAO,EAAE;YACtD,IAAM,cAAc,GAAG,gBAAgB,CACnC,eAAe,EACf,SAAS,EACT,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAC/B,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAClC,CAAC;YAEF,cAAc,CAAC,MAAM,CAAC,wBAAwB,GAAG,OAAO,CAAC;YACzD,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAClC,OAAO,IAAI,CAAC;SACf;KACJ;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACjC,IAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IAC/D,IAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE;QACV,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;KACzB;IACD,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import { splitTextSegment } from 'roosterjs-content-model-api';\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst getOrdinal = (value: number) => {\n const ORDINALS: Record<number, string> = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n };\n return ORDINALS[value] || 'th';\n};\n\n/**\n * The two last characters of ordinal number (st, nd, rd, th)\n */\nconst ORDINAL_LENGTH = 2;\n\n/**\n * @internal\n */ export function transformOrdinals(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n): boolean {\n const value = previousSegment.text.split(' ').pop()?.trim();\n if (value) {\n const ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th\n const numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value = 10\n if (numericValue && getOrdinal(numericValue) === ordinal) {\n const ordinalSegment = splitTextSegment(\n previousSegment,\n paragraph,\n previousSegment.text.length - 3,\n previousSegment.text.length - 1\n );\n\n ordinalSegment.format.superOrSubScriptSequence = 'super';\n context.canUndoByBackspace = true;\n return true;\n }\n }\n return false;\n}\n\nfunction getNumericValue(text: string) {\n const number = text.substring(0, text.length - ORDINAL_LENGTH);\n const isNumber = /^-?\\d+$/.test(number);\n if (isNumber) {\n return parseInt(text);\n }\n return null;\n}\n"]}
1
+ {"version":3,"file":"transformOrdinals.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/numbers/transformOrdinals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAQ/D,IAAM,UAAU,GAAG,UAAC,KAAa;IAC7B,IAAM,QAAQ,GAA2B;QACrC,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,IAAI;KACV,CAAC;IACF,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC,CAAC;AAEF,IAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAE1C;;GAEG;AACH,IAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;GAEG,CAAC,MAAM,UAAU,iBAAiB,CACjC,eAAiC,EACjC,SAA8C,EAC9C,OAAkC;;IAElC,IAAM,KAAK,GAAG,MAAA,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,0CAAE,IAAI,EAAE,CAAC;IAC5D,IAAI,oBAAoB,GAAG,KAAK,CAAC;IACjC,IAAI,KAAK,EAAE;QACP,IAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE;YACX,IAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAC1D,IAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACpD,IAAI,YAAY,GAAkB,IAAI,CAAC;YACvC,IACI,aAAa;gBACb,aAAa,CAAC,WAAW,IAAI,MAAM;gBACnC,CAAC,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC9E,UAAU,CAAC,YAAY,CAAC,KAAK,KAAK,EACpC;gBACE,oBAAoB,GAAG,IAAI,CAAC;aAC/B;SACJ;aAAM;YACH,IAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,sCAAsC;YACtG,IAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,qDAAqD;YAClG,IAAI,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC,KAAK,OAAO,EAAE;gBACtD,oBAAoB,GAAG,IAAI,CAAC;aAC/B;SACJ;QAED,IAAI,oBAAoB,EAAE;YACtB,IAAM,cAAc,GAAG,gBAAgB,CACnC,eAAe,EACf,SAAS,EACT,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAC/B,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAClC,CAAC;YAEF,cAAc,CAAC,MAAM,CAAC,wBAAwB,GAAG,OAAO,CAAC;YACzD,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;SACrC;KACJ;IACD,OAAO,oBAAoB,CAAC;AAChC,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,aAA8B;IAA9B,8BAAA,EAAA,qBAA8B;IACjE,IAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACtF,IAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,QAAQ,EAAE;QACV,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;KACzB;IACD,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import { splitTextSegment } from 'roosterjs-content-model-api';\n\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst getOrdinal = (value: number) => {\n const ORDINALS: Record<number, string> = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n };\n return ORDINALS[value] || 'th';\n};\n\nconst ORDINALS = ['st', 'nd', 'rd', 'th'];\n\n/**\n * The two last characters of ordinal number (st, nd, rd, th)\n */\nconst ORDINAL_LENGTH = 2;\n\n/**\n * @internal\n */ export function transformOrdinals(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n): boolean {\n const value = previousSegment.text.split(' ').pop()?.trim();\n let shouldAddSuperScript = false;\n if (value) {\n const isOrdinal = ORDINALS.indexOf(value) > -1;\n if (isOrdinal) {\n const index = paragraph.segments.indexOf(previousSegment);\n const numberSegment = paragraph.segments[index - 1];\n let numericValue: number | null = null;\n if (\n numberSegment &&\n numberSegment.segmentType == 'Text' &&\n (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&\n getOrdinal(numericValue) === value\n ) {\n shouldAddSuperScript = true;\n }\n } else {\n const ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th\n const numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =\n if (numericValue && getOrdinal(numericValue) === ordinal) {\n shouldAddSuperScript = true;\n }\n }\n\n if (shouldAddSuperScript) {\n const ordinalSegment = splitTextSegment(\n previousSegment,\n paragraph,\n previousSegment.text.length - 3,\n previousSegment.text.length - 1\n );\n\n ordinalSegment.format.superOrSubScriptSequence = 'super';\n context.canUndoByBackspace = true;\n }\n }\n return shouldAddSuperScript;\n}\n\nfunction getNumericValue(text: string, checkFullText: boolean = false): number | null {\n const number = checkFullText ? text : text.substring(0, text.length - ORDINAL_LENGTH);\n const isNumber = /^-?\\d+$/.test(number);\n if (isNumber) {\n return parseInt(text);\n }\n return null;\n}\n"]}
@@ -121,6 +121,7 @@ var EditPlugin = /** @class */ (function () {
121
121
  };
122
122
  EditPlugin.prototype.handleKeyDownEvent = function (editor, event) {
123
123
  var rawEvent = event.rawEvent;
124
+ var hasCtrlOrMetaKey = rawEvent.ctrlKey || rawEvent.metaKey;
124
125
  if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
125
126
  switch (rawEvent.key) {
126
127
  case 'Backspace':
@@ -137,7 +138,7 @@ var EditPlugin = /** @class */ (function () {
137
138
  }
138
139
  break;
139
140
  case 'Tab':
140
- if (this.options.handleTabKey) {
141
+ if (this.options.handleTabKey && !hasCtrlOrMetaKey) {
141
142
  keyboardTab(editor, rawEvent);
142
143
  }
143
144
  break;
@@ -147,7 +148,9 @@ var EditPlugin = /** @class */ (function () {
147
148
  }
148
149
  break;
149
150
  case 'Enter':
150
- keyboardEnter(editor, rawEvent, this.handleNormalEnter);
151
+ if (!hasCtrlOrMetaKey) {
152
+ keyboardEnter(editor, rawEvent, this.handleNormalEnter);
153
+ }
151
154
  break;
152
155
  default:
153
156
  keyboardInput(editor, rawEvent);
@@ -1 +1 @@
1
- {"version":3,"file":"EditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { keyboardDelete } from './keyboardDelete';\nimport { keyboardEnter } from './keyboardEnter';\nimport { keyboardInput } from './keyboardInput';\nimport { keyboardTab } from './keyboardTab';\nimport { parseTableCells } from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n EditorPlugin,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the keyboard handling behavior of Edit plugin\n */\nexport type EditOptions = {\n /**\n * Whether to handle Tab key in keyboard. @default true\n */\n handleTabKey?: boolean;\n};\n\nconst BACKSPACE_KEY = 8;\nconst DELETE_KEY = 46;\n\nconst DefaultOptions: Partial<EditOptions> = {\n handleTabKey: true,\n};\n\n/**\n * Edit plugins helps editor to do editing operation on top of content model.\n * This includes:\n * 1. Delete Key\n * 2. Backspace Key\n * 3. Tab Key\n */\nexport class EditPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private shouldHandleNextInputEvent = false;\n private selectionAfterDelete: DOMSelection | null = null;\n private handleNormalEnter = false;\n\n /**\n * @param options An optional parameter that takes in an object of type EditOptions, which includes the following properties:\n * handleTabKey: A boolean that enables or disables Tab key handling. Defaults to true.\n */\n constructor(private options: EditOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Edit';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.handleNormalEnter = this.editor.isExperimentalFeatureEnabled('HandleEnterKey');\n\n if (editor.getEnvironment().isAndroid) {\n this.disposer = this.editor.attachDomEvent({\n beforeinput: {\n beforeDispatch: e => this.handleBeforeInputEvent(editor, e),\n },\n });\n }\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n this.disposer?.();\n this.disposer = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'keyUp':\n if (this.selectionAfterDelete) {\n this.editor.setDOMSelection(this.selectionAfterDelete);\n this.selectionAfterDelete = null;\n }\n break;\n }\n }\n }\n\n /**\n * Check if the plugin should handle the given event exclusively.\n * Handle an event exclusively means other plugin will not receive this event in\n * onPluginEvent method.\n * If two plugins will return true in willHandleEventExclusively() for the same event,\n * the final result depends on the order of the plugins are added into editor\n * @param event The event to check:\n */\n willHandleEventExclusively(event: PluginEvent) {\n if (\n this.editor &&\n this.options.handleTabKey &&\n event.eventType == 'keyDown' &&\n event.rawEvent.key == 'Tab' &&\n !event.rawEvent.shiftKey\n ) {\n const selection = this.editor.getDOMSelection();\n const startContainer =\n selection?.type == 'range' && selection.range.collapsed\n ? selection.range.startContainer\n : null;\n const table = startContainer\n ? this.editor.getDOMHelper().findClosestElementAncestor(startContainer, 'table')\n : null;\n const parsedTable = table && parseTableCells(table);\n\n if (parsedTable) {\n const lastRow = parsedTable[parsedTable.length - 1];\n const lastCell = lastRow && lastRow[lastRow.length - 1];\n\n if (typeof lastCell == 'object' && lastCell.contains(startContainer)) {\n // When TAB in the last cell of a table, we will generate new table row, so prevent other plugins handling this event\n // e.g. SelectionPlugin will move the focus out of table, which is conflict with this behavior\n return true;\n }\n }\n }\n\n return false;\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n // Use our API to handle BACKSPACE/DELETE key.\n // No need to clear cache here since if we rely on browser's behavior, there will be Input event and its handler will reconcile cache\n keyboardDelete(editor, rawEvent);\n break;\n\n case 'Delete':\n // Use our API to handle BACKSPACE/DELETE key.\n // No need to clear cache here since if we rely on browser's behavior, there will be Input event and its handler will reconcile cache\n // And leave it to browser when shift key is pressed so that browser will trigger cut event\n if (!event.rawEvent.shiftKey) {\n keyboardDelete(editor, rawEvent);\n }\n break;\n\n case 'Tab':\n if (this.options.handleTabKey) {\n keyboardTab(editor, rawEvent);\n }\n break;\n case 'Unidentified':\n if (editor.getEnvironment().isAndroid) {\n this.shouldHandleNextInputEvent = true;\n }\n break;\n\n case 'Enter':\n keyboardEnter(editor, rawEvent, this.handleNormalEnter);\n break;\n\n default:\n keyboardInput(editor, rawEvent);\n break;\n }\n }\n }\n\n private handleBeforeInputEvent(editor: IEditor, rawEvent: Event) {\n // Some Android IMEs doesn't fire correct keydown event for BACKSPACE/DELETE key\n // Here we translate input event to BACKSPACE/DELETE keydown event to be compatible with existing logic\n if (\n !this.shouldHandleNextInputEvent ||\n !(rawEvent instanceof InputEvent) ||\n rawEvent.defaultPrevented\n ) {\n return;\n }\n this.shouldHandleNextInputEvent = false;\n\n let handled = false;\n switch (rawEvent.inputType) {\n case 'deleteContentBackward':\n handled = keyboardDelete(\n editor,\n new KeyboardEvent('keydown', {\n key: 'Backspace',\n keyCode: BACKSPACE_KEY,\n which: BACKSPACE_KEY,\n })\n );\n break;\n case 'deleteContentForward':\n handled = keyboardDelete(\n editor,\n new KeyboardEvent('keydown', {\n key: 'Delete',\n keyCode: DELETE_KEY,\n which: DELETE_KEY,\n })\n );\n break;\n }\n\n if (handled) {\n rawEvent.preventDefault();\n\n // Restore the selection on keyup event to avoid the cursor jump issue\n // See: https://issues.chromium.org/issues/330596261\n this.selectionAfterDelete = editor.getDOMSelection();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"EditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/EditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { keyboardDelete } from './keyboardDelete';\nimport { keyboardEnter } from './keyboardEnter';\nimport { keyboardInput } from './keyboardInput';\nimport { keyboardTab } from './keyboardTab';\nimport { parseTableCells } from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n EditorPlugin,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the keyboard handling behavior of Edit plugin\n */\nexport type EditOptions = {\n /**\n * Whether to handle Tab key in keyboard. @default true\n */\n handleTabKey?: boolean;\n};\n\nconst BACKSPACE_KEY = 8;\nconst DELETE_KEY = 46;\n\nconst DefaultOptions: Partial<EditOptions> = {\n handleTabKey: true,\n};\n\n/**\n * Edit plugins helps editor to do editing operation on top of content model.\n * This includes:\n * 1. Delete Key\n * 2. Backspace Key\n * 3. Tab Key\n */\nexport class EditPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private shouldHandleNextInputEvent = false;\n private selectionAfterDelete: DOMSelection | null = null;\n private handleNormalEnter = false;\n\n /**\n * @param options An optional parameter that takes in an object of type EditOptions, which includes the following properties:\n * handleTabKey: A boolean that enables or disables Tab key handling. Defaults to true.\n */\n constructor(private options: EditOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Edit';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.handleNormalEnter = this.editor.isExperimentalFeatureEnabled('HandleEnterKey');\n\n if (editor.getEnvironment().isAndroid) {\n this.disposer = this.editor.attachDomEvent({\n beforeinput: {\n beforeDispatch: e => this.handleBeforeInputEvent(editor, e),\n },\n });\n }\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n this.disposer?.();\n this.disposer = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'keyUp':\n if (this.selectionAfterDelete) {\n this.editor.setDOMSelection(this.selectionAfterDelete);\n this.selectionAfterDelete = null;\n }\n break;\n }\n }\n }\n\n /**\n * Check if the plugin should handle the given event exclusively.\n * Handle an event exclusively means other plugin will not receive this event in\n * onPluginEvent method.\n * If two plugins will return true in willHandleEventExclusively() for the same event,\n * the final result depends on the order of the plugins are added into editor\n * @param event The event to check:\n */\n willHandleEventExclusively(event: PluginEvent) {\n if (\n this.editor &&\n this.options.handleTabKey &&\n event.eventType == 'keyDown' &&\n event.rawEvent.key == 'Tab' &&\n !event.rawEvent.shiftKey\n ) {\n const selection = this.editor.getDOMSelection();\n const startContainer =\n selection?.type == 'range' && selection.range.collapsed\n ? selection.range.startContainer\n : null;\n const table = startContainer\n ? this.editor.getDOMHelper().findClosestElementAncestor(startContainer, 'table')\n : null;\n const parsedTable = table && parseTableCells(table);\n\n if (parsedTable) {\n const lastRow = parsedTable[parsedTable.length - 1];\n const lastCell = lastRow && lastRow[lastRow.length - 1];\n\n if (typeof lastCell == 'object' && lastCell.contains(startContainer)) {\n // When TAB in the last cell of a table, we will generate new table row, so prevent other plugins handling this event\n // e.g. SelectionPlugin will move the focus out of table, which is conflict with this behavior\n return true;\n }\n }\n }\n\n return false;\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n const hasCtrlOrMetaKey = rawEvent.ctrlKey || rawEvent.metaKey;\n\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n // Use our API to handle BACKSPACE/DELETE key.\n // No need to clear cache here since if we rely on browser's behavior, there will be Input event and its handler will reconcile cache\n keyboardDelete(editor, rawEvent);\n break;\n\n case 'Delete':\n // Use our API to handle BACKSPACE/DELETE key.\n // No need to clear cache here since if we rely on browser's behavior, there will be Input event and its handler will reconcile cache\n // And leave it to browser when shift key is pressed so that browser will trigger cut event\n if (!event.rawEvent.shiftKey) {\n keyboardDelete(editor, rawEvent);\n }\n break;\n\n case 'Tab':\n if (this.options.handleTabKey && !hasCtrlOrMetaKey) {\n keyboardTab(editor, rawEvent);\n }\n break;\n case 'Unidentified':\n if (editor.getEnvironment().isAndroid) {\n this.shouldHandleNextInputEvent = true;\n }\n break;\n\n case 'Enter':\n if (!hasCtrlOrMetaKey) {\n keyboardEnter(editor, rawEvent, this.handleNormalEnter);\n }\n break;\n\n default:\n keyboardInput(editor, rawEvent);\n break;\n }\n }\n }\n\n private handleBeforeInputEvent(editor: IEditor, rawEvent: Event) {\n // Some Android IMEs doesn't fire correct keydown event for BACKSPACE/DELETE key\n // Here we translate input event to BACKSPACE/DELETE keydown event to be compatible with existing logic\n if (\n !this.shouldHandleNextInputEvent ||\n !(rawEvent instanceof InputEvent) ||\n rawEvent.defaultPrevented\n ) {\n return;\n }\n this.shouldHandleNextInputEvent = false;\n\n let handled = false;\n switch (rawEvent.inputType) {\n case 'deleteContentBackward':\n handled = keyboardDelete(\n editor,\n new KeyboardEvent('keydown', {\n key: 'Backspace',\n keyCode: BACKSPACE_KEY,\n which: BACKSPACE_KEY,\n })\n );\n break;\n case 'deleteContentForward':\n handled = keyboardDelete(\n editor,\n new KeyboardEvent('keydown', {\n key: 'Delete',\n keyCode: DELETE_KEY,\n which: DELETE_KEY,\n })\n );\n break;\n }\n\n if (handled) {\n rawEvent.preventDefault();\n\n // Restore the selection on keyup event to avoid the cursor jump issue\n // See: https://issues.chromium.org/issues/330596261\n this.selectionAfterDelete = editor.getDOMSelection();\n }\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { DeleteSelectionStep } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare const handleAutoLink: DeleteSelectionStep;
@@ -0,0 +1,21 @@
1
+ import { promoteLink } from 'roosterjs-content-model-api';
2
+ /**
3
+ * @internal
4
+ */
5
+ export var handleAutoLink = function (context) {
6
+ var deleteResult = context.deleteResult, insertPoint = context.insertPoint;
7
+ if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {
8
+ var marker = insertPoint.marker, paragraph = insertPoint.paragraph;
9
+ var index = paragraph.segments.indexOf(marker);
10
+ var segBefore = index > 0 ? paragraph.segments[index - 1] : null;
11
+ if ((segBefore === null || segBefore === void 0 ? void 0 : segBefore.segmentType) == 'Text' &&
12
+ promoteLink(segBefore, paragraph, {
13
+ autoLink: true,
14
+ }) &&
15
+ context.formatContext) {
16
+ context.formatContext.canUndoByBackspace = true;
17
+ }
18
+ // Do not set deleteResult here since we haven't really start a new paragraph, we need other delete step to keep working on it
19
+ }
20
+ };
21
+ //# sourceMappingURL=handleAutoLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handleAutoLink.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleAutoLink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;GAEG;AACH,MAAM,CAAC,IAAM,cAAc,GAAwB,UAAA,OAAO;IAC9C,IAAA,YAAY,GAAkB,OAAO,aAAzB,EAAE,WAAW,GAAK,OAAO,YAAZ,CAAa;IAE9C,IAAI,YAAY,IAAI,YAAY,IAAI,YAAY,IAAI,iBAAiB,EAAE;QAC3D,IAAA,MAAM,GAAgB,WAAW,OAA3B,EAAE,SAAS,GAAK,WAAW,UAAhB,CAAiB;QAC1C,IAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjD,IAAM,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEnE,IACI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,KAAI,MAAM;YAChC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE;gBAC9B,QAAQ,EAAE,IAAI;aACjB,CAAC;YACF,OAAO,CAAC,aAAa,EACvB;YACE,OAAO,CAAC,aAAa,CAAC,kBAAkB,GAAG,IAAI,CAAC;SACnD;QAED,8HAA8H;KACjI;AACL,CAAC,CAAC","sourcesContent":["import { promoteLink } from 'roosterjs-content-model-api';\nimport type { DeleteSelectionStep } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleAutoLink: DeleteSelectionStep = context => {\n const { deleteResult, insertPoint } = context;\n\n if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {\n const { marker, paragraph } = insertPoint;\n const index = paragraph.segments.indexOf(marker);\n const segBefore = index > 0 ? paragraph.segments[index - 1] : null;\n\n if (\n segBefore?.segmentType == 'Text' &&\n promoteLink(segBefore, paragraph, {\n autoLink: true,\n }) &&\n context.formatContext\n ) {\n context.formatContext.canUndoByBackspace = true;\n }\n\n // Do not set deleteResult here since we haven't really start a new paragraph, we need other delete step to keep working on it\n }\n};\n"]}
@@ -1,4 +1,5 @@
1
1
  import { deleteEmptyQuote } from './deleteSteps/deleteEmptyQuote';
2
+ import { handleAutoLink } from './inputSteps/handleAutoLink';
2
3
  import { handleEnterOnList } from './inputSteps/handleEnterOnList';
3
4
  import { handleEnterOnParagraph } from './inputSteps/handleEnterOnParagraph';
4
5
  import { ChangeSource, deleteSelection, normalizeContentModel, runEditSteps, } from 'roosterjs-content-model-dom';
@@ -16,7 +17,9 @@ export function keyboardEnter(editor, rawEvent, handleNormalEnter) {
16
17
  // For ENTER key, although we may have deleted something, since we still need to split the line, we always treat it as not delete
17
18
  // so further delete steps can keep working
18
19
  result.deleteResult = 'notDeleted';
19
- var steps = rawEvent.shiftKey ? [] : [handleEnterOnList, deleteEmptyQuote];
20
+ var steps = rawEvent.shiftKey
21
+ ? []
22
+ : [handleAutoLink, handleEnterOnList, deleteEmptyQuote];
20
23
  if (handleNormalEnter) {
21
24
  steps.push(handleEnterOnParagraph);
22
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardEnter.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardEnter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EACH,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,YAAY,GACf,MAAM,6BAA6B,CAAC;AAGrC;;GAEG;AACH,MAAM,UAAU,aAAa,CACzB,MAAe,EACf,QAAuB,EACvB,iBAA0B;IAE1B,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;QACX,gEAAgE;QAChE,IAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAEnD,oBAAoB;QACpB,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,EAAE;YACxC,iIAAiI;YACjI,2CAA2C;YAC3C,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;YAEnC,IAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;YAE7E,IAAI,iBAAiB,EAAE;gBACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;aACtC;YAED,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;SAC/B;QAED,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;YAChC,2HAA2H;YAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;YAE7D,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAE7B,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;SACf;aAAM;YACH,OAAO,KAAK,CAAC;SAChB;IACL,CAAC,EACD;QACI,QAAQ,UAAA;QACR,mBAAmB,EAAE,IAAI;QACzB,YAAY,EAAE,YAAY,CAAC,QAAQ;KACtC,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { deleteEmptyQuote } from './deleteSteps/deleteEmptyQuote';\nimport { handleEnterOnList } from './inputSteps/handleEnterOnList';\nimport { handleEnterOnParagraph } from './inputSteps/handleEnterOnParagraph';\nimport {\n ChangeSource,\n deleteSelection,\n normalizeContentModel,\n runEditSteps,\n} from 'roosterjs-content-model-dom';\nimport type { IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardEnter(\n editor: IEditor,\n rawEvent: KeyboardEvent,\n handleNormalEnter: boolean\n) {\n const selection = editor.getDOMSelection();\n\n editor.formatContentModel(\n (model, context) => {\n // 1. delete the expanded selection if any, then merge paragraph\n const result = deleteSelection(model, [], context);\n\n // 2. Add line break\n if (selection && selection.type != 'table') {\n // For ENTER key, although we may have deleted something, since we still need to split the line, we always treat it as not delete\n // so further delete steps can keep working\n result.deleteResult = 'notDeleted';\n\n const steps = rawEvent.shiftKey ? [] : [handleEnterOnList, deleteEmptyQuote];\n\n if (handleNormalEnter) {\n steps.push(handleEnterOnParagraph);\n }\n\n runEditSteps(steps, result);\n }\n\n if (result.deleteResult == 'range') {\n // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here\n context.newPendingFormat = result.insertPoint?.marker.format;\n\n normalizeContentModel(model);\n\n rawEvent.preventDefault();\n return true;\n } else {\n return false;\n }\n },\n {\n rawEvent,\n scrollCaretIntoView: true,\n changeSource: ChangeSource.Keyboard,\n }\n );\n}\n"]}
1
+ {"version":3,"file":"keyboardEnter.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardEnter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EACH,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,YAAY,GACf,MAAM,6BAA6B,CAAC;AAGrC;;GAEG;AACH,MAAM,UAAU,aAAa,CACzB,MAAe,EACf,QAAuB,EACvB,iBAA0B;IAE1B,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;QACX,gEAAgE;QAChE,IAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAEnD,oBAAoB;QACpB,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,OAAO,EAAE;YACxC,iIAAiI;YACjI,2CAA2C;YAC3C,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;YAEnC,IAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ;gBAC3B,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;YAE5D,IAAI,iBAAiB,EAAE;gBACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;aACtC;YAED,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;SAC/B;QAED,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;YAChC,2HAA2H;YAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;YAE7D,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAE7B,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;SACf;aAAM;YACH,OAAO,KAAK,CAAC;SAChB;IACL,CAAC,EACD;QACI,QAAQ,UAAA;QACR,mBAAmB,EAAE,IAAI;QACzB,YAAY,EAAE,YAAY,CAAC,QAAQ;KACtC,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { deleteEmptyQuote } from './deleteSteps/deleteEmptyQuote';\nimport { handleAutoLink } from './inputSteps/handleAutoLink';\nimport { handleEnterOnList } from './inputSteps/handleEnterOnList';\nimport { handleEnterOnParagraph } from './inputSteps/handleEnterOnParagraph';\nimport {\n ChangeSource,\n deleteSelection,\n normalizeContentModel,\n runEditSteps,\n} from 'roosterjs-content-model-dom';\nimport type { IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardEnter(\n editor: IEditor,\n rawEvent: KeyboardEvent,\n handleNormalEnter: boolean\n) {\n const selection = editor.getDOMSelection();\n\n editor.formatContentModel(\n (model, context) => {\n // 1. delete the expanded selection if any, then merge paragraph\n const result = deleteSelection(model, [], context);\n\n // 2. Add line break\n if (selection && selection.type != 'table') {\n // For ENTER key, although we may have deleted something, since we still need to split the line, we always treat it as not delete\n // so further delete steps can keep working\n result.deleteResult = 'notDeleted';\n\n const steps = rawEvent.shiftKey\n ? []\n : [handleAutoLink, handleEnterOnList, deleteEmptyQuote];\n\n if (handleNormalEnter) {\n steps.push(handleEnterOnParagraph);\n }\n\n runEditSteps(steps, result);\n }\n\n if (result.deleteResult == 'range') {\n // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here\n context.newPendingFormat = result.insertPoint?.marker.format;\n\n normalizeContentModel(model);\n\n rawEvent.preventDefault();\n return true;\n } else {\n return false;\n }\n },\n {\n rawEvent,\n scrollCaretIntoView: true,\n changeSource: ChangeSource.Keyboard,\n }\n );\n}\n"]}
@@ -6,7 +6,6 @@ export { DefaultSanitizers } from './paste/DefaultSanitizers';
6
6
  export { EditPlugin, EditOptions } from './edit/EditPlugin';
7
7
  export { AutoFormatPlugin } from './autoFormat/AutoFormatPlugin';
8
8
  export { AutoFormatOptions } from './autoFormat/interface/AutoFormatOptions';
9
- export { AutoLinkOptions } from './autoFormat/interface/AutoLinkOptions';
10
9
  export { ShortcutBold, ShortcutItalic, ShortcutUnderline, ShortcutClearFormat, ShortcutUndo, ShortcutUndo2, ShortcutRedo, ShortcutRedoAlt, ShortcutRedoMacOS, ShortcutBullet, ShortcutNumbering, ShortcutIncreaseFont, ShortcutDecreaseFont, ShortcutIndentList, ShortcutOutdentList, } from './shortcut/shortcuts';
11
10
  export { ShortcutPlugin } from './shortcut/ShortcutPlugin';
12
11
  export { ShortcutKeyDefinition, ShortcutCommand } from './shortcut/ShortcutCommand';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/roosterjs-content-model-plugins/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAe,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,OAAO,EACH,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAsB,MAAM,yCAAyC,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAmB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAiB,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC","sourcesContent":["export { TableEditPlugin } from './tableEdit/TableEditPlugin';\nexport { OnTableEditorCreatedCallback } from './tableEdit/OnTableEditorCreatedCallback';\nexport { TableEditFeatureName } from './tableEdit/editors/features/TableEditFeatureName';\nexport { PastePlugin } from './paste/PastePlugin';\nexport { DefaultSanitizers } from './paste/DefaultSanitizers';\nexport { EditPlugin, EditOptions } from './edit/EditPlugin';\nexport { AutoFormatPlugin } from './autoFormat/AutoFormatPlugin';\nexport { AutoFormatOptions } from './autoFormat/interface/AutoFormatOptions';\nexport { AutoLinkOptions } from './autoFormat/interface/AutoLinkOptions';\n\nexport {\n ShortcutBold,\n ShortcutItalic,\n ShortcutUnderline,\n ShortcutClearFormat,\n ShortcutUndo,\n ShortcutUndo2,\n ShortcutRedo,\n ShortcutRedoAlt,\n ShortcutRedoMacOS,\n ShortcutBullet,\n ShortcutNumbering,\n ShortcutIncreaseFont,\n ShortcutDecreaseFont,\n ShortcutIndentList,\n ShortcutOutdentList,\n} from './shortcut/shortcuts';\nexport { ShortcutPlugin } from './shortcut/ShortcutPlugin';\nexport { ShortcutKeyDefinition, ShortcutCommand } from './shortcut/ShortcutCommand';\nexport { ContextMenuPluginBase, ContextMenuOptions } from './contextMenuBase/ContextMenuPluginBase';\nexport { WatermarkPlugin } from './watermark/WatermarkPlugin';\nexport { WatermarkFormat } from './watermark/WatermarkFormat';\nexport { MarkdownPlugin, MarkdownOptions } from './markdown/MarkdownPlugin';\nexport { HyperlinkPlugin } from './hyperlink/HyperlinkPlugin';\nexport { HyperlinkToolTip } from './hyperlink/HyperlinkToolTip';\nexport { PickerPlugin } from './picker/PickerPlugin';\nexport { PickerHelper } from './picker/PickerHelper';\nexport { PickerSelectionChangMode, PickerDirection, PickerHandler } from './picker/PickerHandler';\nexport { CustomReplacePlugin, CustomReplace } from './customReplace/CustomReplacePlugin';\nexport { ImageEditPlugin } from './imageEdit/ImageEditPlugin';\nexport { ImageEditOptions } from './imageEdit/types/ImageEditOptions';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/roosterjs-content-model-plugins/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAe,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,EACH,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAsB,MAAM,yCAAyC,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAmB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAiB,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC","sourcesContent":["export { TableEditPlugin } from './tableEdit/TableEditPlugin';\nexport { OnTableEditorCreatedCallback } from './tableEdit/OnTableEditorCreatedCallback';\nexport { TableEditFeatureName } from './tableEdit/editors/features/TableEditFeatureName';\nexport { PastePlugin } from './paste/PastePlugin';\nexport { DefaultSanitizers } from './paste/DefaultSanitizers';\nexport { EditPlugin, EditOptions } from './edit/EditPlugin';\nexport { AutoFormatPlugin } from './autoFormat/AutoFormatPlugin';\nexport { AutoFormatOptions } from './autoFormat/interface/AutoFormatOptions';\n\nexport {\n ShortcutBold,\n ShortcutItalic,\n ShortcutUnderline,\n ShortcutClearFormat,\n ShortcutUndo,\n ShortcutUndo2,\n ShortcutRedo,\n ShortcutRedoAlt,\n ShortcutRedoMacOS,\n ShortcutBullet,\n ShortcutNumbering,\n ShortcutIncreaseFont,\n ShortcutDecreaseFont,\n ShortcutIndentList,\n ShortcutOutdentList,\n} from './shortcut/shortcuts';\nexport { ShortcutPlugin } from './shortcut/ShortcutPlugin';\nexport { ShortcutKeyDefinition, ShortcutCommand } from './shortcut/ShortcutCommand';\nexport { ContextMenuPluginBase, ContextMenuOptions } from './contextMenuBase/ContextMenuPluginBase';\nexport { WatermarkPlugin } from './watermark/WatermarkPlugin';\nexport { WatermarkFormat } from './watermark/WatermarkFormat';\nexport { MarkdownPlugin, MarkdownOptions } from './markdown/MarkdownPlugin';\nexport { HyperlinkPlugin } from './hyperlink/HyperlinkPlugin';\nexport { HyperlinkToolTip } from './hyperlink/HyperlinkToolTip';\nexport { PickerPlugin } from './picker/PickerPlugin';\nexport { PickerHelper } from './picker/PickerHelper';\nexport { PickerSelectionChangMode, PickerDirection, PickerHandler } from './picker/PickerHandler';\nexport { CustomReplacePlugin, CustomReplace } from './customReplace/CustomReplacePlugin';\nexport { ImageEditPlugin } from './imageEdit/ImageEditPlugin';\nexport { ImageEditOptions } from './imageEdit/types/ImageEditOptions';\n"]}
package/package.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "description": "Plugins for roosterjs",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.1",
6
- "roosterjs-content-model-core": "^9.11.2",
7
- "roosterjs-content-model-dom": "^9.11.2",
8
- "roosterjs-content-model-types": "^9.11.2",
9
- "roosterjs-content-model-api": "^9.11.2"
6
+ "roosterjs-content-model-core": "^9.12.0",
7
+ "roosterjs-content-model-dom": "^9.12.0",
8
+ "roosterjs-content-model-types": "^9.12.0",
9
+ "roosterjs-content-model-api": "^9.12.0"
10
10
  },
11
- "version": "9.11.2",
11
+ "version": "9.12.0",
12
12
  "main": "./lib/index.js",
13
13
  "typings": "./lib/index.d.ts",
14
14
  "module": "./lib-mjs/index.js",
@@ -1,21 +0,0 @@
1
- /**
2
- * Options to customize the Auto link options in Auto Format Plugin
3
- */
4
- export interface AutoLinkOptions {
5
- /**
6
- * When press backspace before a link, remove the hyperlink
7
- */
8
- autoUnlink?: boolean;
9
- /**
10
- * When paste or type content with a link, create hyperlink for the link
11
- */
12
- autoLink?: boolean;
13
- /**
14
- * When paste content or type content with telephone, create hyperlink for the telephone number
15
- */
16
- autoTel?: boolean;
17
- /**
18
- * When paste or type a content with mailto, create hyperlink for the content
19
- */
20
- autoMailto?: boolean;
21
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=AutoLinkOptions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AutoLinkOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoLinkOptions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Options to customize the Auto link options in Auto Format Plugin\n */\nexport interface AutoLinkOptions {\n /**\n * When press backspace before a link, remove the hyperlink\n */\n autoUnlink?: boolean;\n\n /**\n * When paste or type content with a link, create hyperlink for the link\n */\n autoLink?: boolean;\n\n /**\n * When paste content or type content with telephone, create hyperlink for the telephone number\n */\n autoTel?: boolean;\n\n /**\n * When paste or type a content with mailto, create hyperlink for the content\n */\n autoMailto?: boolean;\n}\n"]}
@@ -1,6 +0,0 @@
1
- import type { AutoLinkOptions } from '../interface/AutoLinkOptions';
2
- import type { ContentModelText, FormatContentModelContext, ShallowMutableContentModelParagraph } from 'roosterjs-content-model-types';
3
- /**
4
- * @internal
5
- */
6
- export declare function createLinkAfterSpace(previousSegment: ContentModelText, paragraph: ShallowMutableContentModelParagraph, context: FormatContentModelContext, autoLinkOptions: AutoLinkOptions): boolean;
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createLinkAfterSpace = void 0;
4
- var getLinkUrl_1 = require("./getLinkUrl");
5
- var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
6
- /**
7
- * @internal
8
- */
9
- function createLinkAfterSpace(previousSegment, paragraph, context, autoLinkOptions) {
10
- var link = previousSegment.text.split(' ').pop();
11
- var url = link === null || link === void 0 ? void 0 : link.trim();
12
- var linkUrl = undefined;
13
- if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
14
- var linkSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - link.trimLeft().length, previousSegment.text.trimRight().length);
15
- linkSegment.link = {
16
- format: {
17
- href: linkUrl,
18
- underline: true,
19
- },
20
- dataset: {},
21
- };
22
- context.canUndoByBackspace = true;
23
- return true;
24
- }
25
- return false;
26
- }
27
- exports.createLinkAfterSpace = createLinkAfterSpace;
28
- //# sourceMappingURL=createLinkAfterSpace.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createLinkAfterSpace.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLinkAfterSpace.ts"],"names":[],"mappings":";;;AAAA,2CAA0C;AAC1C,2EAA+D;AAQ/D;;GAEG;AACH,SAAgB,oBAAoB,CAChC,eAAiC,EACjC,SAA8C,EAC9C,OAAkC,EAClC,eAAgC;IAEhC,IAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACnD,IAAM,GAAG,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,EAAE,CAAC;IACzB,IAAI,OAAO,GAAuB,SAAS,CAAC;IAC5C,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,IAAA,uBAAU,EAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE;QAC7D,IAAM,WAAW,GAAG,IAAA,8CAAgB,EAChC,eAAe,EACf,SAAS,EACT,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EACpD,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAC1C,CAAC;QACF,WAAW,CAAC,IAAI,GAAG;YACf,MAAM,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,IAAI;aAClB;YACD,OAAO,EAAE,EAAE;SACd,CAAC;QAEF,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAElC,OAAO,IAAI,CAAC;KACf;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AA7BD,oDA6BC","sourcesContent":["import { getLinkUrl } from './getLinkUrl';\nimport { splitTextSegment } from 'roosterjs-content-model-api';\nimport type { AutoLinkOptions } from '../interface/AutoLinkOptions';\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function createLinkAfterSpace(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext,\n autoLinkOptions: AutoLinkOptions\n) {\n const link = previousSegment.text.split(' ').pop();\n const url = link?.trim();\n let linkUrl: string | undefined = undefined;\n if (url && link && (linkUrl = getLinkUrl(url, autoLinkOptions))) {\n const linkSegment = splitTextSegment(\n previousSegment,\n paragraph,\n previousSegment.text.length - link.trimLeft().length,\n previousSegment.text.trimRight().length\n );\n linkSegment.link = {\n format: {\n href: linkUrl,\n underline: true,\n },\n dataset: {},\n };\n\n context.canUndoByBackspace = true;\n\n return true;\n }\n return false;\n}\n"]}
@@ -1,5 +0,0 @@
1
- import type { AutoLinkOptions } from '../interface/AutoLinkOptions';
2
- /**
3
- * @internal
4
- */
5
- export declare function getLinkUrl(text: string, autoLinkOptions: AutoLinkOptions): string | undefined;
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLinkUrl = void 0;
4
- var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
5
- var COMMON_REGEX = "[s]*[a-zA-Z0-9+][s]*";
6
- var TELEPHONE_REGEX = "(T|t)el:" + COMMON_REGEX;
7
- var MAILTO_REGEX = "(M|m)ailto:" + COMMON_REGEX;
8
- /**
9
- * @internal
10
- */
11
- function getLinkUrl(text, autoLinkOptions) {
12
- var _a;
13
- var autoLink = autoLinkOptions.autoLink, autoMailto = autoLinkOptions.autoMailto, autoTel = autoLinkOptions.autoTel;
14
- var linkMatch = autoLink ? (_a = (0, roosterjs_content_model_api_1.matchLink)(text)) === null || _a === void 0 ? void 0 : _a.normalizedUrl : undefined;
15
- var telMatch = autoTel ? matchTel(text) : undefined;
16
- var mailtoMatch = autoMailto ? matchMailTo(text) : undefined;
17
- return linkMatch || telMatch || mailtoMatch;
18
- }
19
- exports.getLinkUrl = getLinkUrl;
20
- function matchTel(text) {
21
- return text.match(TELEPHONE_REGEX) ? text.toLocaleLowerCase() : undefined;
22
- }
23
- function matchMailTo(text) {
24
- return text.match(MAILTO_REGEX) ? text.toLocaleLowerCase() : undefined;
25
- }
26
- //# sourceMappingURL=getLinkUrl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getLinkUrl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts"],"names":[],"mappings":";;;AAAA,2EAAwD;AAGxD,IAAM,YAAY,GAAG,sBAAwB,CAAC;AAC9C,IAAM,eAAe,GAAG,aAAW,YAAc,CAAC;AAClD,IAAM,YAAY,GAAG,gBAAc,YAAc,CAAC;AAElD;;GAEG;AACH,SAAgB,UAAU,CAAC,IAAY,EAAE,eAAgC;;IAC7D,IAAA,QAAQ,GAA0B,eAAe,SAAzC,EAAE,UAAU,GAAc,eAAe,WAA7B,EAAE,OAAO,GAAK,eAAe,QAApB,CAAqB;IAC1D,IAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAA,IAAA,uCAAS,EAAC,IAAI,CAAC,0CAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,IAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,IAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/D,OAAO,SAAS,IAAI,QAAQ,IAAI,WAAW,CAAC;AAChD,CAAC;AAPD,gCAOC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC","sourcesContent":["import { matchLink } from 'roosterjs-content-model-api';\nimport type { AutoLinkOptions } from '../interface/AutoLinkOptions';\n\nconst COMMON_REGEX = `[\\s]*[a-zA-Z0-9+][\\s]*`;\nconst TELEPHONE_REGEX = `(T|t)el:${COMMON_REGEX}`;\nconst MAILTO_REGEX = `(M|m)ailto:${COMMON_REGEX}`;\n\n/**\n * @internal\n */\nexport function getLinkUrl(text: string, autoLinkOptions: AutoLinkOptions): string | undefined {\n const { autoLink, autoMailto, autoTel } = autoLinkOptions;\n const linkMatch = autoLink ? matchLink(text)?.normalizedUrl : undefined;\n const telMatch = autoTel ? matchTel(text) : undefined;\n const mailtoMatch = autoMailto ? matchMailTo(text) : undefined;\n\n return linkMatch || telMatch || mailtoMatch;\n}\n\nfunction matchTel(text: string) {\n return text.match(TELEPHONE_REGEX) ? text.toLocaleLowerCase() : undefined;\n}\n\nfunction matchMailTo(text: string) {\n return text.match(MAILTO_REGEX) ? text.toLocaleLowerCase() : undefined;\n}\n"]}
@@ -1,21 +0,0 @@
1
- /**
2
- * Options to customize the Auto link options in Auto Format Plugin
3
- */
4
- export interface AutoLinkOptions {
5
- /**
6
- * When press backspace before a link, remove the hyperlink
7
- */
8
- autoUnlink?: boolean;
9
- /**
10
- * When paste or type content with a link, create hyperlink for the link
11
- */
12
- autoLink?: boolean;
13
- /**
14
- * When paste content or type content with telephone, create hyperlink for the telephone number
15
- */
16
- autoTel?: boolean;
17
- /**
18
- * When paste or type a content with mailto, create hyperlink for the content
19
- */
20
- autoMailto?: boolean;
21
- }
@@ -1,5 +0,0 @@
1
- define(["require", "exports"], function (require, exports) {
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- });
5
- //# sourceMappingURL=AutoLinkOptions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AutoLinkOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoLinkOptions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Options to customize the Auto link options in Auto Format Plugin\n */\nexport interface AutoLinkOptions {\n /**\n * When press backspace before a link, remove the hyperlink\n */\n autoUnlink?: boolean;\n\n /**\n * When paste or type content with a link, create hyperlink for the link\n */\n autoLink?: boolean;\n\n /**\n * When paste content or type content with telephone, create hyperlink for the telephone number\n */\n autoTel?: boolean;\n\n /**\n * When paste or type a content with mailto, create hyperlink for the content\n */\n autoMailto?: boolean;\n}\n"]}
@@ -1,6 +0,0 @@
1
- import type { AutoLinkOptions } from '../interface/AutoLinkOptions';
2
- import type { ContentModelText, FormatContentModelContext, ShallowMutableContentModelParagraph } from 'roosterjs-content-model-types';
3
- /**
4
- * @internal
5
- */
6
- export declare function createLinkAfterSpace(previousSegment: ContentModelText, paragraph: ShallowMutableContentModelParagraph, context: FormatContentModelContext, autoLinkOptions: AutoLinkOptions): boolean;
@@ -1,28 +0,0 @@
1
- define(["require", "exports", "./getLinkUrl", "roosterjs-content-model-api"], function (require, exports, getLinkUrl_1, roosterjs_content_model_api_1) {
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.createLinkAfterSpace = void 0;
5
- /**
6
- * @internal
7
- */
8
- function createLinkAfterSpace(previousSegment, paragraph, context, autoLinkOptions) {
9
- var link = previousSegment.text.split(' ').pop();
10
- var url = link === null || link === void 0 ? void 0 : link.trim();
11
- var linkUrl = undefined;
12
- if (url && link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(url, autoLinkOptions))) {
13
- var linkSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - link.trimLeft().length, previousSegment.text.trimRight().length);
14
- linkSegment.link = {
15
- format: {
16
- href: linkUrl,
17
- underline: true,
18
- },
19
- dataset: {},
20
- };
21
- context.canUndoByBackspace = true;
22
- return true;
23
- }
24
- return false;
25
- }
26
- exports.createLinkAfterSpace = createLinkAfterSpace;
27
- });
28
- //# sourceMappingURL=createLinkAfterSpace.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createLinkAfterSpace.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/link/createLinkAfterSpace.ts"],"names":[],"mappings":";;;;IASA;;OAEG;IACH,SAAgB,oBAAoB,CAChC,eAAiC,EACjC,SAA8C,EAC9C,OAAkC,EAClC,eAAgC;QAEhC,IAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACnD,IAAM,GAAG,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,EAAE,CAAC;QACzB,IAAI,OAAO,GAAuB,SAAS,CAAC;QAC5C,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,IAAA,uBAAU,EAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE;YAC7D,IAAM,WAAW,GAAG,IAAA,8CAAgB,EAChC,eAAe,EACf,SAAS,EACT,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EACpD,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAC1C,CAAC;YACF,WAAW,CAAC,IAAI,GAAG;gBACf,MAAM,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,SAAS,EAAE,IAAI;iBAClB;gBACD,OAAO,EAAE,EAAE;aACd,CAAC;YAEF,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAElC,OAAO,IAAI,CAAC;SACf;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IA7BD,oDA6BC","sourcesContent":["import { getLinkUrl } from './getLinkUrl';\nimport { splitTextSegment } from 'roosterjs-content-model-api';\nimport type { AutoLinkOptions } from '../interface/AutoLinkOptions';\nimport type {\n ContentModelText,\n FormatContentModelContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function createLinkAfterSpace(\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext,\n autoLinkOptions: AutoLinkOptions\n) {\n const link = previousSegment.text.split(' ').pop();\n const url = link?.trim();\n let linkUrl: string | undefined = undefined;\n if (url && link && (linkUrl = getLinkUrl(url, autoLinkOptions))) {\n const linkSegment = splitTextSegment(\n previousSegment,\n paragraph,\n previousSegment.text.length - link.trimLeft().length,\n previousSegment.text.trimRight().length\n );\n linkSegment.link = {\n format: {\n href: linkUrl,\n underline: true,\n },\n dataset: {},\n };\n\n context.canUndoByBackspace = true;\n\n return true;\n }\n return false;\n}\n"]}
@@ -1,5 +0,0 @@
1
- import type { AutoLinkOptions } from '../interface/AutoLinkOptions';
2
- /**
3
- * @internal
4
- */
5
- export declare function getLinkUrl(text: string, autoLinkOptions: AutoLinkOptions): string | undefined;
@@ -1,27 +0,0 @@
1
- define(["require", "exports", "roosterjs-content-model-api"], function (require, exports, roosterjs_content_model_api_1) {
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.getLinkUrl = void 0;
5
- var COMMON_REGEX = "[s]*[a-zA-Z0-9+][s]*";
6
- var TELEPHONE_REGEX = "(T|t)el:" + COMMON_REGEX;
7
- var MAILTO_REGEX = "(M|m)ailto:" + COMMON_REGEX;
8
- /**
9
- * @internal
10
- */
11
- function getLinkUrl(text, autoLinkOptions) {
12
- var _a;
13
- var autoLink = autoLinkOptions.autoLink, autoMailto = autoLinkOptions.autoMailto, autoTel = autoLinkOptions.autoTel;
14
- var linkMatch = autoLink ? (_a = (0, roosterjs_content_model_api_1.matchLink)(text)) === null || _a === void 0 ? void 0 : _a.normalizedUrl : undefined;
15
- var telMatch = autoTel ? matchTel(text) : undefined;
16
- var mailtoMatch = autoMailto ? matchMailTo(text) : undefined;
17
- return linkMatch || telMatch || mailtoMatch;
18
- }
19
- exports.getLinkUrl = getLinkUrl;
20
- function matchTel(text) {
21
- return text.match(TELEPHONE_REGEX) ? text.toLocaleLowerCase() : undefined;
22
- }
23
- function matchMailTo(text) {
24
- return text.match(MAILTO_REGEX) ? text.toLocaleLowerCase() : undefined;
25
- }
26
- });
27
- //# sourceMappingURL=getLinkUrl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getLinkUrl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/link/getLinkUrl.ts"],"names":[],"mappings":";;;;IAGA,IAAM,YAAY,GAAG,sBAAwB,CAAC;IAC9C,IAAM,eAAe,GAAG,aAAW,YAAc,CAAC;IAClD,IAAM,YAAY,GAAG,gBAAc,YAAc,CAAC;IAElD;;OAEG;IACH,SAAgB,UAAU,CAAC,IAAY,EAAE,eAAgC;;QAC7D,IAAA,QAAQ,GAA0B,eAAe,SAAzC,EAAE,UAAU,GAAc,eAAe,WAA7B,EAAE,OAAO,GAAK,eAAe,QAApB,CAAqB;QAC1D,IAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAA,IAAA,uCAAS,EAAC,IAAI,CAAC,0CAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,IAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtD,IAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/D,OAAO,SAAS,IAAI,QAAQ,IAAI,WAAW,CAAC;IAChD,CAAC;IAPD,gCAOC;IAED,SAAS,QAAQ,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9E,CAAC;IAED,SAAS,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,CAAC","sourcesContent":["import { matchLink } from 'roosterjs-content-model-api';\nimport type { AutoLinkOptions } from '../interface/AutoLinkOptions';\n\nconst COMMON_REGEX = `[\\s]*[a-zA-Z0-9+][\\s]*`;\nconst TELEPHONE_REGEX = `(T|t)el:${COMMON_REGEX}`;\nconst MAILTO_REGEX = `(M|m)ailto:${COMMON_REGEX}`;\n\n/**\n * @internal\n */\nexport function getLinkUrl(text: string, autoLinkOptions: AutoLinkOptions): string | undefined {\n const { autoLink, autoMailto, autoTel } = autoLinkOptions;\n const linkMatch = autoLink ? matchLink(text)?.normalizedUrl : undefined;\n const telMatch = autoTel ? matchTel(text) : undefined;\n const mailtoMatch = autoMailto ? matchMailTo(text) : undefined;\n\n return linkMatch || telMatch || mailtoMatch;\n}\n\nfunction matchTel(text: string) {\n return text.match(TELEPHONE_REGEX) ? text.toLocaleLowerCase() : undefined;\n}\n\nfunction matchMailTo(text: string) {\n return text.match(MAILTO_REGEX) ? text.toLocaleLowerCase() : undefined;\n}\n"]}