roosterjs-content-model-core 9.9.0 → 9.9.2
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/command/createModelFromHtml/convertInlineCss.js +9 -7
- package/lib/command/createModelFromHtml/convertInlineCss.js.map +1 -1
- package/lib/corePlugin/format/FormatPlugin.js +6 -1
- package/lib/corePlugin/format/FormatPlugin.js.map +1 -1
- package/lib/corePlugin/selection/SelectionPlugin.js +15 -3
- package/lib/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib-amd/command/createModelFromHtml/convertInlineCss.js +9 -7
- package/lib-amd/command/createModelFromHtml/convertInlineCss.js.map +1 -1
- package/lib-amd/corePlugin/format/FormatPlugin.js +6 -1
- package/lib-amd/corePlugin/format/FormatPlugin.js.map +1 -1
- package/lib-amd/corePlugin/selection/SelectionPlugin.js +15 -3
- package/lib-amd/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib-mjs/command/createModelFromHtml/convertInlineCss.js +9 -7
- package/lib-mjs/command/createModelFromHtml/convertInlineCss.js.map +1 -1
- package/lib-mjs/corePlugin/format/FormatPlugin.js +6 -1
- package/lib-mjs/corePlugin/format/FormatPlugin.js.map +1 -1
- package/lib-mjs/corePlugin/selection/SelectionPlugin.js +15 -3
- package/lib-mjs/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/package.json +3 -3
|
@@ -23,13 +23,15 @@ function retrieveCssRules(doc) {
|
|
|
23
23
|
styles.forEach(function (styleNode) {
|
|
24
24
|
var _a;
|
|
25
25
|
var sheet = styleNode.sheet;
|
|
26
|
-
|
|
27
|
-
var
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
if (sheet) {
|
|
27
|
+
for (var ruleIndex = 0; ruleIndex < sheet.cssRules.length; ruleIndex++) {
|
|
28
|
+
var rule = sheet.cssRules[ruleIndex];
|
|
29
|
+
if (rule.type == CSSRule.STYLE_RULE && rule.selectorText) {
|
|
30
|
+
result.push({
|
|
31
|
+
selectors: splitSelectors(rule.selectorText),
|
|
32
|
+
text: rule.style.cssText,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
(_a = styleNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(styleNode);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertInlineCss.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/convertInlineCss.ts"],"names":[],"mappings":";;;;AAAA,2EAAsD;AAUtD;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,YAAoB;IACxC,IAAM,KAAK,GAAG,cAAc,CAAC;IAC7B,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,IAAI,EAAE,EAAR,CAAQ,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,GAAa;IAC1C,IAAM,MAAM,GAAG,IAAA,qCAAO,EAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,IAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,MAAM,CAAC,OAAO,CAAC,UAAA,SAAS;;QACpB,IAAM,KAAK,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"convertInlineCss.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/convertInlineCss.ts"],"names":[],"mappings":";;;;AAAA,2EAAsD;AAUtD;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,YAAoB;IACxC,IAAM,KAAK,GAAG,cAAc,CAAC;IAC7B,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,IAAI,EAAE,EAAR,CAAQ,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,GAAa;IAC1C,IAAM,MAAM,GAAG,IAAA,qCAAO,EAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,IAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,MAAM,CAAC,OAAO,CAAC,UAAA,SAAS;;QACpB,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAE9B,IAAI,KAAK,EAAE;YACP,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;gBACpE,IAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAiB,CAAC;gBAEvD,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE;oBACtD,MAAM,CAAC,IAAI,CAAC;wBACR,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;wBAC5C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;qBAC3B,CAAC,CAAC;iBACN;aACJ;SACJ;QAED,MAAA,SAAS,CAAC,UAAU,0CAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAClB,CAAC;AAxBD,4CAwBC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,IAAgB,EAAE,QAAmB;4BACzD,CAAC;;QACA,IAAA,KAAsB,QAAQ,CAAC,CAAC,CAAC,EAA/B,SAAS,eAAA,EAAE,IAAI,UAAgB,CAAC;;YAExC,KAAuB,IAAA,6BAAA,sBAAA,SAAS,CAAA,CAAA,oCAAA,2DAAE;gBAA7B,IAAM,QAAQ,sBAAA;gBACf,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE;oBAC/B,SAAS;iBACZ;gBAED,IAAM,KAAK,GAAG,IAAA,qCAAO,EAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAEvD,qEAAqE;gBACrE,+EAA+E;gBAC/E,yCAAyC;gBACzC,KAAK,CAAC,OAAO,CAAC,UAAA,IAAI;oBACd,OAAA,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBAArE,CAAqE,CACxE,CAAC;aACL;;;;;;;;;;IAhBL,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBAApC,CAAC;KAiBT;AACL,CAAC;AAnBD,4CAmBC","sourcesContent":["import { toArray } from 'roosterjs-content-model-dom';\n\n/**\n * @internal\n */\nexport interface CssRule {\n selectors: string[];\n text: string;\n}\n\n/**\n * @internal\n *\n * Splits CSS selectors, avoiding splits within parentheses\n * @param selectorText The CSS selector string\n * @return Array of trimmed selectors\n */\nfunction splitSelectors(selectorText: string) {\n const regex = /(?![^(]*\\)),/;\n return selectorText.split(regex).map(s => s.trim());\n}\n\n/**\n * @internal\n */\nexport function retrieveCssRules(doc: Document): CssRule[] {\n const styles = toArray(doc.querySelectorAll('style'));\n const result: CssRule[] = [];\n\n styles.forEach(styleNode => {\n const sheet = styleNode.sheet;\n\n if (sheet) {\n for (let ruleIndex = 0; ruleIndex < sheet.cssRules.length; ruleIndex++) {\n const rule = sheet.cssRules[ruleIndex] as CSSStyleRule;\n\n if (rule.type == CSSRule.STYLE_RULE && rule.selectorText) {\n result.push({\n selectors: splitSelectors(rule.selectorText),\n text: rule.style.cssText,\n });\n }\n }\n }\n\n styleNode.parentNode?.removeChild(styleNode);\n });\n\n return result;\n}\n\n/**\n * @internal\n */\nexport function convertInlineCss(root: ParentNode, cssRules: CssRule[]) {\n for (let i = cssRules.length - 1; i >= 0; i--) {\n const { selectors, text } = cssRules[i];\n\n for (const selector of selectors) {\n if (!selector || !selector.trim()) {\n continue;\n }\n\n const nodes = toArray(root.querySelectorAll(selector));\n\n // Always put existing styles after so that they have higher priority\n // Which means if both global style and inline style apply to the same element,\n // inline style will have higher priority\n nodes.forEach(node =>\n node.setAttribute('style', text + (node.getAttribute('style') || ''))\n );\n }\n }\n}\n"]}
|
|
@@ -7,6 +7,8 @@ var applyPendingFormat_1 = require("./applyPendingFormat");
|
|
|
7
7
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
8
8
|
// During IME input, KeyDown event will have "Process" as key
|
|
9
9
|
var ProcessKey = 'Process';
|
|
10
|
+
// For some Android IME, KeyDown event will have "Unidentified" as key
|
|
11
|
+
var UnidentifiedKey = 'Unidentified';
|
|
10
12
|
var DefaultStyleKeyMap = {
|
|
11
13
|
backgroundColor: 'backgroundColor',
|
|
12
14
|
textColor: 'color',
|
|
@@ -85,12 +87,15 @@ var FormatPlugin = /** @class */ (function () {
|
|
|
85
87
|
this.checkAndApplyPendingFormat(event.rawEvent.data);
|
|
86
88
|
break;
|
|
87
89
|
case 'keyDown':
|
|
90
|
+
var isAndroidIME = this.editor.getEnvironment().isAndroid && event.rawEvent.key == UnidentifiedKey;
|
|
88
91
|
if ((0, roosterjs_content_model_dom_1.isCursorMovingKey)(event.rawEvent)) {
|
|
89
92
|
this.clearPendingFormat();
|
|
90
93
|
this.lastCheckedNode = null;
|
|
91
94
|
}
|
|
92
95
|
else if (this.defaultFormatKeys.size > 0 &&
|
|
93
|
-
(
|
|
96
|
+
(isAndroidIME ||
|
|
97
|
+
(0, roosterjs_content_model_dom_1.isCharacterValue)(event.rawEvent) ||
|
|
98
|
+
event.rawEvent.key == ProcessKey) &&
|
|
94
99
|
this.shouldApplyDefaultFormat(this.editor)) {
|
|
95
100
|
(0, applyDefaultFormat_1.applyDefaultFormat)(this.editor, this.state.defaultFormat);
|
|
96
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/format/FormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyDefaultFormat } from './applyDefaultFormat';\nimport { applyPendingFormat } from './applyPendingFormat';\nimport {\n getObjectKeys,\n isBlockElement,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n BackgroundColorFormat,\n FontFamilyFormat,\n FontSizeFormat,\n FormatPluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n TextColorFormat,\n} from 'roosterjs-content-model-types';\n\n// During IME input, KeyDown event will have \"Process\" as key\nconst ProcessKey = 'Process';\nconst DefaultStyleKeyMap: Record<\n keyof (FontFamilyFormat & FontSizeFormat & TextColorFormat & BackgroundColorFormat),\n keyof CSSStyleDeclaration\n> = {\n backgroundColor: 'backgroundColor',\n textColor: 'color',\n fontFamily: 'fontFamily',\n fontSize: 'fontSize',\n};\n\n/**\n * FormatPlugin plugins helps editor to do formatting on top of content model.\n * This includes:\n * 1. Handle pending format changes when selection is collapsed\n */\nclass FormatPlugin implements PluginWithState<FormatPluginState> {\n private editor: IEditor | null = null;\n private defaultFormatKeys: Set<keyof CSSStyleDeclaration>;\n private state: FormatPluginState;\n private lastCheckedNode: Node | null = null;\n\n /**\n * Construct a new instance of FormatPlugin class\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n defaultFormat: { ...option.defaultSegmentFormat },\n pendingFormat: null,\n };\n\n this.defaultFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n getObjectKeys(DefaultStyleKeyMap).forEach(key => {\n if (this.state.defaultFormat[key]) {\n this.defaultFormatKeys.add(DefaultStyleKeyMap[key]);\n }\n });\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Format';\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 * Get plugin state object\n */\n getState(): FormatPluginState {\n return this.state;\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 return;\n }\n\n switch (event.eventType) {\n case 'input':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n\n break;\n\n case 'compositionEnd':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n break;\n\n case 'keyDown':\n if (isCursorMovingKey(event.rawEvent)) {\n this.clearPendingFormat();\n this.lastCheckedNode = null;\n } else if (\n this.defaultFormatKeys.size > 0 &&\n (isCharacterValue(event.rawEvent) || event.rawEvent.key == ProcessKey) &&\n this.shouldApplyDefaultFormat(this.editor)\n ) {\n applyDefaultFormat(this.editor, this.state.defaultFormat);\n }\n\n break;\n\n case 'mouseUp':\n case 'contentChanged':\n this.lastCheckedNode = null;\n\n if (!this.canApplyPendingFormat()) {\n this.clearPendingFormat();\n }\n break;\n }\n }\n\n private checkAndApplyPendingFormat(data: string | null) {\n if (this.editor && data && this.state.pendingFormat) {\n applyPendingFormat(this.editor, data, this.state.pendingFormat.format);\n this.clearPendingFormat();\n }\n }\n\n private clearPendingFormat() {\n this.state.pendingFormat = null;\n }\n\n /**\n * @internal\n * Check if this editor can apply pending format\n * @param editor The editor to get format from\n */\n private canApplyPendingFormat(): boolean {\n let result = false;\n\n if (this.state.pendingFormat && this.editor) {\n const selection = this.editor.getDOMSelection();\n const range =\n selection?.type == 'range' && selection.range.collapsed ? selection.range : null;\n const { node, offset } = this.state.pendingFormat.insertPoint;\n\n if (range && range.startContainer == node && range.startOffset == offset) {\n result = true;\n }\n }\n\n return result;\n }\n\n private shouldApplyDefaultFormat(editor: IEditor): boolean {\n const selection = editor.getDOMSelection();\n const range = selection?.type == 'range' ? selection.range : null;\n const posContainer = range?.startContainer ?? null;\n\n if (posContainer && posContainer != this.lastCheckedNode) {\n // Cache last checked parent node so no need to check it again if user is keep typing under the same node\n this.lastCheckedNode = posContainer;\n\n const domHelper = editor.getDOMHelper();\n let element: HTMLElement | null = isNodeOfType(posContainer, 'ELEMENT_NODE')\n ? posContainer\n : posContainer.parentElement;\n const foundFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n while (element?.parentElement && domHelper.isNodeInEditor(element.parentElement)) {\n if (element.getAttribute?.('style')) {\n const style = element.style;\n this.defaultFormatKeys.forEach(key => {\n if (style[key]) {\n foundFormatKeys.add(key);\n }\n });\n\n if (foundFormatKeys.size == this.defaultFormatKeys.size) {\n return false;\n }\n }\n\n if (isBlockElement(element)) {\n break;\n }\n\n element = element.parentElement;\n }\n\n return true;\n } else {\n return false;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of FormatPlugin.\n * @param option The editor option\n */\nexport function createFormatPlugin(option: EditorOptions): PluginWithState<FormatPluginState> {\n return new FormatPlugin(option);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FormatPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/format/FormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyDefaultFormat } from './applyDefaultFormat';\nimport { applyPendingFormat } from './applyPendingFormat';\nimport {\n getObjectKeys,\n isBlockElement,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n BackgroundColorFormat,\n FontFamilyFormat,\n FontSizeFormat,\n FormatPluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n TextColorFormat,\n} from 'roosterjs-content-model-types';\n\n// During IME input, KeyDown event will have \"Process\" as key\nconst ProcessKey = 'Process';\n// For some Android IME, KeyDown event will have \"Unidentified\" as key\nconst UnidentifiedKey = 'Unidentified';\nconst DefaultStyleKeyMap: Record<\n keyof (FontFamilyFormat & FontSizeFormat & TextColorFormat & BackgroundColorFormat),\n keyof CSSStyleDeclaration\n> = {\n backgroundColor: 'backgroundColor',\n textColor: 'color',\n fontFamily: 'fontFamily',\n fontSize: 'fontSize',\n};\n\n/**\n * FormatPlugin plugins helps editor to do formatting on top of content model.\n * This includes:\n * 1. Handle pending format changes when selection is collapsed\n */\nclass FormatPlugin implements PluginWithState<FormatPluginState> {\n private editor: IEditor | null = null;\n private defaultFormatKeys: Set<keyof CSSStyleDeclaration>;\n private state: FormatPluginState;\n private lastCheckedNode: Node | null = null;\n\n /**\n * Construct a new instance of FormatPlugin class\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n defaultFormat: { ...option.defaultSegmentFormat },\n pendingFormat: null,\n };\n\n this.defaultFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n getObjectKeys(DefaultStyleKeyMap).forEach(key => {\n if (this.state.defaultFormat[key]) {\n this.defaultFormatKeys.add(DefaultStyleKeyMap[key]);\n }\n });\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Format';\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 * Get plugin state object\n */\n getState(): FormatPluginState {\n return this.state;\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 return;\n }\n\n switch (event.eventType) {\n case 'input':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n\n break;\n\n case 'compositionEnd':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n break;\n\n case 'keyDown':\n const isAndroidIME =\n this.editor.getEnvironment().isAndroid && event.rawEvent.key == UnidentifiedKey;\n if (isCursorMovingKey(event.rawEvent)) {\n this.clearPendingFormat();\n this.lastCheckedNode = null;\n } else if (\n this.defaultFormatKeys.size > 0 &&\n (isAndroidIME ||\n isCharacterValue(event.rawEvent) ||\n event.rawEvent.key == ProcessKey) &&\n this.shouldApplyDefaultFormat(this.editor)\n ) {\n applyDefaultFormat(this.editor, this.state.defaultFormat);\n }\n\n break;\n\n case 'mouseUp':\n case 'contentChanged':\n this.lastCheckedNode = null;\n\n if (!this.canApplyPendingFormat()) {\n this.clearPendingFormat();\n }\n break;\n }\n }\n\n private checkAndApplyPendingFormat(data: string | null) {\n if (this.editor && data && this.state.pendingFormat) {\n applyPendingFormat(this.editor, data, this.state.pendingFormat.format);\n this.clearPendingFormat();\n }\n }\n\n private clearPendingFormat() {\n this.state.pendingFormat = null;\n }\n\n /**\n * @internal\n * Check if this editor can apply pending format\n * @param editor The editor to get format from\n */\n private canApplyPendingFormat(): boolean {\n let result = false;\n\n if (this.state.pendingFormat && this.editor) {\n const selection = this.editor.getDOMSelection();\n const range =\n selection?.type == 'range' && selection.range.collapsed ? selection.range : null;\n const { node, offset } = this.state.pendingFormat.insertPoint;\n\n if (range && range.startContainer == node && range.startOffset == offset) {\n result = true;\n }\n }\n\n return result;\n }\n\n private shouldApplyDefaultFormat(editor: IEditor): boolean {\n const selection = editor.getDOMSelection();\n const range = selection?.type == 'range' ? selection.range : null;\n const posContainer = range?.startContainer ?? null;\n\n if (posContainer && posContainer != this.lastCheckedNode) {\n // Cache last checked parent node so no need to check it again if user is keep typing under the same node\n this.lastCheckedNode = posContainer;\n\n const domHelper = editor.getDOMHelper();\n let element: HTMLElement | null = isNodeOfType(posContainer, 'ELEMENT_NODE')\n ? posContainer\n : posContainer.parentElement;\n const foundFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n while (element?.parentElement && domHelper.isNodeInEditor(element.parentElement)) {\n if (element.getAttribute?.('style')) {\n const style = element.style;\n this.defaultFormatKeys.forEach(key => {\n if (style[key]) {\n foundFormatKeys.add(key);\n }\n });\n\n if (foundFormatKeys.size == this.defaultFormatKeys.size) {\n return false;\n }\n }\n\n if (isBlockElement(element)) {\n break;\n }\n\n element = element.parentElement;\n }\n\n return true;\n } else {\n return false;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of FormatPlugin.\n * @param option The editor option\n */\nexport function createFormatPlugin(option: EditorOptions): PluginWithState<FormatPluginState> {\n return new FormatPlugin(option);\n}\n"]}
|
|
@@ -415,6 +415,9 @@ var SelectionPlugin = /** @class */ (function () {
|
|
|
415
415
|
if (collapsed && td) {
|
|
416
416
|
this.setRangeSelectionInTable(td, key == Up ? td.childNodes.length : 0, this.editor);
|
|
417
417
|
}
|
|
418
|
+
else if (!td && (lastCo.row == -1 || lastCo.row <= parsedTable.length)) {
|
|
419
|
+
this.selectBeforeOrAfterElement(this.editor, table, change == 1 /* after */, change != 1 /* setSelectionInNextSiblingElement */);
|
|
420
|
+
}
|
|
418
421
|
}
|
|
419
422
|
else if (key == 'TabLeft' || key == 'TabRight') {
|
|
420
423
|
var reverse = key == 'TabLeft';
|
|
@@ -486,14 +489,23 @@ var SelectionPlugin = /** @class */ (function () {
|
|
|
486
489
|
}
|
|
487
490
|
}
|
|
488
491
|
};
|
|
489
|
-
SelectionPlugin.prototype.selectBeforeOrAfterElement = function (editor, element, after) {
|
|
492
|
+
SelectionPlugin.prototype.selectBeforeOrAfterElement = function (editor, element, after, setSelectionInNextSiblingElement) {
|
|
490
493
|
var doc = editor.getDocument();
|
|
491
494
|
var parent = element.parentNode;
|
|
492
495
|
var index = parent && (0, roosterjs_content_model_dom_1.toArray)(parent.childNodes).indexOf(element);
|
|
496
|
+
var sibling;
|
|
493
497
|
if (parent && index !== null && index >= 0) {
|
|
494
498
|
var range = doc.createRange();
|
|
495
|
-
|
|
496
|
-
|
|
499
|
+
if (setSelectionInNextSiblingElement &&
|
|
500
|
+
(sibling = after ? element.nextElementSibling : element.previousElementSibling) &&
|
|
501
|
+
(0, roosterjs_content_model_dom_1.isNodeOfType)(sibling, 'ELEMENT_NODE')) {
|
|
502
|
+
range.selectNodeContents(sibling);
|
|
503
|
+
range.collapse(false /* toStart */);
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
range.setStart(parent, index + (after ? 1 : 0));
|
|
507
|
+
range.collapse();
|
|
508
|
+
}
|
|
497
509
|
this.setDOMSelection({
|
|
498
510
|
type: 'range',
|
|
499
511
|
range: range,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { findCoordinate } from './findCoordinate';\nimport { findTableCellElement } from '../../coreApi/setDOMSelection/findTableCellElement';\nimport { isSingleImageInSelection } from './isSingleImageInSelection';\nimport { normalizePos } from './normalizePos';\nimport {\n isCharacterValue,\n isElementOfType,\n isModifierKey,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n PluginEvent,\n PluginWithState,\n SelectionPluginState,\n EditorOptions,\n DOMHelper,\n ParsedTable,\n TableSelectionInfo,\n TableCellCoordinate,\n RangeSelection,\n MouseUpEvent,\n} from 'roosterjs-content-model-types';\n\nconst MouseLeftButton = 0;\nconst MouseMiddleButton = 1;\nconst MouseRightButton = 2;\nconst Up = 'ArrowUp';\nconst Down = 'ArrowDown';\nconst Left = 'ArrowLeft';\nconst Right = 'ArrowRight';\nconst Tab = 'Tab';\n\n/**\n * @internal\n */\nexport const DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n/**\n * @internal\n */\nexport const DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR = '#C6C6C6';\n\nclass SelectionPlugin implements PluginWithState<SelectionPluginState> {\n private editor: IEditor | null = null;\n private state: SelectionPluginState;\n private disposer: (() => void) | null = null;\n private isSafari = false;\n private isMac = false;\n private scrollTopCache: number = 0;\n\n constructor(options: EditorOptions) {\n this.state = {\n selection: null,\n tableSelection: null,\n imageSelectionBorderColor:\n options.imageSelectionBorderColor ?? DEFAULT_SELECTION_BORDER_COLOR,\n imageSelectionBorderColorDark: options.imageSelectionBorderColor\n ? undefined\n : DEFAULT_SELECTION_BORDER_COLOR,\n tableCellSelectionBackgroundColor:\n options.tableCellSelectionBackgroundColor ??\n DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n tableCellSelectionBackgroundColorDark: options.tableCellSelectionBackgroundColor\n ? undefined\n : DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n };\n }\n\n getName() {\n return 'Selection';\n }\n\n initialize(editor: IEditor) {\n this.editor = editor;\n\n if (!this.state.imageSelectionBorderColorDark && this.state.imageSelectionBorderColor) {\n this.state.imageSelectionBorderColorDark = editor\n .getColorManager()\n .getDarkColor(this.state.imageSelectionBorderColor, undefined, 'border');\n }\n\n if (\n !this.state.tableCellSelectionBackgroundColorDark &&\n this.state.tableCellSelectionBackgroundColor\n ) {\n this.state.tableCellSelectionBackgroundColorDark = editor\n .getColorManager()\n .getDarkColor(\n this.state.tableCellSelectionBackgroundColor,\n undefined,\n 'background'\n );\n }\n\n const env = this.editor.getEnvironment();\n const document = this.editor.getDocument();\n\n this.isSafari = !!env.isSafari;\n this.isMac = !!env.isMac;\n document.addEventListener('selectionchange', this.onSelectionChange);\n if (this.isSafari) {\n this.disposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n drop: { beforeDispatch: this.onDrop },\n });\n } else {\n this.disposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n blur: { beforeDispatch: this.onBlur },\n drop: { beforeDispatch: this.onDrop },\n });\n }\n }\n\n dispose() {\n this.editor?.getDocument().removeEventListener('selectionchange', this.onSelectionChange);\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n\n this.detachMouseEvent();\n this.editor = null;\n }\n\n getState(): SelectionPluginState {\n return this.state;\n }\n\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'mouseDown':\n this.onMouseDown(this.editor, event.rawEvent);\n break;\n\n case 'mouseUp':\n this.onMouseUp(this.editor, event);\n break;\n\n case 'keyDown':\n this.onKeyDown(this.editor, event.rawEvent);\n break;\n\n case 'contentChanged':\n this.state.tableSelection = null;\n break;\n\n case 'scroll':\n if (!this.editor.hasFocus()) {\n this.scrollTopCache = event.scrollContainer.scrollTop;\n }\n break;\n }\n }\n\n private onMouseDown(editor: IEditor, rawEvent: MouseEvent) {\n const selection = editor.getDOMSelection();\n let image: HTMLImageElement | null;\n\n // Image selection\n if (editor.isExperimentalFeatureEnabled('LegacyImageSelection')) {\n if (\n rawEvent.button === MouseRightButton &&\n (image =\n this.getClickingImage(rawEvent) ??\n this.getContainedTargetImage(rawEvent, selection)) &&\n image.isContentEditable\n ) {\n this.selectImageWithRange(image, rawEvent);\n return;\n } else if (selection?.type == 'image' && selection.image !== rawEvent.target) {\n this.selectBeforeOrAfterElement(editor, selection.image);\n return;\n }\n } else {\n if (\n selection?.type == 'image' &&\n (rawEvent.button == MouseLeftButton ||\n (rawEvent.button == MouseRightButton &&\n !this.getClickingImage(rawEvent) &&\n !this.getContainedTargetImage(rawEvent, selection)))\n ) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n if (\n (image =\n this.getClickingImage(rawEvent) ??\n this.getContainedTargetImage(rawEvent, selection)) &&\n image.isContentEditable\n ) {\n this.setDOMSelection(\n {\n type: 'image',\n image: image,\n },\n null\n );\n return;\n }\n }\n\n // Table selection\n if (selection?.type == 'table' && rawEvent.button == MouseLeftButton) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n let tableSelection: TableSelectionInfo | null;\n const target = rawEvent.target as Node;\n\n if (\n target &&\n rawEvent.button == MouseLeftButton &&\n (tableSelection = this.parseTableSelection(target, target, editor.getDOMHelper()))\n ) {\n this.state.tableSelection = tableSelection;\n\n if (rawEvent.detail >= 3) {\n const lastCo = findCoordinate(\n tableSelection.parsedTable,\n rawEvent.target as Node,\n editor.getDOMHelper()\n );\n\n if (lastCo) {\n // Triple click, select the current cell\n tableSelection.lastCo = lastCo;\n this.updateTableSelection(lastCo);\n rawEvent.preventDefault();\n }\n }\n\n this.state.mouseDisposer = editor.attachDomEvent({\n mousemove: {\n beforeDispatch: this.onMouseMove,\n },\n });\n }\n }\n\n private selectImageWithRange(image: HTMLImageElement, event: Event) {\n const range = image.ownerDocument.createRange();\n range.selectNode(image);\n\n const domSelection = this.editor?.getDOMSelection();\n if (domSelection?.type == 'image' && image == domSelection.image) {\n event.preventDefault();\n } else {\n this.setDOMSelection(\n {\n type: 'range',\n isReverted: false,\n range,\n },\n null\n );\n }\n }\n\n private onMouseMove = (event: Event) => {\n if (this.editor && this.state.tableSelection) {\n const hasTableSelection = !!this.state.tableSelection.lastCo;\n const currentNode = event.target as Node;\n const domHelper = this.editor.getDOMHelper();\n\n const range = this.editor.getDocument().createRange();\n const startNode = this.state.tableSelection.startNode;\n const isReverted =\n currentNode.compareDocumentPosition(startNode) == Node.DOCUMENT_POSITION_FOLLOWING;\n\n if (isReverted) {\n range.setStart(currentNode, 0);\n range.setEnd(\n startNode,\n isNodeOfType(startNode, 'TEXT_NODE')\n ? startNode.nodeValue?.length ?? 0\n : startNode.childNodes.length\n );\n } else {\n range.setStart(startNode, 0);\n range.setEnd(currentNode, 0);\n }\n\n // Use common container of the range to search a common table that covers both start and end node\n const tableStart = range.commonAncestorContainer;\n const newTableSelection = this.parseTableSelection(tableStart, startNode, domHelper);\n\n if (newTableSelection) {\n const lastCo = findCoordinate(\n newTableSelection.parsedTable,\n currentNode,\n domHelper\n );\n\n if (newTableSelection.table != this.state.tableSelection.table) {\n // Move mouse into another table (nest table scenario)\n this.state.tableSelection = newTableSelection;\n this.state.tableSelection.lastCo = lastCo ?? undefined;\n }\n\n const updated = lastCo && this.updateTableSelection(lastCo);\n\n if (hasTableSelection || updated) {\n event.preventDefault();\n }\n } else if (this.editor.getDOMSelection()?.type == 'table') {\n // Move mouse out of table\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted,\n },\n this.state.tableSelection\n );\n }\n }\n };\n\n private onMouseUp(editor: IEditor, event: MouseUpEvent) {\n let image: HTMLImageElement | null;\n\n if (\n editor.isExperimentalFeatureEnabled('LegacyImageSelection') &&\n (image = this.getClickingImage(event.rawEvent)) &&\n image.isContentEditable &&\n event.rawEvent.button != MouseMiddleButton &&\n (event.rawEvent.button ==\n MouseRightButton /* it's not possible to drag using right click */ ||\n event.isClicking)\n ) {\n this.selectImageWithRange(image, event.rawEvent);\n }\n\n this.detachMouseEvent();\n }\n\n private onDrop = () => {\n this.detachMouseEvent();\n };\n\n private onKeyDown(editor: IEditor, rawEvent: KeyboardEvent) {\n const key = rawEvent.key;\n const selection = editor.getDOMSelection();\n const win = editor.getDocument().defaultView;\n\n switch (selection?.type) {\n case 'image':\n if (!isModifierKey(rawEvent) && !rawEvent.shiftKey && selection.image.parentNode) {\n if (key === 'Escape') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n rawEvent.stopPropagation();\n } else if (key !== 'Delete' && key !== 'Backspace') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n }\n }\n break;\n\n case 'range':\n if (key == Up || key == Down || key == Left || key == Right || key == Tab) {\n const start = selection.range.startContainer;\n this.state.tableSelection = this.parseTableSelection(\n start,\n start,\n editor.getDOMHelper()\n );\n\n if (this.state.tableSelection && !rawEvent.defaultPrevented) {\n if (key == Tab) {\n this.handleSelectionInTable(this.getTabKey(rawEvent));\n rawEvent.preventDefault();\n } else {\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n\n case 'table':\n if (this.state.tableSelection?.lastCo) {\n const { shiftKey, key } = rawEvent;\n\n if (shiftKey && (key == Left || key == Right)) {\n const isRtl =\n win?.getComputedStyle(this.state.tableSelection.table).direction ==\n 'rtl';\n\n this.updateTableSelectionFromKeyboard(\n 0,\n (key == Left ? -1 : 1) * (isRtl ? -1 : 1)\n );\n rawEvent.preventDefault();\n } else if (shiftKey && (key == Up || key == Down)) {\n this.updateTableSelectionFromKeyboard(key == Up ? -1 : 1, 0);\n rawEvent.preventDefault();\n } else if (key != 'Shift' && !isCharacterValue(rawEvent)) {\n if (key == Up || key == Down || key == Left || key == Right) {\n this.setDOMSelection(null /*domSelection*/, this.state.tableSelection);\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n }\n }\n\n private getTabKey(rawEvent: KeyboardEvent) {\n return rawEvent.shiftKey ? 'TabLeft' : 'TabRight';\n }\n\n private handleSelectionInTable(\n key: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'TabLeft' | 'TabRight'\n ) {\n if (!this.editor || !this.state.tableSelection) {\n return;\n }\n\n const selection = this.editor.getDOMSelection();\n const domHelper = this.editor.getDOMHelper();\n\n if (selection?.type == 'range') {\n const {\n range: { collapsed, startContainer, endContainer, commonAncestorContainer },\n isReverted,\n } = selection;\n const start = isReverted ? endContainer : startContainer;\n const end: Node | null = isReverted ? startContainer : endContainer;\n const tableSel = this.parseTableSelection(commonAncestorContainer, start, domHelper);\n\n if (!tableSel) {\n return;\n }\n\n let lastCo = findCoordinate(tableSel?.parsedTable, end, domHelper);\n let tabMove = false;\n const { parsedTable, firstCo: oldCo, table } = this.state.tableSelection;\n\n if (lastCo && tableSel.table == table) {\n if (lastCo.col != oldCo.col && (key == Up || key == Down)) {\n const change = key == Up ? -1 : 1;\n const originalTd = findTableCellElement(parsedTable, oldCo)?.cell;\n let td: HTMLTableCellElement | null = null;\n\n lastCo = { row: oldCo.row + change, col: oldCo.col };\n\n while (lastCo.row >= 0 && lastCo.row < parsedTable.length) {\n td = findTableCellElement(parsedTable, lastCo)?.cell || null;\n\n if (td == originalTd) {\n lastCo.row += change;\n } else {\n break;\n }\n }\n\n if (collapsed && td) {\n this.setRangeSelectionInTable(\n td,\n key == Up ? td.childNodes.length : 0,\n this.editor\n );\n }\n } else if (key == 'TabLeft' || key == 'TabRight') {\n const reverse = key == 'TabLeft';\n for (\n let step = reverse ? -1 : 1,\n row = lastCo.row ?? 0,\n col = (lastCo.col ?? 0) + step;\n ;\n col += step\n ) {\n if (col < 0 || col >= parsedTable[row].length) {\n row += step;\n if (row < 0) {\n this.selectBeforeOrAfterElement(this.editor, tableSel.table);\n break;\n } else if (row >= parsedTable.length) {\n this.selectBeforeOrAfterElement(\n this.editor,\n tableSel.table,\n true /*after*/\n );\n break;\n }\n col = reverse ? parsedTable[row].length - 1 : 0;\n }\n const cell = parsedTable[row][col];\n\n if (typeof cell != 'string') {\n tabMove = true;\n this.setRangeSelectionInTable(\n cell,\n 0,\n this.editor,\n true /* selectAll */\n );\n lastCo.row = row;\n lastCo.col = col;\n break;\n }\n }\n } else {\n this.state.tableSelection = null;\n }\n\n if (\n collapsed &&\n (lastCo.col != oldCo.col || lastCo.row != oldCo.row) &&\n lastCo.row >= 0 &&\n lastCo.row == parsedTable.length - 1 &&\n lastCo.col == parsedTable[lastCo.row]?.length - 1\n ) {\n this.editor?.announce({ defaultStrings: 'announceOnFocusLastCell' });\n }\n }\n\n if (!collapsed && lastCo && !tabMove) {\n this.state.tableSelection = tableSel;\n this.updateTableSelection(lastCo);\n }\n }\n }\n\n private setRangeSelectionInTable(\n cell: Node,\n nodeOffset: number,\n editor: IEditor,\n selectAll?: boolean\n ) {\n const range = editor.getDocument().createRange();\n if (selectAll) {\n range.selectNodeContents(cell);\n } else {\n // Get deepest editable position in the cell\n const { node, offset } = normalizePos(cell, nodeOffset);\n\n range.setStart(node, offset);\n range.collapse(true /* toStart */);\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n\n private updateTableSelectionFromKeyboard(rowChange: number, colChange: number) {\n if (this.state.tableSelection?.lastCo && this.editor) {\n const { lastCo, parsedTable } = this.state.tableSelection;\n const row = lastCo.row + rowChange;\n const col = lastCo.col + colChange;\n\n if (row >= 0 && row < parsedTable.length && col >= 0 && col < parsedTable[row].length) {\n this.updateTableSelection({ row, col });\n }\n }\n }\n\n private selectBeforeOrAfterElement(editor: IEditor, element: HTMLElement, after?: boolean) {\n const doc = editor.getDocument();\n const parent = element.parentNode;\n const index = parent && toArray(parent.childNodes).indexOf(element);\n\n if (parent && index !== null && index >= 0) {\n const range = doc.createRange();\n range.setStart(parent, index + (after ? 1 : 0));\n range.collapse();\n\n this.setDOMSelection(\n {\n type: 'range',\n range: range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n }\n\n private getClickingImage(event: UIEvent): HTMLImageElement | null {\n const target = event.target as Node;\n\n return isNodeOfType(target, 'ELEMENT_NODE') && isElementOfType(target, 'img')\n ? target\n : null;\n }\n\n // MacOS will not create a mouseUp event if contextMenu event is not prevent defaulted.\n // Make sure we capture image target even if image is wrapped\n private getContainedTargetImage = (\n event: MouseEvent,\n previousSelection: DOMSelection | null\n ): HTMLImageElement | null => {\n if (!this.isMac || !previousSelection || previousSelection.type !== 'image') {\n return null;\n }\n\n const target = event.target as Node;\n if (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n isElementOfType(target, 'span') &&\n target.firstChild === previousSelection.image\n ) {\n return previousSelection.image;\n }\n return null;\n };\n\n private onFocus = () => {\n if (!this.state.skipReselectOnFocus && this.state.selection) {\n this.setDOMSelection(this.state.selection, this.state.tableSelection);\n }\n\n if (this.state.selection?.type == 'range' && !this.isSafari) {\n // Editor is focused, now we can get live selection. So no need to keep a selection if the selection type is range.\n this.state.selection = null;\n }\n\n if (this.scrollTopCache && this.editor) {\n const sc = this.editor.getScrollContainer();\n sc.scrollTop = this.scrollTopCache;\n this.scrollTopCache = 0;\n }\n };\n\n private onBlur = () => {\n if (this.editor) {\n if (!this.state.selection) {\n this.state.selection = this.editor.getDOMSelection();\n }\n const sc = this.editor.getScrollContainer();\n this.scrollTopCache = sc.scrollTop;\n }\n };\n\n private onSelectionChange = () => {\n if (this.editor?.hasFocus() && !this.editor.isInShadowEdit()) {\n const newSelection = this.editor.getDOMSelection();\n\n //If am image selection changed to a wider range due a keyboard event, we should update the selection\n const selection = this.editor.getDocument().getSelection();\n\n if (\n newSelection?.type == 'image' &&\n selection &&\n selection.focusNode &&\n !isSingleImageInSelection(selection)\n ) {\n const range = selection.getRangeAt(0);\n this.editor.setDOMSelection({\n type: 'range',\n range,\n isReverted:\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset,\n });\n }\n\n // Safari has problem to handle onBlur event. When blur, we cannot get the original selection from editor.\n // So we always save a selection whenever editor has focus. Then after blur, we can still use this cached selection.\n if (newSelection?.type == 'range') {\n if (this.isSafari) {\n this.state.selection = newSelection;\n }\n this.trySelectSingleImage(newSelection);\n }\n }\n };\n\n private parseTableSelection(\n tableStart: Node,\n tdStart: Node,\n domHelper: DOMHelper\n ): TableSelectionInfo | null {\n let table: HTMLTableElement | null;\n let parsedTable: ParsedTable | null;\n let firstCo: TableCellCoordinate | null;\n\n if (\n (table = domHelper.findClosestElementAncestor(tableStart, 'table')) &&\n table.isContentEditable &&\n (parsedTable = parseTableCells(table)) &&\n (firstCo = findCoordinate(parsedTable, tdStart, domHelper))\n ) {\n return { table, parsedTable, firstCo, startNode: tdStart };\n } else {\n return null;\n }\n }\n\n private updateTableSelection(lastCo: TableCellCoordinate) {\n if (this.state.tableSelection && this.editor) {\n const {\n table,\n firstCo,\n parsedTable,\n startNode,\n lastCo: oldCo,\n } = this.state.tableSelection;\n\n if (oldCo || firstCo.row != lastCo.row || firstCo.col != lastCo.col) {\n this.state.tableSelection.lastCo = lastCo;\n\n this.setDOMSelection(\n {\n type: 'table',\n table,\n firstRow: firstCo.row,\n firstColumn: firstCo.col,\n lastRow: lastCo.row,\n lastColumn: lastCo.col,\n },\n { table, firstCo, lastCo, parsedTable, startNode }\n );\n\n return true;\n }\n }\n\n return false;\n }\n\n private setDOMSelection(\n selection: DOMSelection | null,\n tableSelection: TableSelectionInfo | null\n ) {\n this.editor?.setDOMSelection(selection);\n this.state.tableSelection = tableSelection;\n }\n\n private detachMouseEvent() {\n if (this.state.mouseDisposer) {\n this.state.mouseDisposer();\n this.state.mouseDisposer = undefined;\n }\n }\n\n private trySelectSingleImage(selection: RangeSelection) {\n if (!selection.range.collapsed) {\n const image = isSingleImageInSelection(selection.range);\n if (image) {\n this.setDOMSelection(\n {\n type: 'image',\n image: image,\n },\n null /*tableSelection*/\n );\n }\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of SelectionPlugin.\n * @param option The editor option\n */\nexport function createSelectionPlugin(\n options: EditorOptions\n): PluginWithState<SelectionPluginState> {\n return new SelectionPlugin(options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SelectionPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { findCoordinate } from './findCoordinate';\nimport { findTableCellElement } from '../../coreApi/setDOMSelection/findTableCellElement';\nimport { isSingleImageInSelection } from './isSingleImageInSelection';\nimport { normalizePos } from './normalizePos';\nimport {\n isCharacterValue,\n isElementOfType,\n isModifierKey,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n PluginEvent,\n PluginWithState,\n SelectionPluginState,\n EditorOptions,\n DOMHelper,\n ParsedTable,\n TableSelectionInfo,\n TableCellCoordinate,\n RangeSelection,\n MouseUpEvent,\n} from 'roosterjs-content-model-types';\n\nconst MouseLeftButton = 0;\nconst MouseMiddleButton = 1;\nconst MouseRightButton = 2;\nconst Up = 'ArrowUp';\nconst Down = 'ArrowDown';\nconst Left = 'ArrowLeft';\nconst Right = 'ArrowRight';\nconst Tab = 'Tab';\n\n/**\n * @internal\n */\nexport const DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n/**\n * @internal\n */\nexport const DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR = '#C6C6C6';\n\nclass SelectionPlugin implements PluginWithState<SelectionPluginState> {\n private editor: IEditor | null = null;\n private state: SelectionPluginState;\n private disposer: (() => void) | null = null;\n private isSafari = false;\n private isMac = false;\n private scrollTopCache: number = 0;\n\n constructor(options: EditorOptions) {\n this.state = {\n selection: null,\n tableSelection: null,\n imageSelectionBorderColor:\n options.imageSelectionBorderColor ?? DEFAULT_SELECTION_BORDER_COLOR,\n imageSelectionBorderColorDark: options.imageSelectionBorderColor\n ? undefined\n : DEFAULT_SELECTION_BORDER_COLOR,\n tableCellSelectionBackgroundColor:\n options.tableCellSelectionBackgroundColor ??\n DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n tableCellSelectionBackgroundColorDark: options.tableCellSelectionBackgroundColor\n ? undefined\n : DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n };\n }\n\n getName() {\n return 'Selection';\n }\n\n initialize(editor: IEditor) {\n this.editor = editor;\n\n if (!this.state.imageSelectionBorderColorDark && this.state.imageSelectionBorderColor) {\n this.state.imageSelectionBorderColorDark = editor\n .getColorManager()\n .getDarkColor(this.state.imageSelectionBorderColor, undefined, 'border');\n }\n\n if (\n !this.state.tableCellSelectionBackgroundColorDark &&\n this.state.tableCellSelectionBackgroundColor\n ) {\n this.state.tableCellSelectionBackgroundColorDark = editor\n .getColorManager()\n .getDarkColor(\n this.state.tableCellSelectionBackgroundColor,\n undefined,\n 'background'\n );\n }\n\n const env = this.editor.getEnvironment();\n const document = this.editor.getDocument();\n\n this.isSafari = !!env.isSafari;\n this.isMac = !!env.isMac;\n document.addEventListener('selectionchange', this.onSelectionChange);\n if (this.isSafari) {\n this.disposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n drop: { beforeDispatch: this.onDrop },\n });\n } else {\n this.disposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n blur: { beforeDispatch: this.onBlur },\n drop: { beforeDispatch: this.onDrop },\n });\n }\n }\n\n dispose() {\n this.editor?.getDocument().removeEventListener('selectionchange', this.onSelectionChange);\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n\n this.detachMouseEvent();\n this.editor = null;\n }\n\n getState(): SelectionPluginState {\n return this.state;\n }\n\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'mouseDown':\n this.onMouseDown(this.editor, event.rawEvent);\n break;\n\n case 'mouseUp':\n this.onMouseUp(this.editor, event);\n break;\n\n case 'keyDown':\n this.onKeyDown(this.editor, event.rawEvent);\n break;\n\n case 'contentChanged':\n this.state.tableSelection = null;\n break;\n\n case 'scroll':\n if (!this.editor.hasFocus()) {\n this.scrollTopCache = event.scrollContainer.scrollTop;\n }\n break;\n }\n }\n\n private onMouseDown(editor: IEditor, rawEvent: MouseEvent) {\n const selection = editor.getDOMSelection();\n let image: HTMLImageElement | null;\n\n // Image selection\n if (editor.isExperimentalFeatureEnabled('LegacyImageSelection')) {\n if (\n rawEvent.button === MouseRightButton &&\n (image =\n this.getClickingImage(rawEvent) ??\n this.getContainedTargetImage(rawEvent, selection)) &&\n image.isContentEditable\n ) {\n this.selectImageWithRange(image, rawEvent);\n return;\n } else if (selection?.type == 'image' && selection.image !== rawEvent.target) {\n this.selectBeforeOrAfterElement(editor, selection.image);\n return;\n }\n } else {\n if (\n selection?.type == 'image' &&\n (rawEvent.button == MouseLeftButton ||\n (rawEvent.button == MouseRightButton &&\n !this.getClickingImage(rawEvent) &&\n !this.getContainedTargetImage(rawEvent, selection)))\n ) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n if (\n (image =\n this.getClickingImage(rawEvent) ??\n this.getContainedTargetImage(rawEvent, selection)) &&\n image.isContentEditable\n ) {\n this.setDOMSelection(\n {\n type: 'image',\n image: image,\n },\n null\n );\n return;\n }\n }\n\n // Table selection\n if (selection?.type == 'table' && rawEvent.button == MouseLeftButton) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n let tableSelection: TableSelectionInfo | null;\n const target = rawEvent.target as Node;\n\n if (\n target &&\n rawEvent.button == MouseLeftButton &&\n (tableSelection = this.parseTableSelection(target, target, editor.getDOMHelper()))\n ) {\n this.state.tableSelection = tableSelection;\n\n if (rawEvent.detail >= 3) {\n const lastCo = findCoordinate(\n tableSelection.parsedTable,\n rawEvent.target as Node,\n editor.getDOMHelper()\n );\n\n if (lastCo) {\n // Triple click, select the current cell\n tableSelection.lastCo = lastCo;\n this.updateTableSelection(lastCo);\n rawEvent.preventDefault();\n }\n }\n\n this.state.mouseDisposer = editor.attachDomEvent({\n mousemove: {\n beforeDispatch: this.onMouseMove,\n },\n });\n }\n }\n\n private selectImageWithRange(image: HTMLImageElement, event: Event) {\n const range = image.ownerDocument.createRange();\n range.selectNode(image);\n\n const domSelection = this.editor?.getDOMSelection();\n if (domSelection?.type == 'image' && image == domSelection.image) {\n event.preventDefault();\n } else {\n this.setDOMSelection(\n {\n type: 'range',\n isReverted: false,\n range,\n },\n null\n );\n }\n }\n\n private onMouseMove = (event: Event) => {\n if (this.editor && this.state.tableSelection) {\n const hasTableSelection = !!this.state.tableSelection.lastCo;\n const currentNode = event.target as Node;\n const domHelper = this.editor.getDOMHelper();\n\n const range = this.editor.getDocument().createRange();\n const startNode = this.state.tableSelection.startNode;\n const isReverted =\n currentNode.compareDocumentPosition(startNode) == Node.DOCUMENT_POSITION_FOLLOWING;\n\n if (isReverted) {\n range.setStart(currentNode, 0);\n range.setEnd(\n startNode,\n isNodeOfType(startNode, 'TEXT_NODE')\n ? startNode.nodeValue?.length ?? 0\n : startNode.childNodes.length\n );\n } else {\n range.setStart(startNode, 0);\n range.setEnd(currentNode, 0);\n }\n\n // Use common container of the range to search a common table that covers both start and end node\n const tableStart = range.commonAncestorContainer;\n const newTableSelection = this.parseTableSelection(tableStart, startNode, domHelper);\n\n if (newTableSelection) {\n const lastCo = findCoordinate(\n newTableSelection.parsedTable,\n currentNode,\n domHelper\n );\n\n if (newTableSelection.table != this.state.tableSelection.table) {\n // Move mouse into another table (nest table scenario)\n this.state.tableSelection = newTableSelection;\n this.state.tableSelection.lastCo = lastCo ?? undefined;\n }\n\n const updated = lastCo && this.updateTableSelection(lastCo);\n\n if (hasTableSelection || updated) {\n event.preventDefault();\n }\n } else if (this.editor.getDOMSelection()?.type == 'table') {\n // Move mouse out of table\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted,\n },\n this.state.tableSelection\n );\n }\n }\n };\n\n private onMouseUp(editor: IEditor, event: MouseUpEvent) {\n let image: HTMLImageElement | null;\n\n if (\n editor.isExperimentalFeatureEnabled('LegacyImageSelection') &&\n (image = this.getClickingImage(event.rawEvent)) &&\n image.isContentEditable &&\n event.rawEvent.button != MouseMiddleButton &&\n (event.rawEvent.button ==\n MouseRightButton /* it's not possible to drag using right click */ ||\n event.isClicking)\n ) {\n this.selectImageWithRange(image, event.rawEvent);\n }\n\n this.detachMouseEvent();\n }\n\n private onDrop = () => {\n this.detachMouseEvent();\n };\n\n private onKeyDown(editor: IEditor, rawEvent: KeyboardEvent) {\n const key = rawEvent.key;\n const selection = editor.getDOMSelection();\n const win = editor.getDocument().defaultView;\n\n switch (selection?.type) {\n case 'image':\n if (!isModifierKey(rawEvent) && !rawEvent.shiftKey && selection.image.parentNode) {\n if (key === 'Escape') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n rawEvent.stopPropagation();\n } else if (key !== 'Delete' && key !== 'Backspace') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n }\n }\n break;\n\n case 'range':\n if (key == Up || key == Down || key == Left || key == Right || key == Tab) {\n const start = selection.range.startContainer;\n this.state.tableSelection = this.parseTableSelection(\n start,\n start,\n editor.getDOMHelper()\n );\n\n if (this.state.tableSelection && !rawEvent.defaultPrevented) {\n if (key == Tab) {\n this.handleSelectionInTable(this.getTabKey(rawEvent));\n rawEvent.preventDefault();\n } else {\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n\n case 'table':\n if (this.state.tableSelection?.lastCo) {\n const { shiftKey, key } = rawEvent;\n\n if (shiftKey && (key == Left || key == Right)) {\n const isRtl =\n win?.getComputedStyle(this.state.tableSelection.table).direction ==\n 'rtl';\n\n this.updateTableSelectionFromKeyboard(\n 0,\n (key == Left ? -1 : 1) * (isRtl ? -1 : 1)\n );\n rawEvent.preventDefault();\n } else if (shiftKey && (key == Up || key == Down)) {\n this.updateTableSelectionFromKeyboard(key == Up ? -1 : 1, 0);\n rawEvent.preventDefault();\n } else if (key != 'Shift' && !isCharacterValue(rawEvent)) {\n if (key == Up || key == Down || key == Left || key == Right) {\n this.setDOMSelection(null /*domSelection*/, this.state.tableSelection);\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n }\n }\n\n private getTabKey(rawEvent: KeyboardEvent) {\n return rawEvent.shiftKey ? 'TabLeft' : 'TabRight';\n }\n\n private handleSelectionInTable(\n key: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'TabLeft' | 'TabRight'\n ) {\n if (!this.editor || !this.state.tableSelection) {\n return;\n }\n\n const selection = this.editor.getDOMSelection();\n const domHelper = this.editor.getDOMHelper();\n\n if (selection?.type == 'range') {\n const {\n range: { collapsed, startContainer, endContainer, commonAncestorContainer },\n isReverted,\n } = selection;\n const start = isReverted ? endContainer : startContainer;\n const end: Node | null = isReverted ? startContainer : endContainer;\n const tableSel = this.parseTableSelection(commonAncestorContainer, start, domHelper);\n\n if (!tableSel) {\n return;\n }\n\n let lastCo = findCoordinate(tableSel?.parsedTable, end, domHelper);\n let tabMove = false;\n const { parsedTable, firstCo: oldCo, table } = this.state.tableSelection;\n\n if (lastCo && tableSel.table == table) {\n if (lastCo.col != oldCo.col && (key == Up || key == Down)) {\n const change = key == Up ? -1 : 1;\n const originalTd = findTableCellElement(parsedTable, oldCo)?.cell;\n let td: HTMLTableCellElement | null = null;\n\n lastCo = { row: oldCo.row + change, col: oldCo.col };\n\n while (lastCo.row >= 0 && lastCo.row < parsedTable.length) {\n td = findTableCellElement(parsedTable, lastCo)?.cell || null;\n\n if (td == originalTd) {\n lastCo.row += change;\n } else {\n break;\n }\n }\n\n if (collapsed && td) {\n this.setRangeSelectionInTable(\n td,\n key == Up ? td.childNodes.length : 0,\n this.editor\n );\n } else if (!td && (lastCo.row == -1 || lastCo.row <= parsedTable.length)) {\n this.selectBeforeOrAfterElement(\n this.editor,\n table,\n change == 1 /* after */,\n change != 1 /* setSelectionInNextSiblingElement */\n );\n }\n } else if (key == 'TabLeft' || key == 'TabRight') {\n const reverse = key == 'TabLeft';\n for (\n let step = reverse ? -1 : 1,\n row = lastCo.row ?? 0,\n col = (lastCo.col ?? 0) + step;\n ;\n col += step\n ) {\n if (col < 0 || col >= parsedTable[row].length) {\n row += step;\n if (row < 0) {\n this.selectBeforeOrAfterElement(this.editor, tableSel.table);\n break;\n } else if (row >= parsedTable.length) {\n this.selectBeforeOrAfterElement(\n this.editor,\n tableSel.table,\n true /*after*/\n );\n break;\n }\n col = reverse ? parsedTable[row].length - 1 : 0;\n }\n const cell = parsedTable[row][col];\n\n if (typeof cell != 'string') {\n tabMove = true;\n this.setRangeSelectionInTable(\n cell,\n 0,\n this.editor,\n true /* selectAll */\n );\n lastCo.row = row;\n lastCo.col = col;\n break;\n }\n }\n } else {\n this.state.tableSelection = null;\n }\n\n if (\n collapsed &&\n (lastCo.col != oldCo.col || lastCo.row != oldCo.row) &&\n lastCo.row >= 0 &&\n lastCo.row == parsedTable.length - 1 &&\n lastCo.col == parsedTable[lastCo.row]?.length - 1\n ) {\n this.editor?.announce({ defaultStrings: 'announceOnFocusLastCell' });\n }\n }\n\n if (!collapsed && lastCo && !tabMove) {\n this.state.tableSelection = tableSel;\n this.updateTableSelection(lastCo);\n }\n }\n }\n\n private setRangeSelectionInTable(\n cell: Node,\n nodeOffset: number,\n editor: IEditor,\n selectAll?: boolean\n ) {\n const range = editor.getDocument().createRange();\n if (selectAll) {\n range.selectNodeContents(cell);\n } else {\n // Get deepest editable position in the cell\n const { node, offset } = normalizePos(cell, nodeOffset);\n\n range.setStart(node, offset);\n range.collapse(true /* toStart */);\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n\n private updateTableSelectionFromKeyboard(rowChange: number, colChange: number) {\n if (this.state.tableSelection?.lastCo && this.editor) {\n const { lastCo, parsedTable } = this.state.tableSelection;\n const row = lastCo.row + rowChange;\n const col = lastCo.col + colChange;\n\n if (row >= 0 && row < parsedTable.length && col >= 0 && col < parsedTable[row].length) {\n this.updateTableSelection({ row, col });\n }\n }\n }\n\n private selectBeforeOrAfterElement(\n editor: IEditor,\n element: HTMLElement,\n after?: boolean,\n setSelectionInNextSiblingElement?: boolean\n ) {\n const doc = editor.getDocument();\n const parent = element.parentNode;\n const index = parent && toArray(parent.childNodes).indexOf(element);\n let sibling: Element | undefined | null;\n\n if (parent && index !== null && index >= 0) {\n const range = doc.createRange();\n if (\n setSelectionInNextSiblingElement &&\n (sibling = after ? element.nextElementSibling : element.previousElementSibling) &&\n isNodeOfType(sibling, 'ELEMENT_NODE')\n ) {\n range.selectNodeContents(sibling);\n range.collapse(false /* toStart */);\n } else {\n range.setStart(parent, index + (after ? 1 : 0));\n range.collapse();\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range: range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n }\n\n private getClickingImage(event: UIEvent): HTMLImageElement | null {\n const target = event.target as Node;\n\n return isNodeOfType(target, 'ELEMENT_NODE') && isElementOfType(target, 'img')\n ? target\n : null;\n }\n\n // MacOS will not create a mouseUp event if contextMenu event is not prevent defaulted.\n // Make sure we capture image target even if image is wrapped\n private getContainedTargetImage = (\n event: MouseEvent,\n previousSelection: DOMSelection | null\n ): HTMLImageElement | null => {\n if (!this.isMac || !previousSelection || previousSelection.type !== 'image') {\n return null;\n }\n\n const target = event.target as Node;\n if (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n isElementOfType(target, 'span') &&\n target.firstChild === previousSelection.image\n ) {\n return previousSelection.image;\n }\n return null;\n };\n\n private onFocus = () => {\n if (!this.state.skipReselectOnFocus && this.state.selection) {\n this.setDOMSelection(this.state.selection, this.state.tableSelection);\n }\n\n if (this.state.selection?.type == 'range' && !this.isSafari) {\n // Editor is focused, now we can get live selection. So no need to keep a selection if the selection type is range.\n this.state.selection = null;\n }\n\n if (this.scrollTopCache && this.editor) {\n const sc = this.editor.getScrollContainer();\n sc.scrollTop = this.scrollTopCache;\n this.scrollTopCache = 0;\n }\n };\n\n private onBlur = () => {\n if (this.editor) {\n if (!this.state.selection) {\n this.state.selection = this.editor.getDOMSelection();\n }\n const sc = this.editor.getScrollContainer();\n this.scrollTopCache = sc.scrollTop;\n }\n };\n\n private onSelectionChange = () => {\n if (this.editor?.hasFocus() && !this.editor.isInShadowEdit()) {\n const newSelection = this.editor.getDOMSelection();\n\n //If am image selection changed to a wider range due a keyboard event, we should update the selection\n const selection = this.editor.getDocument().getSelection();\n\n if (\n newSelection?.type == 'image' &&\n selection &&\n selection.focusNode &&\n !isSingleImageInSelection(selection)\n ) {\n const range = selection.getRangeAt(0);\n this.editor.setDOMSelection({\n type: 'range',\n range,\n isReverted:\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset,\n });\n }\n\n // Safari has problem to handle onBlur event. When blur, we cannot get the original selection from editor.\n // So we always save a selection whenever editor has focus. Then after blur, we can still use this cached selection.\n if (newSelection?.type == 'range') {\n if (this.isSafari) {\n this.state.selection = newSelection;\n }\n this.trySelectSingleImage(newSelection);\n }\n }\n };\n\n private parseTableSelection(\n tableStart: Node,\n tdStart: Node,\n domHelper: DOMHelper\n ): TableSelectionInfo | null {\n let table: HTMLTableElement | null;\n let parsedTable: ParsedTable | null;\n let firstCo: TableCellCoordinate | null;\n\n if (\n (table = domHelper.findClosestElementAncestor(tableStart, 'table')) &&\n table.isContentEditable &&\n (parsedTable = parseTableCells(table)) &&\n (firstCo = findCoordinate(parsedTable, tdStart, domHelper))\n ) {\n return { table, parsedTable, firstCo, startNode: tdStart };\n } else {\n return null;\n }\n }\n\n private updateTableSelection(lastCo: TableCellCoordinate) {\n if (this.state.tableSelection && this.editor) {\n const {\n table,\n firstCo,\n parsedTable,\n startNode,\n lastCo: oldCo,\n } = this.state.tableSelection;\n\n if (oldCo || firstCo.row != lastCo.row || firstCo.col != lastCo.col) {\n this.state.tableSelection.lastCo = lastCo;\n\n this.setDOMSelection(\n {\n type: 'table',\n table,\n firstRow: firstCo.row,\n firstColumn: firstCo.col,\n lastRow: lastCo.row,\n lastColumn: lastCo.col,\n },\n { table, firstCo, lastCo, parsedTable, startNode }\n );\n\n return true;\n }\n }\n\n return false;\n }\n\n private setDOMSelection(\n selection: DOMSelection | null,\n tableSelection: TableSelectionInfo | null\n ) {\n this.editor?.setDOMSelection(selection);\n this.state.tableSelection = tableSelection;\n }\n\n private detachMouseEvent() {\n if (this.state.mouseDisposer) {\n this.state.mouseDisposer();\n this.state.mouseDisposer = undefined;\n }\n }\n\n private trySelectSingleImage(selection: RangeSelection) {\n if (!selection.range.collapsed) {\n const image = isSingleImageInSelection(selection.range);\n if (image) {\n this.setDOMSelection(\n {\n type: 'image',\n image: image,\n },\n null /*tableSelection*/\n );\n }\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of SelectionPlugin.\n * @param option The editor option\n */\nexport function createSelectionPlugin(\n options: EditorOptions\n): PluginWithState<SelectionPluginState> {\n return new SelectionPlugin(options);\n}\n"]}
|
|
@@ -22,13 +22,15 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
22
22
|
styles.forEach(function (styleNode) {
|
|
23
23
|
var _a;
|
|
24
24
|
var sheet = styleNode.sheet;
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
if (sheet) {
|
|
26
|
+
for (var ruleIndex = 0; ruleIndex < sheet.cssRules.length; ruleIndex++) {
|
|
27
|
+
var rule = sheet.cssRules[ruleIndex];
|
|
28
|
+
if (rule.type == CSSRule.STYLE_RULE && rule.selectorText) {
|
|
29
|
+
result.push({
|
|
30
|
+
selectors: splitSelectors(rule.selectorText),
|
|
31
|
+
text: rule.style.cssText,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
(_a = styleNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(styleNode);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertInlineCss.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/convertInlineCss.ts"],"names":[],"mappings":";;;;IAUA;;;;;;OAMG;IACH,SAAS,cAAc,CAAC,YAAoB;QACxC,IAAM,KAAK,GAAG,cAAc,CAAC;QAC7B,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,IAAI,EAAE,EAAR,CAAQ,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,SAAgB,gBAAgB,CAAC,GAAa;QAC1C,IAAM,MAAM,GAAG,IAAA,qCAAO,EAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QACtD,IAAM,MAAM,GAAc,EAAE,CAAC;QAE7B,MAAM,CAAC,OAAO,CAAC,UAAA,SAAS;;YACpB,IAAM,KAAK,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"convertInlineCss.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/convertInlineCss.ts"],"names":[],"mappings":";;;;IAUA;;;;;;OAMG;IACH,SAAS,cAAc,CAAC,YAAoB;QACxC,IAAM,KAAK,GAAG,cAAc,CAAC;QAC7B,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,IAAI,EAAE,EAAR,CAAQ,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,SAAgB,gBAAgB,CAAC,GAAa;QAC1C,IAAM,MAAM,GAAG,IAAA,qCAAO,EAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QACtD,IAAM,MAAM,GAAc,EAAE,CAAC;QAE7B,MAAM,CAAC,OAAO,CAAC,UAAA,SAAS;;YACpB,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;YAE9B,IAAI,KAAK,EAAE;gBACP,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;oBACpE,IAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAiB,CAAC;oBAEvD,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE;wBACtD,MAAM,CAAC,IAAI,CAAC;4BACR,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;4BAC5C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;yBAC3B,CAAC,CAAC;qBACN;iBACJ;aACJ;YAED,MAAA,SAAS,CAAC,UAAU,0CAAE,WAAW,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAClB,CAAC;IAxBD,4CAwBC;IAED;;OAEG;IACH,SAAgB,gBAAgB,CAAC,IAAgB,EAAE,QAAmB;gCACzD,CAAC;;YACA,IAAA,KAAsB,QAAQ,CAAC,CAAC,CAAC,EAA/B,SAAS,eAAA,EAAE,IAAI,UAAgB,CAAC;;gBAExC,KAAuB,IAAA,6BAAA,sBAAA,SAAS,CAAA,CAAA,oCAAA,2DAAE;oBAA7B,IAAM,QAAQ,sBAAA;oBACf,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE;wBAC/B,SAAS;qBACZ;oBAED,IAAM,KAAK,GAAG,IAAA,qCAAO,EAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAEvD,qEAAqE;oBACrE,+EAA+E;oBAC/E,yCAAyC;oBACzC,KAAK,CAAC,OAAO,CAAC,UAAA,IAAI;wBACd,OAAA,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;oBAArE,CAAqE,CACxE,CAAC;iBACL;;;;;;;;;;QAhBL,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;oBAApC,CAAC;SAiBT;IACL,CAAC;IAnBD,4CAmBC","sourcesContent":["import { toArray } from 'roosterjs-content-model-dom';\n\n/**\n * @internal\n */\nexport interface CssRule {\n selectors: string[];\n text: string;\n}\n\n/**\n * @internal\n *\n * Splits CSS selectors, avoiding splits within parentheses\n * @param selectorText The CSS selector string\n * @return Array of trimmed selectors\n */\nfunction splitSelectors(selectorText: string) {\n const regex = /(?![^(]*\\)),/;\n return selectorText.split(regex).map(s => s.trim());\n}\n\n/**\n * @internal\n */\nexport function retrieveCssRules(doc: Document): CssRule[] {\n const styles = toArray(doc.querySelectorAll('style'));\n const result: CssRule[] = [];\n\n styles.forEach(styleNode => {\n const sheet = styleNode.sheet;\n\n if (sheet) {\n for (let ruleIndex = 0; ruleIndex < sheet.cssRules.length; ruleIndex++) {\n const rule = sheet.cssRules[ruleIndex] as CSSStyleRule;\n\n if (rule.type == CSSRule.STYLE_RULE && rule.selectorText) {\n result.push({\n selectors: splitSelectors(rule.selectorText),\n text: rule.style.cssText,\n });\n }\n }\n }\n\n styleNode.parentNode?.removeChild(styleNode);\n });\n\n return result;\n}\n\n/**\n * @internal\n */\nexport function convertInlineCss(root: ParentNode, cssRules: CssRule[]) {\n for (let i = cssRules.length - 1; i >= 0; i--) {\n const { selectors, text } = cssRules[i];\n\n for (const selector of selectors) {\n if (!selector || !selector.trim()) {\n continue;\n }\n\n const nodes = toArray(root.querySelectorAll(selector));\n\n // Always put existing styles after so that they have higher priority\n // Which means if both global style and inline style apply to the same element,\n // inline style will have higher priority\n nodes.forEach(node =>\n node.setAttribute('style', text + (node.getAttribute('style') || ''))\n );\n }\n }\n}\n"]}
|
|
@@ -4,6 +4,8 @@ define(["require", "exports", "tslib", "./applyDefaultFormat", "./applyPendingFo
|
|
|
4
4
|
exports.createFormatPlugin = void 0;
|
|
5
5
|
// During IME input, KeyDown event will have "Process" as key
|
|
6
6
|
var ProcessKey = 'Process';
|
|
7
|
+
// For some Android IME, KeyDown event will have "Unidentified" as key
|
|
8
|
+
var UnidentifiedKey = 'Unidentified';
|
|
7
9
|
var DefaultStyleKeyMap = {
|
|
8
10
|
backgroundColor: 'backgroundColor',
|
|
9
11
|
textColor: 'color',
|
|
@@ -82,12 +84,15 @@ define(["require", "exports", "tslib", "./applyDefaultFormat", "./applyPendingFo
|
|
|
82
84
|
this.checkAndApplyPendingFormat(event.rawEvent.data);
|
|
83
85
|
break;
|
|
84
86
|
case 'keyDown':
|
|
87
|
+
var isAndroidIME = this.editor.getEnvironment().isAndroid && event.rawEvent.key == UnidentifiedKey;
|
|
85
88
|
if ((0, roosterjs_content_model_dom_1.isCursorMovingKey)(event.rawEvent)) {
|
|
86
89
|
this.clearPendingFormat();
|
|
87
90
|
this.lastCheckedNode = null;
|
|
88
91
|
}
|
|
89
92
|
else if (this.defaultFormatKeys.size > 0 &&
|
|
90
|
-
(
|
|
93
|
+
(isAndroidIME ||
|
|
94
|
+
(0, roosterjs_content_model_dom_1.isCharacterValue)(event.rawEvent) ||
|
|
95
|
+
event.rawEvent.key == ProcessKey) &&
|
|
91
96
|
this.shouldApplyDefaultFormat(this.editor)) {
|
|
92
97
|
(0, applyDefaultFormat_1.applyDefaultFormat)(this.editor, this.state.defaultFormat);
|
|
93
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/format/FormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyDefaultFormat } from './applyDefaultFormat';\nimport { applyPendingFormat } from './applyPendingFormat';\nimport {\n getObjectKeys,\n isBlockElement,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n BackgroundColorFormat,\n FontFamilyFormat,\n FontSizeFormat,\n FormatPluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n TextColorFormat,\n} from 'roosterjs-content-model-types';\n\n// During IME input, KeyDown event will have \"Process\" as key\nconst ProcessKey = 'Process';\nconst DefaultStyleKeyMap: Record<\n keyof (FontFamilyFormat & FontSizeFormat & TextColorFormat & BackgroundColorFormat),\n keyof CSSStyleDeclaration\n> = {\n backgroundColor: 'backgroundColor',\n textColor: 'color',\n fontFamily: 'fontFamily',\n fontSize: 'fontSize',\n};\n\n/**\n * FormatPlugin plugins helps editor to do formatting on top of content model.\n * This includes:\n * 1. Handle pending format changes when selection is collapsed\n */\nclass FormatPlugin implements PluginWithState<FormatPluginState> {\n private editor: IEditor | null = null;\n private defaultFormatKeys: Set<keyof CSSStyleDeclaration>;\n private state: FormatPluginState;\n private lastCheckedNode: Node | null = null;\n\n /**\n * Construct a new instance of FormatPlugin class\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n defaultFormat: { ...option.defaultSegmentFormat },\n pendingFormat: null,\n };\n\n this.defaultFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n getObjectKeys(DefaultStyleKeyMap).forEach(key => {\n if (this.state.defaultFormat[key]) {\n this.defaultFormatKeys.add(DefaultStyleKeyMap[key]);\n }\n });\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Format';\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 * Get plugin state object\n */\n getState(): FormatPluginState {\n return this.state;\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 return;\n }\n\n switch (event.eventType) {\n case 'input':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n\n break;\n\n case 'compositionEnd':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n break;\n\n case 'keyDown':\n if (isCursorMovingKey(event.rawEvent)) {\n this.clearPendingFormat();\n this.lastCheckedNode = null;\n } else if (\n this.defaultFormatKeys.size > 0 &&\n (isCharacterValue(event.rawEvent) || event.rawEvent.key == ProcessKey) &&\n this.shouldApplyDefaultFormat(this.editor)\n ) {\n applyDefaultFormat(this.editor, this.state.defaultFormat);\n }\n\n break;\n\n case 'mouseUp':\n case 'contentChanged':\n this.lastCheckedNode = null;\n\n if (!this.canApplyPendingFormat()) {\n this.clearPendingFormat();\n }\n break;\n }\n }\n\n private checkAndApplyPendingFormat(data: string | null) {\n if (this.editor && data && this.state.pendingFormat) {\n applyPendingFormat(this.editor, data, this.state.pendingFormat.format);\n this.clearPendingFormat();\n }\n }\n\n private clearPendingFormat() {\n this.state.pendingFormat = null;\n }\n\n /**\n * @internal\n * Check if this editor can apply pending format\n * @param editor The editor to get format from\n */\n private canApplyPendingFormat(): boolean {\n let result = false;\n\n if (this.state.pendingFormat && this.editor) {\n const selection = this.editor.getDOMSelection();\n const range =\n selection?.type == 'range' && selection.range.collapsed ? selection.range : null;\n const { node, offset } = this.state.pendingFormat.insertPoint;\n\n if (range && range.startContainer == node && range.startOffset == offset) {\n result = true;\n }\n }\n\n return result;\n }\n\n private shouldApplyDefaultFormat(editor: IEditor): boolean {\n const selection = editor.getDOMSelection();\n const range = selection?.type == 'range' ? selection.range : null;\n const posContainer = range?.startContainer ?? null;\n\n if (posContainer && posContainer != this.lastCheckedNode) {\n // Cache last checked parent node so no need to check it again if user is keep typing under the same node\n this.lastCheckedNode = posContainer;\n\n const domHelper = editor.getDOMHelper();\n let element: HTMLElement | null = isNodeOfType(posContainer, 'ELEMENT_NODE')\n ? posContainer\n : posContainer.parentElement;\n const foundFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n while (element?.parentElement && domHelper.isNodeInEditor(element.parentElement)) {\n if (element.getAttribute?.('style')) {\n const style = element.style;\n this.defaultFormatKeys.forEach(key => {\n if (style[key]) {\n foundFormatKeys.add(key);\n }\n });\n\n if (foundFormatKeys.size == this.defaultFormatKeys.size) {\n return false;\n }\n }\n\n if (isBlockElement(element)) {\n break;\n }\n\n element = element.parentElement;\n }\n\n return true;\n } else {\n return false;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of FormatPlugin.\n * @param option The editor option\n */\nexport function createFormatPlugin(option: EditorOptions): PluginWithState<FormatPluginState> {\n return new FormatPlugin(option);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FormatPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/format/FormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyDefaultFormat } from './applyDefaultFormat';\nimport { applyPendingFormat } from './applyPendingFormat';\nimport {\n getObjectKeys,\n isBlockElement,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n BackgroundColorFormat,\n FontFamilyFormat,\n FontSizeFormat,\n FormatPluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n TextColorFormat,\n} from 'roosterjs-content-model-types';\n\n// During IME input, KeyDown event will have \"Process\" as key\nconst ProcessKey = 'Process';\n// For some Android IME, KeyDown event will have \"Unidentified\" as key\nconst UnidentifiedKey = 'Unidentified';\nconst DefaultStyleKeyMap: Record<\n keyof (FontFamilyFormat & FontSizeFormat & TextColorFormat & BackgroundColorFormat),\n keyof CSSStyleDeclaration\n> = {\n backgroundColor: 'backgroundColor',\n textColor: 'color',\n fontFamily: 'fontFamily',\n fontSize: 'fontSize',\n};\n\n/**\n * FormatPlugin plugins helps editor to do formatting on top of content model.\n * This includes:\n * 1. Handle pending format changes when selection is collapsed\n */\nclass FormatPlugin implements PluginWithState<FormatPluginState> {\n private editor: IEditor | null = null;\n private defaultFormatKeys: Set<keyof CSSStyleDeclaration>;\n private state: FormatPluginState;\n private lastCheckedNode: Node | null = null;\n\n /**\n * Construct a new instance of FormatPlugin class\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n defaultFormat: { ...option.defaultSegmentFormat },\n pendingFormat: null,\n };\n\n this.defaultFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n getObjectKeys(DefaultStyleKeyMap).forEach(key => {\n if (this.state.defaultFormat[key]) {\n this.defaultFormatKeys.add(DefaultStyleKeyMap[key]);\n }\n });\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Format';\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 * Get plugin state object\n */\n getState(): FormatPluginState {\n return this.state;\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 return;\n }\n\n switch (event.eventType) {\n case 'input':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n\n break;\n\n case 'compositionEnd':\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n break;\n\n case 'keyDown':\n const isAndroidIME =\n this.editor.getEnvironment().isAndroid && event.rawEvent.key == UnidentifiedKey;\n if (isCursorMovingKey(event.rawEvent)) {\n this.clearPendingFormat();\n this.lastCheckedNode = null;\n } else if (\n this.defaultFormatKeys.size > 0 &&\n (isAndroidIME ||\n isCharacterValue(event.rawEvent) ||\n event.rawEvent.key == ProcessKey) &&\n this.shouldApplyDefaultFormat(this.editor)\n ) {\n applyDefaultFormat(this.editor, this.state.defaultFormat);\n }\n\n break;\n\n case 'mouseUp':\n case 'contentChanged':\n this.lastCheckedNode = null;\n\n if (!this.canApplyPendingFormat()) {\n this.clearPendingFormat();\n }\n break;\n }\n }\n\n private checkAndApplyPendingFormat(data: string | null) {\n if (this.editor && data && this.state.pendingFormat) {\n applyPendingFormat(this.editor, data, this.state.pendingFormat.format);\n this.clearPendingFormat();\n }\n }\n\n private clearPendingFormat() {\n this.state.pendingFormat = null;\n }\n\n /**\n * @internal\n * Check if this editor can apply pending format\n * @param editor The editor to get format from\n */\n private canApplyPendingFormat(): boolean {\n let result = false;\n\n if (this.state.pendingFormat && this.editor) {\n const selection = this.editor.getDOMSelection();\n const range =\n selection?.type == 'range' && selection.range.collapsed ? selection.range : null;\n const { node, offset } = this.state.pendingFormat.insertPoint;\n\n if (range && range.startContainer == node && range.startOffset == offset) {\n result = true;\n }\n }\n\n return result;\n }\n\n private shouldApplyDefaultFormat(editor: IEditor): boolean {\n const selection = editor.getDOMSelection();\n const range = selection?.type == 'range' ? selection.range : null;\n const posContainer = range?.startContainer ?? null;\n\n if (posContainer && posContainer != this.lastCheckedNode) {\n // Cache last checked parent node so no need to check it again if user is keep typing under the same node\n this.lastCheckedNode = posContainer;\n\n const domHelper = editor.getDOMHelper();\n let element: HTMLElement | null = isNodeOfType(posContainer, 'ELEMENT_NODE')\n ? posContainer\n : posContainer.parentElement;\n const foundFormatKeys = new Set<keyof CSSStyleDeclaration>();\n\n while (element?.parentElement && domHelper.isNodeInEditor(element.parentElement)) {\n if (element.getAttribute?.('style')) {\n const style = element.style;\n this.defaultFormatKeys.forEach(key => {\n if (style[key]) {\n foundFormatKeys.add(key);\n }\n });\n\n if (foundFormatKeys.size == this.defaultFormatKeys.size) {\n return false;\n }\n }\n\n if (isBlockElement(element)) {\n break;\n }\n\n element = element.parentElement;\n }\n\n return true;\n } else {\n return false;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of FormatPlugin.\n * @param option The editor option\n */\nexport function createFormatPlugin(option: EditorOptions): PluginWithState<FormatPluginState> {\n return new FormatPlugin(option);\n}\n"]}
|
|
@@ -411,6 +411,9 @@ define(["require", "exports", "./findCoordinate", "../../coreApi/setDOMSelection
|
|
|
411
411
|
if (collapsed && td) {
|
|
412
412
|
this.setRangeSelectionInTable(td, key == Up ? td.childNodes.length : 0, this.editor);
|
|
413
413
|
}
|
|
414
|
+
else if (!td && (lastCo.row == -1 || lastCo.row <= parsedTable.length)) {
|
|
415
|
+
this.selectBeforeOrAfterElement(this.editor, table, change == 1 /* after */, change != 1 /* setSelectionInNextSiblingElement */);
|
|
416
|
+
}
|
|
414
417
|
}
|
|
415
418
|
else if (key == 'TabLeft' || key == 'TabRight') {
|
|
416
419
|
var reverse = key == 'TabLeft';
|
|
@@ -482,14 +485,23 @@ define(["require", "exports", "./findCoordinate", "../../coreApi/setDOMSelection
|
|
|
482
485
|
}
|
|
483
486
|
}
|
|
484
487
|
};
|
|
485
|
-
SelectionPlugin.prototype.selectBeforeOrAfterElement = function (editor, element, after) {
|
|
488
|
+
SelectionPlugin.prototype.selectBeforeOrAfterElement = function (editor, element, after, setSelectionInNextSiblingElement) {
|
|
486
489
|
var doc = editor.getDocument();
|
|
487
490
|
var parent = element.parentNode;
|
|
488
491
|
var index = parent && (0, roosterjs_content_model_dom_1.toArray)(parent.childNodes).indexOf(element);
|
|
492
|
+
var sibling;
|
|
489
493
|
if (parent && index !== null && index >= 0) {
|
|
490
494
|
var range = doc.createRange();
|
|
491
|
-
|
|
492
|
-
|
|
495
|
+
if (setSelectionInNextSiblingElement &&
|
|
496
|
+
(sibling = after ? element.nextElementSibling : element.previousElementSibling) &&
|
|
497
|
+
(0, roosterjs_content_model_dom_1.isNodeOfType)(sibling, 'ELEMENT_NODE')) {
|
|
498
|
+
range.selectNodeContents(sibling);
|
|
499
|
+
range.collapse(false /* toStart */);
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
range.setStart(parent, index + (after ? 1 : 0));
|
|
503
|
+
range.collapse();
|
|
504
|
+
}
|
|
493
505
|
this.setDOMSelection({
|
|
494
506
|
type: 'range',
|
|
495
507
|
range: range,
|