roosterjs-content-model-plugins 9.27.0 → 9.29.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/edit/EditPlugin.js +2 -0
- package/lib/edit/EditPlugin.js.map +1 -1
- package/lib/edit/inputSteps/handleEnterOnList.js +1 -0
- package/lib/edit/inputSteps/handleEnterOnList.js.map +1 -1
- package/lib/edit/keyboardEnter.js +7 -3
- package/lib/edit/keyboardEnter.js.map +1 -1
- package/lib/edit/tabUtils/handleTabOnParagraph.d.ts +1 -1
- package/lib/edit/tabUtils/handleTabOnParagraph.js +8 -3
- package/lib/edit/tabUtils/handleTabOnParagraph.js.map +1 -1
- package/lib/edit/utils/splitParagraph.d.ts +2 -2
- package/lib/edit/utils/splitParagraph.js +8 -43
- package/lib/edit/utils/splitParagraph.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js.map +1 -1
- package/lib/paste/PastePlugin.js +4 -1
- package/lib/paste/PastePlugin.js.map +1 -1
- package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js +1 -5
- package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
- package/lib/paste/WordDesktop/getStyleMetadata.js +25 -14
- package/lib/paste/WordDesktop/getStyleMetadata.js.map +1 -1
- package/lib/paste/WordDesktop/processWordLists.js +52 -4
- package/lib/paste/WordDesktop/processWordLists.js.map +1 -1
- package/lib/paste/pasteSourceValidations/getPasteSource.d.ts +3 -2
- package/lib/paste/pasteSourceValidations/getPasteSource.js +2 -1
- package/lib/paste/pasteSourceValidations/getPasteSource.js.map +1 -1
- package/lib/paste/pasteSourceValidations/isWordDesktopDocument.js +7 -2
- package/lib/paste/pasteSourceValidations/isWordDesktopDocument.js.map +1 -1
- package/lib/paste/processors/pasteButtonProcessor.d.ts +7 -0
- package/lib/paste/processors/pasteButtonProcessor.js +36 -0
- package/lib/paste/processors/pasteButtonProcessor.js.map +1 -0
- package/lib/paste/utils/customListUtils.d.ts +1 -1
- package/lib/paste/utils/customListUtils.js +10 -5
- package/lib/paste/utils/customListUtils.js.map +1 -1
- package/lib/tableEdit/TableEditPlugin.d.ts +7 -4
- package/lib/tableEdit/TableEditPlugin.js +28 -17
- package/lib/tableEdit/TableEditPlugin.js.map +1 -1
- package/lib/tableEdit/TableWithRoot.d.ts +15 -0
- package/lib/tableEdit/TableWithRoot.js +3 -0
- package/lib/tableEdit/TableWithRoot.js.map +1 -0
- package/lib/tableEdit/editors/TableEditor.d.ts +4 -2
- package/lib/tableEdit/editors/TableEditor.js +9 -3
- package/lib/tableEdit/editors/TableEditor.js.map +1 -1
- package/lib/tableEdit/editors/features/TableInserter.d.ts +4 -3
- package/lib/tableEdit/editors/features/TableInserter.js +7 -5
- package/lib/tableEdit/editors/features/TableInserter.js.map +1 -1
- package/lib-amd/edit/EditPlugin.js +2 -1
- package/lib-amd/edit/EditPlugin.js.map +1 -1
- package/lib-amd/edit/inputSteps/handleEnterOnList.js +1 -0
- package/lib-amd/edit/inputSteps/handleEnterOnList.js.map +1 -1
- package/lib-amd/edit/keyboardEnter.js +7 -3
- package/lib-amd/edit/keyboardEnter.js.map +1 -1
- package/lib-amd/edit/tabUtils/handleTabOnParagraph.d.ts +1 -1
- package/lib-amd/edit/tabUtils/handleTabOnParagraph.js +8 -3
- package/lib-amd/edit/tabUtils/handleTabOnParagraph.js.map +1 -1
- package/lib-amd/edit/utils/splitParagraph.d.ts +2 -2
- package/lib-amd/edit/utils/splitParagraph.js +8 -43
- package/lib-amd/edit/utils/splitParagraph.js.map +1 -1
- package/lib-amd/index.d.ts +1 -0
- package/lib-amd/index.js.map +1 -1
- package/lib-amd/paste/PastePlugin.js +3 -2
- package/lib-amd/paste/PastePlugin.js.map +1 -1
- package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js +1 -5
- package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
- package/lib-amd/paste/WordDesktop/getStyleMetadata.js +25 -14
- package/lib-amd/paste/WordDesktop/getStyleMetadata.js.map +1 -1
- package/lib-amd/paste/WordDesktop/processWordLists.js +51 -4
- package/lib-amd/paste/WordDesktop/processWordLists.js.map +1 -1
- package/lib-amd/paste/pasteSourceValidations/getPasteSource.d.ts +3 -2
- package/lib-amd/paste/pasteSourceValidations/getPasteSource.js +2 -1
- package/lib-amd/paste/pasteSourceValidations/getPasteSource.js.map +1 -1
- package/lib-amd/paste/pasteSourceValidations/isWordDesktopDocument.js +7 -2
- package/lib-amd/paste/pasteSourceValidations/isWordDesktopDocument.js.map +1 -1
- package/lib-amd/paste/processors/pasteButtonProcessor.d.ts +7 -0
- package/lib-amd/paste/processors/pasteButtonProcessor.js +36 -0
- package/lib-amd/paste/processors/pasteButtonProcessor.js.map +1 -0
- package/lib-amd/paste/utils/customListUtils.d.ts +1 -1
- package/lib-amd/paste/utils/customListUtils.js +10 -6
- package/lib-amd/paste/utils/customListUtils.js.map +1 -1
- package/lib-amd/tableEdit/TableEditPlugin.d.ts +7 -4
- package/lib-amd/tableEdit/TableEditPlugin.js +28 -18
- package/lib-amd/tableEdit/TableEditPlugin.js.map +1 -1
- package/lib-amd/tableEdit/TableWithRoot.d.ts +15 -0
- package/lib-amd/tableEdit/TableWithRoot.js +5 -0
- package/lib-amd/tableEdit/TableWithRoot.js.map +1 -0
- package/lib-amd/tableEdit/editors/TableEditor.d.ts +4 -2
- package/lib-amd/tableEdit/editors/TableEditor.js +9 -3
- package/lib-amd/tableEdit/editors/TableEditor.js.map +1 -1
- package/lib-amd/tableEdit/editors/features/TableInserter.d.ts +4 -3
- package/lib-amd/tableEdit/editors/features/TableInserter.js +7 -5
- package/lib-amd/tableEdit/editors/features/TableInserter.js.map +1 -1
- package/lib-mjs/edit/EditPlugin.js +2 -0
- package/lib-mjs/edit/EditPlugin.js.map +1 -1
- package/lib-mjs/edit/inputSteps/handleEnterOnList.js +2 -1
- package/lib-mjs/edit/inputSteps/handleEnterOnList.js.map +1 -1
- package/lib-mjs/edit/keyboardEnter.js +7 -3
- package/lib-mjs/edit/keyboardEnter.js.map +1 -1
- package/lib-mjs/edit/tabUtils/handleTabOnParagraph.d.ts +1 -1
- package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js +8 -3
- package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js.map +1 -1
- package/lib-mjs/edit/utils/splitParagraph.d.ts +2 -2
- package/lib-mjs/edit/utils/splitParagraph.js +10 -45
- package/lib-mjs/edit/utils/splitParagraph.js.map +1 -1
- package/lib-mjs/index.d.ts +1 -0
- package/lib-mjs/index.js.map +1 -1
- package/lib-mjs/paste/PastePlugin.js +4 -1
- package/lib-mjs/paste/PastePlugin.js.map +1 -1
- package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js +1 -5
- package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
- package/lib-mjs/paste/WordDesktop/getStyleMetadata.js +25 -14
- package/lib-mjs/paste/WordDesktop/getStyleMetadata.js.map +1 -1
- package/lib-mjs/paste/WordDesktop/processWordLists.js +52 -4
- package/lib-mjs/paste/WordDesktop/processWordLists.js.map +1 -1
- package/lib-mjs/paste/pasteSourceValidations/getPasteSource.d.ts +3 -2
- package/lib-mjs/paste/pasteSourceValidations/getPasteSource.js +2 -1
- package/lib-mjs/paste/pasteSourceValidations/getPasteSource.js.map +1 -1
- package/lib-mjs/paste/pasteSourceValidations/isWordDesktopDocument.js +7 -2
- package/lib-mjs/paste/pasteSourceValidations/isWordDesktopDocument.js.map +1 -1
- package/lib-mjs/paste/processors/pasteButtonProcessor.d.ts +7 -0
- package/lib-mjs/paste/processors/pasteButtonProcessor.js +32 -0
- package/lib-mjs/paste/processors/pasteButtonProcessor.js.map +1 -0
- package/lib-mjs/paste/utils/customListUtils.d.ts +1 -1
- package/lib-mjs/paste/utils/customListUtils.js +10 -5
- package/lib-mjs/paste/utils/customListUtils.js.map +1 -1
- package/lib-mjs/tableEdit/TableEditPlugin.d.ts +7 -4
- package/lib-mjs/tableEdit/TableEditPlugin.js +28 -17
- package/lib-mjs/tableEdit/TableEditPlugin.js.map +1 -1
- package/lib-mjs/tableEdit/TableWithRoot.d.ts +15 -0
- package/lib-mjs/tableEdit/TableWithRoot.js +2 -0
- package/lib-mjs/tableEdit/TableWithRoot.js.map +1 -0
- package/lib-mjs/tableEdit/editors/TableEditor.d.ts +4 -2
- package/lib-mjs/tableEdit/editors/TableEditor.js +9 -3
- package/lib-mjs/tableEdit/editors/TableEditor.js.map +1 -1
- package/lib-mjs/tableEdit/editors/features/TableInserter.d.ts +4 -3
- package/lib-mjs/tableEdit/editors/features/TableInserter.js +7 -5
- package/lib-mjs/tableEdit/editors/features/TableInserter.js.map +1 -1
- package/package.json +5 -5
package/lib/edit/EditPlugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EditPlugin = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
4
5
|
var keyboardDelete_1 = require("./keyboardDelete");
|
|
5
6
|
var keyboardEnter_1 = require("./keyboardEnter");
|
|
6
7
|
var keyboardInput_1 = require("./keyboardInput");
|
|
@@ -39,6 +40,7 @@ var EditPlugin = /** @class */ (function () {
|
|
|
39
40
|
this.shouldHandleNextInputEvent = false;
|
|
40
41
|
this.selectionAfterDelete = null;
|
|
41
42
|
this.handleNormalEnter = function (editor) { return false; };
|
|
43
|
+
this.options = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultOptions), options);
|
|
42
44
|
}
|
|
43
45
|
EditPlugin.prototype.createNormalEnterChecker = function (result) {
|
|
44
46
|
return result ? function () { return true; } : function () { return false; };
|
|
@@ -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 /**\n * Whether expanded selection within a text node should be handled by CM when pressing Backspace/Delete key.\n * @default true\n */\n handleExpandedSelectionOnDelete?: boolean;\n\n /**\n * Callback function to determine whether the Rooster should handle the Enter key press.\n * If the function returns true, the Rooster will handle the Enter key press instead of the browser.\n * @param editor - The editor instance.\n * @returns A boolean\n */\n shouldHandleEnterKey?: ((editor: IEditor) => boolean) | boolean;\n};\n\nconst BACKSPACE_KEY = 8;\nconst DELETE_KEY = 46;\n/**\n * According to https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html\n * 229 can be sent in variants generated when Long press (iOS) or using IM.\n *\n * Other cases: https://stackoverflow.com/questions/25043934/is-it-ok-to-ignore-keydown-events-with-keycode-229\n */\nconst DEAD_KEY = 229;\n\nconst DefaultOptions: Partial<EditOptions> = {\n handleTabKey: true,\n handleExpandedSelectionOnDelete: 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: (editor: IEditor) => boolean = (editor: IEditor) => 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 private createNormalEnterChecker(result: boolean) {\n return result ? () => true : () => false;\n }\n\n private getHandleNormalEnter(editor: IEditor) {\n switch (typeof this.options.shouldHandleEnterKey) {\n case 'function':\n return this.options.shouldHandleEnterKey;\n break;\n case 'boolean':\n return this.createNormalEnterChecker(this.options.shouldHandleEnterKey);\n break;\n default:\n return this.createNormalEnterChecker(\n editor.isExperimentalFeatureEnabled('HandleEnterKey')\n );\n break;\n }\n }\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.getHandleNormalEnter(editor);\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, this.options.handleExpandedSelectionOnDelete);\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(\n editor,\n rawEvent,\n this.options.handleExpandedSelectionOnDelete\n );\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 (\n !hasCtrlOrMetaKey &&\n !event.rawEvent.isComposing &&\n event.rawEvent.keyCode !== DEAD_KEY\n ) {\n keyboardEnter(editor, rawEvent, this.handleNormalEnter(editor));\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 this.options.handleExpandedSelectionOnDelete\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 this.options.handleExpandedSelectionOnDelete\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 /**\n * Whether expanded selection within a text node should be handled by CM when pressing Backspace/Delete key.\n * @default true\n */\n handleExpandedSelectionOnDelete?: boolean;\n\n /**\n * Callback function to determine whether the Rooster should handle the Enter key press.\n * If the function returns true, the Rooster will handle the Enter key press instead of the browser.\n * @param editor - The editor instance.\n * @returns A boolean\n */\n shouldHandleEnterKey?: ((editor: IEditor) => boolean) | boolean;\n};\n\nconst BACKSPACE_KEY = 8;\nconst DELETE_KEY = 46;\n/**\n * According to https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html\n * 229 can be sent in variants generated when Long press (iOS) or using IM.\n *\n * Other cases: https://stackoverflow.com/questions/25043934/is-it-ok-to-ignore-keydown-events-with-keycode-229\n */\nconst DEAD_KEY = 229;\n\nconst DefaultOptions: Partial<EditOptions> = {\n handleTabKey: true,\n handleExpandedSelectionOnDelete: 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: (editor: IEditor) => boolean = (editor: IEditor) => 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 this.options = { ...DefaultOptions, ...options };\n }\n\n private createNormalEnterChecker(result: boolean) {\n return result ? () => true : () => false;\n }\n\n private getHandleNormalEnter(editor: IEditor) {\n switch (typeof this.options.shouldHandleEnterKey) {\n case 'function':\n return this.options.shouldHandleEnterKey;\n break;\n case 'boolean':\n return this.createNormalEnterChecker(this.options.shouldHandleEnterKey);\n break;\n default:\n return this.createNormalEnterChecker(\n editor.isExperimentalFeatureEnabled('HandleEnterKey')\n );\n break;\n }\n }\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.getHandleNormalEnter(editor);\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, this.options.handleExpandedSelectionOnDelete);\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(\n editor,\n rawEvent,\n this.options.handleExpandedSelectionOnDelete\n );\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 (\n !hasCtrlOrMetaKey &&\n !event.rawEvent.isComposing &&\n event.rawEvent.keyCode !== DEAD_KEY\n ) {\n keyboardEnter(editor, rawEvent, this.handleNormalEnter(editor));\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 this.options.handleExpandedSelectionOnDelete\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 this.options.handleExpandedSelectionOnDelete\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"]}
|
|
@@ -70,6 +70,7 @@ var createNewListItem = function (context, listItem, listParent) {
|
|
|
70
70
|
var levels = createNewListLevel(listItem);
|
|
71
71
|
var newListItem = (0, roosterjs_content_model_dom_1.createListItem)(levels, listItem.formatHolder.format);
|
|
72
72
|
newListItem.blocks.push(newParagraph);
|
|
73
|
+
(0, roosterjs_content_model_dom_1.copyFormat)(newListItem.format, listItem.format, roosterjs_content_model_dom_1.ListFormats);
|
|
73
74
|
var remainingBlockCount = listItem.blocks.length - paraIndex - 1;
|
|
74
75
|
if (paraIndex >= 0 && remainingBlockCount > 0) {
|
|
75
76
|
(_a = newListItem.blocks).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)((0, roosterjs_content_model_dom_1.mutateBlock)(listItem).blocks.splice(paraIndex + 1, remainingBlockCount)), false));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleEnterOnList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts"],"names":[],"mappings":"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","sourcesContent":["import { getListAnnounceData } from 'roosterjs-content-model-api';\nimport { splitParagraph } from '../utils/splitParagraph';\nimport {\n createListItem,\n createListLevel,\n getClosestAncestorBlockGroupIndex,\n isBlockGroupOfType,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n ContentModelListItem,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelListItem,\n ShallowMutableContentModelListItem,\n ValidDeleteSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleEnterOnList: DeleteSelectionStep = context => {\n const { deleteResult, insertPoint } = context;\n\n if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {\n const { path } = insertPoint;\n const index = getClosestAncestorBlockGroupIndex(\n path,\n ['ListItem'],\n ['TableCell', 'FormatContainer']\n );\n\n const readonlyListItem = path[index];\n const listParent = path[index + 1];\n\n if (readonlyListItem?.blockGroupType === 'ListItem' && listParent) {\n let listItem = mutateBlock(readonlyListItem);\n\n if (isEmptyListItem(listItem)) {\n listItem.levels.pop();\n } else {\n listItem = createNewListItem(context, listItem, listParent);\n\n if (context.formatContext) {\n context.formatContext.announceData = getListAnnounceData([\n listItem,\n ...path.slice(index + 1),\n ]);\n }\n }\n\n const listIndex = listParent.blocks.indexOf(listItem);\n const nextBlock = listParent.blocks[listIndex + 1];\n\n if (nextBlock) {\n if (\n isBlockGroupOfType<ContentModelListItem>(nextBlock, 'ListItem') &&\n nextBlock.levels[0]\n ) {\n nextBlock.levels.forEach(level => {\n // Remove startNumberOverride so that next list item can join current list, unless it is 1.\n // List start with 1 means it should be an explicit new list and should never join another list before it\n if (level.format.startNumberOverride !== 1) {\n level.format.startNumberOverride = undefined;\n }\n });\n\n if (listItem.levels.length == 0) {\n const nextBlockIndex = findIndex(\n listParent.blocks,\n nextBlock.levels.length\n );\n\n nextBlock.levels[\n nextBlock.levels.length - 1\n ].format.startNumberOverride = nextBlockIndex;\n }\n }\n }\n\n context.deleteResult = 'range';\n }\n }\n};\n\nconst isEmptyListItem = (listItem: ReadonlyContentModelListItem) => {\n return listItem.blocks.length === 1 && isEmptyParagraph(listItem.blocks[0]);\n};\n\nconst isEmptyParagraph = (block: ReadonlyContentModelBlock) => {\n return (\n block.blockType === 'Paragraph' &&\n block.segments.length === 2 &&\n block.segments[0].segmentType === 'SelectionMarker' &&\n block.segments[1].segmentType === 'Br'\n );\n};\n\nconst createNewListItem = (\n context: ValidDeleteSelectionContext,\n listItem: ReadonlyContentModelListItem,\n listParent: ReadonlyContentModelBlockGroup\n) => {\n const { insertPoint } = context;\n const listIndex = listParent.blocks.indexOf(listItem);\n const currentPara = insertPoint.paragraph;\n const paraIndex = listItem.blocks.indexOf(currentPara);\n const newParagraph = splitParagraph(insertPoint);\n\n const levels = createNewListLevel(listItem);\n const newListItem: ShallowMutableContentModelListItem = createListItem(\n levels,\n listItem.formatHolder.format\n );\n\n newListItem.blocks.push(newParagraph);\n\n const remainingBlockCount = listItem.blocks.length - paraIndex - 1;\n\n if (paraIndex >= 0 && remainingBlockCount > 0) {\n newListItem.blocks.push(\n ...mutateBlock(listItem).blocks.splice(paraIndex + 1, remainingBlockCount)\n );\n }\n\n insertPoint.paragraph = newParagraph;\n mutateBlock(listParent).blocks.splice(listIndex + 1, 0, newListItem);\n\n if (context.lastParagraph == currentPara) {\n context.lastParagraph = newParagraph;\n }\n\n return newListItem;\n};\n\nconst createNewListLevel = (listItem: ReadonlyContentModelListItem) => {\n return listItem.levels.map(level => {\n return createListLevel(\n level.listType,\n {\n ...level.format,\n startNumberOverride: undefined,\n displayForDummyItem: undefined, // When ENTER, we should create a new regular list item, so force its dummy item display to undefined\n },\n level.dataset\n );\n });\n};\n\nconst findIndex = (blocks: readonly ReadonlyContentModelBlock[], levelLength: number) => {\n let counter = 1;\n for (let i = 0; i < blocks.length; i++) {\n const listItem = blocks[i];\n\n if (\n isBlockGroupOfType<ContentModelListItem>(listItem, 'ListItem') &&\n listItem.levels.length === levelLength\n ) {\n counter++;\n } else if (\n isBlockGroupOfType<ContentModelListItem>(listItem, 'ListItem') &&\n listItem.levels.length == 0\n ) {\n return counter;\n }\n }\n\n return counter;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"handleEnterOnList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts"],"names":[],"mappings":"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","sourcesContent":["import { getListAnnounceData } from 'roosterjs-content-model-api';\nimport { splitParagraph } from '../utils/splitParagraph';\nimport {\n copyFormat,\n createListItem,\n createListLevel,\n getClosestAncestorBlockGroupIndex,\n isBlockGroupOfType,\n ListFormats,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n ContentModelBlockFormat,\n ContentModelListItem,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelListItem,\n ShallowMutableContentModelListItem,\n ValidDeleteSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleEnterOnList: DeleteSelectionStep = context => {\n const { deleteResult, insertPoint } = context;\n\n if (deleteResult == 'notDeleted' || deleteResult == 'nothingToDelete') {\n const { path } = insertPoint;\n const index = getClosestAncestorBlockGroupIndex(\n path,\n ['ListItem'],\n ['TableCell', 'FormatContainer']\n );\n\n const readonlyListItem = path[index];\n const listParent = path[index + 1];\n\n if (readonlyListItem?.blockGroupType === 'ListItem' && listParent) {\n let listItem = mutateBlock(readonlyListItem);\n\n if (isEmptyListItem(listItem)) {\n listItem.levels.pop();\n } else {\n listItem = createNewListItem(context, listItem, listParent);\n\n if (context.formatContext) {\n context.formatContext.announceData = getListAnnounceData([\n listItem,\n ...path.slice(index + 1),\n ]);\n }\n }\n\n const listIndex = listParent.blocks.indexOf(listItem);\n const nextBlock = listParent.blocks[listIndex + 1];\n\n if (nextBlock) {\n if (\n isBlockGroupOfType<ContentModelListItem>(nextBlock, 'ListItem') &&\n nextBlock.levels[0]\n ) {\n nextBlock.levels.forEach(level => {\n // Remove startNumberOverride so that next list item can join current list, unless it is 1.\n // List start with 1 means it should be an explicit new list and should never join another list before it\n if (level.format.startNumberOverride !== 1) {\n level.format.startNumberOverride = undefined;\n }\n });\n\n if (listItem.levels.length == 0) {\n const nextBlockIndex = findIndex(\n listParent.blocks,\n nextBlock.levels.length\n );\n\n nextBlock.levels[\n nextBlock.levels.length - 1\n ].format.startNumberOverride = nextBlockIndex;\n }\n }\n }\n\n context.deleteResult = 'range';\n }\n }\n};\n\nconst isEmptyListItem = (listItem: ReadonlyContentModelListItem) => {\n return listItem.blocks.length === 1 && isEmptyParagraph(listItem.blocks[0]);\n};\n\nconst isEmptyParagraph = (block: ReadonlyContentModelBlock) => {\n return (\n block.blockType === 'Paragraph' &&\n block.segments.length === 2 &&\n block.segments[0].segmentType === 'SelectionMarker' &&\n block.segments[1].segmentType === 'Br'\n );\n};\n\nconst createNewListItem = (\n context: ValidDeleteSelectionContext,\n listItem: ReadonlyContentModelListItem,\n listParent: ReadonlyContentModelBlockGroup\n) => {\n const { insertPoint } = context;\n const listIndex = listParent.blocks.indexOf(listItem);\n const currentPara = insertPoint.paragraph;\n const paraIndex = listItem.blocks.indexOf(currentPara);\n const newParagraph = splitParagraph(insertPoint);\n\n const levels = createNewListLevel(listItem);\n const newListItem: ShallowMutableContentModelListItem = createListItem(\n levels,\n listItem.formatHolder.format\n );\n\n newListItem.blocks.push(newParagraph);\n\n copyFormat<ContentModelBlockFormat>(newListItem.format, listItem.format, ListFormats);\n\n const remainingBlockCount = listItem.blocks.length - paraIndex - 1;\n\n if (paraIndex >= 0 && remainingBlockCount > 0) {\n newListItem.blocks.push(\n ...mutateBlock(listItem).blocks.splice(paraIndex + 1, remainingBlockCount)\n );\n }\n\n insertPoint.paragraph = newParagraph;\n mutateBlock(listParent).blocks.splice(listIndex + 1, 0, newListItem);\n\n if (context.lastParagraph == currentPara) {\n context.lastParagraph = newParagraph;\n }\n\n return newListItem;\n};\n\nconst createNewListLevel = (listItem: ReadonlyContentModelListItem) => {\n return listItem.levels.map(level => {\n return createListLevel(\n level.listType,\n {\n ...level.format,\n startNumberOverride: undefined,\n displayForDummyItem: undefined, // When ENTER, we should create a new regular list item, so force its dummy item display to undefined\n },\n level.dataset\n );\n });\n};\n\nconst findIndex = (blocks: readonly ReadonlyContentModelBlock[], levelLength: number) => {\n let counter = 1;\n for (let i = 0; i < blocks.length; i++) {\n const listItem = blocks[i];\n\n if (\n isBlockGroupOfType<ContentModelListItem>(listItem, 'ListItem') &&\n listItem.levels.length === levelLength\n ) {\n counter++;\n } else if (\n isBlockGroupOfType<ContentModelListItem>(listItem, 'ListItem') &&\n listItem.levels.length == 0\n ) {\n return counter;\n }\n }\n\n return counter;\n};\n"]}
|
|
@@ -12,7 +12,7 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
|
12
12
|
function keyboardEnter(editor, rawEvent, handleNormalEnter) {
|
|
13
13
|
var selection = editor.getDOMSelection();
|
|
14
14
|
editor.formatContentModel(function (model, context) {
|
|
15
|
-
var _a;
|
|
15
|
+
var _a, _b;
|
|
16
16
|
// 1. delete the expanded selection if any, then merge paragraph
|
|
17
17
|
var result = (0, roosterjs_content_model_dom_1.deleteSelection)(model, [], context);
|
|
18
18
|
// 2. Add line break
|
|
@@ -23,14 +23,14 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
|
|
|
23
23
|
var steps = rawEvent.shiftKey
|
|
24
24
|
? []
|
|
25
25
|
: [handleAutoLink_1.handleAutoLink, handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
|
|
26
|
-
if (handleNormalEnter) {
|
|
26
|
+
if (handleNormalEnter || hasEnterForEntity((_a = result.insertPoint) === null || _a === void 0 ? void 0 : _a.paragraph)) {
|
|
27
27
|
steps.push(handleEnterOnParagraph_1.handleEnterOnParagraph);
|
|
28
28
|
}
|
|
29
29
|
(0, roosterjs_content_model_dom_1.runEditSteps)(steps, result);
|
|
30
30
|
}
|
|
31
31
|
if (result.deleteResult == 'range') {
|
|
32
32
|
// We have deleted something, next input should inherit the segment format from deleted content, so set pending format here
|
|
33
|
-
context.newPendingFormat = (
|
|
33
|
+
context.newPendingFormat = (_b = result.insertPoint) === null || _b === void 0 ? void 0 : _b.marker.format;
|
|
34
34
|
(0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
|
|
35
35
|
rawEvent.preventDefault();
|
|
36
36
|
return true;
|
|
@@ -47,4 +47,8 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
exports.keyboardEnter = keyboardEnter;
|
|
50
|
+
function hasEnterForEntity(paragraph) {
|
|
51
|
+
return (paragraph &&
|
|
52
|
+
(paragraph.isImplicit || paragraph.segments.some(function (x) { return x.segmentType == 'SelectionMarker'; })));
|
|
53
|
+
}
|
|
50
54
|
//# sourceMappingURL=keyboardEnter.js.map
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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,IAAI,iBAAiB,CAAC,MAAA,MAAM,CAAC,WAAW,0CAAE,SAAS,CAAC,EAAE;gBACvE,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;AAED,SAAS,iBAAiB,CAAC,SAAoD;IAC3E,OAAO,CACH,SAAS;QACT,CAAC,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,IAAI,iBAAiB,EAAlC,CAAkC,CAAC,CAAC,CAC7F,CAAC;AACN,CAAC","sourcesContent":["import { deleteEmptyQuote } from './deleteSteps/deleteEmptyQuote';\nimport { handleAutoLink } from './inputSteps/handleAutoLink';\nimport { handleEnterOnList } from './inputSteps/handleEnterOnList';\nimport { handleEnterOnParagraph } from './inputSteps/handleEnterOnParagraph';\nimport {\n ChangeSource,\n deleteSelection,\n normalizeContentModel,\n runEditSteps,\n} from 'roosterjs-content-model-dom';\nimport type { IEditor, ReadonlyContentModelParagraph } 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 || hasEnterForEntity(result.insertPoint?.paragraph)) {\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\nfunction hasEnterForEntity(paragraph: ReadonlyContentModelParagraph | undefined) {\n return (\n paragraph &&\n (paragraph.isImplicit || paragraph.segments.some(x => x.segmentType == 'SelectionMarker'))\n );\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import type { FormatContentModelContext, ReadonlyContentModelDocument, ReadonlyC
|
|
|
3
3
|
* @internal
|
|
4
4
|
The handleTabOnParagraph function will handle the tab key in following scenarios:
|
|
5
5
|
* 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.
|
|
6
|
-
* 2. When the selection is collapsed and the cursor is at the start of a paragraph,
|
|
6
|
+
* 2. When the selection is collapsed and the cursor is at the start of a paragraph, add 4 spaces.
|
|
7
7
|
* 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.
|
|
8
8
|
* 4. When the selection is not collapsed, replace the selected range with a single space.
|
|
9
9
|
* 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph
|
|
@@ -9,7 +9,7 @@ var space = ' ';
|
|
|
9
9
|
* @internal
|
|
10
10
|
The handleTabOnParagraph function will handle the tab key in following scenarios:
|
|
11
11
|
* 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.
|
|
12
|
-
* 2. When the selection is collapsed and the cursor is at the start of a paragraph,
|
|
12
|
+
* 2. When the selection is collapsed and the cursor is at the start of a paragraph, add 4 spaces.
|
|
13
13
|
* 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.
|
|
14
14
|
* 4. When the selection is not collapsed, replace the selected range with a single space.
|
|
15
15
|
* 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph
|
|
@@ -23,8 +23,10 @@ var space = ' ';
|
|
|
23
23
|
function handleTabOnParagraph(model, paragraph, rawEvent, context) {
|
|
24
24
|
var selectedSegments = paragraph.segments.filter(function (segment) { return segment.isSelected; });
|
|
25
25
|
var isCollapsed = selectedSegments.length === 1 && selectedSegments[0].segmentType === 'SelectionMarker';
|
|
26
|
-
var isAllSelected = paragraph.segments.every(function (segment) {
|
|
27
|
-
|
|
26
|
+
var isAllSelected = paragraph.segments.every(function (segment) {
|
|
27
|
+
return segment.isSelected || (segment.segmentType == 'Text' && segment.text.trim().length == 0);
|
|
28
|
+
});
|
|
29
|
+
if (isAllSelected) {
|
|
28
30
|
var _a = paragraph.format, marginLeft = _a.marginLeft, marginRight = _a.marginRight, direction = _a.direction;
|
|
29
31
|
var isRtl = direction === 'rtl';
|
|
30
32
|
if (rawEvent.shiftKey &&
|
|
@@ -64,6 +66,9 @@ function handleTabOnParagraph(model, paragraph, rawEvent, context) {
|
|
|
64
66
|
(0, roosterjs_content_model_dom_1.mutateBlock)(paragraph).segments.splice(markerIndex, 0, tabText);
|
|
65
67
|
}
|
|
66
68
|
else {
|
|
69
|
+
if (markerIndex <= 0) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
67
72
|
var tabText = paragraph.segments[markerIndex - 1];
|
|
68
73
|
var tabSpacesLength = tabSpaces.length;
|
|
69
74
|
if (tabText.segmentType == 'Text') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleTabOnParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnParagraph.ts"],"names":[],"mappings":";;;AAAA,2EAAkE;AAClE,2EAKqC;AAOrC,IAAM,SAAS,GAAG,MAAM,CAAC;AACzB,IAAM,KAAK,GAAG,GAAG,CAAC;AAElB;;;;;;;;;;;;;;GAcG;AACH,SAAgB,oBAAoB,CAChC,KAAmC,EACnC,SAAwC,EACxC,QAAuB,EACvB,OAAmC;IAEnC,IAAM,gBAAgB,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,UAAU,EAAlB,CAAkB,CAAC,CAAC;IAClF,IAAM,WAAW,GACb,gBAAgB,CAAC,MAAM,KAAK,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,iBAAiB,CAAC;IAC3F,IAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"handleTabOnParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/tabUtils/handleTabOnParagraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { setModelIndentation } from 'roosterjs-content-model-api';\nimport {\n createSelectionMarker,\n createText,\n mutateBlock,\n mutateSegment,\n} from 'roosterjs-content-model-dom';\nimport type {\n FormatContentModelContext,\n ReadonlyContentModelDocument,\n ReadonlyContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst tabSpaces = ' ';\nconst space = ' ';\n\n/**\n * @internal\n The handleTabOnParagraph function will handle the tab key in following scenarios:\n * 1. When the selection is collapsed and the cursor is at the end of a paragraph, add 4 spaces.\n * 2. When the selection is collapsed and the cursor is at the start of a paragraph, add 4 spaces.\n * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, add 4 spaces.\n * 4. When the selection is not collapsed, replace the selected range with a single space.\n * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to indent the whole paragraph\n The handleTabOnParagraph function will handle the shift + tab key in a indented paragraph in following scenarios:\n * 1. When the selection is collapsed and the cursor is at the end of a paragraph, remove 4 spaces.\n * 2. When the selection is collapsed and the cursor is at the start of a paragraph, call setModelIndention function to outdent the whole paragraph\n * 3. When the selection is collapsed and the cursor is at the middle of a paragraph, remove 4 spaces.\n * 4. When the selection is not collapsed, replace the selected range with a 4 space.\n * 5. When the selection is not collapsed, but all segments are selected, call setModelIndention function to outdent the whole paragraph\n */\nexport function handleTabOnParagraph(\n model: ReadonlyContentModelDocument,\n paragraph: ReadonlyContentModelParagraph,\n rawEvent: KeyboardEvent,\n context?: FormatContentModelContext\n) {\n const selectedSegments = paragraph.segments.filter(segment => segment.isSelected);\n const isCollapsed =\n selectedSegments.length === 1 && selectedSegments[0].segmentType === 'SelectionMarker';\n const isAllSelected = paragraph.segments.every(\n segment =>\n segment.isSelected || (segment.segmentType == 'Text' && segment.text.trim().length == 0)\n );\n if (isAllSelected) {\n const { marginLeft, marginRight, direction } = paragraph.format;\n const isRtl = direction === 'rtl';\n if (\n rawEvent.shiftKey &&\n ((!isRtl && (!marginLeft || marginLeft == '0px')) ||\n (isRtl && (!marginRight || marginRight == '0px')))\n ) {\n return false;\n }\n setModelIndentation(\n model,\n rawEvent.shiftKey ? 'outdent' : 'indent',\n undefined /*length*/,\n context\n );\n } else {\n if (!isCollapsed) {\n let firstSelectedSegmentIndex: number | undefined = undefined;\n let lastSelectedSegmentIndex: number | undefined = undefined;\n\n paragraph.segments.forEach((segment, index) => {\n if (segment.isSelected) {\n if (!firstSelectedSegmentIndex) {\n firstSelectedSegmentIndex = index;\n }\n lastSelectedSegmentIndex = index;\n }\n });\n if (firstSelectedSegmentIndex && lastSelectedSegmentIndex) {\n const firstSelectedSegment = paragraph.segments[firstSelectedSegmentIndex];\n const spaceText = createText(\n rawEvent.shiftKey ? tabSpaces : space,\n firstSelectedSegment.format\n );\n const marker = createSelectionMarker(firstSelectedSegment.format);\n\n mutateBlock(paragraph).segments.splice(\n firstSelectedSegmentIndex,\n lastSelectedSegmentIndex - firstSelectedSegmentIndex + 1,\n spaceText,\n marker\n );\n } else {\n return false;\n }\n } else {\n const markerIndex = paragraph.segments.findIndex(\n segment => segment.segmentType === 'SelectionMarker'\n );\n\n if (!rawEvent.shiftKey) {\n const markerFormat = paragraph.segments[markerIndex].format;\n const tabText = createText(tabSpaces, markerFormat);\n\n mutateBlock(paragraph).segments.splice(markerIndex, 0, tabText);\n } else {\n if (markerIndex <= 0) {\n return false;\n }\n const tabText = paragraph.segments[markerIndex - 1];\n const tabSpacesLength = tabSpaces.length;\n\n if (tabText.segmentType == 'Text') {\n const tabSpaceTextLength = tabText.text.length - tabSpacesLength;\n\n if (tabText.text === tabSpaces) {\n mutateBlock(paragraph).segments.splice(markerIndex - 1, 1);\n } else if (tabText.text.substring(tabSpaceTextLength) === tabSpaces) {\n mutateSegment(paragraph, tabText, text => {\n text.text = text.text.substring(0, tabSpaceTextLength);\n });\n } else {\n return false;\n }\n }\n }\n }\n }\n rawEvent.preventDefault();\n return true;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InsertPoint, ShallowMutableContentModelParagraph } from 'roosterjs-content-model-types';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
* Split the given paragraph from insert point into two paragraphs,
|
|
@@ -7,4 +7,4 @@ import type { ContentModelBlockFormat, InsertPoint, ShallowMutableContentModelPa
|
|
|
7
7
|
* @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied
|
|
8
8
|
* @returns The new paragraph it created
|
|
9
9
|
*/
|
|
10
|
-
export declare function splitParagraph(insertPoint: InsertPoint
|
|
10
|
+
export declare function splitParagraph(insertPoint: InsertPoint): ShallowMutableContentModelParagraph;
|
|
@@ -3,22 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.splitParagraph = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
6
|
-
var DEFAULT_FORMAT_KEYS = [
|
|
7
|
-
'backgroundColor',
|
|
8
|
-
'direction',
|
|
9
|
-
'textAlign',
|
|
10
|
-
'htmlAlign',
|
|
11
|
-
'lineHeight',
|
|
12
|
-
'textIndent',
|
|
13
|
-
'marginTop',
|
|
14
|
-
'marginRight',
|
|
15
|
-
'marginBottom',
|
|
16
|
-
'marginLeft',
|
|
17
|
-
'paddingTop',
|
|
18
|
-
'paddingRight',
|
|
19
|
-
'paddingBottom',
|
|
20
|
-
'paddingLeft',
|
|
21
|
-
];
|
|
22
6
|
/**
|
|
23
7
|
* @internal
|
|
24
8
|
* Split the given paragraph from insert point into two paragraphs,
|
|
@@ -27,42 +11,23 @@ var DEFAULT_FORMAT_KEYS = [
|
|
|
27
11
|
* @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied
|
|
28
12
|
* @returns The new paragraph it created
|
|
29
13
|
*/
|
|
30
|
-
function splitParagraph(insertPoint
|
|
14
|
+
function splitParagraph(insertPoint) {
|
|
31
15
|
var _a;
|
|
32
|
-
if (formatKeys === void 0) { formatKeys = DEFAULT_FORMAT_KEYS; }
|
|
33
16
|
var paragraph = insertPoint.paragraph, marker = insertPoint.marker;
|
|
34
|
-
var
|
|
35
|
-
|
|
17
|
+
var newParagraph = (0, roosterjs_content_model_dom_1.createParagraph)(false /*isImplicit*/, {}, paragraph.segmentFormat);
|
|
18
|
+
(0, roosterjs_content_model_dom_1.copyFormat)(newParagraph.format, paragraph.format, roosterjs_content_model_dom_1.ParagraphFormats);
|
|
36
19
|
var markerIndex = paragraph.segments.indexOf(marker);
|
|
37
20
|
var segments = paragraph.segments.splice(markerIndex, paragraph.segments.length - markerIndex);
|
|
38
|
-
|
|
21
|
+
(_a = newParagraph.segments).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(segments), false));
|
|
22
|
+
if (paragraph.segments.length == 0 && !paragraph.isImplicit) {
|
|
39
23
|
paragraph.segments.push((0, roosterjs_content_model_dom_1.createBr)(marker.format));
|
|
40
24
|
}
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
else if (paragraph.segments.length > 0) {
|
|
26
|
+
(0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(paragraph);
|
|
27
|
+
}
|
|
43
28
|
insertPoint.paragraph = newParagraph;
|
|
44
29
|
(0, roosterjs_content_model_dom_1.normalizeParagraph)(paragraph);
|
|
45
30
|
return newParagraph;
|
|
46
31
|
}
|
|
47
32
|
exports.splitParagraph = splitParagraph;
|
|
48
|
-
var createNewFormat = function (format, formatKeys) {
|
|
49
|
-
var e_1, _a, _b;
|
|
50
|
-
var newFormat = {};
|
|
51
|
-
try {
|
|
52
|
-
for (var formatKeys_1 = (0, tslib_1.__values)(formatKeys), formatKeys_1_1 = formatKeys_1.next(); !formatKeys_1_1.done; formatKeys_1_1 = formatKeys_1.next()) {
|
|
53
|
-
var key = formatKeys_1_1.value;
|
|
54
|
-
if (format[key]) {
|
|
55
|
-
newFormat = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, newFormat), (_b = {}, _b[key] = format[key], _b));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
60
|
-
finally {
|
|
61
|
-
try {
|
|
62
|
-
if (formatKeys_1_1 && !formatKeys_1_1.done && (_a = formatKeys_1.return)) _a.call(formatKeys_1);
|
|
63
|
-
}
|
|
64
|
-
finally { if (e_1) throw e_1.error; }
|
|
65
|
-
}
|
|
66
|
-
return newFormat;
|
|
67
|
-
};
|
|
68
33
|
//# sourceMappingURL=splitParagraph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"splitParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/utils/splitParagraph.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"splitParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/utils/splitParagraph.ts"],"names":[],"mappings":";;;;AAAA,2EAOqC;AAMrC;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,WAAwB;;IAC3C,IAAA,SAAS,GAAa,WAAW,UAAxB,EAAE,MAAM,GAAK,WAAW,OAAhB,CAAiB;IAC1C,IAAM,YAAY,GAAwC,IAAA,6CAAe,EACrE,KAAK,CAAC,cAAc,EACpB,EAAE,EACF,SAAS,CAAC,aAAa,CAC1B,CAAC;IAEF,IAAA,wCAAU,EAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,8CAAgB,CAAC,CAAC;IAEpE,IAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,IAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CACtC,WAAW,EACX,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAC1C,CAAC;IAEF,CAAA,KAAA,YAAY,CAAC,QAAQ,CAAA,CAAC,IAAI,8DAAI,QAAQ,WAAE;IAExC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;QACzD,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,sCAAQ,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;KACpD;SAAM,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;QACtC,IAAA,qDAAuB,EAAC,SAAS,CAAC,CAAC;KACtC;IAED,WAAW,CAAC,SAAS,GAAG,YAAY,CAAC;IAErC,IAAA,gDAAkB,EAAC,SAAS,CAAC,CAAC;IAE9B,OAAO,YAAY,CAAC;AACxB,CAAC;AA7BD,wCA6BC","sourcesContent":["import {\n copyFormat,\n createBr,\n createParagraph,\n normalizeParagraph,\n ParagraphFormats,\n setParagraphNotImplicit,\n} from 'roosterjs-content-model-dom';\nimport type {\n InsertPoint,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Split the given paragraph from insert point into two paragraphs,\n * and move the selection marker to the beginning of the second paragraph\n * @param insertPoint The input insert point which includes the paragraph and selection marker\n * @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied\n * @returns The new paragraph it created\n */\nexport function splitParagraph(insertPoint: InsertPoint) {\n const { paragraph, marker } = insertPoint;\n const newParagraph: ShallowMutableContentModelParagraph = createParagraph(\n false /*isImplicit*/,\n {},\n paragraph.segmentFormat\n );\n\n copyFormat(newParagraph.format, paragraph.format, ParagraphFormats);\n\n const markerIndex = paragraph.segments.indexOf(marker);\n const segments = paragraph.segments.splice(\n markerIndex,\n paragraph.segments.length - markerIndex\n );\n\n newParagraph.segments.push(...segments);\n\n if (paragraph.segments.length == 0 && !paragraph.isImplicit) {\n paragraph.segments.push(createBr(marker.format));\n } else if (paragraph.segments.length > 0) {\n setParagraphNotImplicit(paragraph);\n }\n\n insertPoint.paragraph = newParagraph;\n\n normalizeParagraph(paragraph);\n\n return newParagraph;\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { TableEditPlugin } from './tableEdit/TableEditPlugin';
|
|
2
2
|
export { OnTableEditorCreatedCallback } from './tableEdit/OnTableEditorCreatedCallback';
|
|
3
3
|
export { TableEditFeatureName } from './tableEdit/editors/features/TableEditFeatureName';
|
|
4
|
+
export { TableWithRoot } from './tableEdit/TableWithRoot';
|
|
4
5
|
export { PastePlugin } from './paste/PastePlugin';
|
|
5
6
|
export { DefaultSanitizers } from './paste/DefaultSanitizers';
|
|
6
7
|
export { EditPlugin, EditOptions } from './edit/EditPlugin';
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/roosterjs-content-model-plugins/lib/index.ts"],"names":[],"mappings":";;;AAAA,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAIxB,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,iEAAgE;AAAvD,oHAAA,gBAAgB,OAAA;AACzB,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;AAExB,8EAA6E;AAApE,4HAAA,oBAAoB,OAAA","sourcesContent":["export { TableEditPlugin } from './tableEdit/TableEditPlugin';\nexport { OnTableEditorCreatedCallback } from './tableEdit/OnTableEditorCreatedCallback';\nexport { TableEditFeatureName } from './tableEdit/editors/features/TableEditFeatureName';\nexport { TableWithRoot } from './tableEdit/TableWithRoot';\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 { isModelEmptyFast } from './watermark/isModelEmptyFast';\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';\nexport { HiddenPropertyPlugin } from './hiddenProperty/HiddenPropertyPlugin';\nexport { HiddenPropertyOptions } from './hiddenProperty/HiddenPropertyOptions';\n"]}
|
package/lib/paste/PastePlugin.js
CHANGED
|
@@ -9,12 +9,14 @@ var DefaultSanitizers_1 = require("./DefaultSanitizers");
|
|
|
9
9
|
var deprecatedColorParser_1 = require("./parsers/deprecatedColorParser");
|
|
10
10
|
var getPasteSource_1 = require("./pasteSourceValidations/getPasteSource");
|
|
11
11
|
var linkParser_1 = require("./parsers/linkParser");
|
|
12
|
+
var pasteButtonProcessor_1 = require("./processors/pasteButtonProcessor");
|
|
12
13
|
var constants_1 = require("./pasteSourceValidations/constants");
|
|
13
14
|
var processPastedContentFromExcel_1 = require("./Excel/processPastedContentFromExcel");
|
|
14
15
|
var processPastedContentFromOneNote_1 = require("./oneNote/processPastedContentFromOneNote");
|
|
15
16
|
var processPastedContentFromPowerPoint_1 = require("./PowerPoint/processPastedContentFromPowerPoint");
|
|
16
17
|
var processPastedContentFromWordDesktop_1 = require("./WordDesktop/processPastedContentFromWordDesktop");
|
|
17
18
|
var processPastedContentWacComponents_1 = require("./WacComponents/processPastedContentWacComponents");
|
|
19
|
+
var setProcessor_1 = require("./utils/setProcessor");
|
|
18
20
|
/**
|
|
19
21
|
* Paste plugin, handles BeforePaste event and reformat some special content, including:
|
|
20
22
|
* 1. Content copied from Word
|
|
@@ -75,7 +77,7 @@ var PastePlugin = /** @class */ (function () {
|
|
|
75
77
|
if (!event.domToModelOption) {
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
|
-
var pasteSource = (0, getPasteSource_1.getPasteSource)(event, false);
|
|
80
|
+
var pasteSource = (0, getPasteSource_1.getPasteSource)(event, false /* shouldConvertSingleImage */, this.editor.getEnvironment());
|
|
79
81
|
var pasteType = event.pasteType;
|
|
80
82
|
switch (pasteSource) {
|
|
81
83
|
case 'wordDesktop':
|
|
@@ -106,6 +108,7 @@ var PastePlugin = /** @class */ (function () {
|
|
|
106
108
|
(0, addParser_1.addParser)(event.domToModelOption, 'tableCell', deprecatedColorParser_1.deprecatedBorderColorParser);
|
|
107
109
|
(0, addParser_1.addParser)(event.domToModelOption, 'tableCell', tableBorderParser);
|
|
108
110
|
(0, addParser_1.addParser)(event.domToModelOption, 'table', deprecatedColorParser_1.deprecatedBorderColorParser);
|
|
111
|
+
(0, setProcessor_1.setProcessor)(event.domToModelOption, 'button', pasteButtonProcessor_1.pasteButtonProcessor);
|
|
109
112
|
if (pasteType === 'mergeFormat') {
|
|
110
113
|
(0, addParser_1.addParser)(event.domToModelOption, 'block', blockElementParser);
|
|
111
114
|
(0, addParser_1.addParser)(event.domToModelOption, 'listLevel', blockElementParser);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PastePlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addParser } from './utils/addParser';\nimport { BorderKeys, getObjectKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from './utils/chainSanitizerCallback';\nimport { DefaultSanitizers } from './DefaultSanitizers';\nimport { deprecatedBorderColorParser } from './parsers/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './parsers/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromOneNote } from './oneNote/processPastedContentFromOneNote';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type {\n BeforePasteEvent,\n BorderFormat,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n DomToModelOptionForSanitizing,\n EditorPlugin,\n FormatParser,\n IEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n */\nexport class PastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(\n private allowExcelNoBorderTable?: boolean,\n private domToModelForSanitizing: Pick<\n DomToModelOptionForSanitizing,\n | 'additionalAllowedTags'\n | 'additionalDisallowedTags'\n | 'styleSanitizers'\n | 'attributeSanitizers'\n > = {\n styleSanitizers: DefaultSanitizers,\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n attributeSanitizers: {},\n }\n ) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Paste';\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 || event.eventType != 'beforePaste') {\n return;\n }\n\n if (!event.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(event, false);\n const pasteType = event.pasteType;\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(event);\n break;\n case 'wacComponents':\n processPastedContentWacComponents(event);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n case 'excelNonNativeEvent':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n event,\n this.editor.getDOMCreator(),\n !!this.allowExcelNoBorderTable,\n pasteSource != 'excelNonNativeEvent' /* isNativeEvent */\n );\n }\n break;\n case 'googleSheets':\n event.domToModelOption.additionalAllowedTags.push(\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME as Lowercase<string>\n );\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(event, this.editor.getDOMCreator());\n break;\n\n case 'oneNoteDesktop':\n processPastedContentFromOneNote(event);\n break;\n }\n\n addParser(event.domToModelOption, 'link', parseLink);\n addParser(event.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(event.domToModelOption, 'tableCell', tableBorderParser);\n addParser(event.domToModelOption, 'table', deprecatedBorderColorParser);\n\n if (pasteType === 'mergeFormat') {\n addParser(event.domToModelOption, 'block', blockElementParser);\n addParser(event.domToModelOption, 'listLevel', blockElementParser);\n }\n\n this.setEventSanitizers(event);\n }\n\n private setEventSanitizers(event: BeforePasteEvent) {\n if (this.domToModelForSanitizing) {\n const {\n styleSanitizers,\n attributeSanitizers,\n additionalAllowedTags,\n additionalDisallowedTags,\n } = this.domToModelForSanitizing;\n getObjectKeys(styleSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.styleSanitizers,\n key,\n styleSanitizers[key]\n )\n );\n getObjectKeys(attributeSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.attributeSanitizers,\n key,\n attributeSanitizers[key]\n )\n );\n event.domToModelOption.additionalAllowedTags.push(...additionalAllowedTags);\n event.domToModelOption.additionalDisallowedTags.push(...additionalDisallowedTags);\n }\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PastePlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addParser } from './utils/addParser';\nimport { BorderKeys, getObjectKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from './utils/chainSanitizerCallback';\nimport { DefaultSanitizers } from './DefaultSanitizers';\nimport { deprecatedBorderColorParser } from './parsers/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './parsers/linkParser';\nimport { pasteButtonProcessor } from './processors/pasteButtonProcessor';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromOneNote } from './oneNote/processPastedContentFromOneNote';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport { setProcessor } from './utils/setProcessor';\nimport type {\n BeforePasteEvent,\n BorderFormat,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n DomToModelOptionForSanitizing,\n EditorPlugin,\n FormatParser,\n IEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n */\nexport class PastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(\n private allowExcelNoBorderTable?: boolean,\n private domToModelForSanitizing: Pick<\n DomToModelOptionForSanitizing,\n | 'additionalAllowedTags'\n | 'additionalDisallowedTags'\n | 'styleSanitizers'\n | 'attributeSanitizers'\n > = {\n styleSanitizers: DefaultSanitizers,\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n attributeSanitizers: {},\n }\n ) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Paste';\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 || event.eventType != 'beforePaste') {\n return;\n }\n\n if (!event.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(\n event,\n false /* shouldConvertSingleImage */,\n this.editor.getEnvironment()\n );\n const pasteType = event.pasteType;\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(event);\n break;\n case 'wacComponents':\n processPastedContentWacComponents(event);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n case 'excelNonNativeEvent':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n event,\n this.editor.getDOMCreator(),\n !!this.allowExcelNoBorderTable,\n pasteSource != 'excelNonNativeEvent' /* isNativeEvent */\n );\n }\n break;\n case 'googleSheets':\n event.domToModelOption.additionalAllowedTags.push(\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME as Lowercase<string>\n );\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(event, this.editor.getDOMCreator());\n break;\n\n case 'oneNoteDesktop':\n processPastedContentFromOneNote(event);\n break;\n }\n\n addParser(event.domToModelOption, 'link', parseLink);\n addParser(event.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(event.domToModelOption, 'tableCell', tableBorderParser);\n addParser(event.domToModelOption, 'table', deprecatedBorderColorParser);\n setProcessor(event.domToModelOption, 'button', pasteButtonProcessor);\n\n if (pasteType === 'mergeFormat') {\n addParser(event.domToModelOption, 'block', blockElementParser);\n addParser(event.domToModelOption, 'listLevel', blockElementParser);\n }\n\n this.setEventSanitizers(event);\n }\n\n private setEventSanitizers(event: BeforePasteEvent) {\n if (this.domToModelForSanitizing) {\n const {\n styleSanitizers,\n attributeSanitizers,\n additionalAllowedTags,\n additionalDisallowedTags,\n } = this.domToModelForSanitizing;\n getObjectKeys(styleSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.styleSanitizers,\n key,\n styleSanitizers[key]\n )\n );\n getObjectKeys(attributeSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.attributeSanitizers,\n key,\n attributeSanitizers[key]\n )\n );\n event.domToModelOption.additionalAllowedTags.push(...additionalAllowedTags);\n event.domToModelOption.additionalDisallowedTags.push(...additionalDisallowedTags);\n }\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
|
|
@@ -52,11 +52,7 @@ function processPastedContentFromPowerPoint(event, domCreator) {
|
|
|
52
52
|
: undefined,
|
|
53
53
|
};
|
|
54
54
|
// Process the Div element as a list item.
|
|
55
|
-
(0, customListUtils_1.processAsListItem)(context, element, group, listMetadata, function (listItem) {
|
|
56
|
-
var _a;
|
|
57
|
-
var currentMarkerSize = listItem.formatHolder.format.fontSize;
|
|
58
|
-
var bulletElementSize = (_a = bulletElement.parentElement) === null || _a === void 0 ? void 0 : _a.style.fontSize;
|
|
59
|
-
listItem.formatHolder.format.fontSize = bulletElementSize || currentMarkerSize;
|
|
55
|
+
(0, customListUtils_1.processAsListItem)(context, element, group, listMetadata, bulletElement, function (listItem) {
|
|
60
56
|
if (isNewList_1) {
|
|
61
57
|
listItem.levels[listItem.levels.length - 1].format.startNumberOverride = parseInt(startNumberOverrideOrBullet_1);
|
|
62
58
|
}
|