roosterjs-content-model-plugins 9.11.2 → 9.13.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 (94) 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 +6 -1
  16. package/lib/edit/keyboardEnter.js.map +1 -1
  17. package/lib/edit/keyboardInput.js +2 -0
  18. package/lib/edit/keyboardInput.js.map +1 -1
  19. package/lib/edit/keyboardTab.js +5 -0
  20. package/lib/edit/keyboardTab.js.map +1 -1
  21. package/lib/index.d.ts +0 -1
  22. package/lib/index.js.map +1 -1
  23. package/lib-amd/autoFormat/AutoFormatPlugin.js +20 -2
  24. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  25. package/lib-amd/autoFormat/interface/AutoFormatOptions.d.ts +1 -1
  26. package/lib-amd/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  27. package/lib-amd/autoFormat/link/createLink.d.ts +1 -2
  28. package/lib-amd/autoFormat/link/createLink.js +11 -17
  29. package/lib-amd/autoFormat/link/createLink.js.map +1 -1
  30. package/lib-amd/autoFormat/numbers/transformOrdinals.js +26 -7
  31. package/lib-amd/autoFormat/numbers/transformOrdinals.js.map +1 -1
  32. package/lib-amd/edit/EditPlugin.js +5 -2
  33. package/lib-amd/edit/EditPlugin.js.map +1 -1
  34. package/lib-amd/edit/inputSteps/handleAutoLink.d.ts +5 -0
  35. package/lib-amd/edit/inputSteps/handleAutoLink.js +26 -0
  36. package/lib-amd/edit/inputSteps/handleAutoLink.js.map +1 -0
  37. package/lib-amd/edit/keyboardEnter.js +6 -2
  38. package/lib-amd/edit/keyboardEnter.js.map +1 -1
  39. package/lib-amd/edit/keyboardInput.js +2 -0
  40. package/lib-amd/edit/keyboardInput.js.map +1 -1
  41. package/lib-amd/edit/keyboardTab.js +5 -0
  42. package/lib-amd/edit/keyboardTab.js.map +1 -1
  43. package/lib-amd/index.d.ts +0 -1
  44. package/lib-amd/index.js.map +1 -1
  45. package/lib-mjs/autoFormat/AutoFormatPlugin.js +20 -3
  46. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  47. package/lib-mjs/autoFormat/interface/AutoFormatOptions.d.ts +1 -1
  48. package/lib-mjs/autoFormat/interface/AutoFormatOptions.js.map +1 -1
  49. package/lib-mjs/autoFormat/link/createLink.d.ts +1 -2
  50. package/lib-mjs/autoFormat/link/createLink.js +12 -19
  51. package/lib-mjs/autoFormat/link/createLink.js.map +1 -1
  52. package/lib-mjs/autoFormat/numbers/transformOrdinals.js +26 -7
  53. package/lib-mjs/autoFormat/numbers/transformOrdinals.js.map +1 -1
  54. package/lib-mjs/edit/EditPlugin.js +5 -2
  55. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  56. package/lib-mjs/edit/inputSteps/handleAutoLink.d.ts +5 -0
  57. package/lib-mjs/edit/inputSteps/handleAutoLink.js +21 -0
  58. package/lib-mjs/edit/inputSteps/handleAutoLink.js.map +1 -0
  59. package/lib-mjs/edit/keyboardEnter.js +6 -1
  60. package/lib-mjs/edit/keyboardEnter.js.map +1 -1
  61. package/lib-mjs/edit/keyboardInput.js +2 -0
  62. package/lib-mjs/edit/keyboardInput.js.map +1 -1
  63. package/lib-mjs/edit/keyboardTab.js +5 -0
  64. package/lib-mjs/edit/keyboardTab.js.map +1 -1
  65. package/lib-mjs/index.d.ts +0 -1
  66. package/lib-mjs/index.js.map +1 -1
  67. package/package.json +5 -5
  68. package/lib/autoFormat/interface/AutoLinkOptions.d.ts +0 -21
  69. package/lib/autoFormat/interface/AutoLinkOptions.js +0 -3
  70. package/lib/autoFormat/interface/AutoLinkOptions.js.map +0 -1
  71. package/lib/autoFormat/link/createLinkAfterSpace.d.ts +0 -6
  72. package/lib/autoFormat/link/createLinkAfterSpace.js +0 -28
  73. package/lib/autoFormat/link/createLinkAfterSpace.js.map +0 -1
  74. package/lib/autoFormat/link/getLinkUrl.d.ts +0 -5
  75. package/lib/autoFormat/link/getLinkUrl.js +0 -26
  76. package/lib/autoFormat/link/getLinkUrl.js.map +0 -1
  77. package/lib-amd/autoFormat/interface/AutoLinkOptions.d.ts +0 -21
  78. package/lib-amd/autoFormat/interface/AutoLinkOptions.js +0 -5
  79. package/lib-amd/autoFormat/interface/AutoLinkOptions.js.map +0 -1
  80. package/lib-amd/autoFormat/link/createLinkAfterSpace.d.ts +0 -6
  81. package/lib-amd/autoFormat/link/createLinkAfterSpace.js +0 -28
  82. package/lib-amd/autoFormat/link/createLinkAfterSpace.js.map +0 -1
  83. package/lib-amd/autoFormat/link/getLinkUrl.d.ts +0 -5
  84. package/lib-amd/autoFormat/link/getLinkUrl.js +0 -27
  85. package/lib-amd/autoFormat/link/getLinkUrl.js.map +0 -1
  86. package/lib-mjs/autoFormat/interface/AutoLinkOptions.d.ts +0 -21
  87. package/lib-mjs/autoFormat/interface/AutoLinkOptions.js +0 -2
  88. package/lib-mjs/autoFormat/interface/AutoLinkOptions.js.map +0 -1
  89. package/lib-mjs/autoFormat/link/createLinkAfterSpace.d.ts +0 -6
  90. package/lib-mjs/autoFormat/link/createLinkAfterSpace.js +0 -24
  91. package/lib-mjs/autoFormat/link/createLinkAfterSpace.js.map +0 -1
  92. package/lib-mjs/autoFormat/link/getLinkUrl.d.ts +0 -5
  93. package/lib-mjs/autoFormat/link/getLinkUrl.js +0 -22
  94. package/lib-mjs/autoFormat/link/getLinkUrl.js.map +0 -1
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AutoFormatPlugin = void 0;
4
4
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
5
5
  var createLink_1 = require("./link/createLink");
6
- var createLinkAfterSpace_1 = require("./link/createLinkAfterSpace");
7
6
  var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
8
7
  var keyboardListTrigger_1 = require("./list/keyboardListTrigger");
9
8
  var transformFraction_1 = require("./numbers/transformFraction");
@@ -113,11 +112,14 @@ var AutoFormatPlugin = /** @class */ (function () {
113
112
  shouldList = (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, autoBullet, autoNumbering);
114
113
  }
115
114
  if (autoLink || autoTel || autoMailto) {
116
- shouldLink = (0, createLinkAfterSpace_1.createLinkAfterSpace)(previousSegment, paragraph, context, {
115
+ shouldLink = !!(0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
117
116
  autoLink: autoLink,
118
117
  autoTel: autoTel,
119
118
  autoMailto: autoMailto,
120
119
  });
120
+ if (shouldLink) {
121
+ context.canUndoByBackspace = true;
122
+ }
121
123
  }
122
124
  if (autoHyphen) {
123
125
  shouldHyphen = (0, transformHyphen_1.transformHyphen)(previousSegment, paragraph, context);
@@ -141,6 +143,7 @@ var AutoFormatPlugin = /** @class */ (function () {
141
143
  }
142
144
  };
143
145
  AutoFormatPlugin.prototype.handleKeyDownEvent = function (editor, event) {
146
+ var _this = this;
144
147
  var rawEvent = event.rawEvent;
145
148
  if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
146
149
  switch (rawEvent.key) {
@@ -149,6 +152,20 @@ var AutoFormatPlugin = /** @class */ (function () {
149
152
  (0, unlink_1.unlink)(editor, rawEvent);
150
153
  }
151
154
  break;
155
+ case 'Tab':
156
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, _previousSegment, paragraph, _markerFormat, context) {
157
+ var _a = _this.options, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering;
158
+ var shouldList = false;
159
+ if (autoBullet || autoNumbering) {
160
+ shouldList = (0, keyboardListTrigger_1.keyboardListTrigger)(model, paragraph, context, autoBullet, autoNumbering);
161
+ context.canUndoByBackspace = shouldList;
162
+ event.rawEvent.preventDefault();
163
+ }
164
+ return shouldList;
165
+ }, {
166
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoFormat,
167
+ apiName: 'autoToggleList',
168
+ });
152
169
  }
153
170
  }
154
171
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { createLink } from './link/createLink';\nimport { createLinkAfterSpace } from './link/createLinkAfterSpace';\nimport { formatTextSegmentBeforeSelectionMarker } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\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 }\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 }\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 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n autoLink,\n autoHyphen,\n autoFraction,\n autoOrdinals,\n autoMailto,\n autoTel,\n } = this.options;\n let shouldHyphen = false;\n let shouldLink = false;\n let shouldList = false;\n let shouldFraction = false;\n let shouldOrdinals = false;\n\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering\n );\n }\n\n if (autoLink || autoTel || autoMailto) {\n shouldLink = createLinkAfterSpace(\n previousSegment,\n paragraph,\n context,\n {\n autoLink,\n autoTel,\n autoMailto,\n }\n );\n }\n\n if (autoHyphen) {\n shouldHyphen = transformHyphen(previousSegment, paragraph, context);\n }\n\n if (autoFraction) {\n shouldFraction = transformFraction(\n previousSegment,\n paragraph,\n context\n );\n }\n\n if (autoOrdinals) {\n shouldOrdinals = transformOrdinals(\n previousSegment,\n paragraph,\n context\n );\n }\n\n formatOptions.apiName = getApiName(shouldList, shouldHyphen);\n formatOptions.changeSource = getChangeSource(\n shouldList,\n shouldHyphen,\n shouldLink\n );\n\n return (\n shouldList ||\n shouldHyphen ||\n shouldLink ||\n shouldFraction ||\n shouldOrdinals\n );\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (shouldList: boolean, shouldHyphen: boolean) => {\n return shouldList ? 'autoToggleList' : shouldHyphen ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (shouldList: boolean, shouldHyphen: boolean, shouldLink: boolean) => {\n return shouldList || shouldHyphen\n ? ChangeSource.AutoFormat\n : shouldLink\n ? ChangeSource.AutoLink\n : '';\n};\n"]}
1
+ {"version":3,"file":"AutoFormatPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/AutoFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { keyboardListTrigger } from './list/keyboardListTrigger';\nimport { transformFraction } from './numbers/transformFraction';\nimport { transformHyphen } from './hyphen/transformHyphen';\nimport { transformOrdinals } from './numbers/transformOrdinals';\nimport { unlink } from './link/unlink';\nimport type { AutoFormatOptions } from './interface/AutoFormatOptions';\nimport type {\n ContentChangedEvent,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nconst DefaultOptions: Partial<AutoFormatOptions> = {\n autoBullet: false,\n autoNumbering: false,\n autoUnlink: false,\n autoLink: false,\n autoHyphen: false,\n autoFraction: false,\n autoOrdinals: false,\n};\n\n/**\n * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.\n * It can be customized with options to enable or disable auto list features.\n */\nexport class AutoFormatPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n /**\n * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:\n * - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.\n * - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.\n * - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.\n * - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.\n * - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.\n * - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.\n * - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.\n * - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.\n * - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.\n */\n constructor(private options: AutoFormatOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'AutoFormat';\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 }\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 }\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 'input':\n this.handleEditorInputEvent(this.editor, event);\n break;\n case 'keyDown':\n this.handleKeyDownEvent(this.editor, event);\n break;\n case 'contentChanged':\n this.handleContentChangedEvent(this.editor, event);\n break;\n }\n }\n }\n\n private handleEditorInputEvent(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed\n ) {\n switch (rawEvent.data) {\n case ' ':\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n };\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n const {\n autoBullet,\n autoNumbering,\n autoLink,\n autoHyphen,\n autoFraction,\n autoOrdinals,\n autoMailto,\n autoTel,\n } = this.options;\n let shouldHyphen = false;\n let shouldLink = false;\n let shouldList = false;\n let shouldFraction = false;\n let shouldOrdinals = false;\n\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering\n );\n }\n\n if (autoLink || autoTel || autoMailto) {\n shouldLink = !!promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (shouldLink) {\n context.canUndoByBackspace = true;\n }\n }\n\n if (autoHyphen) {\n shouldHyphen = transformHyphen(previousSegment, paragraph, context);\n }\n\n if (autoFraction) {\n shouldFraction = transformFraction(\n previousSegment,\n paragraph,\n context\n );\n }\n\n if (autoOrdinals) {\n shouldOrdinals = transformOrdinals(\n previousSegment,\n paragraph,\n context\n );\n }\n\n formatOptions.apiName = getApiName(shouldList, shouldHyphen);\n formatOptions.changeSource = getChangeSource(\n shouldList,\n shouldHyphen,\n shouldLink\n );\n\n return (\n shouldList ||\n shouldHyphen ||\n shouldLink ||\n shouldFraction ||\n shouldOrdinals\n );\n },\n formatOptions\n );\n\n break;\n }\n }\n }\n\n private handleKeyDownEvent(editor: IEditor, event: KeyDownEvent) {\n const rawEvent = event.rawEvent;\n if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {\n switch (rawEvent.key) {\n case 'Backspace':\n if (this.options.autoUnlink) {\n unlink(editor, rawEvent);\n }\n break;\n case 'Tab':\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, _previousSegment, paragraph, _markerFormat, context) => {\n const { autoBullet, autoNumbering } = this.options;\n let shouldList = false;\n if (autoBullet || autoNumbering) {\n shouldList = keyboardListTrigger(\n model,\n paragraph,\n context,\n autoBullet,\n autoNumbering\n );\n context.canUndoByBackspace = shouldList;\n event.rawEvent.preventDefault();\n }\n\n return shouldList;\n },\n {\n changeSource: ChangeSource.AutoFormat,\n apiName: 'autoToggleList',\n }\n );\n }\n }\n }\n\n private handleContentChangedEvent(editor: IEditor, event: ContentChangedEvent) {\n const { autoLink, autoTel, autoMailto } = this.options;\n if (event.source == 'Paste' && (autoLink || autoTel || autoMailto)) {\n createLink(editor, {\n autoLink,\n autoTel,\n autoMailto,\n });\n }\n }\n}\n\nconst getApiName = (shouldList: boolean, shouldHyphen: boolean) => {\n return shouldList ? 'autoToggleList' : shouldHyphen ? 'autoHyphen' : '';\n};\n\nconst getChangeSource = (shouldList: boolean, shouldHyphen: boolean, shouldLink: boolean) => {\n return shouldList || shouldHyphen\n ? ChangeSource.AutoFormat\n : shouldLink\n ? ChangeSource.AutoLink\n : '';\n};\n"]}
@@ -1,4 +1,4 @@
1
- import type { AutoLinkOptions } from './AutoLinkOptions';
1
+ import type { AutoLinkOptions } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * Options to customize the Content Model Auto Format Plugin
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from './AutoLinkOptions';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n}\n"]}
1
+ {"version":3,"file":"AutoFormatOptions.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/autoFormat/interface/AutoFormatOptions.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutoLinkOptions } from 'roosterjs-content-model-types';\n\n/**\n * Options to customize the Content Model Auto Format Plugin\n */\nexport interface AutoFormatOptions extends AutoLinkOptions {\n /**\n * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.\n */\n autoBullet?: boolean;\n\n /**\n * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.\n */\n autoNumbering?: boolean;\n\n /**\n * Transform -- into hyphen, if typed between two words\n */\n autoHyphen?: boolean;\n\n /**\n * Transform 1/2, 1/4, 3/4 into fraction character\n */\n autoFraction?: boolean;\n\n /**\n * Transform ordinal numbers into superscript\n */\n autoOrdinals?: boolean;\n}\n"]}
@@ -1,5 +1,4 @@
1
- import type { AutoLinkOptions } from '../interface/AutoLinkOptions';
2
- import type { IEditor } from 'roosterjs-content-model-types';
1
+ import type { IEditor, AutoLinkOptions } from 'roosterjs-content-model-types';
3
2
  /**
4
3
  * @internal
5
4
  */
@@ -3,33 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLink = void 0;
4
4
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
5
5
  var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
6
- var getLinkUrl_1 = require("./getLinkUrl");
7
6
  /**
8
7
  * @internal
9
8
  */
10
9
  function createLink(editor, autoLinkOptions) {
11
10
  var anchorNode = null;
12
11
  var links = [];
13
- (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (_model, linkSegment, _paragraph) {
14
- if (linkSegment.link) {
15
- links.push(linkSegment.link);
12
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (_model, segment, paragraph) {
13
+ var promotedSegment = null;
14
+ if (segment.link) {
15
+ links.push(segment.link);
16
16
  return true;
17
17
  }
18
- var linkUrl = undefined;
19
- if (!linkSegment.link && (linkUrl = (0, getLinkUrl_1.getLinkUrl)(linkSegment.text, autoLinkOptions))) {
20
- (0, roosterjs_content_model_dom_1.addLink)(linkSegment, {
21
- format: {
22
- href: linkUrl,
23
- underline: true,
24
- },
25
- dataset: {},
26
- });
27
- if (linkSegment.link) {
28
- links.push(linkSegment.link);
29
- }
18
+ else if ((promotedSegment = (0, roosterjs_content_model_api_1.promoteLink)(segment, paragraph, autoLinkOptions)) &&
19
+ promotedSegment.link) {
20
+ links.push(promotedSegment.link);
30
21
  return true;
31
22
  }
32
- return false;
23
+ else {
24
+ return false;
25
+ }
33
26
  }, {
34
27
  changeSource: roosterjs_content_model_dom_1.ChangeSource.AutoLink,
35
28
  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,2EAAoE;AACpE,2EAAqF;AACrF,2CAA0C;AAI1C;;GAEG;AACH,SAAgB,UAAU,CAAC,MAAe,EAAE,eAAgC;IACxE,IAAI,UAAU,GAAgB,IAAI,CAAC;IACnC,IAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,IAAA,oEAAsC,EAClC,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,IAAA,uBAAU,EAAC,WAAW,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,EAAE;YAChF,IAAA,qCAAO,EAAC,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,0CAAY,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;AArCD,gCAqCC","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,2EAA2D;AAC3D,2EAAkG;AAQlG;;GAEG;AACH,SAAgB,UAAU,CAAC,MAAe,EAAE,eAAgC;IACxE,IAAI,UAAU,GAAgB,IAAI,CAAC;IACnC,IAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,IAAA,oEAAsC,EAClC,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,IAAA,yCAAW,EAAC,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,0CAAY,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;AAlCD,gCAkCC","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"]}
@@ -10,6 +10,7 @@ var getOrdinal = function (value) {
10
10
  };
11
11
  return ORDINALS[value] || 'th';
12
12
  };
13
+ var ORDINALS = ['st', 'nd', 'rd', 'th'];
13
14
  /**
14
15
  * The two last characters of ordinal number (st, nd, rd, th)
15
16
  */
@@ -19,21 +20,39 @@ var ORDINAL_LENGTH = 2;
19
20
  */ function transformOrdinals(previousSegment, paragraph, context) {
20
21
  var _a;
21
22
  var value = (_a = previousSegment.text.split(' ').pop()) === null || _a === void 0 ? void 0 : _a.trim();
23
+ var shouldAddSuperScript = false;
22
24
  if (value) {
23
- var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
24
- var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value = 10
25
- if (numericValue && getOrdinal(numericValue) === ordinal) {
25
+ var isOrdinal = ORDINALS.indexOf(value) > -1;
26
+ if (isOrdinal) {
27
+ var index = paragraph.segments.indexOf(previousSegment);
28
+ var numberSegment = paragraph.segments[index - 1];
29
+ var numericValue = null;
30
+ if (numberSegment &&
31
+ numberSegment.segmentType == 'Text' &&
32
+ (numericValue = getNumericValue(numberSegment.text, true /* checkFullText */)) &&
33
+ getOrdinal(numericValue) === value) {
34
+ shouldAddSuperScript = true;
35
+ }
36
+ }
37
+ else {
38
+ var ordinal = value.substring(value.length - ORDINAL_LENGTH); // This value is equal st, nd, rd, th
39
+ var numericValue = getNumericValue(value); //This is the numeric part. Ex: 10th, numeric value =
40
+ if (numericValue && getOrdinal(numericValue) === ordinal) {
41
+ shouldAddSuperScript = true;
42
+ }
43
+ }
44
+ if (shouldAddSuperScript) {
26
45
  var ordinalSegment = (0, roosterjs_content_model_api_1.splitTextSegment)(previousSegment, paragraph, previousSegment.text.length - 3, previousSegment.text.length - 1);
27
46
  ordinalSegment.format.superOrSubScriptSequence = 'super';
28
47
  context.canUndoByBackspace = true;
29
- return true;
30
48
  }
31
49
  }
32
- return false;
50
+ return shouldAddSuperScript;
33
51
  }
34
52
  exports.transformOrdinals = transformOrdinals;
35
- function getNumericValue(text) {
36
- var number = text.substring(0, text.length - ORDINAL_LENGTH);
53
+ function getNumericValue(text, checkFullText) {
54
+ if (checkFullText === void 0) { checkFullText = false; }
55
+ var number = checkFullText ? text : text.substring(0, text.length - ORDINAL_LENGTH);
37
56
  var isNumber = /^-?\d+$/.test(number);
38
57
  if (isNumber) {
39
58
  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,2EAA+D;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,SAAgB,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,IAAA,8CAAgB,EACnC,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;AAvBG,8CAuBH;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,2EAA+D;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,SAAgB,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,IAAA,8CAAgB,EACnC,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;AA1CG,8CA0CH;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"]}
@@ -124,6 +124,7 @@ var EditPlugin = /** @class */ (function () {
124
124
  };
125
125
  EditPlugin.prototype.handleKeyDownEvent = function (editor, event) {
126
126
  var rawEvent = event.rawEvent;
127
+ var hasCtrlOrMetaKey = rawEvent.ctrlKey || rawEvent.metaKey;
127
128
  if (!rawEvent.defaultPrevented && !event.handledByEditFeature) {
128
129
  switch (rawEvent.key) {
129
130
  case 'Backspace':
@@ -140,7 +141,7 @@ var EditPlugin = /** @class */ (function () {
140
141
  }
141
142
  break;
142
143
  case 'Tab':
143
- if (this.options.handleTabKey) {
144
+ if (this.options.handleTabKey && !hasCtrlOrMetaKey) {
144
145
  (0, keyboardTab_1.keyboardTab)(editor, rawEvent);
145
146
  }
146
147
  break;
@@ -150,7 +151,9 @@ var EditPlugin = /** @class */ (function () {
150
151
  }
151
152
  break;
152
153
  case 'Enter':
153
- (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter);
154
+ if (!hasCtrlOrMetaKey) {
155
+ (0, keyboardEnter_1.keyboardEnter)(editor, rawEvent, this.handleNormalEnter);
156
+ }
154
157
  break;
155
158
  default:
156
159
  (0, keyboardInput_1.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,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleAutoLink = void 0;
4
+ var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
5
+ /**
6
+ * @internal
7
+ */
8
+ var handleAutoLink = function (context) {
9
+ var deleteResult = context.deleteResult, insertPoint = context.insertPoint;
10
+ if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {
11
+ var marker = insertPoint.marker, paragraph = insertPoint.paragraph;
12
+ var index = paragraph.segments.indexOf(marker);
13
+ var segBefore = index > 0 ? paragraph.segments[index - 1] : null;
14
+ if ((segBefore === null || segBefore === void 0 ? void 0 : segBefore.segmentType) == 'Text' &&
15
+ (0, roosterjs_content_model_api_1.promoteLink)(segBefore, paragraph, {
16
+ autoLink: true,
17
+ }) &&
18
+ context.formatContext) {
19
+ context.formatContext.canUndoByBackspace = true;
20
+ }
21
+ // Do not set deleteResult here since we haven't really start a new paragraph, we need other delete step to keep working on it
22
+ }
23
+ };
24
+ exports.handleAutoLink = handleAutoLink;
25
+ //# 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,2EAA0D;AAG1D;;GAEG;AACI,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,IAAA,yCAAW,EAAC,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;AApBW,QAAA,cAAc,kBAoBzB","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"]}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.keyboardEnter = void 0;
4
4
  var deleteEmptyQuote_1 = require("./deleteSteps/deleteEmptyQuote");
5
+ var handleAutoLink_1 = require("./inputSteps/handleAutoLink");
5
6
  var handleEnterOnList_1 = require("./inputSteps/handleEnterOnList");
6
7
  var handleEnterOnParagraph_1 = require("./inputSteps/handleEnterOnParagraph");
7
8
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
@@ -19,7 +20,9 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
19
20
  // For ENTER key, although we may have deleted something, since we still need to split the line, we always treat it as not delete
20
21
  // so further delete steps can keep working
21
22
  result.deleteResult = 'notDeleted';
22
- var steps = rawEvent.shiftKey ? [] : [handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
23
+ var steps = rawEvent.shiftKey
24
+ ? []
25
+ : [handleAutoLink_1.handleAutoLink, handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
23
26
  if (handleNormalEnter) {
24
27
  steps.push(handleEnterOnParagraph_1.handleEnterOnParagraph);
25
28
  }
@@ -39,6 +42,8 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
39
42
  rawEvent: rawEvent,
40
43
  scrollCaretIntoView: true,
41
44
  changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
45
+ getChangeData: function () { return rawEvent.which; },
46
+ apiName: 'handleEnterKey',
42
47
  });
43
48
  }
44
49
  exports.keyboardEnter = keyboardEnter;
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardEnter.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardEnter.ts"],"names":[],"mappings":";;;AAAA,mEAAkE;AAClE,oEAAmE;AACnE,8EAA6E;AAC7E,2EAKqC;AAGrC;;GAEG;AACH,SAAgB,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,IAAA,6CAAe,EAAC,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,qCAAiB,EAAE,mCAAgB,CAAC,CAAC;YAE7E,IAAI,iBAAiB,EAAE;gBACnB,KAAK,CAAC,IAAI,CAAC,+CAAsB,CAAC,CAAC;aACtC;YAED,IAAA,0CAAY,EAAC,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,IAAA,mDAAqB,EAAC,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,0CAAY,CAAC,QAAQ;KACtC,CACJ,CAAC;AACN,CAAC;AA7CD,sCA6CC","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,mEAAkE;AAClE,8DAA6D;AAC7D,oEAAmE;AACnE,8EAA6E;AAC7E,2EAKqC;AAGrC;;GAEG;AACH,SAAgB,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,IAAA,6CAAe,EAAC,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,+BAAc,EAAE,qCAAiB,EAAE,mCAAgB,CAAC,CAAC;YAE5D,IAAI,iBAAiB,EAAE;gBACnB,KAAK,CAAC,IAAI,CAAC,+CAAsB,CAAC,CAAC;aACtC;YAED,IAAA,0CAAY,EAAC,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,IAAA,mDAAqB,EAAC,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,0CAAY,CAAC,QAAQ;QACnC,aAAa,EAAE,cAAM,OAAA,QAAQ,CAAC,KAAK,EAAd,CAAc;QACnC,OAAO,EAAE,gBAAgB;KAC5B,CACJ,CAAC;AACN,CAAC;AAjDD,sCAiDC","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 getChangeData: () => rawEvent.which,\n apiName: 'handleEnterKey',\n }\n );\n}\n"]}
@@ -28,6 +28,8 @@ function keyboardInput(editor, rawEvent) {
28
28
  scrollCaretIntoView: true,
29
29
  rawEvent: rawEvent,
30
30
  changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
31
+ getChangeData: function () { return rawEvent.which; },
32
+ apiName: 'handleInputKey',
31
33
  });
32
34
  return true;
33
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardInput.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts"],"names":[],"mappings":";;;AAAA,2EAKqC;AAGrC;;GAEG;AACH,SAAgB,aAAa,CAAC,MAAe,EAAE,QAAuB;IAClE,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAClD,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;YACX,IAAM,MAAM,GAAG,IAAA,6CAAe,EAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAEnD,oJAAoJ;YACpJ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAEhC,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;gBAChC,2HAA2H;gBAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;gBAE7D,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;gBAE7B,sFAAsF;gBACtF,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD;YACI,mBAAmB,EAAE,IAAI;YACzB,QAAQ,UAAA;YACR,YAAY,EAAE,0CAAY,CAAC,QAAQ;SACtC,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AAlCD,sCAkCC;AAED,SAAS,2BAA2B,CAAC,SAA8B,EAAE,QAAuB;IACxF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IAAI,CAAC,IAAA,2CAAa,EAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;QAC1F,OAAO,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC;KAClE;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC","sourcesContent":["import {\n ChangeSource,\n deleteSelection,\n isModifierKey,\n normalizeContentModel,\n} from 'roosterjs-content-model-dom';\nimport type { DOMSelection, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardInput(editor: IEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (shouldInputWithContentModel(selection, rawEvent)) {\n editor.takeSnapshot();\n\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(model, [], context);\n\n // Skip undo snapshot here and add undo snapshot before the operation so that we don't add another undo snapshot in middle of this replace operation\n context.skipUndoSnapshot = true;\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 // Do not preventDefault since we still want browser to handle the final input for now\n return true;\n } else {\n return false;\n }\n },\n {\n scrollCaretIntoView: true,\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n }\n );\n\n return true;\n }\n}\n\nfunction shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (!isModifierKey(rawEvent) && (rawEvent.key == 'Space' || rawEvent.key.length == 1)) {\n return selection.type != 'range' || !selection.range.collapsed;\n } else {\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"keyboardInput.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts"],"names":[],"mappings":";;;AAAA,2EAKqC;AAGrC;;GAEG;AACH,SAAgB,aAAa,CAAC,MAAe,EAAE,QAAuB;IAClE,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAClD,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;YACX,IAAM,MAAM,GAAG,IAAA,6CAAe,EAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAEnD,oJAAoJ;YACpJ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAEhC,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;gBAChC,2HAA2H;gBAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;gBAE7D,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;gBAE7B,sFAAsF;gBACtF,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD;YACI,mBAAmB,EAAE,IAAI;YACzB,QAAQ,UAAA;YACR,YAAY,EAAE,0CAAY,CAAC,QAAQ;YACnC,aAAa,EAAE,cAAM,OAAA,QAAQ,CAAC,KAAK,EAAd,CAAc;YACnC,OAAO,EAAE,gBAAgB;SAC5B,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AApCD,sCAoCC;AAED,SAAS,2BAA2B,CAAC,SAA8B,EAAE,QAAuB;IACxF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IAAI,CAAC,IAAA,2CAAa,EAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;QAC1F,OAAO,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC;KAClE;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC","sourcesContent":["import {\n ChangeSource,\n deleteSelection,\n isModifierKey,\n normalizeContentModel,\n} from 'roosterjs-content-model-dom';\nimport type { DOMSelection, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardInput(editor: IEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (shouldInputWithContentModel(selection, rawEvent)) {\n editor.takeSnapshot();\n\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(model, [], context);\n\n // Skip undo snapshot here and add undo snapshot before the operation so that we don't add another undo snapshot in middle of this replace operation\n context.skipUndoSnapshot = true;\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 // Do not preventDefault since we still want browser to handle the final input for now\n return true;\n } else {\n return false;\n }\n },\n {\n scrollCaretIntoView: true,\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n apiName: 'handleInputKey',\n }\n );\n\n return true;\n }\n}\n\nfunction shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (!isModifierKey(rawEvent) && (rawEvent.key == 'Space' || rawEvent.key.length == 1)) {\n return selection.type != 'range' || !selection.range.collapsed;\n } else {\n return false;\n }\n}\n"]}
@@ -18,6 +18,9 @@ function keyboardTab(editor, rawEvent) {
18
18
  return handleTab(model, rawEvent, context);
19
19
  }, {
20
20
  apiName: 'handleTabKey',
21
+ rawEvent: rawEvent,
22
+ changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
23
+ getChangeData: function () { return rawEvent.which; },
21
24
  });
22
25
  return true;
23
26
  case 'table':
@@ -25,7 +28,9 @@ function keyboardTab(editor, rawEvent) {
25
28
  return (0, handleTabOnTable_1.handleTabOnTable)(model, rawEvent);
26
29
  }, {
27
30
  apiName: 'handleTabKey',
31
+ rawEvent: rawEvent,
28
32
  changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
33
+ getChangeData: function () { return rawEvent.which; },
29
34
  });
30
35
  return true;
31
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardTab.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardTab.ts"],"names":[],"mappings":";;;AAAA,8DAA6D;AAC7D,wEAAuE;AACvE,gEAA+D;AAC/D,wEAAuE;AACvE,2EAAkE;AAClE,2EAIqC;AASrC;;GAEG;AACH,SAAgB,WAAW,CAAC,MAAe,EAAE,QAAuB;IAChE,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,QAAQ,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,EAAE;QACrB,KAAK,OAAO;YACR,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;gBACX,OAAO,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC,EACD;gBACI,OAAO,EAAE,cAAc;aAC1B,CACJ,CAAC;YAEF,OAAO,IAAI,CAAC;QAChB,KAAK,OAAO;YACR,MAAM,CAAC,kBAAkB,CACrB,UAAA,KAAK;gBACD,OAAO,IAAA,mCAAgB,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC7C,CAAC,EACD;gBACI,OAAO,EAAE,cAAc;gBACvB,YAAY,EAAE,0CAAY,CAAC,QAAQ;aACtC,CACJ,CAAC;YACF,OAAO,IAAI,CAAC;KACnB;AACL,CAAC;AA3BD,kCA2BC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CACd,KAAmC,EACnC,QAAuB,EACvB,OAAkC;IAElC,IAAM,MAAM,GAAG,IAAA,kDAAoB,EAC/B,KAAK,EACL,CAAC,UAAU,EAAE,WAAW,CAAC,EACzB,EAAE,CACL,CAAC;IACF,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;QACnB,IAAA,iDAAmB,EAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrE,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;KACf;SAAM,IAAI,IAAA,gDAAkB,EAAwB,KAAK,EAAE,WAAW,CAAC,EAAE;QACtE,OAAO,IAAA,2CAAoB,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;KACvD;SAAM,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,MAAK,WAAW,EAAE;QACzC,OAAO,IAAA,2CAAoB,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;KAChE;SAAM,IAAI,IAAA,gDAAkB,EAAuB,KAAK,EAAE,UAAU,CAAC,EAAE;QACpE,OAAO,IAAA,iCAAe,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;KAC3D;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import { handleTabOnList } from './tabUtils/handleTabOnList';\nimport { handleTabOnParagraph } from './tabUtils/handleTabOnParagraph';\nimport { handleTabOnTable } from './tabUtils/handleTabOnTable';\nimport { handleTabOnTableCell } from './tabUtils/handleTabOnTableCell';\nimport { setModelIndentation } from 'roosterjs-content-model-api';\nimport {\n ChangeSource,\n getOperationalBlocks,\n isBlockGroupOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n ContentModelListItem,\n ContentModelTableCell,\n FormatContentModelContext,\n IEditor,\n ReadonlyContentModelDocument,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardTab(editor: IEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n switch (selection?.type) {\n case 'range':\n editor.formatContentModel(\n (model, context) => {\n return handleTab(model, rawEvent, context);\n },\n {\n apiName: 'handleTabKey',\n }\n );\n\n return true;\n case 'table':\n editor.formatContentModel(\n model => {\n return handleTabOnTable(model, rawEvent);\n },\n {\n apiName: 'handleTabKey',\n changeSource: ChangeSource.Keyboard,\n }\n );\n return true;\n }\n}\n\n/**\n * If multiple blocks are selected, indent or outdent the selected blocks with setModelIndentation.\n * If only one block is selected:\n * - If it is a table cell, call handleTabOnTableCell to handle the tab key.\n * - If it is a paragraph, call handleTabOnParagraph to handle the tab key.\n * - If it is a list item, call handleTabOnList to handle the tab key.\n */\nfunction handleTab(\n model: ReadonlyContentModelDocument,\n rawEvent: KeyboardEvent,\n context: FormatContentModelContext\n) {\n const blocks = getOperationalBlocks<ContentModelListItem | ContentModelTableCell>(\n model,\n ['ListItem', 'TableCell'],\n []\n );\n const block = blocks.length > 0 ? blocks[0].block : undefined;\n\n if (blocks.length > 1) {\n setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');\n rawEvent.preventDefault();\n return true;\n } else if (isBlockGroupOfType<ContentModelTableCell>(block, 'TableCell')) {\n return handleTabOnTableCell(model, block, rawEvent);\n } else if (block?.blockType === 'Paragraph') {\n return handleTabOnParagraph(model, block, rawEvent, context);\n } else if (isBlockGroupOfType<ContentModelListItem>(block, 'ListItem')) {\n return handleTabOnList(model, block, rawEvent, context);\n }\n return false;\n}\n"]}
1
+ {"version":3,"file":"keyboardTab.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/edit/keyboardTab.ts"],"names":[],"mappings":";;;AAAA,8DAA6D;AAC7D,wEAAuE;AACvE,gEAA+D;AAC/D,wEAAuE;AACvE,2EAAkE;AAClE,2EAIqC;AASrC;;GAEG;AACH,SAAgB,WAAW,CAAC,MAAe,EAAE,QAAuB;IAChE,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,QAAQ,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,EAAE;QACrB,KAAK,OAAO;YACR,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;gBACX,OAAO,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC,EACD;gBACI,OAAO,EAAE,cAAc;gBACvB,QAAQ,UAAA;gBACR,YAAY,EAAE,0CAAY,CAAC,QAAQ;gBACnC,aAAa,EAAE,cAAM,OAAA,QAAQ,CAAC,KAAK,EAAd,CAAc;aACtC,CACJ,CAAC;YAEF,OAAO,IAAI,CAAC;QAChB,KAAK,OAAO;YACR,MAAM,CAAC,kBAAkB,CACrB,UAAA,KAAK;gBACD,OAAO,IAAA,mCAAgB,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC7C,CAAC,EACD;gBACI,OAAO,EAAE,cAAc;gBACvB,QAAQ,UAAA;gBACR,YAAY,EAAE,0CAAY,CAAC,QAAQ;gBACnC,aAAa,EAAE,cAAM,OAAA,QAAQ,CAAC,KAAK,EAAd,CAAc;aACtC,CACJ,CAAC;YACF,OAAO,IAAI,CAAC;KACnB;AACL,CAAC;AAhCD,kCAgCC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CACd,KAAmC,EACnC,QAAuB,EACvB,OAAkC;IAElC,IAAM,MAAM,GAAG,IAAA,kDAAoB,EAC/B,KAAK,EACL,CAAC,UAAU,EAAE,WAAW,CAAC,EACzB,EAAE,CACL,CAAC;IACF,IAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;QACnB,IAAA,iDAAmB,EAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrE,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;KACf;SAAM,IAAI,IAAA,gDAAkB,EAAwB,KAAK,EAAE,WAAW,CAAC,EAAE;QACtE,OAAO,IAAA,2CAAoB,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;KACvD;SAAM,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,MAAK,WAAW,EAAE;QACzC,OAAO,IAAA,2CAAoB,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;KAChE;SAAM,IAAI,IAAA,gDAAkB,EAAuB,KAAK,EAAE,UAAU,CAAC,EAAE;QACpE,OAAO,IAAA,iCAAe,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;KAC3D;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import { handleTabOnList } from './tabUtils/handleTabOnList';\nimport { handleTabOnParagraph } from './tabUtils/handleTabOnParagraph';\nimport { handleTabOnTable } from './tabUtils/handleTabOnTable';\nimport { handleTabOnTableCell } from './tabUtils/handleTabOnTableCell';\nimport { setModelIndentation } from 'roosterjs-content-model-api';\nimport {\n ChangeSource,\n getOperationalBlocks,\n isBlockGroupOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n ContentModelListItem,\n ContentModelTableCell,\n FormatContentModelContext,\n IEditor,\n ReadonlyContentModelDocument,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardTab(editor: IEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n switch (selection?.type) {\n case 'range':\n editor.formatContentModel(\n (model, context) => {\n return handleTab(model, rawEvent, context);\n },\n {\n apiName: 'handleTabKey',\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n }\n );\n\n return true;\n case 'table':\n editor.formatContentModel(\n model => {\n return handleTabOnTable(model, rawEvent);\n },\n {\n apiName: 'handleTabKey',\n rawEvent,\n changeSource: ChangeSource.Keyboard,\n getChangeData: () => rawEvent.which,\n }\n );\n return true;\n }\n}\n\n/**\n * If multiple blocks are selected, indent or outdent the selected blocks with setModelIndentation.\n * If only one block is selected:\n * - If it is a table cell, call handleTabOnTableCell to handle the tab key.\n * - If it is a paragraph, call handleTabOnParagraph to handle the tab key.\n * - If it is a list item, call handleTabOnList to handle the tab key.\n */\nfunction handleTab(\n model: ReadonlyContentModelDocument,\n rawEvent: KeyboardEvent,\n context: FormatContentModelContext\n) {\n const blocks = getOperationalBlocks<ContentModelListItem | ContentModelTableCell>(\n model,\n ['ListItem', 'TableCell'],\n []\n );\n const block = blocks.length > 0 ? blocks[0].block : undefined;\n\n if (blocks.length > 1) {\n setModelIndentation(model, rawEvent.shiftKey ? 'outdent' : 'indent');\n rawEvent.preventDefault();\n return true;\n } else if (isBlockGroupOfType<ContentModelTableCell>(block, 'TableCell')) {\n return handleTabOnTableCell(model, block, rawEvent);\n } else if (block?.blockType === 'Paragraph') {\n return handleTabOnParagraph(model, block, rawEvent, context);\n } else if (isBlockGroupOfType<ContentModelListItem>(block, 'ListItem')) {\n return handleTabOnList(model, block, rawEvent, context);\n }\n return false;\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -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';
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/roosterjs-content-model-plugins/lib/index.ts"],"names":[],"mappings":";;;AAAA,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAGxB,mDAAkD;AAAzC,0GAAA,WAAW,OAAA;AACpB,+DAA8D;AAArD,sHAAA,iBAAiB,OAAA;AAC1B,gDAA4D;AAAnD,wGAAA,UAAU,OAAA;AACnB,kEAAiE;AAAxD,oHAAA,gBAAgB,OAAA;AAIzB,kDAgB8B;AAf1B,yGAAA,YAAY,OAAA;AACZ,2GAAA,cAAc,OAAA;AACd,8GAAA,iBAAiB,OAAA;AACjB,gHAAA,mBAAmB,OAAA;AACnB,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AACb,yGAAA,YAAY,OAAA;AACZ,4GAAA,eAAe,OAAA;AACf,8GAAA,iBAAiB,OAAA;AACjB,2GAAA,cAAc,OAAA;AACd,8GAAA,iBAAiB,OAAA;AACjB,iHAAA,oBAAoB,OAAA;AACpB,iHAAA,oBAAoB,OAAA;AACpB,+GAAA,kBAAkB,OAAA;AAClB,gHAAA,mBAAmB,OAAA;AAEvB,4DAA2D;AAAlD,gHAAA,cAAc,OAAA;AAEvB,iFAAoG;AAA3F,8HAAA,qBAAqB,OAAA;AAC9B,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAExB,4DAA4E;AAAnE,gHAAA,cAAc,OAAA;AACvB,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAExB,sDAAqD;AAA5C,4GAAA,YAAY,OAAA;AAGrB,2EAAyF;AAAhF,0HAAA,mBAAmB,OAAA;AAC5B,+DAA8D;AAArD,kHAAA,eAAe,OAAA","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,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAGxB,mDAAkD;AAAzC,0GAAA,WAAW,OAAA;AACpB,+DAA8D;AAArD,sHAAA,iBAAiB,OAAA;AAC1B,gDAA4D;AAAnD,wGAAA,UAAU,OAAA;AACnB,kEAAiE;AAAxD,oHAAA,gBAAgB,OAAA;AAGzB,kDAgB8B;AAf1B,yGAAA,YAAY,OAAA;AACZ,2GAAA,cAAc,OAAA;AACd,8GAAA,iBAAiB,OAAA;AACjB,gHAAA,mBAAmB,OAAA;AACnB,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AACb,yGAAA,YAAY,OAAA;AACZ,4GAAA,eAAe,OAAA;AACf,8GAAA,iBAAiB,OAAA;AACjB,2GAAA,cAAc,OAAA;AACd,8GAAA,iBAAiB,OAAA;AACjB,iHAAA,oBAAoB,OAAA;AACpB,iHAAA,oBAAoB,OAAA;AACpB,+GAAA,kBAAkB,OAAA;AAClB,gHAAA,mBAAmB,OAAA;AAEvB,4DAA2D;AAAlD,gHAAA,cAAc,OAAA;AAEvB,iFAAoG;AAA3F,8HAAA,qBAAqB,OAAA;AAC9B,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAExB,4DAA4E;AAAnE,gHAAA,cAAc,OAAA;AACvB,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAExB,sDAAqD;AAA5C,4GAAA,YAAY,OAAA;AAGrB,2EAAyF;AAAhF,0HAAA,mBAAmB,OAAA;AAC5B,+DAA8D;AAArD,kHAAA,eAAe,OAAA","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"]}