roosterjs-content-model-core 9.52.0 → 9.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/command/cutCopy/getContentForCopy.js +4 -1
- package/lib/command/cutCopy/getContentForCopy.js.map +1 -1
- package/lib/coreApi/announce/announce.js +1 -0
- package/lib/coreApi/announce/announce.js.map +1 -1
- package/lib/coreApi/createContentModel/createContentModel.js +3 -0
- package/lib/coreApi/createContentModel/createContentModel.js.map +1 -1
- package/lib/coreApi/getDOMSelection/getDOMSelection.js +12 -9
- package/lib/coreApi/getDOMSelection/getDOMSelection.js.map +1 -1
- package/lib/coreApi/setDOMSelection/setDOMSelection.js +7 -8
- package/lib/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
- package/lib/coreApi/setEditorStyle/ensureUniqueId.js +2 -2
- package/lib/coreApi/setEditorStyle/ensureUniqueId.js.map +1 -1
- package/lib/coreApi/setEditorStyle/setEditorStyle.js +1 -1
- package/lib/coreApi/setEditorStyle/setEditorStyle.js.map +1 -1
- package/lib/corePlugin/cache/CachePlugin.js +5 -0
- package/lib/corePlugin/cache/CachePlugin.js.map +1 -1
- package/lib/corePlugin/cache/MutationType.d.ts +12 -1
- package/lib/corePlugin/cache/MutationType.js.map +1 -1
- package/lib/corePlugin/cache/areSameSelections.d.ts +0 -4
- package/lib/corePlugin/cache/areSameSelections.js +3 -10
- package/lib/corePlugin/cache/areSameSelections.js.map +1 -1
- package/lib/corePlugin/cache/domIndexerImpl.d.ts +1 -0
- package/lib/corePlugin/cache/domIndexerImpl.js +41 -6
- package/lib/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib/corePlugin/cache/textMutationObserver.js +10 -0
- package/lib/corePlugin/cache/textMutationObserver.js.map +1 -1
- package/lib/corePlugin/lifecycle/LifecyclePlugin.js +1 -0
- package/lib/corePlugin/lifecycle/LifecyclePlugin.js.map +1 -1
- package/lib/corePlugin/selection/SelectionPlugin.js +10 -7
- package/lib/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib/editor/core/DOMHelperImpl.d.ts +4 -0
- package/lib/editor/core/DOMHelperImpl.js +61 -1
- package/lib/editor/core/DOMHelperImpl.js.map +1 -1
- package/lib/editor/core/createEditorCore.js +4 -1
- package/lib/editor/core/createEditorCore.js.map +1 -1
- package/lib/override/containerSizeFormatParser.js +2 -0
- package/lib/override/containerSizeFormatParser.js.map +1 -1
- package/lib/utils/areSameRanges.d.ts +5 -0
- package/lib/utils/areSameRanges.js +13 -0
- package/lib/utils/areSameRanges.js.map +1 -0
- package/lib/utils/createAriaLiveElement.js +0 -1
- package/lib/utils/createAriaLiveElement.js.map +1 -1
- package/lib-amd/command/cutCopy/getContentForCopy.js +4 -1
- package/lib-amd/command/cutCopy/getContentForCopy.js.map +1 -1
- package/lib-amd/coreApi/announce/announce.js +1 -0
- package/lib-amd/coreApi/announce/announce.js.map +1 -1
- package/lib-amd/coreApi/createContentModel/createContentModel.js +3 -0
- package/lib-amd/coreApi/createContentModel/createContentModel.js.map +1 -1
- package/lib-amd/coreApi/getDOMSelection/getDOMSelection.js +12 -9
- package/lib-amd/coreApi/getDOMSelection/getDOMSelection.js.map +1 -1
- package/lib-amd/coreApi/setDOMSelection/setDOMSelection.js +8 -8
- package/lib-amd/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
- package/lib-amd/coreApi/setEditorStyle/ensureUniqueId.js +2 -2
- package/lib-amd/coreApi/setEditorStyle/ensureUniqueId.js.map +1 -1
- package/lib-amd/coreApi/setEditorStyle/setEditorStyle.js +1 -1
- package/lib-amd/coreApi/setEditorStyle/setEditorStyle.js.map +1 -1
- package/lib-amd/corePlugin/cache/CachePlugin.js +5 -0
- package/lib-amd/corePlugin/cache/CachePlugin.js.map +1 -1
- package/lib-amd/corePlugin/cache/MutationType.d.ts +12 -1
- package/lib-amd/corePlugin/cache/MutationType.js.map +1 -1
- package/lib-amd/corePlugin/cache/areSameSelections.d.ts +0 -4
- package/lib-amd/corePlugin/cache/areSameSelections.js +3 -11
- package/lib-amd/corePlugin/cache/areSameSelections.js.map +1 -1
- package/lib-amd/corePlugin/cache/domIndexerImpl.d.ts +1 -0
- package/lib-amd/corePlugin/cache/domIndexerImpl.js +41 -6
- package/lib-amd/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib-amd/corePlugin/cache/textMutationObserver.js +10 -0
- package/lib-amd/corePlugin/cache/textMutationObserver.js.map +1 -1
- package/lib-amd/corePlugin/lifecycle/LifecyclePlugin.js +1 -0
- package/lib-amd/corePlugin/lifecycle/LifecyclePlugin.js.map +1 -1
- package/lib-amd/corePlugin/selection/SelectionPlugin.js +10 -7
- package/lib-amd/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib-amd/editor/core/DOMHelperImpl.d.ts +4 -0
- package/lib-amd/editor/core/DOMHelperImpl.js +61 -2
- package/lib-amd/editor/core/DOMHelperImpl.js.map +1 -1
- package/lib-amd/editor/core/createEditorCore.js +4 -1
- package/lib-amd/editor/core/createEditorCore.js.map +1 -1
- package/lib-amd/override/containerSizeFormatParser.js +2 -0
- package/lib-amd/override/containerSizeFormatParser.js.map +1 -1
- package/lib-amd/utils/areSameRanges.d.ts +5 -0
- package/lib-amd/utils/areSameRanges.js +15 -0
- package/lib-amd/utils/areSameRanges.js.map +1 -0
- package/lib-amd/utils/createAriaLiveElement.js +0 -1
- package/lib-amd/utils/createAriaLiveElement.js.map +1 -1
- package/lib-mjs/command/cutCopy/getContentForCopy.js +5 -2
- package/lib-mjs/command/cutCopy/getContentForCopy.js.map +1 -1
- package/lib-mjs/coreApi/announce/announce.js +1 -0
- package/lib-mjs/coreApi/announce/announce.js.map +1 -1
- package/lib-mjs/coreApi/createContentModel/createContentModel.js +3 -0
- package/lib-mjs/coreApi/createContentModel/createContentModel.js.map +1 -1
- package/lib-mjs/coreApi/getDOMSelection/getDOMSelection.js +12 -9
- package/lib-mjs/coreApi/getDOMSelection/getDOMSelection.js.map +1 -1
- package/lib-mjs/coreApi/setDOMSelection/setDOMSelection.js +7 -8
- package/lib-mjs/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
- package/lib-mjs/coreApi/setEditorStyle/ensureUniqueId.js +2 -2
- package/lib-mjs/coreApi/setEditorStyle/ensureUniqueId.js.map +1 -1
- package/lib-mjs/coreApi/setEditorStyle/setEditorStyle.js +1 -1
- package/lib-mjs/coreApi/setEditorStyle/setEditorStyle.js.map +1 -1
- package/lib-mjs/corePlugin/cache/CachePlugin.js +5 -0
- package/lib-mjs/corePlugin/cache/CachePlugin.js.map +1 -1
- package/lib-mjs/corePlugin/cache/MutationType.d.ts +12 -1
- package/lib-mjs/corePlugin/cache/MutationType.js.map +1 -1
- package/lib-mjs/corePlugin/cache/areSameSelections.d.ts +0 -4
- package/lib-mjs/corePlugin/cache/areSameSelections.js +1 -7
- package/lib-mjs/corePlugin/cache/areSameSelections.js.map +1 -1
- package/lib-mjs/corePlugin/cache/domIndexerImpl.d.ts +1 -0
- package/lib-mjs/corePlugin/cache/domIndexerImpl.js +41 -6
- package/lib-mjs/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib-mjs/corePlugin/cache/textMutationObserver.js +10 -0
- package/lib-mjs/corePlugin/cache/textMutationObserver.js.map +1 -1
- package/lib-mjs/corePlugin/lifecycle/LifecyclePlugin.js +1 -0
- package/lib-mjs/corePlugin/lifecycle/LifecyclePlugin.js.map +1 -1
- package/lib-mjs/corePlugin/selection/SelectionPlugin.js +10 -7
- package/lib-mjs/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib-mjs/editor/core/DOMHelperImpl.d.ts +4 -0
- package/lib-mjs/editor/core/DOMHelperImpl.js +61 -1
- package/lib-mjs/editor/core/DOMHelperImpl.js.map +1 -1
- package/lib-mjs/editor/core/createEditorCore.js +4 -1
- package/lib-mjs/editor/core/createEditorCore.js.map +1 -1
- package/lib-mjs/override/containerSizeFormatParser.js +2 -0
- package/lib-mjs/override/containerSizeFormatParser.js.map +1 -1
- package/lib-mjs/utils/areSameRanges.d.ts +5 -0
- package/lib-mjs/utils/areSameRanges.js +9 -0
- package/lib-mjs/utils/areSameRanges.js.map +1 -0
- package/lib-mjs/utils/createAriaLiveElement.js +0 -1
- package/lib-mjs/utils/createAriaLiveElement.js.map +1 -1
- package/package.json +3 -3
- package/lib/coreApi/setDOMSelection/addRangeToSelection.d.ts +0 -4
- package/lib/coreApi/setDOMSelection/addRangeToSelection.js +0 -27
- package/lib/coreApi/setDOMSelection/addRangeToSelection.js.map +0 -1
- package/lib-amd/coreApi/setDOMSelection/addRangeToSelection.d.ts +0 -4
- package/lib-amd/coreApi/setDOMSelection/addRangeToSelection.js +0 -28
- package/lib-amd/coreApi/setDOMSelection/addRangeToSelection.js.map +0 -1
- package/lib-mjs/coreApi/setDOMSelection/addRangeToSelection.d.ts +0 -4
- package/lib-mjs/coreApi/setDOMSelection/addRangeToSelection.js +0 -23
- package/lib-mjs/coreApi/setDOMSelection/addRangeToSelection.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getContentForCopy.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/getContentForCopy.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"getContentForCopy.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/getContentForCopy.ts"],"names":[],"mappings":"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","sourcesContent":["import { adjustImageSelectionOnSafari } from './adjustImageSelectionOnSafari';\nimport { adjustSelectionForCopyCut } from './adjustSelectionForCopyCut';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport {\n contentModelToDom,\n contentModelToText,\n createDomToModelContext,\n createModelToDomContext,\n domToContentModel,\n trimModelForSelection,\n isElementOfType,\n isNodeOfType,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n OnNodeCreated,\n TextAndHtmlContentForCopy,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * Get the content for the copy event\n * @param editor The editor object\n * @param isCut if the event cut the content.\n * @param event the clipboard event that triggered the copy/cut\n * @returns\n */\nexport function getContentForCopy(\n editor: IEditor,\n isCut: boolean,\n event: ClipboardEvent\n): TextAndHtmlContentForCopy | null {\n const selection = editor.getDOMSelection();\n adjustImageSelectionOnSafari(editor, selection);\n\n if (selection && (selection.type !== 'range' || !selection.range.collapsed)) {\n const pasteModel = editor.getContentModelCopy('disconnected');\n const context = createModelToDomContext();\n trimModelForSelection(pasteModel, selection);\n\n if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n context.onNodeCreated = onNodeCreated;\n const doc = editor.getDocument();\n const tempDiv = doc.createElement('div');\n\n const selectionForCopy = contentModelToDom(doc, tempDiv, pasteModel, context);\n const newRange = selectionForCopy ? domSelectionToRange(doc, selectionForCopy) : null;\n if (newRange) {\n const { clonedRoot } = editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event,\n isCut,\n });\n\n // Build the text content from the (possibly modified) cloned root DOM tree so that any\n // changes made by beforeCutCopy event handlers are reflected in the plain text result as well\n const textModel = domToContentModel(clonedRoot, createDomToModelContext());\n\n return {\n htmlContent: clonedRoot,\n textContent: contentModelToText(textModel),\n };\n }\n }\n return null;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n"]}
|
|
@@ -16,6 +16,7 @@ define(["require", "exports", "../../utils/createAriaLiveElement"], function (re
|
|
|
16
16
|
var textToAnnounce = formatString(template || text, formatStrings);
|
|
17
17
|
if (!core.lifecycle.announceContainer) {
|
|
18
18
|
core.lifecycle.announceContainer = (0, createAriaLiveElement_1.createAriaLiveElement)(core.physicalRoot.ownerDocument);
|
|
19
|
+
core.domHelper.appendToRoot(core.lifecycle.announceContainer);
|
|
19
20
|
}
|
|
20
21
|
if (textToAnnounce && core.lifecycle.announceContainer) {
|
|
21
22
|
var announceContainer = core.lifecycle.announceContainer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announce.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/announce/announce.ts"],"names":[],"mappings":";;;;IAGA,IAAM,UAAU,GAAG,GAAG,CAAC;IAEvB;;;;;OAKG;IACI,IAAM,QAAQ,GAAa,UAAC,IAAI,EAAE,YAAY;QACzC,IAAA,IAAI,GAAqE,YAAY,KAAjF,EAAE,cAAc,GAAqD,YAAY,eAAjE,EAAE,KAAmD,YAAY,cAA7C,EAAlB,aAAa,mBAAG,EAAE,KAAA,EAAE,KAA+B,YAAY,aAAjB,EAA1B,YAAY,mBAAG,WAAW,KAAA,CAAkB;QACtF,IAAA,qBAAqB,GAAK,IAAI,CAAC,SAAS,sBAAnB,CAAoB;QACjD,IAAM,QAAQ,GAAG,cAAc,KAAI,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAG,cAAc,CAAC,CAAA,CAAC;QAC3E,IAAI,cAAc,GAAG,YAAY,CAAC,QAAQ,IAAI,IAAI,EAAE,aAAa,CAAC,CAAC;QAEnE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;YACnC,IAAI,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAA,6CAAqB,EAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"announce.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/announce/announce.ts"],"names":[],"mappings":";;;;IAGA,IAAM,UAAU,GAAG,GAAG,CAAC;IAEvB;;;;;OAKG;IACI,IAAM,QAAQ,GAAa,UAAC,IAAI,EAAE,YAAY;QACzC,IAAA,IAAI,GAAqE,YAAY,KAAjF,EAAE,cAAc,GAAqD,YAAY,eAAjE,EAAE,KAAmD,YAAY,cAA7C,EAAlB,aAAa,mBAAG,EAAE,KAAA,EAAE,KAA+B,YAAY,aAAjB,EAA1B,YAAY,mBAAG,WAAW,KAAA,CAAkB;QACtF,IAAA,qBAAqB,GAAK,IAAI,CAAC,SAAS,sBAAnB,CAAoB;QACjD,IAAM,QAAQ,GAAG,cAAc,KAAI,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAG,cAAc,CAAC,CAAA,CAAC;QAC3E,IAAI,cAAc,GAAG,YAAY,CAAC,QAAQ,IAAI,IAAI,EAAE,aAAa,CAAC,CAAC;QAEnE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;YACnC,IAAI,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAA,6CAAqB,EAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;YAC1F,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;SACjE;QAED,IAAI,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;YAC5C,IAAA,iBAAiB,GAAK,IAAI,CAAC,SAAS,kBAAnB,CAAoB;YAC7C,IAAI,iBAAiB,CAAC,QAAQ,IAAI,YAAY,EAAE;gBAC5C,iBAAiB,CAAC,QAAQ,GAAG,YAAY,CAAC;aAC7C;YAED,IAAI,cAAc,IAAI,iBAAiB,CAAC,WAAW,EAAE;gBACjD,cAAc,IAAI,UAAU,CAAC;aAChC;YAED,IAAI,iBAAiB,EAAE;gBACnB,iBAAiB,CAAC,WAAW,GAAG,cAAc,CAAC;aAClD;SACJ;IACL,CAAC,CAAC;IAzBW,QAAA,QAAQ,YAyBnB;IAEF,SAAS,YAAY,CAAC,IAAwB,EAAE,aAAuB;QACnE,IAAI,IAAI,IAAI,SAAS,EAAE;YACnB,OAAO,IAAI,CAAC;SACf;QAED,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,UAAC,CAAC,EAAE,GAAW;YAC7C,IAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YACrC,OAAO,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IAChB,CAAC","sourcesContent":["import { createAriaLiveElement } from '../../utils/createAriaLiveElement';\nimport type { Announce } from 'roosterjs-content-model-types';\n\nconst DOT_STRING = '.';\n\n/**\n * @internal\n * Announce the given data\n * @param core The EditorCore object\n * @param announceData Data to announce\n */\nexport const announce: Announce = (core, announceData) => {\n const { text, defaultStrings, formatStrings = [], ariaLiveMode = 'assertive' } = announceData;\n const { announcerStringGetter } = core.lifecycle;\n const template = defaultStrings && announcerStringGetter?.(defaultStrings);\n let textToAnnounce = formatString(template || text, formatStrings);\n\n if (!core.lifecycle.announceContainer) {\n core.lifecycle.announceContainer = createAriaLiveElement(core.physicalRoot.ownerDocument);\n core.domHelper.appendToRoot(core.lifecycle.announceContainer);\n }\n\n if (textToAnnounce && core.lifecycle.announceContainer) {\n const { announceContainer } = core.lifecycle;\n if (announceContainer.ariaLive != ariaLiveMode) {\n announceContainer.ariaLive = ariaLiveMode;\n }\n\n if (textToAnnounce == announceContainer.textContent) {\n textToAnnounce += DOT_STRING;\n }\n\n if (announceContainer) {\n announceContainer.textContent = textToAnnounce;\n }\n }\n};\n\nfunction formatString(text: string | undefined, formatStrings: string[]) {\n if (text == undefined) {\n return text;\n }\n\n text = text.replace(/\\{(\\d+)\\}/g, (_, sub: string) => {\n const index = parseInt(sub);\n const replace = formatStrings[index];\n return replace ?? '';\n });\n\n return text;\n}\n"]}
|
|
@@ -33,6 +33,9 @@ define(["require", "exports", "../../corePlugin/cache/updateCache", "roosterjs-c
|
|
|
33
33
|
var domToModelContext = option
|
|
34
34
|
? (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, settings.builtIn, settings.customized, option)
|
|
35
35
|
: (0, roosterjs_content_model_dom_1.createDomToModelContextWithConfig)(settings.calculated, editorContext);
|
|
36
|
+
if (option === null || option === void 0 ? void 0 : option.skipFormatContainerFallbackCheck) {
|
|
37
|
+
domToModelContext.skipFormatContainerFallbackCheck = true;
|
|
38
|
+
}
|
|
36
39
|
if (selection) {
|
|
37
40
|
domToModelContext.selection = selection;
|
|
38
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createContentModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/createContentModel/createContentModel.ts"],"names":[],"mappings":";;;;IASA;;;;;;OAMG;IACI,IAAM,kBAAkB,GAAuB,UAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB;;QAClF,6EAA6E;QAC7E,MAAA,IAAI,CAAC,KAAK,CAAC,oBAAoB,0CAAE,cAAc,EAAE,CAAC;QAClD,IAAM,eAAe,GACjB,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,OAAO,MAAM,CAAC,oBAAoB,KAAK,WAAW,CAAC,CAAC;QAE9F,IAAI,CAAC,iBAAiB,IAAI,eAAe,EAAE;YACvC,IAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAE3C,IAAI,WAAW,EAAE;gBACb,6EAA6E;gBAC7E,OAAO,IAAI,CAAC,SAAS,CAAC,kBAAkB;oBACpC,CAAC,CAAC,IAAA,wCAAU,EAAC,WAAW,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;oBACzD,CAAC,CAAC,WAAW,CAAC;aACrB;SACJ;QAED,IAAM,SAAS,GACX,iBAAiB,IAAI,MAAM;YACvB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3E,IAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEpE,aAAa,CAAC,oBAAoB,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAAC;QAElE,IAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;QACrD,IAAM,iBAAiB,GAAG,MAAM;YAC5B,CAAC,CAAC,IAAA,qDAAuB,EAAC,aAAa,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YACvF,CAAC,CAAC,IAAA,+DAAiC,EAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAE5E,IAAI,SAAS,EAAE;YACX,iBAAiB,CAAC,SAAS,GAAG,SAAS,CAAC;SAC3C;QAED,IAAM,KAAK,GAAG,IAAA,+CAAiB,EAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAErE,IAAI,SAAS,EAAE;YACX,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SAC7C;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"createContentModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/createContentModel/createContentModel.ts"],"names":[],"mappings":";;;;IASA;;;;;;OAMG;IACI,IAAM,kBAAkB,GAAuB,UAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB;;QAClF,6EAA6E;QAC7E,MAAA,IAAI,CAAC,KAAK,CAAC,oBAAoB,0CAAE,cAAc,EAAE,CAAC;QAClD,IAAM,eAAe,GACjB,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,OAAO,MAAM,CAAC,oBAAoB,KAAK,WAAW,CAAC,CAAC;QAE9F,IAAI,CAAC,iBAAiB,IAAI,eAAe,EAAE;YACvC,IAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAE3C,IAAI,WAAW,EAAE;gBACb,6EAA6E;gBAC7E,OAAO,IAAI,CAAC,SAAS,CAAC,kBAAkB;oBACpC,CAAC,CAAC,IAAA,wCAAU,EAAC,WAAW,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;oBACzD,CAAC,CAAC,WAAW,CAAC;aACrB;SACJ;QAED,IAAM,SAAS,GACX,iBAAiB,IAAI,MAAM;YACvB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3E,IAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEpE,aAAa,CAAC,oBAAoB,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAAC;QAElE,IAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;QACrD,IAAM,iBAAiB,GAAG,MAAM;YAC5B,CAAC,CAAC,IAAA,qDAAuB,EAAC,aAAa,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YACvF,CAAC,CAAC,IAAA,+DAAiC,EAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAE5E,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gCAAgC,EAAE;YAC1C,iBAAiB,CAAC,gCAAgC,GAAG,IAAI,CAAC;SAC7D;QAED,IAAI,SAAS,EAAE;YACX,iBAAiB,CAAC,SAAS,GAAG,SAAS,CAAC;SAC3C;QAED,IAAM,KAAK,GAAG,IAAA,+CAAiB,EAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAErE,IAAI,SAAS,EAAE;YACX,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SAC7C;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;IA9CW,QAAA,kBAAkB,sBA8C7B","sourcesContent":["import { updateCache } from '../../corePlugin/cache/updateCache';\nimport {\n cloneModel,\n createDomToModelContext,\n createDomToModelContextWithConfig,\n domToContentModel,\n} from 'roosterjs-content-model-dom';\nimport type { CreateContentModel } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Create Content Model from DOM tree in this editor\n * @param core The editor core object\n * @param option The option to customize the behavior of DOM to Content Model conversion\n * @param selectionOverride When passed, use this selection range instead of current selection in editor\n */\nexport const createContentModel: CreateContentModel = (core, option, selectionOverride) => {\n // Flush all mutations if any, so that we can get an up-to-date Content Model\n core.cache.textMutationObserver?.flushMutations();\n const tryGetFromCache =\n !option || (option.tryGetFromCache && typeof option.recalculateTableSize === 'undefined');\n\n if (!selectionOverride && tryGetFromCache) {\n const cachedModel = core.cache.cachedModel;\n\n if (cachedModel) {\n // When in shadow edit, use a cloned model so we won't pollute the cached one\n return core.lifecycle.shadowEditFragment\n ? cloneModel(cachedModel, { includeCachedElement: true })\n : cachedModel;\n }\n }\n\n const selection =\n selectionOverride == 'none'\n ? undefined\n : selectionOverride || core.api.getDOMSelection(core) || undefined;\n const saveIndex = !option && !selectionOverride;\n const editorContext = core.api.createEditorContext(core, saveIndex);\n\n editorContext.recalculateTableSize = option?.recalculateTableSize;\n\n const settings = core.environment.domToModelSettings;\n const domToModelContext = option\n ? createDomToModelContext(editorContext, settings.builtIn, settings.customized, option)\n : createDomToModelContextWithConfig(settings.calculated, editorContext);\n\n if (option?.skipFormatContainerFallbackCheck) {\n domToModelContext.skipFormatContainerFallbackCheck = true;\n }\n\n if (selection) {\n domToModelContext.selection = selection;\n }\n\n const model = domToContentModel(core.logicalRoot, domToModelContext);\n\n if (saveIndex) {\n updateCache(core.cache, model, selection);\n }\n\n return model;\n};\n"]}
|
|
@@ -19,16 +19,19 @@ define(["require", "exports"], function (require, exports) {
|
|
|
19
19
|
exports.getDOMSelection = getDOMSelection;
|
|
20
20
|
function getNewSelection(core) {
|
|
21
21
|
var _a;
|
|
22
|
+
var range = core.domHelper.getSelectionRange();
|
|
23
|
+
if (!range || !core.logicalRoot.contains(range.commonAncestorContainer)) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
22
26
|
var selection = (_a = core.logicalRoot.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
: null;
|
|
27
|
+
var isReverted = selection
|
|
28
|
+
? selection.focusNode != range.endContainer || selection.focusOffset != range.endOffset
|
|
29
|
+
: false;
|
|
30
|
+
return {
|
|
31
|
+
type: 'range',
|
|
32
|
+
range: range,
|
|
33
|
+
isReverted: isReverted,
|
|
34
|
+
};
|
|
32
35
|
}
|
|
33
36
|
});
|
|
34
37
|
//# sourceMappingURL=getDOMSelection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/getDOMSelection/getDOMSelection.ts"],"names":[],"mappings":";;;;IAEA;;OAEG;IACI,IAAM,eAAe,GAAoB,UAAA,IAAI;QAChD,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;YACnC,OAAO,IAAI,CAAC;SACf;aAAM;YACH,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;YAE3C,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;gBACzE,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;SAC/B;IACL,CAAC,CAAC;IAVW,QAAA,eAAe,mBAU1B;IAEF,SAAS,eAAe,CAAC,IAAgB;;QACrC,IAAM,
|
|
1
|
+
{"version":3,"file":"getDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/getDOMSelection/getDOMSelection.ts"],"names":[],"mappings":";;;;IAEA;;OAEG;IACI,IAAM,eAAe,GAAoB,UAAA,IAAI;QAChD,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;YACnC,OAAO,IAAI,CAAC;SACf;aAAM;YACH,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;YAE3C,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;gBACzE,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;SAC/B;IACL,CAAC,CAAC;IAVW,QAAA,eAAe,mBAU1B;IAEF,SAAS,eAAe,CAAC,IAAgB;;QACrC,IAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,CAAC;QAEjD,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE;YACrE,OAAO,IAAI,CAAC;SACf;QAED,IAAM,SAAS,GAAG,MAAA,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,WAAW,0CAAE,YAAY,EAAE,CAAC;QAC7E,IAAM,UAAU,GAAG,SAAS;YACxB,CAAC,CAAC,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,YAAY,IAAI,SAAS,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS;YACvF,CAAC,CAAC,KAAK,CAAC;QAEZ,OAAO;YACH,IAAI,EAAE,OAAO;YACb,KAAK,OAAA;YACL,UAAU,YAAA;SACb,CAAC;IACN,CAAC","sourcesContent":["import type { DOMSelection, GetDOMSelection, EditorCore } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const getDOMSelection: GetDOMSelection = core => {\n if (core.lifecycle.shadowEditFragment) {\n return null;\n } else {\n const selection = core.selection.selection;\n\n return selection && (selection.type != 'range' || !core.domHelper.hasFocus())\n ? selection\n : getNewSelection(core);\n }\n};\n\nfunction getNewSelection(core: EditorCore): DOMSelection | null {\n const range = core.domHelper.getSelectionRange();\n\n if (!range || !core.logicalRoot.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n const selection = core.logicalRoot.ownerDocument.defaultView?.getSelection();\n const isReverted = selection\n ? selection.focusNode != range.endContainer || selection.focusOffset != range.endOffset\n : false;\n\n return {\n type: 'range',\n range,\n isReverted,\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
define(["require", "exports", "
|
|
1
|
+
define(["require", "exports", "../../corePlugin/cache/areSameSelections", "../setEditorStyle/ensureUniqueId", "./findLastedCoInMergedCell", "./findTableCellElement", "roosterjs-content-model-dom", "./setTableCellsStyle", "./toggleCaret"], function (require, exports, areSameSelections_1, ensureUniqueId_1, findLastedCoInMergedCell_1, findTableCellElement_1, roosterjs_content_model_dom_1, setTableCellsStyle_1, toggleCaret_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.setDOMSelection = void 0;
|
|
@@ -20,7 +20,6 @@ define(["require", "exports", "./addRangeToSelection", "../../corePlugin/cache/a
|
|
|
20
20
|
// We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.
|
|
21
21
|
// Set skipReselectOnFocus to skip this behavior
|
|
22
22
|
var skipReselectOnFocus = core.selection.skipReselectOnFocus;
|
|
23
|
-
var doc = core.physicalRoot.ownerDocument;
|
|
24
23
|
var isDarkMode = core.lifecycle.isDarkMode;
|
|
25
24
|
core.selection.skipReselectOnFocus = true;
|
|
26
25
|
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);
|
|
@@ -36,7 +35,7 @@ define(["require", "exports", "./addRangeToSelection", "../../corePlugin/cache/a
|
|
|
36
35
|
: core.selection.imageSelectionBorderColor;
|
|
37
36
|
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "outline-style:solid!important; outline-color:" + (imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR) + "!important;", [(0, roosterjs_content_model_dom_1.getSafeIdSelector)((0, ensureUniqueId_1.ensureUniqueId)(image, IMAGE_ID))]);
|
|
38
37
|
core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, TRANSPARENT_SELECTION_CSS_RULE, [SELECTION_SELECTOR]);
|
|
39
|
-
setRangeSelection(
|
|
38
|
+
setRangeSelection(core, image, false /* collapse */);
|
|
40
39
|
break;
|
|
41
40
|
case 'table':
|
|
42
41
|
var table = selection.table, firstColumn = selection.firstColumn, firstRow = selection.firstRow, lastColumn = selection.lastColumn, lastRow = selection.lastRow;
|
|
@@ -73,11 +72,11 @@ define(["require", "exports", "./addRangeToSelection", "../../corePlugin/cache/a
|
|
|
73
72
|
(0, toggleCaret_1.toggleCaret)(core, true /* hide */);
|
|
74
73
|
var nodeToSelect = ((_a = firstCell.cell) === null || _a === void 0 ? void 0 : _a.firstElementChild) || firstCell.cell;
|
|
75
74
|
if (nodeToSelect) {
|
|
76
|
-
setRangeSelection(
|
|
75
|
+
setRangeSelection(core, nodeToSelect || undefined, true /* collapse */);
|
|
77
76
|
}
|
|
78
77
|
break;
|
|
79
78
|
case 'range':
|
|
80
|
-
|
|
79
|
+
core.domHelper.setSelectionRange(selection.range, selection.isReverted);
|
|
81
80
|
core.selection.selection = core.domHelper.hasFocus() ? null : selection;
|
|
82
81
|
break;
|
|
83
82
|
default:
|
|
@@ -97,9 +96,10 @@ define(["require", "exports", "./addRangeToSelection", "../../corePlugin/cache/a
|
|
|
97
96
|
}
|
|
98
97
|
};
|
|
99
98
|
exports.setDOMSelection = setDOMSelection;
|
|
100
|
-
function setRangeSelection(
|
|
99
|
+
function setRangeSelection(core, element, collapse) {
|
|
101
100
|
var _a;
|
|
102
|
-
if (element &&
|
|
101
|
+
if (element && core.domHelper.isNodeInEditor(element)) {
|
|
102
|
+
var doc = core.physicalRoot.ownerDocument;
|
|
103
103
|
var range = doc.createRange();
|
|
104
104
|
var isReverted = undefined;
|
|
105
105
|
range.selectNode(element);
|
|
@@ -115,7 +115,7 @@ define(["require", "exports", "./addRangeToSelection", "../../corePlugin/cache/a
|
|
|
115
115
|
selection.focusOffset != range_1.endOffset;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
core.domHelper.setSelectionRange(range, isReverted);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './addRangeToSelection';\nimport { areSameSelections } from '../../corePlugin/cache/areSameSelections';\nimport { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { findLastedCoInMergedCell } from './findLastedCoInMergedCell';\nimport { findTableCellElement } from './findTableCellElement';\nimport { getSafeIdSelector, parseTableCells } from 'roosterjs-content-model-dom';\nimport { setTableCellsStyle } from './setTableCellsStyle';\nimport { toggleCaret } from './toggleCaret';\nimport type { SelectionChangedEvent, SetDOMSelection } from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';\nconst IMAGE_ID = 'image';\nconst TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';\nconst SELECTION_SELECTOR = '*::selection';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\n const existingSelection = core.api.getDOMSelection(core);\n\n if (existingSelection && selection && areSameSelections(existingSelection, selection)) {\n return;\n }\n\n // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.\n // Set skipReselectOnFocus to skip this behavior\n const skipReselectOnFocus = core.selection.skipReselectOnFocus;\n\n const doc = core.physicalRoot.ownerDocument;\n const isDarkMode = core.lifecycle.isDarkMode;\n core.selection.skipReselectOnFocus = true;\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);\n core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, null /*cssRule*/);\n\n toggleCaret(core, false /* hide */);\n\n try {\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n core.selection.selection = selection;\n\n const imageSelectionColor = isDarkMode\n ? core.selection.imageSelectionBorderColorDark\n : core.selection.imageSelectionBorderColor;\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `outline-style:solid!important; outline-color:${\n imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR\n }!important;`,\n [getSafeIdSelector(ensureUniqueId(image, IMAGE_ID))]\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n setRangeSelection(doc, image, false /* collapse */);\n break;\n case 'table':\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(selection.table);\n let firstCell = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n cell: <HTMLTableCellElement | null>null,\n };\n let lastCell = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n firstCell = findTableCellElement(parsedTable, firstCell) || firstCell;\n lastCell = findLastedCoInMergedCell(parsedTable, lastCell) || lastCell;\n\n if (\n isNaN(firstCell.row) ||\n isNaN(firstCell.col) ||\n isNaN(lastCell.row) ||\n isNaN(lastCell.col)\n ) {\n return;\n }\n\n selection = {\n type: 'table',\n table,\n firstRow: firstCell.row,\n firstColumn: firstCell.col,\n lastRow: lastCell.row,\n lastColumn: lastCell.col,\n tableSelectionInfo: selection.tableSelectionInfo,\n };\n\n core.selection.selection = selection;\n\n setTableCellsStyle(core, table, parsedTable, firstCell, lastCell);\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n toggleCaret(core, true /* hide */);\n\n const nodeToSelect = firstCell.cell?.firstElementChild || firstCell.cell;\n\n if (nodeToSelect) {\n setRangeSelection(\n doc,\n (nodeToSelect as HTMLElement) || undefined,\n true /* collapse */\n );\n }\n\n break;\n case 'range':\n addRangeToSelection(doc, selection.range, selection.isReverted);\n\n core.selection.selection = core.domHelper.hasFocus() ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: SelectionChangedEvent = {\n eventType: 'selectionChanged',\n newSelection: selection,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined, collapse: boolean) {\n if (element && doc.contains(element)) {\n const range = doc.createRange();\n let isReverted: boolean | undefined = undefined;\n\n range.selectNode(element);\n if (collapse) {\n range.collapse();\n } else {\n const selection = doc.defaultView?.getSelection();\n const range = selection && selection.rangeCount > 0 && selection.getRangeAt(0);\n if (selection && range) {\n isReverted =\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset;\n }\n }\n\n addRangeToSelection(doc, range, isReverted);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelections } from '../../corePlugin/cache/areSameSelections';\nimport { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { findLastedCoInMergedCell } from './findLastedCoInMergedCell';\nimport { findTableCellElement } from './findTableCellElement';\nimport { getSafeIdSelector, parseTableCells } from 'roosterjs-content-model-dom';\nimport { setTableCellsStyle } from './setTableCellsStyle';\nimport { toggleCaret } from './toggleCaret';\nimport type {\n EditorCore,\n SelectionChangedEvent,\n SetDOMSelection,\n} from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';\nconst IMAGE_ID = 'image';\nconst TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';\nconst SELECTION_SELECTOR = '*::selection';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\n const existingSelection = core.api.getDOMSelection(core);\n\n if (existingSelection && selection && areSameSelections(existingSelection, selection)) {\n return;\n }\n\n // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.\n // Set skipReselectOnFocus to skip this behavior\n const skipReselectOnFocus = core.selection.skipReselectOnFocus;\n\n const isDarkMode = core.lifecycle.isDarkMode;\n core.selection.skipReselectOnFocus = true;\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);\n core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, null /*cssRule*/);\n\n toggleCaret(core, false /* hide */);\n\n try {\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n core.selection.selection = selection;\n\n const imageSelectionColor = isDarkMode\n ? core.selection.imageSelectionBorderColorDark\n : core.selection.imageSelectionBorderColor;\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `outline-style:solid!important; outline-color:${\n imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR\n }!important;`,\n [getSafeIdSelector(ensureUniqueId(image, IMAGE_ID))]\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n setRangeSelection(core, image, false /* collapse */);\n break;\n case 'table':\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(selection.table);\n let firstCell = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n cell: <HTMLTableCellElement | null>null,\n };\n let lastCell = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n firstCell = findTableCellElement(parsedTable, firstCell) || firstCell;\n lastCell = findLastedCoInMergedCell(parsedTable, lastCell) || lastCell;\n\n if (\n isNaN(firstCell.row) ||\n isNaN(firstCell.col) ||\n isNaN(lastCell.row) ||\n isNaN(lastCell.col)\n ) {\n return;\n }\n\n selection = {\n type: 'table',\n table,\n firstRow: firstCell.row,\n firstColumn: firstCell.col,\n lastRow: lastCell.row,\n lastColumn: lastCell.col,\n tableSelectionInfo: selection.tableSelectionInfo,\n };\n\n core.selection.selection = selection;\n\n setTableCellsStyle(core, table, parsedTable, firstCell, lastCell);\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n toggleCaret(core, true /* hide */);\n\n const nodeToSelect = firstCell.cell?.firstElementChild || firstCell.cell;\n\n if (nodeToSelect) {\n setRangeSelection(\n core,\n (nodeToSelect as HTMLElement) || undefined,\n true /* collapse */\n );\n }\n\n break;\n case 'range':\n core.domHelper.setSelectionRange(selection.range, selection.isReverted);\n\n core.selection.selection = core.domHelper.hasFocus() ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: SelectionChangedEvent = {\n eventType: 'selectionChanged',\n newSelection: selection,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction setRangeSelection(core: EditorCore, element: HTMLElement | undefined, collapse: boolean) {\n if (element && core.domHelper.isNodeInEditor(element)) {\n const doc = core.physicalRoot.ownerDocument;\n const range = doc.createRange();\n let isReverted: boolean | undefined = undefined;\n\n range.selectNode(element);\n if (collapse) {\n range.collapse();\n } else {\n const selection = doc.defaultView?.getSelection();\n const range = selection && selection.rangeCount > 0 && selection.getRangeAt(0);\n if (selection && range) {\n isReverted =\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset;\n }\n }\n\n core.domHelper.setSelectionRange(range, isReverted);\n }\n}\n"]}
|
|
@@ -7,9 +7,9 @@ define(["require", "exports", "roosterjs-content-model-dom"], function (require,
|
|
|
7
7
|
*/
|
|
8
8
|
function ensureUniqueId(element, idPrefix) {
|
|
9
9
|
idPrefix = element.id || idPrefix;
|
|
10
|
-
var
|
|
10
|
+
var root = element.getRootNode();
|
|
11
11
|
var i = 0;
|
|
12
|
-
while (!element.id ||
|
|
12
|
+
while (!element.id || root.querySelectorAll((0, roosterjs_content_model_dom_1.getSafeIdSelector)(element.id)).length > 1) {
|
|
13
13
|
element.id = idPrefix + '_' + i++;
|
|
14
14
|
}
|
|
15
15
|
return element.id;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensureUniqueId.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setEditorStyle/ensureUniqueId.ts"],"names":[],"mappings":";;;;IAEA;;OAEG;IACH,SAAgB,cAAc,CAAC,OAAoB,EAAE,QAAgB;QACjE,QAAQ,GAAG,OAAO,CAAC,EAAE,IAAI,QAAQ,CAAC;QAElC,IAAM,
|
|
1
|
+
{"version":3,"file":"ensureUniqueId.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setEditorStyle/ensureUniqueId.ts"],"names":[],"mappings":";;;;IAEA;;OAEG;IACH,SAAgB,cAAc,CAAC,OAAoB,EAAE,QAAgB;QACjE,QAAQ,GAAG,OAAO,CAAC,EAAE,IAAI,QAAQ,CAAC;QAElC,IAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAA2B,CAAC;QAC5D,IAAI,CAAC,GAAG,CAAC,CAAC;QAEV,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAA,+CAAiB,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YACnF,OAAO,CAAC,EAAE,GAAG,QAAQ,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;SACrC;QAED,OAAO,OAAO,CAAC,EAAE,CAAC;IACtB,CAAC;IAXD,wCAWC","sourcesContent":["import { getSafeIdSelector } from 'roosterjs-content-model-dom';\n\n/**\n * @internal\n */\nexport function ensureUniqueId(element: HTMLElement, idPrefix: string): string {\n idPrefix = element.id || idPrefix;\n\n const root = element.getRootNode() as Document | ShadowRoot;\n let i = 0;\n\n while (!element.id || root.querySelectorAll(getSafeIdSelector(element.id)).length > 1) {\n element.id = idPrefix + '_' + i++;\n }\n\n return element.id;\n}\n"]}
|
|
@@ -13,7 +13,7 @@ define(["require", "exports", "./ensureUniqueId", "roosterjs-content-model-dom"]
|
|
|
13
13
|
if (!styleElement && cssRule) {
|
|
14
14
|
var doc = core.physicalRoot.ownerDocument;
|
|
15
15
|
styleElement = doc.createElement('style');
|
|
16
|
-
|
|
16
|
+
core.domHelper.appendToRoot(styleElement);
|
|
17
17
|
styleElement.dataset.roosterjsStyleKey = key;
|
|
18
18
|
core.lifecycle.styleElements[key] = styleElement;
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setEditorStyle.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setEditorStyle/setEditorStyle.ts"],"names":[],"mappings":";;;;IAIA,IAAM,wBAAwB,GAAG,IAAI,CAAC;IACtC,IAAM,cAAc,GAAG,YAAY,CAAC;IAEpC;;OAEG;IACI,IAAM,cAAc,GAAmB,UAC1C,IAAI,EACJ,GAAG,EACH,OAAO,EACP,YAAY,EACZ,aAAwC;QAAxC,8BAAA,EAAA,wCAAwC;QAExC,IAAI,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAErD,IAAI,CAAC,YAAY,IAAI,OAAO,EAAE;YAC1B,IAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC;YAE5C,YAAY,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC1C,
|
|
1
|
+
{"version":3,"file":"setEditorStyle.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setEditorStyle/setEditorStyle.ts"],"names":[],"mappings":";;;;IAIA,IAAM,wBAAwB,GAAG,IAAI,CAAC;IACtC,IAAM,cAAc,GAAG,YAAY,CAAC;IAEpC;;OAEG;IACI,IAAM,cAAc,GAAmB,UAC1C,IAAI,EACJ,GAAG,EACH,OAAO,EACP,YAAY,EACZ,aAAwC;QAAxC,8BAAA,EAAA,wCAAwC;QAExC,IAAI,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAErD,IAAI,CAAC,YAAY,IAAI,OAAO,EAAE;YAC1B,IAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC;YAE5C,YAAY,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAE1C,YAAY,CAAC,OAAO,CAAC,iBAAiB,GAAG,GAAG,CAAC;YAC7C,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;SACpD;QAED,IAAM,KAAK,GAAG,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAC;QAElC,IAAI,KAAK,EAAE;YACP,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;gBACjD,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;aACvB;YAED,IAAI,OAAO,EAAE;gBACT,IAAM,YAAY,GAAG,IAAA,+CAAiB,EAClC,IAAA,+BAAc,EAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CACpD,CAAC;gBACF,IAAM,SAAS,GAAG,CAAC,YAAY;oBAC3B,CAAC,CAAC,CAAC,YAAY,CAAC;oBAChB,CAAC,CAAC,OAAO,YAAY,KAAK,QAAQ;wBAClC,CAAC,CAAC,CAAI,YAAY,UAAK,YAAc,CAAC;wBACtC,CAAC,CAAC,cAAc,CACV,YAAY,EACZ,YAAY,EACZ,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,oBAAoB;yBAC1D,CAAC;gBAER,SAAS,CAAC,OAAO,CAAC,UAAA,QAAQ;oBACtB,KAAK,CAAC,UAAU,CAAI,QAAQ,UAAK,OAAO,MAAG,CAAC,CAAC;gBACjD,CAAC,CAAC,CAAC;aACN;SACJ;IACL,CAAC,CAAC;IA7CW,QAAA,cAAc,kBA6CzB;IAEF,SAAS,cAAc,CAAC,YAAoB,EAAE,YAAsB,EAAE,MAAc;QAChF,IAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,aAAa,GAAa,EAAE,CAAC;QACjC,IAAI,GAAG,GAAG,CAAC,CAAC;QAEZ,YAAY,CAAC,OAAO,CAAC,UAAA,WAAW;YAC5B,IAAI,GAAG,IAAI,MAAM,EAAE;gBACf,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACrC,aAAa,GAAG,EAAE,CAAC;gBACnB,GAAG,GAAG,CAAC,CAAC;aACX;YAED,IAAM,QAAQ,GAAM,YAAY,SAAI,WAAa,CAAC;YAElD,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,4CAA4C;YACxE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAErC,OAAO,MAAM,CAAC;IAClB,CAAC","sourcesContent":["import { ensureUniqueId } from './ensureUniqueId';\nimport { getSafeIdSelector } from 'roosterjs-content-model-dom';\nimport type { SetEditorStyle } from 'roosterjs-content-model-types';\n\nconst MAX_RULE_SELECTOR_LENGTH = 9000;\nconst CONTENT_DIV_ID = 'contentDiv';\n\n/**\n * @internal\n */\nexport const setEditorStyle: SetEditorStyle = (\n core,\n key,\n cssRule,\n subSelectors,\n maxRuleLength = MAX_RULE_SELECTOR_LENGTH\n) => {\n let styleElement = core.lifecycle.styleElements[key];\n\n if (!styleElement && cssRule) {\n const doc = core.physicalRoot.ownerDocument;\n\n styleElement = doc.createElement('style');\n core.domHelper.appendToRoot(styleElement);\n\n styleElement.dataset.roosterjsStyleKey = key;\n core.lifecycle.styleElements[key] = styleElement;\n }\n\n const sheet = styleElement?.sheet;\n\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n sheet.deleteRule(i);\n }\n\n if (cssRule) {\n const rootSelector = getSafeIdSelector(\n ensureUniqueId(core.physicalRoot, CONTENT_DIV_ID)\n );\n const selectors = !subSelectors\n ? [rootSelector]\n : typeof subSelectors === 'string'\n ? [`${rootSelector}::${subSelectors}`]\n : buildSelectors(\n rootSelector,\n subSelectors,\n maxRuleLength - cssRule.length - 3 // minus 3 for \" {}\"\n );\n\n selectors.forEach(selector => {\n sheet.insertRule(`${selector} {${cssRule}}`);\n });\n }\n }\n};\n\nfunction buildSelectors(rootSelector: string, subSelectors: string[], maxLen: number): string[] {\n const result: string[] = [];\n\n let stringBuilder: string[] = [];\n let len = 0;\n\n subSelectors.forEach(subSelector => {\n if (len >= maxLen) {\n result.push(stringBuilder.join(','));\n stringBuilder = [];\n len = 0;\n }\n\n const selector = `${rootSelector} ${subSelector}`;\n\n len += selector.length + 1; // Add 1 for potential \",\" between selectors\n stringBuilder.push(selector);\n });\n\n result.push(stringBuilder.join(','));\n\n return result;\n}\n"]}
|
|
@@ -31,6 +31,11 @@ define(["require", "exports", "./areSameSelections", "./ParagraphMapImpl", "./te
|
|
|
31
31
|
_this.invalidateCache();
|
|
32
32
|
}
|
|
33
33
|
break;
|
|
34
|
+
case 'attribute':
|
|
35
|
+
if (!_this.state.domIndexer.reconcileImageAttribute(mutation.element, mutation.attributeName)) {
|
|
36
|
+
_this.invalidateCache();
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
34
39
|
case 'unknown':
|
|
35
40
|
_this.invalidateCache();
|
|
36
41
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CachePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/CachePlugin.ts"],"names":[],"mappings":";;;;IAcA;;OAEG;IACH;QAII;;;;WAIG;QACH,qBAAY,MAAqB,EAAE,UAA0B;YAA7D,iBAcC;YAtBO,WAAM,GAAmB,IAAI,CAAC;YAyG9B,eAAU,GAAG,UAAC,QAAkB;gBACpC,IAAI,KAAI,CAAC,MAAM,EAAE;oBACb,QAAQ,QAAQ,CAAC,IAAI,EAAE;wBACnB,KAAK,WAAW;4BACZ,IACI,CAAC,KAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CACrC,QAAQ,CAAC,UAAU,EACnB,QAAQ,CAAC,YAAY,CACxB,EACH;gCACE,KAAI,CAAC,eAAe,EAAE,CAAC;6BAC1B;4BACD,MAAM;wBAEV,KAAK,MAAM;4BACP,KAAI,CAAC,iBAAiB,CAAC,KAAI,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;4BAC1D,MAAM;wBAEV,KAAK,WAAW;4BACZ,IAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;4BAEjC,IAAI,CAAC,KAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE;gCACpD,KAAI,CAAC,eAAe,EAAE,CAAC;6BAC1B;4BAED,MAAM;wBAEV,KAAK,SAAS;4BACV,KAAI,CAAC,eAAe,EAAE,CAAC;4BACvB,MAAM;qBACb;iBACJ;YACL,CAAC,CAAC;YAEM,4BAAuB,GAAG;;gBAC9B,IAAI,MAAA,KAAI,CAAC,MAAM,0CAAE,QAAQ,EAAE,EAAE;oBACzB,KAAI,CAAC,iBAAiB,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC;iBACvC;YACL,CAAC,CAAC;YAtIE,IAAI,CAAC,KAAK,GAAG;gBACT,UAAU,EAAE,IAAI,+BAAc,CAC1B,MAAM,CAAC,oBAAoB;oBACvB,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAC/B,yCAAyC,CAC5C,IAAI,CAAC,CACb;gBACD,oBAAoB,EAAE,IAAA,iDAA0B,EAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC;aAChF,CAAC;YAEF,IAAI,MAAM,CAAC,kBAAkB,EAAE;gBAC3B,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAA,qCAAkB,GAAE,CAAC;aAClD;QACL,CAAC;QAED;;WAEG;QACH,6BAAO,GAAP;YACI,OAAO,OAAO,CAAC;QACnB,CAAC;QAED;;;;;WAKG;QACH,gCAAU,GAAV,UAAW,MAAe;YACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;YAE5F,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,cAAc,EAAE,CAAC;QACrD,CAAC;QAED;;;;WAIG;QACH,6BAAO,GAAP;YACI,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,aAAa,EAAE,CAAC;YAEhD,IAAI,IAAI,CAAC,MAAM,EAAE;gBACb,IAAI,CAAC,MAAM;qBACN,WAAW,EAAE;qBACb,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBAC1E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;aACtB;QACL,CAAC;QAED;;WAEG;QACH,8BAAQ,GAAR;YACI,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;QAED;;;;;WAKG;QACH,mCAAa,GAAb,UAAc,KAAkB;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBACd,OAAO;aACV;YAED,QAAQ,KAAK,CAAC,SAAS,EAAE;gBACrB,KAAK,oBAAoB;oBACrB,IAAI,CAAC,eAAe,EAAE,CAAC;oBAEvB,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,aAAa,EAAE,CAAC;oBAChD,IAAI,CAAC,KAAK,CAAC,oBAAoB,GAAG,IAAA,iDAA0B,EACxD,KAAK,CAAC,WAAW,EACjB,IAAI,CAAC,UAAU,CAClB,CAAC;oBACF,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,cAAc,EAAE,CAAC;oBACjD,MAAM;gBAEV,KAAK,kBAAkB;oBACnB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACpC,MAAM;gBAEV,KAAK,gBAAgB;oBACT,IAAA,YAAY,GAAgB,KAAK,aAArB,EAAE,SAAS,GAAK,KAAK,UAAV,CAAW;oBAE1C,IAAI,YAAY,EAAE;wBACd,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;qBACpD;oBAED,MAAM;aACb;QACL,CAAC;QA0CO,qCAAe,GAAvB;;YACI,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,cAAc,EAAE,CAAA,EAAE;gBAChC,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBACxB,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;iBACtC;gBAED,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;oBAC5B,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC;iBAC1C;gBAED,wEAAwE;gBACxE,kEAAkE;gBAClE,MAAA,IAAI,CAAC,KAAK,CAAC,YAAY,0CAAE,KAAK,EAAE,CAAC;aACpC;QACL,CAAC;QAEO,uCAAiB,GAAzB,UAA0B,MAAe,EAAE,WAAqB;YAC5D,IAAI,MAAM,CAAC,cAAc,EAAE,EAAE;gBACzB,OAAO;aACV;YAED,IAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,0EAA0E;YAElH,IAAM,UAAU,GAAG,MAAM,CAAC,eAAe,EAAE,IAAI,SAAS,CAAC;YACzD,IAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YACrC,IAAM,kBAAkB,GACpB,WAAW;gBACX,CAAC,eAAe;gBAChB,CAAC,UAAU;gBACX,CAAC,IAAA,qCAAiB,EAAC,UAAU,EAAE,eAAe,CAAC,CAAC;YAEpD,IAAI,kBAAkB,EAAE;gBACpB,IACI,CAAC,KAAK;oBACN,CAAC,UAAU;oBACX,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,eAAe,CAAC,EAC/E;oBACE,IAAI,CAAC,eAAe,EAAE,CAAC;iBAC1B;qBAAM;oBACH,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;iBAC9C;aACJ;iBAAM;gBACH,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,eAAe,CAAC;aAChD;QACL,CAAC;QACL,kBAAC;IAAD,CAAC,AAhMD,IAgMC;IAED;;;;;OAKG;IACH,SAAgB,iBAAiB,CAC7B,MAAqB,EACrB,UAA0B;QAE1B,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IALD,8CAKC","sourcesContent":["import { areSameSelections } from './areSameSelections';\nimport { createParagraphMap } from './ParagraphMapImpl';\nimport { createTextMutationObserver } from './textMutationObserver';\nimport { DomIndexerImpl } from './domIndexerImpl';\nimport { updateCache } from './updateCache';\nimport type { Mutation } from './MutationType';\nimport type {\n CachePluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass CachePlugin implements PluginWithState<CachePluginState> {\n private editor: IEditor | null = null;\n private state: CachePluginState;\n\n /**\n * Construct a new instance of CachePlugin class\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\n constructor(option: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n domIndexer: new DomIndexerImpl(\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf(\n 'KeepSelectionMarkerWhenEnteringTextNode'\n ) >= 0\n ),\n textMutationObserver: createTextMutationObserver(contentDiv, this.onMutation),\n };\n\n if (option.enableParagraphMap) {\n this.state.paragraphMap = createParagraphMap();\n }\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Cache';\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.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\n\n this.state.textMutationObserver.startObserving();\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.state.textMutationObserver.stopObserving();\n\n if (this.editor) {\n this.editor\n .getDocument()\n .removeEventListener('selectionchange', this.onNativeSelectionChange);\n this.editor = null;\n }\n }\n\n /**\n * Get plugin state object\n */\n getState(): CachePluginState {\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 'logicalRootChanged':\n this.invalidateCache();\n\n this.state.textMutationObserver.stopObserving();\n this.state.textMutationObserver = createTextMutationObserver(\n event.logicalRoot,\n this.onMutation\n );\n this.state.textMutationObserver.startObserving();\n break;\n\n case 'selectionChanged':\n this.updateCachedModel(this.editor);\n break;\n\n case 'contentChanged':\n const { contentModel, selection } = event;\n\n if (contentModel) {\n updateCache(this.state, contentModel, selection);\n }\n\n break;\n }\n }\n\n private onMutation = (mutation: Mutation) => {\n if (this.editor) {\n switch (mutation.type) {\n case 'childList':\n if (\n !this.state.domIndexer.reconcileChildList(\n mutation.addedNodes,\n mutation.removedNodes\n )\n ) {\n this.invalidateCache();\n }\n break;\n\n case 'text':\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n break;\n\n case 'elementId':\n const element = mutation.element;\n\n if (!this.state.domIndexer.reconcileElementId(element)) {\n this.invalidateCache();\n }\n\n break;\n\n case 'unknown':\n this.invalidateCache();\n break;\n }\n }\n };\n\n private onNativeSelectionChange = () => {\n if (this.editor?.hasFocus()) {\n this.updateCachedModel(this.editor);\n }\n };\n\n private invalidateCache() {\n if (!this.editor?.isInShadowEdit()) {\n if (this.state.cachedModel) {\n this.state.cachedModel = undefined;\n }\n\n if (this.state.cachedSelection) {\n this.state.cachedSelection = undefined;\n }\n\n // Clear paragraph indexer to prevent stale references to old paragraphs\n // It will be rebuild next time when we create a new Content Model\n this.state.paragraphMap?.clear();\n }\n }\n\n private updateCachedModel(editor: IEditor, forceUpdate?: boolean) {\n if (editor.isInShadowEdit()) {\n return;\n }\n\n const cachedSelection = this.state.cachedSelection;\n this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range\n\n const newRangeEx = editor.getDOMSelection() || undefined;\n const model = this.state.cachedModel;\n const isSelectionChanged =\n forceUpdate ||\n !cachedSelection ||\n !newRangeEx ||\n !areSameSelections(newRangeEx, cachedSelection);\n\n if (isSelectionChanged) {\n if (\n !model ||\n !newRangeEx ||\n !this.state.domIndexer.reconcileSelection(model, newRangeEx, cachedSelection)\n ) {\n this.invalidateCache();\n } else {\n updateCache(this.state, model, newRangeEx);\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of CachePlugin class.\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\nexport function createCachePlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<CachePluginState> {\n return new CachePlugin(option, contentDiv);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"CachePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/CachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelections } from './areSameSelections';\nimport { createParagraphMap } from './ParagraphMapImpl';\nimport { createTextMutationObserver } from './textMutationObserver';\nimport { DomIndexerImpl } from './domIndexerImpl';\nimport { updateCache } from './updateCache';\nimport type { Mutation } from './MutationType';\nimport type {\n CachePluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass CachePlugin implements PluginWithState<CachePluginState> {\n private editor: IEditor | null = null;\n private state: CachePluginState;\n\n /**\n * Construct a new instance of CachePlugin class\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\n constructor(option: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n domIndexer: new DomIndexerImpl(\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf(\n 'KeepSelectionMarkerWhenEnteringTextNode'\n ) >= 0\n ),\n textMutationObserver: createTextMutationObserver(contentDiv, this.onMutation),\n };\n\n if (option.enableParagraphMap) {\n this.state.paragraphMap = createParagraphMap();\n }\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Cache';\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.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\n\n this.state.textMutationObserver.startObserving();\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.state.textMutationObserver.stopObserving();\n\n if (this.editor) {\n this.editor\n .getDocument()\n .removeEventListener('selectionchange', this.onNativeSelectionChange);\n this.editor = null;\n }\n }\n\n /**\n * Get plugin state object\n */\n getState(): CachePluginState {\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 'logicalRootChanged':\n this.invalidateCache();\n\n this.state.textMutationObserver.stopObserving();\n this.state.textMutationObserver = createTextMutationObserver(\n event.logicalRoot,\n this.onMutation\n );\n this.state.textMutationObserver.startObserving();\n break;\n\n case 'selectionChanged':\n this.updateCachedModel(this.editor);\n break;\n\n case 'contentChanged':\n const { contentModel, selection } = event;\n\n if (contentModel) {\n updateCache(this.state, contentModel, selection);\n }\n\n break;\n }\n }\n\n private onMutation = (mutation: Mutation) => {\n if (this.editor) {\n switch (mutation.type) {\n case 'childList':\n if (\n !this.state.domIndexer.reconcileChildList(\n mutation.addedNodes,\n mutation.removedNodes\n )\n ) {\n this.invalidateCache();\n }\n break;\n\n case 'text':\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n break;\n\n case 'elementId':\n const element = mutation.element;\n\n if (!this.state.domIndexer.reconcileElementId(element)) {\n this.invalidateCache();\n }\n\n break;\n\n case 'attribute':\n if (\n !this.state.domIndexer.reconcileImageAttribute(\n mutation.element,\n mutation.attributeName\n )\n ) {\n this.invalidateCache();\n }\n\n break;\n\n case 'unknown':\n this.invalidateCache();\n break;\n }\n }\n };\n\n private onNativeSelectionChange = () => {\n if (this.editor?.hasFocus()) {\n this.updateCachedModel(this.editor);\n }\n };\n\n private invalidateCache() {\n if (!this.editor?.isInShadowEdit()) {\n if (this.state.cachedModel) {\n this.state.cachedModel = undefined;\n }\n\n if (this.state.cachedSelection) {\n this.state.cachedSelection = undefined;\n }\n\n // Clear paragraph indexer to prevent stale references to old paragraphs\n // It will be rebuild next time when we create a new Content Model\n this.state.paragraphMap?.clear();\n }\n }\n\n private updateCachedModel(editor: IEditor, forceUpdate?: boolean) {\n if (editor.isInShadowEdit()) {\n return;\n }\n\n const cachedSelection = this.state.cachedSelection;\n this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range\n\n const newRangeEx = editor.getDOMSelection() || undefined;\n const model = this.state.cachedModel;\n const isSelectionChanged =\n forceUpdate ||\n !cachedSelection ||\n !newRangeEx ||\n !areSameSelections(newRangeEx, cachedSelection);\n\n if (isSelectionChanged) {\n if (\n !model ||\n !newRangeEx ||\n !this.state.domIndexer.reconcileSelection(model, newRangeEx, cachedSelection)\n ) {\n this.invalidateCache();\n } else {\n updateCache(this.state, model, newRangeEx);\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of CachePlugin class.\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\nexport function createCachePlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<CachePluginState> {\n return new CachePlugin(option, contentDiv);\n}\n"]}
|
|
@@ -10,6 +10,10 @@ export declare type MutationType =
|
|
|
10
10
|
* Element id is changed
|
|
11
11
|
*/
|
|
12
12
|
| 'elementId'
|
|
13
|
+
/**
|
|
14
|
+
* An attribute (such as src or data-*) is changed on an element
|
|
15
|
+
*/
|
|
16
|
+
| 'attribute'
|
|
13
17
|
/**
|
|
14
18
|
* Only text is changed
|
|
15
19
|
*/
|
|
@@ -35,6 +39,13 @@ export interface UnknownMutation extends MutationBase<'unknown'> {
|
|
|
35
39
|
export interface ElementIdMutation extends MutationBase<'elementId'> {
|
|
36
40
|
element: HTMLElement;
|
|
37
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export interface AttributeMutation extends MutationBase<'attribute'> {
|
|
46
|
+
element: HTMLElement;
|
|
47
|
+
attributeName: string;
|
|
48
|
+
}
|
|
38
49
|
/**
|
|
39
50
|
* @internal
|
|
40
51
|
*/
|
|
@@ -50,4 +61,4 @@ export interface ChildListMutation extends MutationBase<'childList'> {
|
|
|
50
61
|
/**
|
|
51
62
|
* @internal
|
|
52
63
|
*/
|
|
53
|
-
export declare type Mutation = UnknownMutation | ElementIdMutation | TextMutation | ChildListMutation;
|
|
64
|
+
export declare type Mutation = UnknownMutation | ElementIdMutation | AttributeMutation | TextMutation | ChildListMutation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MutationType.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/MutationType.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @internal Type of mutations\n */\nexport type MutationType =\n /**\n * We found some change happened but we cannot handle it, so set mutation type as \"unknown\"\n */\n | 'unknown'\n /**\n * Element id is changed\n */\n | 'elementId'\n /**\n * Only text is changed\n */\n | 'text'\n /**\n * Child list is changed\n */\n | 'childList';\n\n/**\n * @internal\n */\nexport interface MutationBase<T extends MutationType> {\n type: T;\n}\n\n/**\n * @internal\n */\nexport interface UnknownMutation extends MutationBase<'unknown'> {}\n\n/**\n * @internal\n */\nexport interface ElementIdMutation extends MutationBase<'elementId'> {\n element: HTMLElement;\n}\n\n/**\n * @internal\n */\nexport interface TextMutation extends MutationBase<'text'> {}\n\n/**\n * @internal\n */\nexport interface ChildListMutation extends MutationBase<'childList'> {\n addedNodes: Node[];\n removedNodes: Node[];\n}\n\n/**\n * @internal\n */\nexport type Mutation
|
|
1
|
+
{"version":3,"file":"MutationType.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/MutationType.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @internal Type of mutations\n */\nexport type MutationType =\n /**\n * We found some change happened but we cannot handle it, so set mutation type as \"unknown\"\n */\n | 'unknown'\n /**\n * Element id is changed\n */\n | 'elementId'\n /**\n * An attribute (such as src or data-*) is changed on an element\n */\n | 'attribute'\n /**\n * Only text is changed\n */\n | 'text'\n /**\n * Child list is changed\n */\n | 'childList';\n\n/**\n * @internal\n */\nexport interface MutationBase<T extends MutationType> {\n type: T;\n}\n\n/**\n * @internal\n */\nexport interface UnknownMutation extends MutationBase<'unknown'> {}\n\n/**\n * @internal\n */\nexport interface ElementIdMutation extends MutationBase<'elementId'> {\n element: HTMLElement;\n}\n\n/**\n * @internal\n */\nexport interface AttributeMutation extends MutationBase<'attribute'> {\n element: HTMLElement;\n attributeName: string;\n}\n\n/**\n * @internal\n */\nexport interface TextMutation extends MutationBase<'text'> {}\n\n/**\n * @internal\n */\nexport interface ChildListMutation extends MutationBase<'childList'> {\n addedNodes: Node[];\n removedNodes: Node[];\n}\n\n/**\n * @internal\n */\nexport type Mutation =\n | UnknownMutation\n | ElementIdMutation\n | AttributeMutation\n | TextMutation\n | ChildListMutation;\n"]}
|
|
@@ -8,7 +8,3 @@ export declare function areSameSelections(sel1: DOMSelection, sel2: DOMSelection
|
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
10
|
export declare function areSameTableSelections(t1: TableSelection, t2: TableSelection): boolean;
|
|
11
|
-
/**
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
export declare function areSameRanges(r1: Range, r2: Range): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
define(["require", "exports"], function (require, exports) {
|
|
1
|
+
define(["require", "exports", "../../utils/areSameRanges"], function (require, exports, areSameRanges_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.
|
|
4
|
+
exports.areSameTableSelections = exports.areSameSelections = void 0;
|
|
5
5
|
/**
|
|
6
6
|
* @internal
|
|
7
7
|
* Check if the given selections are the same
|
|
@@ -27,7 +27,7 @@ define(["require", "exports"], function (require, exports) {
|
|
|
27
27
|
range1.endOffset == end.offset);
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
|
-
return areSameRanges(range1, sel2.range);
|
|
30
|
+
return (0, areSameRanges_1.areSameRanges)(range1, sel2.range);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
@@ -46,7 +46,6 @@ define(["require", "exports"], function (require, exports) {
|
|
|
46
46
|
'firstRow',
|
|
47
47
|
'lastRow',
|
|
48
48
|
];
|
|
49
|
-
var RangeKeys = ['startContainer', 'endContainer', 'startOffset', 'endOffset'];
|
|
50
49
|
/**
|
|
51
50
|
* @internal
|
|
52
51
|
*/
|
|
@@ -54,13 +53,6 @@ define(["require", "exports"], function (require, exports) {
|
|
|
54
53
|
return areSame(t1, t2, TableSelectionKeys);
|
|
55
54
|
}
|
|
56
55
|
exports.areSameTableSelections = areSameTableSelections;
|
|
57
|
-
/**
|
|
58
|
-
* @internal
|
|
59
|
-
*/
|
|
60
|
-
function areSameRanges(r1, r2) {
|
|
61
|
-
return areSame(r1, r2, RangeKeys);
|
|
62
|
-
}
|
|
63
|
-
exports.areSameRanges = areSameRanges;
|
|
64
56
|
function isCacheSelection(sel) {
|
|
65
57
|
return !!sel.start;
|
|
66
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"areSameSelections.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"areSameSelections.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts"],"names":[],"mappings":";;;;IASA;;;OAGG;IACH,SAAgB,iBAAiB,CAC7B,IAAkB,EAClB,IAAmC;QAEnC,IAAI,IAAI,IAAI,IAAI,EAAE;YACd,OAAO,IAAI,CAAC;SACf;QAED,QAAQ,IAAI,CAAC,IAAI,EAAE;YACf,KAAK,OAAO;gBACR,OAAO,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;YAE5D,KAAK,OAAO;gBACR,OAAO,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAEtE,KAAK,OAAO,CAAC;YACb;gBACI,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,EAAE;oBACtB,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;oBAE1B,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE;wBAChB,IAAA,KAAK,GAAU,IAAI,MAAd,EAAE,GAAG,GAAK,IAAI,IAAT,CAAU;wBAE5B,OAAO,CACH,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI;4BACnC,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC,IAAI;4BAC/B,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM;4BAClC,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CACjC,CAAC;qBACL;yBAAM;wBACH,OAAO,IAAA,6BAAa,EAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;qBAC5C;iBACJ;qBAAM;oBACH,OAAO,KAAK,CAAC;iBAChB;SACR;IACL,CAAC;IApCD,8CAoCC;IAED,SAAS,OAAO,CAAI,EAAK,EAAE,EAAK,EAAE,IAAiB;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,UAAA,CAAC,IAAI,OAAA,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAd,CAAc,CAAC,CAAC;IAC3C,CAAC;IAED,IAAM,kBAAkB,GAA6B;QACjD,OAAO;QACP,aAAa;QACb,YAAY;QACZ,UAAU;QACV,SAAS;KACZ,CAAC;IAEF;;OAEG;IACH,SAAgB,sBAAsB,CAAC,EAAkB,EAAE,EAAkB;QACzE,OAAO,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAC/C,CAAC;IAFD,wDAEC;IAED,SAAS,gBAAgB,CACrB,GAA4C;QAE5C,OAAO,CAAC,CAAE,GAA8B,CAAC,KAAK,CAAC;IACnD,CAAC","sourcesContent":["import { areSameRanges } from '../../utils/areSameRanges';\nimport type {\n CacheSelection,\n DOMSelection,\n RangeSelection,\n RangeSelectionForCache,\n TableSelection,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Check if the given selections are the same\n */\nexport function areSameSelections(\n sel1: DOMSelection,\n sel2: DOMSelection | CacheSelection\n): boolean {\n if (sel1 == sel2) {\n return true;\n }\n\n switch (sel1.type) {\n case 'image':\n return sel2.type == 'image' && sel2.image == sel1.image;\n\n case 'table':\n return sel2.type == 'table' && areSameTableSelections(sel1, sel2);\n\n case 'range':\n default:\n if (sel2.type == 'range') {\n const range1 = sel1.range;\n\n if (isCacheSelection(sel2)) {\n const { start, end } = sel2;\n\n return (\n range1.startContainer == start.node &&\n range1.endContainer == end.node &&\n range1.startOffset == start.offset &&\n range1.endOffset == end.offset\n );\n } else {\n return areSameRanges(range1, sel2.range);\n }\n } else {\n return false;\n }\n }\n}\n\nfunction areSame<O>(o1: O, o2: O, keys: (keyof O)[]) {\n return keys.every(k => o1[k] == o2[k]);\n}\n\nconst TableSelectionKeys: (keyof TableSelection)[] = [\n 'table',\n 'firstColumn',\n 'lastColumn',\n 'firstRow',\n 'lastRow',\n];\n\n/**\n * @internal\n */\nexport function areSameTableSelections(t1: TableSelection, t2: TableSelection): boolean {\n return areSame(t1, t2, TableSelectionKeys);\n}\n\nfunction isCacheSelection(\n sel: RangeSelectionForCache | RangeSelection\n): sel is RangeSelectionForCache {\n return !!(sel as RangeSelectionForCache).start;\n}\n"]}
|
|
@@ -53,6 +53,7 @@ export declare class DomIndexerImpl implements DomIndexer {
|
|
|
53
53
|
reconcileSelection(model: ContentModelDocument, newSelection: DOMSelection, oldSelection?: CacheSelection): boolean;
|
|
54
54
|
reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean;
|
|
55
55
|
reconcileElementId(element: HTMLElement): boolean;
|
|
56
|
+
reconcileImageAttribute(element: HTMLElement, attributeName: string): boolean;
|
|
56
57
|
private onBlockEntityDelimiter;
|
|
57
58
|
private isCollapsed;
|
|
58
59
|
private reconcileNodeSelection;
|
|
@@ -160,7 +160,13 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
160
160
|
}
|
|
161
161
|
else {
|
|
162
162
|
var marker1 = this.reconcileNodeSelection(startContainer, startOffset);
|
|
163
|
-
|
|
163
|
+
// Pass marker1 to the second call so its adjacent-marker cleanup
|
|
164
|
+
// does not consume the SelectionMarker we just inserted. Without
|
|
165
|
+
// this guard, when marker1 lands directly next to endContainer's
|
|
166
|
+
// segment in paragraph.segments (e.g. startOffset == startContainer
|
|
167
|
+
// text length), the second splice would absorb marker1 and leave
|
|
168
|
+
// setSelection with a dangling reference. See issue #3341.
|
|
169
|
+
var marker2 = this.reconcileNodeSelection(endContainer, endOffset, undefined, undefined, marker1);
|
|
164
170
|
if (marker1 && marker2) {
|
|
165
171
|
if (newSelection.isReverted) {
|
|
166
172
|
model.hasRevertedRangeSelection = true;
|
|
@@ -226,6 +232,33 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
226
232
|
return false;
|
|
227
233
|
}
|
|
228
234
|
};
|
|
235
|
+
DomIndexerImpl.prototype.reconcileImageAttribute = function (element, attributeName) {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
if ((0, roosterjs_content_model_dom_1.isElementOfType)(element, 'img')) {
|
|
238
|
+
var image = (_a = getIndexedSegmentItem(element)) === null || _a === void 0 ? void 0 : _a.segments[0];
|
|
239
|
+
if ((image === null || image === void 0 ? void 0 : image.segmentType) == 'Image') {
|
|
240
|
+
if (attributeName == 'src') {
|
|
241
|
+
// Use getAttribute('src') instead of retrieving src directly, in case the src
|
|
242
|
+
// has port and may be stripped by browser. This matches imageProcessor.
|
|
243
|
+
image.src = (_b = element.getAttribute('src')) !== null && _b !== void 0 ? _b : '';
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
else if (attributeName.indexOf('data-') == 0) {
|
|
247
|
+
// A data-* attribute may be added, modified or removed. Rebuild the whole
|
|
248
|
+
// dataset from DOM to keep it in sync, the same way imageProcessor builds it.
|
|
249
|
+
var dataset_1 = image.dataset;
|
|
250
|
+
(0, roosterjs_content_model_dom_1.getObjectKeys)(dataset_1).forEach(function (key) {
|
|
251
|
+
delete dataset_1[key];
|
|
252
|
+
});
|
|
253
|
+
(0, roosterjs_content_model_dom_1.getObjectKeys)(element.dataset).forEach(function (key) {
|
|
254
|
+
dataset_1[key] = element.dataset[key] || '';
|
|
255
|
+
});
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return false;
|
|
261
|
+
};
|
|
229
262
|
DomIndexerImpl.prototype.onBlockEntityDelimiter = function (node, entity, parent) {
|
|
230
263
|
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(node) && node.firstChild) {
|
|
231
264
|
var indexedDelimiter = node.firstChild;
|
|
@@ -236,10 +269,10 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
236
269
|
var start = selection.start, end = selection.end;
|
|
237
270
|
return start.node == end.node && start.offset == end.offset;
|
|
238
271
|
};
|
|
239
|
-
DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat, selectionMarker) {
|
|
272
|
+
DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat, selectionMarker, preserveMarker) {
|
|
240
273
|
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'TEXT_NODE')) {
|
|
241
274
|
if (isIndexedSegment(node)) {
|
|
242
|
-
return this.reconcileTextSelection(node, offset, undefined, selectionMarker);
|
|
275
|
+
return this.reconcileTextSelection(node, offset, undefined, selectionMarker, preserveMarker);
|
|
243
276
|
}
|
|
244
277
|
else if (isIndexedDelimiter(node)) {
|
|
245
278
|
return this.reconcileDelimiterSelection(node, defaultFormat);
|
|
@@ -269,7 +302,7 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
269
302
|
}
|
|
270
303
|
return marker;
|
|
271
304
|
};
|
|
272
|
-
DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset, selectionMarker) {
|
|
305
|
+
DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset, selectionMarker, preserveMarker) {
|
|
273
306
|
var _a;
|
|
274
307
|
var _b, _c, _d, _e, _f, _g;
|
|
275
308
|
var _h = textNode.__roosterjsContentModel, paragraph = _h.paragraph, segments = _h.segments;
|
|
@@ -322,11 +355,13 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
322
355
|
var lastIndex = paragraph.segments.indexOf(last);
|
|
323
356
|
if (firstIndex >= 0 && lastIndex >= 0) {
|
|
324
357
|
while (firstIndex > 0 &&
|
|
325
|
-
paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'
|
|
358
|
+
paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker' &&
|
|
359
|
+
paragraph.segments[firstIndex - 1] !== preserveMarker) {
|
|
326
360
|
firstIndex--;
|
|
327
361
|
}
|
|
328
362
|
while (lastIndex < paragraph.segments.length - 1 &&
|
|
329
|
-
paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'
|
|
363
|
+
paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker' &&
|
|
364
|
+
paragraph.segments[lastIndex + 1] !== preserveMarker) {
|
|
330
365
|
lastIndex++;
|
|
331
366
|
}
|
|
332
367
|
(_a = paragraph.segments).splice.apply(_a, (0, tslib_1.__spreadArray)([firstIndex, lastIndex - firstIndex + 1], (0, tslib_1.__read)(newSegments), false));
|