roosterjs-content-model-plugins 9.38.0 → 9.39.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 (34) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.d.ts +2 -0
  2. package/lib/autoFormat/AutoFormatPlugin.js +34 -0
  3. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  4. package/lib/tableEdit/editors/TableEditor.js +2 -2
  5. package/lib/tableEdit/editors/TableEditor.js.map +1 -1
  6. package/lib/tableEdit/editors/features/CellResizer.d.ts +2 -1
  7. package/lib/tableEdit/editors/features/CellResizer.js +17 -2
  8. package/lib/tableEdit/editors/features/CellResizer.js.map +1 -1
  9. package/lib/touch/TouchPlugin.d.ts +1 -2
  10. package/lib/touch/TouchPlugin.js +38 -57
  11. package/lib/touch/TouchPlugin.js.map +1 -1
  12. package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +2 -0
  13. package/lib-amd/autoFormat/AutoFormatPlugin.js +34 -1
  14. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  15. package/lib-amd/tableEdit/editors/TableEditor.js +2 -2
  16. package/lib-amd/tableEdit/editors/TableEditor.js.map +1 -1
  17. package/lib-amd/tableEdit/editors/features/CellResizer.d.ts +2 -1
  18. package/lib-amd/tableEdit/editors/features/CellResizer.js +17 -2
  19. package/lib-amd/tableEdit/editors/features/CellResizer.js.map +1 -1
  20. package/lib-amd/touch/TouchPlugin.d.ts +1 -2
  21. package/lib-amd/touch/TouchPlugin.js +39 -56
  22. package/lib-amd/touch/TouchPlugin.js.map +1 -1
  23. package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +2 -0
  24. package/lib-mjs/autoFormat/AutoFormatPlugin.js +34 -0
  25. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  26. package/lib-mjs/tableEdit/editors/TableEditor.js +2 -2
  27. package/lib-mjs/tableEdit/editors/TableEditor.js.map +1 -1
  28. package/lib-mjs/tableEdit/editors/features/CellResizer.d.ts +2 -1
  29. package/lib-mjs/tableEdit/editors/features/CellResizer.js +18 -3
  30. package/lib-mjs/tableEdit/editors/features/CellResizer.js.map +1 -1
  31. package/lib-mjs/touch/TouchPlugin.d.ts +1 -2
  32. package/lib-mjs/touch/TouchPlugin.js +38 -57
  33. package/lib-mjs/touch/TouchPlugin.js.map +1 -1
  34. package/package.json +5 -5
@@ -39,6 +39,8 @@ export declare class AutoFormatPlugin implements EditorPlugin {
39
39
  * called, plugin should not call to any editor method since it will result in error.
40
40
  */
41
41
  dispose(): void;
42
+ private shouldHandleInputEventExclusively;
43
+ willHandleEventExclusively(event: PluginEvent): boolean;
42
44
  /**
43
45
  * Core method for a plugin. Once an event happens in editor, editor will call this
44
46
  * method of each plugin to handle the event as long as the event is not handled
@@ -6,6 +6,7 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
6
6
  var checkAndInsertHorizontalLine_1 = require("./horizontalLine/checkAndInsertHorizontalLine");
7
7
  var createLink_1 = require("./link/createLink");
8
8
  var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
9
+ var getListTypeStyle_1 = require("./list/getListTypeStyle");
9
10
  var keyboardListTrigger_1 = require("./list/keyboardListTrigger");
10
11
  var transformFraction_1 = require("./numbers/transformFraction");
11
12
  var transformHyphen_1 = require("./hyphen/transformHyphen");
@@ -139,6 +140,39 @@ var AutoFormatPlugin = /** @class */ (function () {
139
140
  AutoFormatPlugin.prototype.dispose = function () {
140
141
  this.editor = null;
141
142
  };
143
+ AutoFormatPlugin.prototype.shouldHandleInputEventExclusively = function (editor, event) {
144
+ var _this = this;
145
+ var rawEvent = event.rawEvent;
146
+ var selection = editor.getDOMSelection();
147
+ var shouldHandle = false;
148
+ if (rawEvent.inputType === 'insertText' &&
149
+ selection &&
150
+ selection.type === 'range' &&
151
+ selection.range.collapsed &&
152
+ rawEvent.data == ' ') {
153
+ (0, roosterjs_content_model_api_1.formatTextSegmentBeforeSelectionMarker)(editor, function (model, previousSegment, paragraph) {
154
+ var _a = _this.options, autoLink = _a.autoLink, autoTel = _a.autoTel, autoMailto = _a.autoMailto, autoBullet = _a.autoBullet, autoNumbering = _a.autoNumbering;
155
+ var list = (0, getListTypeStyle_1.getListTypeStyle)(model, autoBullet, autoNumbering);
156
+ var link = (0, roosterjs_content_model_api_1.promoteLink)(previousSegment, paragraph, {
157
+ autoLink: autoLink,
158
+ autoTel: autoTel,
159
+ autoMailto: autoMailto,
160
+ });
161
+ shouldHandle = !!link || !!list;
162
+ return false;
163
+ });
164
+ }
165
+ return shouldHandle;
166
+ };
167
+ AutoFormatPlugin.prototype.willHandleEventExclusively = function (event) {
168
+ if (this.editor) {
169
+ switch (event.eventType) {
170
+ case 'input':
171
+ return this.shouldHandleInputEventExclusively(this.editor, event);
172
+ }
173
+ }
174
+ return false;
175
+ };
142
176
  /**
143
177
  * Core method for a plugin. Once an event happens in editor, editor will call this
144
178
  * method of each plugin to handle the event as long as the event is not handled
@@ -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 { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\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 ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ninterface Feature {\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n changeSource: string;\n apiName: string;\n}\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 removeListMargins: false,\n autoHorizontalLine: 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 * - removeListMargins: A boolean to remove list margins when it is automatically triggered. 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 * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. 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 autoLink: Feature = {\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n apiName: 'autoLink',\n changeSource: ChangeSource.AutoLink,\n };\n\n private tabFeatures: Feature[] = [\n {\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n apiName: 'autoToggleList',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private features: Feature[] = [\n ...this.tabFeatures,\n {\n enabled: !!this.options.autoHyphen,\n apiName: 'autoHyphen',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoFraction,\n apiName: 'autoFraction',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoOrdinals,\n apiName: 'autoOrdinal',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private enterFeatures: Feature[] = [\n {\n enabled: !!this.options.autoHorizontalLine,\n transformFunction: (model, _previousSegment, paragraph, context) =>\n checkAndInsertHorizontalLine(model, paragraph, context),\n apiName: 'autoHorizontalLine',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private handleKeyboardEvents(editor: IEditor, features: Feature[]): FormatContentModelOptions {\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let featureApplied: Feature | undefined = undefined;\n for (const feature of features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n featureApplied = feature;\n break;\n }\n }\n }\n\n if (featureApplied) {\n formatOptions.changeSource = featureApplied.changeSource;\n formatOptions.apiName = featureApplied.apiName;\n }\n\n return !!featureApplied;\n },\n formatOptions\n );\n return formatOptions;\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 this.handleKeyboardEvents(editor, this.features);\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 if (!rawEvent.shiftKey) {\n const eventHandled = this.handleKeyboardEvents(editor, this.tabFeatures);\n if (eventHandled.apiName == 'autoToggleList') {\n event.rawEvent.preventDefault();\n }\n }\n break;\n case 'Enter':\n const eventHandled = this.handleKeyboardEvents(editor, this.enterFeatures);\n if (eventHandled.apiName == 'autoHorizontalLine') {\n event.rawEvent.preventDefault();\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 createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\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 { checkAndInsertHorizontalLine } from './horizontalLine/checkAndInsertHorizontalLine';\nimport { createLink } from './link/createLink';\nimport { formatTextSegmentBeforeSelectionMarker, promoteLink } from 'roosterjs-content-model-api';\nimport { getListTypeStyle } from './list/getListTypeStyle';\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 ContentModelText,\n EditorInputEvent,\n EditorPlugin,\n FormatContentModelContext,\n FormatContentModelOptions,\n IEditor,\n KeyDownEvent,\n PluginEvent,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\ninterface Feature {\n enabled: boolean;\n transformFunction: (\n model: ReadonlyContentModelDocument,\n previousSegment: ContentModelText,\n paragraph: ShallowMutableContentModelParagraph,\n context: FormatContentModelContext\n ) => boolean | HTMLElement;\n changeSource: string;\n apiName: string;\n}\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 removeListMargins: false,\n autoHorizontalLine: 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 * - removeListMargins: A boolean to remove list margins when it is automatically triggered. 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 * - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. 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 private shouldHandleInputEventExclusively(editor: IEditor, event: EditorInputEvent) {\n const rawEvent = event.rawEvent;\n const selection = editor.getDOMSelection();\n let shouldHandle = false;\n if (\n rawEvent.inputType === 'insertText' &&\n selection &&\n selection.type === 'range' &&\n selection.range.collapsed &&\n rawEvent.data == ' '\n ) {\n formatTextSegmentBeforeSelectionMarker(editor, (model, previousSegment, paragraph) => {\n const { autoLink, autoTel, autoMailto, autoBullet, autoNumbering } = this.options;\n const list = getListTypeStyle(model, autoBullet, autoNumbering);\n const link = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n shouldHandle = !!link || !!list;\n return false;\n });\n }\n return shouldHandle;\n }\n\n willHandleEventExclusively(event: PluginEvent) {\n if (this.editor) {\n switch (event.eventType) {\n case 'input':\n return this.shouldHandleInputEventExclusively(this.editor, event);\n }\n }\n return false;\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 autoLink: Feature = {\n enabled: !!(this.options.autoLink || this.options.autoTel || this.options.autoMailto),\n transformFunction: (_model, previousSegment, paragraph, context) => {\n const { autoLink, autoTel, autoMailto } = this.options;\n const linkSegment = promoteLink(previousSegment, paragraph, {\n autoLink,\n autoTel,\n autoMailto,\n });\n\n if (linkSegment) {\n return createAnchor(linkSegment.link?.format.href || '', linkSegment.text);\n }\n return false;\n },\n apiName: 'autoLink',\n changeSource: ChangeSource.AutoLink,\n };\n\n private tabFeatures: Feature[] = [\n {\n enabled: !!(this.options.autoBullet || this.options.autoNumbering),\n transformFunction: (model, _previousSegment, paragraph, context) =>\n keyboardListTrigger(\n model,\n paragraph,\n context,\n this.options.autoBullet,\n this.options.autoNumbering,\n this.options.removeListMargins\n ),\n apiName: 'autoToggleList',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private features: Feature[] = [\n ...this.tabFeatures,\n {\n enabled: !!this.options.autoHyphen,\n apiName: 'autoHyphen',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformHyphen(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoFraction,\n apiName: 'autoFraction',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformFraction(previousSegment, paragraph, context),\n },\n {\n enabled: !!this.options.autoOrdinals,\n apiName: 'autoOrdinal',\n changeSource: ChangeSource.Format,\n transformFunction: (_model, previousSegment, paragraph, context) =>\n transformOrdinals(previousSegment, paragraph, context),\n },\n ];\n\n private enterFeatures: Feature[] = [\n {\n enabled: !!this.options.autoHorizontalLine,\n transformFunction: (model, _previousSegment, paragraph, context) =>\n checkAndInsertHorizontalLine(model, paragraph, context),\n apiName: 'autoHorizontalLine',\n changeSource: ChangeSource.AutoFormat,\n },\n this.autoLink,\n ];\n\n private handleKeyboardEvents(editor: IEditor, features: Feature[]): FormatContentModelOptions {\n const formatOptions: FormatContentModelOptions = {\n changeSource: '',\n apiName: '',\n getChangeData: undefined,\n };\n\n formatTextSegmentBeforeSelectionMarker(\n editor,\n (model, previousSegment, paragraph, _markerFormat, context) => {\n let featureApplied: Feature | undefined = undefined;\n for (const feature of features) {\n if (feature.enabled) {\n const result = feature.transformFunction(\n model,\n previousSegment,\n paragraph,\n context\n );\n if (result) {\n if (typeof result !== 'boolean') {\n formatOptions.getChangeData = () => result;\n }\n featureApplied = feature;\n break;\n }\n }\n }\n\n if (featureApplied) {\n formatOptions.changeSource = featureApplied.changeSource;\n formatOptions.apiName = featureApplied.apiName;\n }\n\n return !!featureApplied;\n },\n formatOptions\n );\n return formatOptions;\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 this.handleKeyboardEvents(editor, this.features);\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 if (!rawEvent.shiftKey) {\n const eventHandled = this.handleKeyboardEvents(editor, this.tabFeatures);\n if (eventHandled.apiName == 'autoToggleList') {\n event.rawEvent.preventDefault();\n }\n }\n break;\n case 'Enter':\n const eventHandled = this.handleKeyboardEvents(editor, this.enterFeatures);\n if (eventHandled.apiName == 'autoHorizontalLine') {\n event.rawEvent.preventDefault();\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 createAnchor = (url: string, text: string) => {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.textContent = text;\n return anchor;\n};\n"]}
@@ -268,8 +268,8 @@ var TableEditor = /** @class */ (function () {
268
268
  this.disposeCellResizers();
269
269
  }
270
270
  if (!this.horizontalResizer && td) {
271
- this.horizontalResizer = (0, CellResizer_1.createCellResizer)(this.editor, td, this.table, this.isRTL, true /*isHorizontal*/, this.onStartCellResize, this.onFinishEditing, this.anchorContainer);
272
- this.verticalResizer = (0, CellResizer_1.createCellResizer)(this.editor, td, this.table, this.isRTL, false /*isHorizontal*/, this.onStartCellResize, this.onFinishEditing, this.anchorContainer);
271
+ this.horizontalResizer = (0, CellResizer_1.createCellResizer)(this.editor, td, this.table, this.isRTL, true /*isHorizontal*/, this.onStartCellResize, this.onFinishEditing, this.anchorContainer, this.onTableEditorCreated);
272
+ this.verticalResizer = (0, CellResizer_1.createCellResizer)(this.editor, td, this.table, this.isRTL, false /*isHorizontal*/, this.onStartCellResize, this.onFinishEditing, this.anchorContainer, this.onTableEditorCreated);
273
273
  }
274
274
  };
275
275
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TableEditor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/editors/TableEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCellResizer } from './features/CellResizer';\nimport { createTableInserter } from './features/TableInserter';\nimport { createTableMover } from './features/TableMover';\nimport { createTableResizer } from './features/TableResizer';\nimport { disposeTableEditFeature } from './features/TableEditFeature';\nimport { isNodeOfType, normalizeRect, parseTableCells } from 'roosterjs-content-model-dom';\nimport type { OnTableEditorCreatedCallback } from '../OnTableEditorCreatedCallback';\nimport type { TableEditFeature } from './features/TableEditFeature';\nimport type { IEditor, TableSelection } from 'roosterjs-content-model-types';\nimport type { TableEditFeatureName } from './features/TableEditFeatureName';\n\nconst INSERTER_HOVER_OFFSET = 6;\nconst enum TOP_OR_SIDE {\n top = 0,\n side = 1,\n}\n/**\n * @internal\n *\n * A table has 6 hot areas to be resized/edited (take LTR example):\n *\n * [6] [ ]\n * +[ 1 ]+--------------------+\n * |[ ]| |\n * [ ] [ ] |\n * [ ] [ ] |\n * [2] [3] |\n * [ ] [ ] |\n * [ ][ 4 ]| |\n * +------------------+--------------------+\n * | | |\n * | | |\n * | | |\n * +------------------+--------------------+\n * [5]\n *\n * 1 - Hover area to show insert column button\n * 2 - Hover area to show insert row button\n * 3 - Hover area to show vertical resizing bar\n * 4 - Hover area to show horizontal resizing bar\n * 5 - Hover area to show whole table resize handle\n * 6 - Hover area to show whole table mover handle\n *\n * When set a different current table or change current TD, we need to update these areas\n */\nexport class TableEditor {\n // 1, 2 - Insert a column or a row\n private horizontalInserter: TableEditFeature | null = null;\n private verticalInserter: TableEditFeature | null = null;\n\n // 3, 4 - Resize a column or a row from a cell\n private horizontalResizer: TableEditFeature | null = null;\n private verticalResizer: TableEditFeature | null = null;\n\n // 5 - Resize whole table\n private tableResizer: TableEditFeature | null = null;\n\n // 6 - Move as well as select whole table\n private tableMover: TableEditFeature | null = null;\n\n private isRTL: boolean;\n private range: Range | null = null;\n private isCurrentlyEditing: boolean;\n\n constructor(\n private editor: IEditor,\n public readonly table: HTMLTableElement,\n public readonly logicalRoot: HTMLDivElement | null,\n private onChanged: () => void,\n private anchorContainer?: HTMLElement,\n private contentDiv?: EventTarget | null,\n private onTableEditorCreated?: OnTableEditorCreatedCallback,\n private disableFeatures?: TableEditFeatureName[]\n ) {\n this.isRTL = editor.getDocument().defaultView?.getComputedStyle(table).direction == 'rtl';\n this.setEditorFeatures();\n this.isCurrentlyEditing = false;\n }\n\n dispose() {\n this.disposeTableResizer();\n this.disposeCellResizers();\n this.disposeTableInserter();\n this.disposeTableMover();\n }\n\n isEditing(): boolean {\n return this.isCurrentlyEditing;\n }\n\n isOwnedElement(node: Node) {\n return [\n this.tableResizer,\n this.tableMover,\n this.horizontalInserter,\n this.verticalInserter,\n this.horizontalResizer,\n this.verticalResizer,\n ]\n .filter(feature => !!feature?.div)\n .some(feature => feature?.div == node);\n }\n\n /**\n * public only for testing purposes\n */\n public onMouseMove(x: number, y: number) {\n // Get whole table rect\n const tableRect = normalizeRect(this.table.getBoundingClientRect());\n\n if (!tableRect) {\n return;\n }\n\n // Determine if cursor is on top or side\n const topOrSide =\n y <= tableRect.top + INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.top\n : this.isRTL\n ? x >= tableRect.right - INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.side\n : undefined\n : x <= tableRect.left + INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.side\n : undefined;\n const topOrSideBinary = topOrSide ? 1 : 0;\n\n // i is row index, j is column index\n for (let i = 0; i < this.table.rows.length; i++) {\n const tr = this.table.rows[i];\n let j = 0;\n for (; j < tr.cells.length; j++) {\n const td = tr.cells[j];\n const tdRect = normalizeRect(td.getBoundingClientRect());\n\n if (!tdRect || !tableRect) {\n continue;\n }\n\n // Determine the cell the cursor is in range of\n // Offset is only used for first row and column\n const lessThanBottom = y <= tdRect.bottom;\n const lessThanRight = this.isRTL\n ? x <= tdRect.right + INSERTER_HOVER_OFFSET * topOrSideBinary\n : x <= tdRect.right;\n const moreThanLeft = this.isRTL\n ? x >= tdRect.left\n : x >= tdRect.left - INSERTER_HOVER_OFFSET * topOrSideBinary;\n\n if (lessThanBottom && lessThanRight && moreThanLeft) {\n if (i === 0 && topOrSide == TOP_OR_SIDE.top) {\n const center = (tdRect.left + tdRect.right) / 2;\n const isOnRightHalf = this.isRTL ? x < center : x > center;\n !this.isFeatureDisabled('VerticalTableInserter') &&\n this.setInserterTd(\n isOnRightHalf ? td : tr.cells[j - 1],\n false /*isHorizontal*/\n );\n } else if (j === 0 && topOrSide == TOP_OR_SIDE.side) {\n const tdAbove = this.table.rows[i - 1]?.cells[0];\n const tdAboveRect = tdAbove\n ? normalizeRect(tdAbove.getBoundingClientRect())\n : null;\n\n const isTdNotAboveMerged = !tdAboveRect\n ? null\n : this.isRTL\n ? tdAboveRect.right === tdRect.right\n : tdAboveRect.left === tdRect.left;\n\n !this.isFeatureDisabled('HorizontalTableInserter') &&\n this.setInserterTd(\n y < (tdRect.top + tdRect.bottom) / 2 && isTdNotAboveMerged\n ? tdAbove\n : td,\n true /*isHorizontal*/\n );\n } else {\n this.setInserterTd(null);\n }\n\n !this.isFeatureDisabled('CellResizer') && this.setResizingTd(td);\n\n //Cell found\n break;\n }\n }\n\n if (j < tr.cells.length) {\n break;\n }\n }\n\n // Create Mover and Resizer\n this.setEditorFeatures();\n }\n\n private setEditorFeatures() {\n const disableSelector = this.isFeatureDisabled('TableSelector');\n const disableMovement = this.isFeatureDisabled('TableMover');\n if (!this.tableMover && !(disableSelector && disableMovement)) {\n this.tableMover = createTableMover(\n this.table,\n this.editor,\n this.isRTL,\n disableSelector ? () => {} : this.onSelect,\n this.onStartTableMove,\n this.onEndTableMove,\n this.contentDiv,\n this.anchorContainer,\n this.onEditorCreated,\n disableMovement\n );\n }\n\n if (!this.tableResizer && !this.isFeatureDisabled('TableResizer')) {\n this.tableResizer = createTableResizer(\n this.table,\n this.editor,\n this.isRTL,\n this.onStartTableResize,\n this.onFinishEditing,\n this.contentDiv,\n this.anchorContainer,\n this.onTableEditorCreated\n );\n }\n }\n\n private onEditorCreated = (featureType: TableEditFeatureName, element: HTMLElement) => {\n const disposer = this.onTableEditorCreated?.(featureType, element);\n const onMouseOut = element && this.getOnMouseOut(element);\n if (onMouseOut) {\n element.addEventListener('mouseout', onMouseOut);\n }\n\n return () => {\n disposer?.();\n if (onMouseOut) {\n element.removeEventListener('mouseout', onMouseOut);\n }\n };\n };\n\n private setResizingTd(td: HTMLTableCellElement) {\n if (this.horizontalResizer && this.horizontalResizer.node != td) {\n this.disposeCellResizers();\n }\n\n if (!this.horizontalResizer && td) {\n this.horizontalResizer = createCellResizer(\n this.editor,\n td,\n this.table,\n this.isRTL,\n true /*isHorizontal*/,\n this.onStartCellResize,\n this.onFinishEditing,\n this.anchorContainer\n );\n this.verticalResizer = createCellResizer(\n this.editor,\n td,\n this.table,\n this.isRTL,\n false /*isHorizontal*/,\n this.onStartCellResize,\n this.onFinishEditing,\n this.anchorContainer\n );\n }\n }\n\n /**\n * create or remove TableInserter\n * @param td td to attach to, set this to null to remove inserters (both horizontal and vertical)\n */\n private setInserterTd(td: HTMLTableCellElement | null, isHorizontal?: boolean) {\n const inserter = isHorizontal ? this.horizontalInserter : this.verticalInserter;\n if (td === null || (inserter && inserter.node != td)) {\n this.disposeTableInserter();\n }\n\n if (!this.horizontalInserter && !this.verticalInserter && td) {\n const newInserter = createTableInserter(\n this.editor,\n td,\n this.table,\n this.isRTL,\n !!isHorizontal,\n this.onBeforeEditTable,\n this.onAfterInsert,\n this.anchorContainer,\n this.onEditorCreated\n );\n if (isHorizontal) {\n this.horizontalInserter = newInserter;\n } else {\n this.verticalInserter = newInserter;\n }\n }\n }\n\n private disposeTableResizer() {\n if (this.tableResizer) {\n disposeTableEditFeature(this.tableResizer);\n this.tableResizer = null;\n }\n }\n\n private disposeTableInserter() {\n if (this.horizontalInserter) {\n disposeTableEditFeature(this.horizontalInserter);\n this.horizontalInserter = null;\n }\n if (this.verticalInserter) {\n disposeTableEditFeature(this.verticalInserter);\n this.verticalInserter = null;\n }\n }\n\n private disposeCellResizers() {\n if (this.horizontalResizer) {\n disposeTableEditFeature(this.horizontalResizer);\n this.horizontalResizer = null;\n }\n if (this.verticalResizer) {\n disposeTableEditFeature(this.verticalResizer);\n this.verticalResizer = null;\n }\n }\n\n private disposeTableMover() {\n if (this.tableMover) {\n disposeTableEditFeature(this.tableMover);\n this.tableMover = null;\n }\n }\n\n private onFinishEditing = (): false => {\n this.editor.focus();\n\n if (this.range) {\n this.editor.setDOMSelection({ type: 'range', range: this.range, isReverted: false });\n this.range = null;\n }\n\n this.editor.takeSnapshot(); // Pass in an empty callback to make sure ContentChangedEvent is triggered\n this.onChanged();\n this.isCurrentlyEditing = false;\n\n return false;\n };\n\n private onStartTableResize = () => {\n this.isCurrentlyEditing = true;\n this.onStartResize();\n };\n\n private onStartCellResize = () => {\n this.isCurrentlyEditing = true;\n this.disposeTableResizer();\n this.onStartResize();\n };\n\n private onStartTableMove = () => {\n this.onBeforeEditTable();\n this.isCurrentlyEditing = true;\n this.disposeTableResizer();\n this.disposeTableInserter();\n this.disposeCellResizers();\n };\n\n private onStartResize() {\n this.onBeforeEditTable();\n this.isCurrentlyEditing = true;\n const range = this.editor.getDOMSelection();\n\n if (range && range.type == 'range') {\n this.range = range.range;\n }\n\n this.editor.takeSnapshot();\n }\n\n private onEndTableMove = (disposeHandler: boolean) => {\n if (disposeHandler) {\n this.disposeTableMover();\n }\n return this.onFinishEditing();\n };\n\n private onBeforeEditTable = () => {\n this.editor.setLogicalRoot(this.logicalRoot);\n };\n\n private onAfterInsert = () => {\n this.disposeTableResizer();\n this.onFinishEditing();\n };\n\n /**\n * Public only for testing purposes\n * @param table the table to select\n */\n public onSelect = (table: HTMLTableElement) => {\n this.editor.focus();\n\n if (table) {\n const parsedTable = parseTableCells(table);\n const selection: TableSelection = {\n table: table,\n firstRow: 0,\n firstColumn: 0,\n lastRow: parsedTable.length - 1,\n lastColumn: (parsedTable[0]?.length ?? 0) - 1,\n type: 'table',\n };\n\n this.editor.setDOMSelection(selection);\n }\n };\n\n private getOnMouseOut = (feature: HTMLElement) => {\n return (ev: MouseEvent) => {\n if (\n feature &&\n ev.relatedTarget != feature &&\n isNodeOfType(this.contentDiv as Node, 'ELEMENT_NODE') &&\n isNodeOfType(ev.relatedTarget as Node, 'ELEMENT_NODE') &&\n !(this.contentDiv == ev.relatedTarget) &&\n !this.isEditing()\n ) {\n this.dispose();\n }\n };\n };\n\n private isFeatureDisabled(feature: TableEditFeatureName) {\n return this.disableFeatures?.includes(feature);\n }\n}\n"]}
1
+ {"version":3,"file":"TableEditor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/editors/TableEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCellResizer } from './features/CellResizer';\nimport { createTableInserter } from './features/TableInserter';\nimport { createTableMover } from './features/TableMover';\nimport { createTableResizer } from './features/TableResizer';\nimport { disposeTableEditFeature } from './features/TableEditFeature';\nimport { isNodeOfType, normalizeRect, parseTableCells } from 'roosterjs-content-model-dom';\nimport type { OnTableEditorCreatedCallback } from '../OnTableEditorCreatedCallback';\nimport type { TableEditFeature } from './features/TableEditFeature';\nimport type { IEditor, TableSelection } from 'roosterjs-content-model-types';\nimport type { TableEditFeatureName } from './features/TableEditFeatureName';\n\nconst INSERTER_HOVER_OFFSET = 6;\nconst enum TOP_OR_SIDE {\n top = 0,\n side = 1,\n}\n/**\n * @internal\n *\n * A table has 6 hot areas to be resized/edited (take LTR example):\n *\n * [6] [ ]\n * +[ 1 ]+--------------------+\n * |[ ]| |\n * [ ] [ ] |\n * [ ] [ ] |\n * [2] [3] |\n * [ ] [ ] |\n * [ ][ 4 ]| |\n * +------------------+--------------------+\n * | | |\n * | | |\n * | | |\n * +------------------+--------------------+\n * [5]\n *\n * 1 - Hover area to show insert column button\n * 2 - Hover area to show insert row button\n * 3 - Hover area to show vertical resizing bar\n * 4 - Hover area to show horizontal resizing bar\n * 5 - Hover area to show whole table resize handle\n * 6 - Hover area to show whole table mover handle\n *\n * When set a different current table or change current TD, we need to update these areas\n */\nexport class TableEditor {\n // 1, 2 - Insert a column or a row\n private horizontalInserter: TableEditFeature | null = null;\n private verticalInserter: TableEditFeature | null = null;\n\n // 3, 4 - Resize a column or a row from a cell\n private horizontalResizer: TableEditFeature | null = null;\n private verticalResizer: TableEditFeature | null = null;\n\n // 5 - Resize whole table\n private tableResizer: TableEditFeature | null = null;\n\n // 6 - Move as well as select whole table\n private tableMover: TableEditFeature | null = null;\n\n private isRTL: boolean;\n private range: Range | null = null;\n private isCurrentlyEditing: boolean;\n\n constructor(\n private editor: IEditor,\n public readonly table: HTMLTableElement,\n public readonly logicalRoot: HTMLDivElement | null,\n private onChanged: () => void,\n private anchorContainer?: HTMLElement,\n private contentDiv?: EventTarget | null,\n private onTableEditorCreated?: OnTableEditorCreatedCallback,\n private disableFeatures?: TableEditFeatureName[]\n ) {\n this.isRTL = editor.getDocument().defaultView?.getComputedStyle(table).direction == 'rtl';\n this.setEditorFeatures();\n this.isCurrentlyEditing = false;\n }\n\n dispose() {\n this.disposeTableResizer();\n this.disposeCellResizers();\n this.disposeTableInserter();\n this.disposeTableMover();\n }\n\n isEditing(): boolean {\n return this.isCurrentlyEditing;\n }\n\n isOwnedElement(node: Node) {\n return [\n this.tableResizer,\n this.tableMover,\n this.horizontalInserter,\n this.verticalInserter,\n this.horizontalResizer,\n this.verticalResizer,\n ]\n .filter(feature => !!feature?.div)\n .some(feature => feature?.div == node);\n }\n\n /**\n * public only for testing purposes\n */\n public onMouseMove(x: number, y: number) {\n // Get whole table rect\n const tableRect = normalizeRect(this.table.getBoundingClientRect());\n\n if (!tableRect) {\n return;\n }\n\n // Determine if cursor is on top or side\n const topOrSide =\n y <= tableRect.top + INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.top\n : this.isRTL\n ? x >= tableRect.right - INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.side\n : undefined\n : x <= tableRect.left + INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.side\n : undefined;\n const topOrSideBinary = topOrSide ? 1 : 0;\n\n // i is row index, j is column index\n for (let i = 0; i < this.table.rows.length; i++) {\n const tr = this.table.rows[i];\n let j = 0;\n for (; j < tr.cells.length; j++) {\n const td = tr.cells[j];\n const tdRect = normalizeRect(td.getBoundingClientRect());\n\n if (!tdRect || !tableRect) {\n continue;\n }\n\n // Determine the cell the cursor is in range of\n // Offset is only used for first row and column\n const lessThanBottom = y <= tdRect.bottom;\n const lessThanRight = this.isRTL\n ? x <= tdRect.right + INSERTER_HOVER_OFFSET * topOrSideBinary\n : x <= tdRect.right;\n const moreThanLeft = this.isRTL\n ? x >= tdRect.left\n : x >= tdRect.left - INSERTER_HOVER_OFFSET * topOrSideBinary;\n\n if (lessThanBottom && lessThanRight && moreThanLeft) {\n if (i === 0 && topOrSide == TOP_OR_SIDE.top) {\n const center = (tdRect.left + tdRect.right) / 2;\n const isOnRightHalf = this.isRTL ? x < center : x > center;\n !this.isFeatureDisabled('VerticalTableInserter') &&\n this.setInserterTd(\n isOnRightHalf ? td : tr.cells[j - 1],\n false /*isHorizontal*/\n );\n } else if (j === 0 && topOrSide == TOP_OR_SIDE.side) {\n const tdAbove = this.table.rows[i - 1]?.cells[0];\n const tdAboveRect = tdAbove\n ? normalizeRect(tdAbove.getBoundingClientRect())\n : null;\n\n const isTdNotAboveMerged = !tdAboveRect\n ? null\n : this.isRTL\n ? tdAboveRect.right === tdRect.right\n : tdAboveRect.left === tdRect.left;\n\n !this.isFeatureDisabled('HorizontalTableInserter') &&\n this.setInserterTd(\n y < (tdRect.top + tdRect.bottom) / 2 && isTdNotAboveMerged\n ? tdAbove\n : td,\n true /*isHorizontal*/\n );\n } else {\n this.setInserterTd(null);\n }\n\n !this.isFeatureDisabled('CellResizer') && this.setResizingTd(td);\n\n //Cell found\n break;\n }\n }\n\n if (j < tr.cells.length) {\n break;\n }\n }\n\n // Create Mover and Resizer\n this.setEditorFeatures();\n }\n\n private setEditorFeatures() {\n const disableSelector = this.isFeatureDisabled('TableSelector');\n const disableMovement = this.isFeatureDisabled('TableMover');\n if (!this.tableMover && !(disableSelector && disableMovement)) {\n this.tableMover = createTableMover(\n this.table,\n this.editor,\n this.isRTL,\n disableSelector ? () => {} : this.onSelect,\n this.onStartTableMove,\n this.onEndTableMove,\n this.contentDiv,\n this.anchorContainer,\n this.onEditorCreated,\n disableMovement\n );\n }\n\n if (!this.tableResizer && !this.isFeatureDisabled('TableResizer')) {\n this.tableResizer = createTableResizer(\n this.table,\n this.editor,\n this.isRTL,\n this.onStartTableResize,\n this.onFinishEditing,\n this.contentDiv,\n this.anchorContainer,\n this.onTableEditorCreated\n );\n }\n }\n\n private onEditorCreated = (featureType: TableEditFeatureName, element: HTMLElement) => {\n const disposer = this.onTableEditorCreated?.(featureType, element);\n const onMouseOut = element && this.getOnMouseOut(element);\n if (onMouseOut) {\n element.addEventListener('mouseout', onMouseOut);\n }\n\n return () => {\n disposer?.();\n if (onMouseOut) {\n element.removeEventListener('mouseout', onMouseOut);\n }\n };\n };\n\n private setResizingTd(td: HTMLTableCellElement) {\n if (this.horizontalResizer && this.horizontalResizer.node != td) {\n this.disposeCellResizers();\n }\n\n if (!this.horizontalResizer && td) {\n this.horizontalResizer = createCellResizer(\n this.editor,\n td,\n this.table,\n this.isRTL,\n true /*isHorizontal*/,\n this.onStartCellResize,\n this.onFinishEditing,\n this.anchorContainer,\n this.onTableEditorCreated\n );\n this.verticalResizer = createCellResizer(\n this.editor,\n td,\n this.table,\n this.isRTL,\n false /*isHorizontal*/,\n this.onStartCellResize,\n this.onFinishEditing,\n this.anchorContainer,\n this.onTableEditorCreated\n );\n }\n }\n\n /**\n * create or remove TableInserter\n * @param td td to attach to, set this to null to remove inserters (both horizontal and vertical)\n */\n private setInserterTd(td: HTMLTableCellElement | null, isHorizontal?: boolean) {\n const inserter = isHorizontal ? this.horizontalInserter : this.verticalInserter;\n if (td === null || (inserter && inserter.node != td)) {\n this.disposeTableInserter();\n }\n\n if (!this.horizontalInserter && !this.verticalInserter && td) {\n const newInserter = createTableInserter(\n this.editor,\n td,\n this.table,\n this.isRTL,\n !!isHorizontal,\n this.onBeforeEditTable,\n this.onAfterInsert,\n this.anchorContainer,\n this.onEditorCreated\n );\n if (isHorizontal) {\n this.horizontalInserter = newInserter;\n } else {\n this.verticalInserter = newInserter;\n }\n }\n }\n\n private disposeTableResizer() {\n if (this.tableResizer) {\n disposeTableEditFeature(this.tableResizer);\n this.tableResizer = null;\n }\n }\n\n private disposeTableInserter() {\n if (this.horizontalInserter) {\n disposeTableEditFeature(this.horizontalInserter);\n this.horizontalInserter = null;\n }\n if (this.verticalInserter) {\n disposeTableEditFeature(this.verticalInserter);\n this.verticalInserter = null;\n }\n }\n\n private disposeCellResizers() {\n if (this.horizontalResizer) {\n disposeTableEditFeature(this.horizontalResizer);\n this.horizontalResizer = null;\n }\n if (this.verticalResizer) {\n disposeTableEditFeature(this.verticalResizer);\n this.verticalResizer = null;\n }\n }\n\n private disposeTableMover() {\n if (this.tableMover) {\n disposeTableEditFeature(this.tableMover);\n this.tableMover = null;\n }\n }\n\n private onFinishEditing = (): false => {\n this.editor.focus();\n\n if (this.range) {\n this.editor.setDOMSelection({ type: 'range', range: this.range, isReverted: false });\n this.range = null;\n }\n\n this.editor.takeSnapshot(); // Pass in an empty callback to make sure ContentChangedEvent is triggered\n this.onChanged();\n this.isCurrentlyEditing = false;\n\n return false;\n };\n\n private onStartTableResize = () => {\n this.isCurrentlyEditing = true;\n this.onStartResize();\n };\n\n private onStartCellResize = () => {\n this.isCurrentlyEditing = true;\n this.disposeTableResizer();\n this.onStartResize();\n };\n\n private onStartTableMove = () => {\n this.onBeforeEditTable();\n this.isCurrentlyEditing = true;\n this.disposeTableResizer();\n this.disposeTableInserter();\n this.disposeCellResizers();\n };\n\n private onStartResize() {\n this.onBeforeEditTable();\n this.isCurrentlyEditing = true;\n const range = this.editor.getDOMSelection();\n\n if (range && range.type == 'range') {\n this.range = range.range;\n }\n\n this.editor.takeSnapshot();\n }\n\n private onEndTableMove = (disposeHandler: boolean) => {\n if (disposeHandler) {\n this.disposeTableMover();\n }\n return this.onFinishEditing();\n };\n\n private onBeforeEditTable = () => {\n this.editor.setLogicalRoot(this.logicalRoot);\n };\n\n private onAfterInsert = () => {\n this.disposeTableResizer();\n this.onFinishEditing();\n };\n\n /**\n * Public only for testing purposes\n * @param table the table to select\n */\n public onSelect = (table: HTMLTableElement) => {\n this.editor.focus();\n\n if (table) {\n const parsedTable = parseTableCells(table);\n const selection: TableSelection = {\n table: table,\n firstRow: 0,\n firstColumn: 0,\n lastRow: parsedTable.length - 1,\n lastColumn: (parsedTable[0]?.length ?? 0) - 1,\n type: 'table',\n };\n\n this.editor.setDOMSelection(selection);\n }\n };\n\n private getOnMouseOut = (feature: HTMLElement) => {\n return (ev: MouseEvent) => {\n if (\n feature &&\n ev.relatedTarget != feature &&\n isNodeOfType(this.contentDiv as Node, 'ELEMENT_NODE') &&\n isNodeOfType(ev.relatedTarget as Node, 'ELEMENT_NODE') &&\n !(this.contentDiv == ev.relatedTarget) &&\n !this.isEditing()\n ) {\n this.dispose();\n }\n };\n };\n\n private isFeatureDisabled(feature: TableEditFeatureName) {\n return this.disableFeatures?.includes(feature);\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import type { TableEditFeature } from './TableEditFeature';
2
2
  import type { IEditor, ReadonlyContentModelTable } from 'roosterjs-content-model-types';
3
+ import type { OnTableEditorCreatedCallback } from '../../OnTableEditorCreatedCallback';
3
4
  /**
4
5
  * @internal
5
6
  */
@@ -11,7 +12,7 @@ export declare const VERTICAL_RESIZER_ID = "verticalResizer";
11
12
  /**
12
13
  * @internal
13
14
  */
14
- export declare function createCellResizer(editor: IEditor, td: HTMLTableCellElement, table: HTMLTableElement, isRTL: boolean, isHorizontal: boolean, onStart: () => void, onEnd: () => false, anchorContainer?: HTMLElement): TableEditFeature | null;
15
+ export declare function createCellResizer(editor: IEditor, td: HTMLTableCellElement, table: HTMLTableElement, isRTL: boolean, isHorizontal: boolean, onStart: () => void, onEnd: () => false, anchorContainer?: HTMLElement, onTableEditorCreated?: OnTableEditorCreatedCallback): TableEditFeature | null;
15
16
  /**
16
17
  * @internal
17
18
  * Exported for testing
@@ -18,7 +18,7 @@ exports.VERTICAL_RESIZER_ID = 'verticalResizer';
18
18
  /**
19
19
  * @internal
20
20
  */
21
- function createCellResizer(editor, td, table, isRTL, isHorizontal, onStart, onEnd, anchorContainer) {
21
+ function createCellResizer(editor, td, table, isRTL, isHorizontal, onStart, onEnd, anchorContainer, onTableEditorCreated) {
22
22
  var document = td.ownerDocument;
23
23
  var createElementData = {
24
24
  tag: 'div',
@@ -44,10 +44,25 @@ function createCellResizer(editor, td, table, isRTL, isHorizontal, onStart, onEn
44
44
  onDragging: isHorizontal ? onDraggingHorizontal : onDraggingVertical,
45
45
  onDragEnd: onEnd,
46
46
  };
47
- var featureHandler = new DragAndDropHelper_1.DragAndDropHelper(div, context, setPosition, handler, zoomScale, editor.getEnvironment().isMobileOrTablet);
47
+ var featureHandler = new CellResizer(div, context, setPosition, handler, zoomScale, editor.getEnvironment().isMobileOrTablet, onTableEditorCreated);
48
48
  return { node: td, div: div, featureHandler: featureHandler };
49
49
  }
50
50
  exports.createCellResizer = createCellResizer;
51
+ var CellResizer = /** @class */ (function (_super) {
52
+ (0, tslib_1.__extends)(CellResizer, _super);
53
+ function CellResizer(trigger, context, onSubmit, handler, zoomScale, forceMobile, onTableEditorCreated) {
54
+ var _this = _super.call(this, trigger, context, onSubmit, handler, zoomScale, forceMobile) || this;
55
+ _this.disposer = onTableEditorCreated === null || onTableEditorCreated === void 0 ? void 0 : onTableEditorCreated('CellResizer', trigger);
56
+ return _this;
57
+ }
58
+ CellResizer.prototype.dispose = function () {
59
+ var _a;
60
+ (_a = this.disposer) === null || _a === void 0 ? void 0 : _a.call(this);
61
+ this.disposer = undefined;
62
+ _super.prototype.dispose.call(this);
63
+ };
64
+ return CellResizer;
65
+ }(DragAndDropHelper_1.DragAndDropHelper));
51
66
  /**
52
67
  * @internal
53
68
  * Exported for testing
@@ -1 +1 @@
1
- {"version":3,"file":"CellResizer.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/CellResizer.ts"],"names":[],"mappings":"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","sourcesContent":["import { createElement } from '../../../pluginUtils/CreateElement/createElement';\nimport { DragAndDropHelper } from '../../../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport { getCMTableFromTable } from '../utils/getTableFromContentModel';\nimport type { TableEditFeature } from './TableEditFeature';\nimport {\n isElementOfType,\n normalizeRect,\n MIN_ALLOWED_TABLE_CELL_WIDTH,\n mutateBlock,\n MIN_ALLOWED_TABLE_CELL_HEIGHT,\n parseValueWithUnit,\n} from 'roosterjs-content-model-dom';\nimport type { DragAndDropHandler } from '../../../pluginUtils/DragAndDrop/DragAndDropHandler';\nimport type { IEditor, ReadonlyContentModelTable } from 'roosterjs-content-model-types';\n\nconst CELL_RESIZER_WIDTH = 4;\n/**\n * @internal\n */\nexport const HORIZONTAL_RESIZER_ID = 'horizontalResizer';\n/**\n * @internal\n */\nexport const VERTICAL_RESIZER_ID = 'verticalResizer';\n\n/**\n * @internal\n */\nexport function createCellResizer(\n editor: IEditor,\n td: HTMLTableCellElement,\n table: HTMLTableElement,\n isRTL: boolean,\n isHorizontal: boolean,\n onStart: () => void,\n onEnd: () => false,\n anchorContainer?: HTMLElement\n): TableEditFeature | null {\n const document = td.ownerDocument;\n const createElementData = {\n tag: 'div',\n style: `position: fixed; cursor: ${isHorizontal ? 'row' : 'col'}-resize; user-select: none`,\n };\n const zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n const div = createElement(createElementData, document) as HTMLDivElement;\n\n (anchorContainer || document.body).appendChild(div);\n\n const context: CellResizerContext = {\n editor,\n td,\n table,\n isRTL,\n zoomScale,\n onStart,\n originalWidth: parseValueWithUnit(table.style.width),\n };\n const setPosition = isHorizontal ? setHorizontalPosition : setVerticalPosition;\n setPosition(context, div);\n\n const handler: DragAndDropHandler<CellResizerContext, CellResizerInitValue> = {\n onDragStart,\n // Horizontal modifies row height, vertical modifies column width\n onDragging: isHorizontal ? onDraggingHorizontal : onDraggingVertical,\n onDragEnd: onEnd,\n };\n\n const featureHandler = new DragAndDropHelper<CellResizerContext, CellResizerInitValue>(\n div,\n context,\n setPosition,\n handler,\n zoomScale,\n editor.getEnvironment().isMobileOrTablet\n );\n\n return { node: td, div, featureHandler };\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface CellResizerContext {\n editor: IEditor;\n td: HTMLTableCellElement;\n table: HTMLTableElement;\n isRTL: boolean;\n zoomScale: number;\n originalWidth: number;\n onStart: () => void;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface CellResizerInitValue {\n cmTable: ReadonlyContentModelTable | undefined;\n anchorColumn: number | undefined;\n anchorRow: number | undefined;\n anchorRowHeight: number;\n allWidths: number[];\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragStart(context: CellResizerContext, event: MouseEvent): CellResizerInitValue {\n const { td, onStart } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n\n // Get cell coordinates\n const columnIndex = td.cellIndex;\n const row =\n td.parentElement && isElementOfType(td.parentElement, 'tr') ? td.parentElement : undefined;\n const rowIndex = row?.rowIndex;\n\n if (rowIndex == undefined) {\n return {\n cmTable: undefined,\n anchorColumn: undefined,\n anchorRow: undefined,\n anchorRowHeight: -1,\n allWidths: [],\n }; // Just a fallback\n }\n\n const { editor, table } = context;\n\n // Get Table block in content model\n const cmTable = getCMTableFromTable(editor, table);\n\n if (rect && cmTable) {\n onStart();\n\n return {\n cmTable,\n anchorColumn: columnIndex,\n anchorRow: rowIndex,\n anchorRowHeight: cmTable.rows[rowIndex].height,\n allWidths: [...cmTable.widths],\n };\n } else {\n return {\n cmTable,\n anchorColumn: undefined,\n anchorRow: undefined,\n anchorRowHeight: -1,\n allWidths: [],\n }; // Just a fallback\n }\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDraggingHorizontal(\n context: CellResizerContext,\n event: MouseEvent,\n initValue: CellResizerInitValue,\n deltaX: number,\n deltaY: number\n) {\n const { table } = context;\n const { cmTable, anchorRow, anchorRowHeight } = initValue;\n\n // Assign new widths and heights to the CM table\n if (cmTable && anchorRow != undefined && cmTable.rows[anchorRow] != undefined) {\n // Modify the CM Table size\n mutateBlock(cmTable).rows[anchorRow].height = (anchorRowHeight ?? 0) + deltaY;\n\n // Normalize the new height value\n const newHeight = Math.max(cmTable.rows[anchorRow].height, MIN_ALLOWED_TABLE_CELL_HEIGHT);\n\n // Writeback CM Table size changes to DOM Table\n const tableRow = table.rows[anchorRow];\n for (let col = 0; col < tableRow.cells.length; col++) {\n const td = tableRow.cells[col];\n td.style.height = newHeight + 'px';\n td.style.boxSizing = 'border-box';\n }\n\n return true;\n } else {\n return false;\n }\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDraggingVertical(\n context: CellResizerContext,\n event: MouseEvent,\n initValue: CellResizerInitValue,\n deltaX: number\n) {\n const { table, isRTL } = context;\n const { cmTable, anchorColumn, allWidths } = initValue;\n\n // Assign new widths and heights to the CM table\n if (cmTable && anchorColumn != undefined) {\n const mutableTable = mutateBlock(cmTable);\n\n // Modify the CM Table size\n const lastColumn = anchorColumn == cmTable.widths.length - 1;\n const change = deltaX * (isRTL ? -1 : 1);\n // This is the last column\n if (lastColumn) {\n // Only the last column changes\n // Normalize the new width value\n const newWidth = Math.max(\n allWidths[anchorColumn] + change,\n MIN_ALLOWED_TABLE_CELL_WIDTH\n );\n mutableTable.widths[anchorColumn] = newWidth;\n } else {\n // Any other two columns\n const anchorChange = allWidths[anchorColumn] + change;\n const nextAnchorChange = allWidths[anchorColumn + 1] - change;\n if (\n anchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH ||\n nextAnchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH\n ) {\n return false;\n }\n mutableTable.widths[anchorColumn] = anchorChange;\n mutableTable.widths[anchorColumn + 1] = nextAnchorChange;\n }\n\n // Writeback CM Table size changes to DOM Table\n for (let row = 0; row < table.rows.length; row++) {\n const tableRow = table.rows[row];\n for (let col = 0; col < tableRow.cells.length; col++) {\n const td = tableRow.cells[col];\n\n td.style.width = cmTable.widths[col] + 'px';\n td.style.boxSizing = 'border-box';\n }\n }\n\n if (context.originalWidth > 0) {\n const newWidth = context.originalWidth + change + 'px';\n\n mutableTable.format.width = newWidth;\n table.style.width = newWidth;\n }\n\n return true;\n } else {\n return false;\n }\n}\n\nfunction setHorizontalPosition(context: CellResizerContext, trigger: HTMLElement) {\n const { td } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n if (rect) {\n trigger.id = HORIZONTAL_RESIZER_ID;\n trigger.style.top = rect.bottom - CELL_RESIZER_WIDTH + 'px';\n trigger.style.left = rect.left + 'px';\n trigger.style.width = rect.right - rect.left + 'px';\n trigger.style.height = CELL_RESIZER_WIDTH + 'px';\n }\n}\n\nfunction setVerticalPosition(context: CellResizerContext, trigger: HTMLElement) {\n const { td, isRTL } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n if (rect) {\n trigger.id = VERTICAL_RESIZER_ID;\n trigger.style.top = rect.top + 'px';\n trigger.style.left = (isRTL ? rect.left : rect.right) - CELL_RESIZER_WIDTH + 1 + 'px';\n trigger.style.width = CELL_RESIZER_WIDTH + 'px';\n trigger.style.height = rect.bottom - rect.top + 'px';\n }\n}\n"]}
1
+ {"version":3,"file":"CellResizer.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-plugins/lib/tableEdit/editors/features/CellResizer.ts"],"names":[],"mappings":"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","sourcesContent":["import { createElement } from '../../../pluginUtils/CreateElement/createElement';\nimport { DragAndDropHelper } from '../../../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport { getCMTableFromTable } from '../utils/getTableFromContentModel';\nimport type { TableEditFeature } from './TableEditFeature';\nimport {\n isElementOfType,\n normalizeRect,\n MIN_ALLOWED_TABLE_CELL_WIDTH,\n mutateBlock,\n MIN_ALLOWED_TABLE_CELL_HEIGHT,\n parseValueWithUnit,\n} from 'roosterjs-content-model-dom';\nimport type { DragAndDropHandler } from '../../../pluginUtils/DragAndDrop/DragAndDropHandler';\nimport type { IEditor, ReadonlyContentModelTable } from 'roosterjs-content-model-types';\nimport type { OnTableEditorCreatedCallback } from '../../OnTableEditorCreatedCallback';\n\nconst CELL_RESIZER_WIDTH = 4;\n/**\n * @internal\n */\nexport const HORIZONTAL_RESIZER_ID = 'horizontalResizer';\n/**\n * @internal\n */\nexport const VERTICAL_RESIZER_ID = 'verticalResizer';\n\n/**\n * @internal\n */\nexport function createCellResizer(\n editor: IEditor,\n td: HTMLTableCellElement,\n table: HTMLTableElement,\n isRTL: boolean,\n isHorizontal: boolean,\n onStart: () => void,\n onEnd: () => false,\n anchorContainer?: HTMLElement,\n onTableEditorCreated?: OnTableEditorCreatedCallback\n): TableEditFeature | null {\n const document = td.ownerDocument;\n const createElementData = {\n tag: 'div',\n style: `position: fixed; cursor: ${isHorizontal ? 'row' : 'col'}-resize; user-select: none`,\n };\n const zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n const div = createElement(createElementData, document) as HTMLDivElement;\n\n (anchorContainer || document.body).appendChild(div);\n\n const context: CellResizerContext = {\n editor,\n td,\n table,\n isRTL,\n zoomScale,\n onStart,\n originalWidth: parseValueWithUnit(table.style.width),\n };\n const setPosition = isHorizontal ? setHorizontalPosition : setVerticalPosition;\n setPosition(context, div);\n\n const handler: DragAndDropHandler<CellResizerContext, CellResizerInitValue> = {\n onDragStart,\n // Horizontal modifies row height, vertical modifies column width\n onDragging: isHorizontal ? onDraggingHorizontal : onDraggingVertical,\n onDragEnd: onEnd,\n };\n\n const featureHandler = new CellResizer(\n div,\n context,\n setPosition,\n handler,\n zoomScale,\n editor.getEnvironment().isMobileOrTablet,\n onTableEditorCreated\n );\n\n return { node: td, div, featureHandler };\n}\n\nclass CellResizer extends DragAndDropHelper<CellResizerContext, CellResizerInitValue> {\n private disposer: undefined | (() => void);\n\n constructor(\n trigger: HTMLElement,\n context: CellResizerContext,\n onSubmit: (context: CellResizerContext, trigger: HTMLElement) => void,\n handler: DragAndDropHandler<CellResizerContext, CellResizerInitValue>,\n zoomScale: number,\n forceMobile?: boolean,\n onTableEditorCreated?: OnTableEditorCreatedCallback\n ) {\n super(trigger, context, onSubmit, handler, zoomScale, forceMobile);\n this.disposer = onTableEditorCreated?.('CellResizer', trigger);\n }\n\n dispose(): void {\n this.disposer?.();\n this.disposer = undefined;\n super.dispose();\n }\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface CellResizerContext {\n editor: IEditor;\n td: HTMLTableCellElement;\n table: HTMLTableElement;\n isRTL: boolean;\n zoomScale: number;\n originalWidth: number;\n onStart: () => void;\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport interface CellResizerInitValue {\n cmTable: ReadonlyContentModelTable | undefined;\n anchorColumn: number | undefined;\n anchorRow: number | undefined;\n anchorRowHeight: number;\n allWidths: number[];\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDragStart(context: CellResizerContext, event: MouseEvent): CellResizerInitValue {\n const { td, onStart } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n\n // Get cell coordinates\n const columnIndex = td.cellIndex;\n const row =\n td.parentElement && isElementOfType(td.parentElement, 'tr') ? td.parentElement : undefined;\n const rowIndex = row?.rowIndex;\n\n if (rowIndex == undefined) {\n return {\n cmTable: undefined,\n anchorColumn: undefined,\n anchorRow: undefined,\n anchorRowHeight: -1,\n allWidths: [],\n }; // Just a fallback\n }\n\n const { editor, table } = context;\n\n // Get Table block in content model\n const cmTable = getCMTableFromTable(editor, table);\n\n if (rect && cmTable) {\n onStart();\n\n return {\n cmTable,\n anchorColumn: columnIndex,\n anchorRow: rowIndex,\n anchorRowHeight: cmTable.rows[rowIndex].height,\n allWidths: [...cmTable.widths],\n };\n } else {\n return {\n cmTable,\n anchorColumn: undefined,\n anchorRow: undefined,\n anchorRowHeight: -1,\n allWidths: [],\n }; // Just a fallback\n }\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDraggingHorizontal(\n context: CellResizerContext,\n event: MouseEvent,\n initValue: CellResizerInitValue,\n deltaX: number,\n deltaY: number\n) {\n const { table } = context;\n const { cmTable, anchorRow, anchorRowHeight } = initValue;\n\n // Assign new widths and heights to the CM table\n if (cmTable && anchorRow != undefined && cmTable.rows[anchorRow] != undefined) {\n // Modify the CM Table size\n mutateBlock(cmTable).rows[anchorRow].height = (anchorRowHeight ?? 0) + deltaY;\n\n // Normalize the new height value\n const newHeight = Math.max(cmTable.rows[anchorRow].height, MIN_ALLOWED_TABLE_CELL_HEIGHT);\n\n // Writeback CM Table size changes to DOM Table\n const tableRow = table.rows[anchorRow];\n for (let col = 0; col < tableRow.cells.length; col++) {\n const td = tableRow.cells[col];\n td.style.height = newHeight + 'px';\n td.style.boxSizing = 'border-box';\n }\n\n return true;\n } else {\n return false;\n }\n}\n\n/**\n * @internal\n * Exported for testing\n */\nexport function onDraggingVertical(\n context: CellResizerContext,\n event: MouseEvent,\n initValue: CellResizerInitValue,\n deltaX: number\n) {\n const { table, isRTL } = context;\n const { cmTable, anchorColumn, allWidths } = initValue;\n\n // Assign new widths and heights to the CM table\n if (cmTable && anchorColumn != undefined) {\n const mutableTable = mutateBlock(cmTable);\n\n // Modify the CM Table size\n const lastColumn = anchorColumn == cmTable.widths.length - 1;\n const change = deltaX * (isRTL ? -1 : 1);\n // This is the last column\n if (lastColumn) {\n // Only the last column changes\n // Normalize the new width value\n const newWidth = Math.max(\n allWidths[anchorColumn] + change,\n MIN_ALLOWED_TABLE_CELL_WIDTH\n );\n mutableTable.widths[anchorColumn] = newWidth;\n } else {\n // Any other two columns\n const anchorChange = allWidths[anchorColumn] + change;\n const nextAnchorChange = allWidths[anchorColumn + 1] - change;\n if (\n anchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH ||\n nextAnchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH\n ) {\n return false;\n }\n mutableTable.widths[anchorColumn] = anchorChange;\n mutableTable.widths[anchorColumn + 1] = nextAnchorChange;\n }\n\n // Writeback CM Table size changes to DOM Table\n for (let row = 0; row < table.rows.length; row++) {\n const tableRow = table.rows[row];\n for (let col = 0; col < tableRow.cells.length; col++) {\n const td = tableRow.cells[col];\n\n td.style.width = cmTable.widths[col] + 'px';\n td.style.boxSizing = 'border-box';\n }\n }\n\n if (context.originalWidth > 0) {\n const newWidth = context.originalWidth + change + 'px';\n\n mutableTable.format.width = newWidth;\n table.style.width = newWidth;\n }\n\n return true;\n } else {\n return false;\n }\n}\n\nfunction setHorizontalPosition(context: CellResizerContext, trigger: HTMLElement) {\n const { td } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n if (rect) {\n trigger.id = HORIZONTAL_RESIZER_ID;\n trigger.style.top = rect.bottom - CELL_RESIZER_WIDTH + 'px';\n trigger.style.left = rect.left + 'px';\n trigger.style.width = rect.right - rect.left + 'px';\n trigger.style.height = CELL_RESIZER_WIDTH + 'px';\n }\n}\n\nfunction setVerticalPosition(context: CellResizerContext, trigger: HTMLElement) {\n const { td, isRTL } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n if (rect) {\n trigger.id = VERTICAL_RESIZER_ID;\n trigger.style.top = rect.top + 'px';\n trigger.style.left = (isRTL ? rect.left : rect.right) - CELL_RESIZER_WIDTH + 1 + 'px';\n trigger.style.width = CELL_RESIZER_WIDTH + 'px';\n trigger.style.height = rect.bottom - rect.top + 'px';\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { EditorPlugin, IEditor, PluginEvent, ReadonlyContentModelDocument } from 'roosterjs-content-model-types';
1
+ import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * Touch plugin to manage touch behaviors
4
4
  */
@@ -29,5 +29,4 @@ export declare class TouchPlugin implements EditorPlugin {
29
29
  * @param event PluginEvent object
30
30
  */
31
31
  onPluginEvent(event: PluginEvent): void;
32
- repositionTouchSelection: (model: ReadonlyContentModelDocument) => boolean;
33
32
  }
@@ -2,14 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TouchPlugin = void 0;
4
4
  var getNodePositionFromEvent_1 = require("../utils/getNodePositionFromEvent");
5
- var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
6
- var roosterjs_content_model_api_1 = require("roosterjs-content-model-api");
7
5
  var MAX_TOUCH_MOVE_DISTANCE = 6; // the max number of offsets for the touch selection to move
8
6
  var POINTER_DETECTION_DELAY = 150; // Delay time to wait for selection to be updated and also detect if pointerup is a tap or part of double tap
9
7
  var PUNCTUATION_MATCHING_REGEX = /[.,;:!]/;
10
8
  var SPACE_MATCHING_REGEX = /\s/;
11
- var CARET_CSS_RULE = 'caret-color: transparent';
12
- var HIDE_CURSOR_CSS_KEY = '_DOMSelectionHideCursor';
13
9
  /**
14
10
  * Touch plugin to manage touch behaviors
15
11
  */
@@ -22,55 +18,6 @@ var TouchPlugin = /** @class */ (function () {
22
18
  this.timer = 0;
23
19
  this.isDblClicked = false;
24
20
  this.isTouchPenPointerEvent = false;
25
- this.repositionTouchSelection = function (model) {
26
- var _a, _b;
27
- var segmentAndParagraphs = (0, roosterjs_content_model_dom_1.getSelectedSegmentsAndParagraphs)(model, false /*includingFormatHolder*/, true /*includingEntity*/, true /*mutate*/);
28
- var isCollapsedSelection = segmentAndParagraphs.length >= 1 &&
29
- segmentAndParagraphs.every(function (x) { return x[0].segmentType == 'SelectionMarker'; });
30
- // 1. adjust selection to a word if selection is collapsed
31
- if (isCollapsedSelection) {
32
- var para = segmentAndParagraphs[0][1];
33
- var segments = (0, roosterjs_content_model_api_1.adjustWordSelection)(model, segmentAndParagraphs[0][0]);
34
- if (segments.length > 2 &&
35
- segments.some(function (x) { return x.segmentType == 'Text' && !x.isSelected; }) &&
36
- para) {
37
- var selectionMarkerIndexInWord = segments.findIndex(function (segment) { return segment.segmentType == 'SelectionMarker'; });
38
- var selectionMarkerIndexInPara = para.segments.findIndex(function (segment) { return segment.segmentType == 'SelectionMarker'; });
39
- var leftSelectionSegmentsInWord_1 = segments[selectionMarkerIndexInWord - 1];
40
- var rightSelectionSegmentsInWord_1 = segments[selectionMarkerIndexInWord + 1];
41
- var leftCursorWordLength = leftSelectionSegmentsInWord_1.segmentType == 'Text'
42
- ? leftSelectionSegmentsInWord_1.text.length
43
- : 0;
44
- var rightCursorWordLength = rightSelectionSegmentsInWord_1.segmentType == 'Text'
45
- ? rightSelectionSegmentsInWord_1.text.length
46
- : 0;
47
- // Move the cursor to the closest edge of the word if the distance is within threshold = 6
48
- if (rightCursorWordLength > leftCursorWordLength) {
49
- if (leftCursorWordLength < MAX_TOUCH_MOVE_DISTANCE) {
50
- // Move cursor to beginning of word
51
- // Remove old marker
52
- (0, roosterjs_content_model_dom_1.mutateBlock)(para).segments.splice(selectionMarkerIndexInPara, 1);
53
- // Add new marker
54
- var indexSegmentBeforeMarker = para.segments.findIndex(function (segment) { return segment === leftSelectionSegmentsInWord_1; });
55
- var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_a = segments[selectionMarkerIndexInPara]) === null || _a === void 0 ? void 0 : _a.format) || para.format);
56
- (0, roosterjs_content_model_dom_1.mutateBlock)(para).segments.splice(indexSegmentBeforeMarker, 0, marker);
57
- }
58
- }
59
- else {
60
- // Move cursor to end of word
61
- if (rightCursorWordLength < MAX_TOUCH_MOVE_DISTANCE) {
62
- // Add new marker
63
- var indexSegmentAfterMarker = para.segments.findIndex(function (segment) { return segment === rightSelectionSegmentsInWord_1; });
64
- var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_b = segments[selectionMarkerIndexInPara]) === null || _b === void 0 ? void 0 : _b.format) || para.format);
65
- (0, roosterjs_content_model_dom_1.mutateBlock)(para).segments.splice(indexSegmentAfterMarker + 1, 0, marker);
66
- // Remove old marker
67
- (0, roosterjs_content_model_dom_1.mutateBlock)(para).segments.splice(selectionMarkerIndexInPara, 1);
68
- }
69
- }
70
- }
71
- }
72
- return true;
73
- };
74
21
  }
75
22
  /**
76
23
  * Get a friendly name of this plugin
@@ -111,7 +58,7 @@ var TouchPlugin = /** @class */ (function () {
111
58
  case 'pointerDown':
112
59
  this.isDblClicked = false;
113
60
  this.isTouchPenPointerEvent = true;
114
- this.editor.setEditorStyle(HIDE_CURSOR_CSS_KEY, CARET_CSS_RULE);
61
+ event.originalEvent.preventDefault();
115
62
  var targetWindow = ((_a = this.editor.getDocument()) === null || _a === void 0 ? void 0 : _a.defaultView) || window;
116
63
  if (this.timer) {
117
64
  targetWindow.clearTimeout(this.timer);
@@ -120,13 +67,47 @@ var TouchPlugin = /** @class */ (function () {
120
67
  _this.timer = 0;
121
68
  if (_this.editor) {
122
69
  if (!_this.isDblClicked) {
123
- _this.editor.formatContentModel(function (model) {
124
- return _this.repositionTouchSelection(model);
70
+ _this.editor.focus();
71
+ var caretPosition = (0, getNodePositionFromEvent_1.getNodePositionFromEvent)(_this.editor, event.rawEvent.x, event.rawEvent.y);
72
+ var newRange = _this.editor.getDocument().createRange();
73
+ if (caretPosition) {
74
+ var node = caretPosition.node, offset = caretPosition.offset;
75
+ // Place cursor at same position of browser handler by default
76
+ newRange.setStart(node, offset);
77
+ newRange.setEnd(node, offset);
78
+ var nodeTextContent = node.textContent || '';
79
+ var charAtSelection = nodeTextContent[offset];
80
+ if (node.nodeType === Node.TEXT_NODE &&
81
+ charAtSelection &&
82
+ !SPACE_MATCHING_REGEX.test(charAtSelection) &&
83
+ !PUNCTUATION_MATCHING_REGEX.test(charAtSelection)) {
84
+ var _a = findWordBoundaries(nodeTextContent, offset), wordStart = _a.wordStart, wordEnd = _a.wordEnd;
85
+ // Move cursor to the calculated offset
86
+ var leftCursorWordLength = offset - wordStart;
87
+ var rightCursorWordLength = wordEnd - offset;
88
+ var movingOffset = leftCursorWordLength >= rightCursorWordLength
89
+ ? rightCursorWordLength
90
+ : -leftCursorWordLength;
91
+ movingOffset =
92
+ Math.abs(movingOffset) > MAX_TOUCH_MOVE_DISTANCE
93
+ ? 0
94
+ : movingOffset;
95
+ var newOffsetPosition = offset + movingOffset;
96
+ if (movingOffset !== 0 &&
97
+ nodeTextContent.length >= newOffsetPosition) {
98
+ newRange.setStart(node, newOffsetPosition);
99
+ newRange.setEnd(node, newOffsetPosition);
100
+ }
101
+ }
102
+ }
103
+ _this.editor.setDOMSelection({
104
+ type: 'range',
105
+ range: newRange,
106
+ isReverted: false,
125
107
  });
126
108
  // reset values
127
109
  _this.isTouchPenPointerEvent = false;
128
110
  }
129
- _this.editor.setEditorStyle(HIDE_CURSOR_CSS_KEY, null);
130
111
  }
131
112
  }, POINTER_DETECTION_DELAY);
132
113
  break;