roosterjs-content-model-core 0.22.0 → 0.23.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/coreApi/createContentModel.js +2 -2
- package/lib/coreApi/createContentModel.js.map +1 -1
- package/lib/coreApi/paste.d.ts +9 -0
- package/lib/coreApi/paste.js +57 -0
- package/lib/coreApi/paste.js.map +1 -0
- package/lib/coreApi/setContentModel.js +2 -2
- package/lib/coreApi/setContentModel.js.map +1 -1
- package/lib/coreApi/setDOMSelection.js +10 -7
- package/lib/coreApi/setDOMSelection.js.map +1 -1
- package/lib/corePlugin/ContentModelCachePlugin.js.map +1 -1
- package/lib/corePlugin/ContentModelCopyPastePlugin.d.ts +6 -1
- package/lib/corePlugin/ContentModelCopyPastePlugin.js +40 -9
- package/lib/corePlugin/ContentModelCopyPastePlugin.js.map +1 -1
- package/lib/corePlugin/ContentModelFormatPlugin.js.map +1 -1
- package/lib/corePlugin/DOMEventPlugin.js +9 -38
- package/lib/corePlugin/DOMEventPlugin.js.map +1 -1
- package/lib/corePlugin/EntityPlugin.js +1 -1
- package/lib/corePlugin/EntityPlugin.js.map +1 -1
- package/lib/corePlugin/LifecyclePlugin.js.map +1 -1
- package/lib/corePlugin/SelectionPlugin.js +9 -8
- package/lib/corePlugin/SelectionPlugin.js.map +1 -1
- package/lib/corePlugin/UndoPlugin.js.map +1 -1
- package/lib/corePlugin/utils/applyDefaultFormat.d.ts +1 -2
- package/lib/corePlugin/utils/applyDefaultFormat.js +1 -1
- package/lib/corePlugin/utils/applyDefaultFormat.js.map +1 -1
- package/lib/editor/DarkColorHandlerImpl.d.ts +9 -0
- package/lib/editor/DarkColorHandlerImpl.js +45 -10
- package/lib/editor/DarkColorHandlerImpl.js.map +1 -1
- package/lib/editor/StandaloneEditor.d.ts +164 -0
- package/lib/editor/StandaloneEditor.js +281 -0
- package/lib/editor/StandaloneEditor.js.map +1 -0
- package/lib/editor/createStandaloneEditorCore.d.ts +8 -3
- package/lib/editor/createStandaloneEditorCore.js +20 -13
- package/lib/editor/createStandaloneEditorCore.js.map +1 -1
- package/lib/editor/createStandaloneEditorDefaultSettings.d.ts +9 -3
- package/lib/editor/createStandaloneEditorDefaultSettings.js +33 -23
- package/lib/editor/createStandaloneEditorDefaultSettings.js.map +1 -1
- package/lib/editor/standaloneCoreApiMap.d.ts +2 -2
- package/lib/editor/standaloneCoreApiMap.js +2 -0
- package/lib/editor/standaloneCoreApiMap.js.map +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +3 -6
- package/lib/index.js.map +1 -1
- package/lib/override/containerWidthFormatParser.d.ts +5 -0
- package/lib/override/containerWidthFormatParser.js +14 -0
- package/lib/override/containerWidthFormatParser.js.map +1 -0
- package/lib/override/pasteDisplayFormatParser.d.ts +5 -0
- package/lib/override/pasteDisplayFormatParser.js +14 -0
- package/lib/override/pasteDisplayFormatParser.js.map +1 -0
- package/lib/override/pasteEntityProcessor.d.ts +5 -0
- package/lib/override/pasteEntityProcessor.js +24 -0
- package/lib/override/pasteEntityProcessor.js.map +1 -0
- package/lib/override/pasteGeneralProcessor.d.ts +9 -0
- package/lib/override/pasteGeneralProcessor.js +41 -0
- package/lib/override/pasteGeneralProcessor.js.map +1 -0
- package/lib/override/pasteTextProcessor.d.ts +5 -0
- package/lib/override/pasteTextProcessor.js +17 -0
- package/lib/override/pasteTextProcessor.js.map +1 -0
- package/lib/publicApi/selection/deleteSegment.js +1 -1
- package/lib/publicApi/selection/deleteSegment.js.map +1 -1
- package/lib/utils/paste/convertInlineCss.d.ts +5 -0
- package/lib/utils/paste/convertInlineCss.js +41 -0
- package/lib/utils/paste/convertInlineCss.js.map +1 -0
- package/lib/utils/paste/createPasteFragment.d.ts +5 -0
- package/lib/utils/paste/createPasteFragment.js +76 -0
- package/lib/utils/paste/createPasteFragment.js.map +1 -0
- package/lib/utils/paste/generatePasteOptionFromPlugins.d.ts +6 -0
- package/lib/utils/paste/generatePasteOptionFromPlugins.js +56 -0
- package/lib/utils/paste/generatePasteOptionFromPlugins.js.map +1 -0
- package/lib/utils/paste/mergePasteContent.d.ts +5 -0
- package/lib/utils/paste/mergePasteContent.js +72 -0
- package/lib/utils/paste/mergePasteContent.js.map +1 -0
- package/lib/utils/paste/retrieveHtmlInfo.d.ts +21 -0
- package/lib/utils/paste/retrieveHtmlInfo.js +87 -0
- package/lib/utils/paste/retrieveHtmlInfo.js.map +1 -0
- package/lib/utils/sanitizeElement.d.ts +17 -0
- package/lib/utils/sanitizeElement.js +352 -0
- package/lib/utils/sanitizeElement.js.map +1 -0
- package/lib-amd/coreApi/createContentModel.js +3 -2
- package/lib-amd/coreApi/createContentModel.js.map +1 -1
- package/lib-amd/coreApi/paste.d.ts +9 -0
- package/lib-amd/coreApi/paste.js +52 -0
- package/lib-amd/coreApi/paste.js.map +1 -0
- package/lib-amd/coreApi/setContentModel.js +3 -2
- package/lib-amd/coreApi/setContentModel.js.map +1 -1
- package/lib-amd/coreApi/setDOMSelection.js +10 -7
- package/lib-amd/coreApi/setDOMSelection.js.map +1 -1
- package/lib-amd/corePlugin/ContentModelCachePlugin.js.map +1 -1
- package/lib-amd/corePlugin/ContentModelCopyPastePlugin.d.ts +6 -1
- package/lib-amd/corePlugin/ContentModelCopyPastePlugin.js +41 -9
- package/lib-amd/corePlugin/ContentModelCopyPastePlugin.js.map +1 -1
- package/lib-amd/corePlugin/ContentModelFormatPlugin.js.map +1 -1
- package/lib-amd/corePlugin/DOMEventPlugin.js +9 -38
- package/lib-amd/corePlugin/DOMEventPlugin.js.map +1 -1
- package/lib-amd/corePlugin/EntityPlugin.js +1 -1
- package/lib-amd/corePlugin/EntityPlugin.js.map +1 -1
- package/lib-amd/corePlugin/LifecyclePlugin.js.map +1 -1
- package/lib-amd/corePlugin/SelectionPlugin.js +9 -8
- package/lib-amd/corePlugin/SelectionPlugin.js.map +1 -1
- package/lib-amd/corePlugin/UndoPlugin.js.map +1 -1
- package/lib-amd/corePlugin/utils/applyDefaultFormat.d.ts +1 -2
- package/lib-amd/corePlugin/utils/applyDefaultFormat.js +1 -1
- package/lib-amd/corePlugin/utils/applyDefaultFormat.js.map +1 -1
- package/lib-amd/editor/DarkColorHandlerImpl.d.ts +9 -0
- package/lib-amd/editor/DarkColorHandlerImpl.js +45 -10
- package/lib-amd/editor/DarkColorHandlerImpl.js.map +1 -1
- package/lib-amd/editor/StandaloneEditor.d.ts +164 -0
- package/lib-amd/editor/StandaloneEditor.js +279 -0
- package/lib-amd/editor/StandaloneEditor.js.map +1 -0
- package/lib-amd/editor/createStandaloneEditorCore.d.ts +8 -3
- package/lib-amd/editor/createStandaloneEditorCore.js +19 -12
- package/lib-amd/editor/createStandaloneEditorCore.js.map +1 -1
- package/lib-amd/editor/createStandaloneEditorDefaultSettings.d.ts +9 -3
- package/lib-amd/editor/createStandaloneEditorDefaultSettings.js +33 -23
- package/lib-amd/editor/createStandaloneEditorDefaultSettings.js.map +1 -1
- package/lib-amd/editor/standaloneCoreApiMap.d.ts +2 -2
- package/lib-amd/editor/standaloneCoreApiMap.js +2 -1
- package/lib-amd/editor/standaloneCoreApiMap.js.map +1 -1
- package/lib-amd/index.d.ts +1 -2
- package/lib-amd/index.js +3 -4
- package/lib-amd/index.js.map +1 -1
- package/lib-amd/override/containerWidthFormatParser.d.ts +5 -0
- package/lib-amd/override/containerWidthFormatParser.js +16 -0
- package/lib-amd/override/containerWidthFormatParser.js.map +1 -0
- package/lib-amd/override/pasteDisplayFormatParser.d.ts +5 -0
- package/lib-amd/override/pasteDisplayFormatParser.js +16 -0
- package/lib-amd/override/pasteDisplayFormatParser.js.map +1 -0
- package/lib-amd/override/pasteEntityProcessor.d.ts +5 -0
- package/lib-amd/override/pasteEntityProcessor.js +25 -0
- package/lib-amd/override/pasteEntityProcessor.js.map +1 -0
- package/lib-amd/override/pasteGeneralProcessor.d.ts +9 -0
- package/lib-amd/override/pasteGeneralProcessor.js +41 -0
- package/lib-amd/override/pasteGeneralProcessor.js.map +1 -0
- package/lib-amd/override/pasteTextProcessor.d.ts +5 -0
- package/lib-amd/override/pasteTextProcessor.js +18 -0
- package/lib-amd/override/pasteTextProcessor.js.map +1 -0
- package/lib-amd/publicApi/selection/deleteSegment.js +1 -1
- package/lib-amd/publicApi/selection/deleteSegment.js.map +1 -1
- package/lib-amd/utils/paste/convertInlineCss.d.ts +5 -0
- package/lib-amd/utils/paste/convertInlineCss.js +41 -0
- package/lib-amd/utils/paste/convertInlineCss.js.map +1 -0
- package/lib-amd/utils/paste/createPasteFragment.d.ts +5 -0
- package/lib-amd/utils/paste/createPasteFragment.js +77 -0
- package/lib-amd/utils/paste/createPasteFragment.js.map +1 -0
- package/lib-amd/utils/paste/generatePasteOptionFromPlugins.d.ts +6 -0
- package/lib-amd/utils/paste/generatePasteOptionFromPlugins.js +58 -0
- package/lib-amd/utils/paste/generatePasteOptionFromPlugins.js.map +1 -0
- package/lib-amd/utils/paste/mergePasteContent.d.ts +5 -0
- package/lib-amd/utils/paste/mergePasteContent.js +64 -0
- package/lib-amd/utils/paste/mergePasteContent.js.map +1 -0
- package/lib-amd/utils/paste/retrieveHtmlInfo.d.ts +21 -0
- package/lib-amd/utils/paste/retrieveHtmlInfo.js +87 -0
- package/lib-amd/utils/paste/retrieveHtmlInfo.js.map +1 -0
- package/lib-amd/utils/sanitizeElement.d.ts +17 -0
- package/lib-amd/utils/sanitizeElement.js +353 -0
- package/lib-amd/utils/sanitizeElement.js.map +1 -0
- package/lib-mjs/coreApi/createContentModel.js +2 -2
- package/lib-mjs/coreApi/createContentModel.js.map +1 -1
- package/lib-mjs/coreApi/paste.d.ts +9 -0
- package/lib-mjs/coreApi/paste.js +53 -0
- package/lib-mjs/coreApi/paste.js.map +1 -0
- package/lib-mjs/coreApi/setContentModel.js +2 -2
- package/lib-mjs/coreApi/setContentModel.js.map +1 -1
- package/lib-mjs/coreApi/setDOMSelection.js +10 -7
- package/lib-mjs/coreApi/setDOMSelection.js.map +1 -1
- package/lib-mjs/corePlugin/ContentModelCachePlugin.js.map +1 -1
- package/lib-mjs/corePlugin/ContentModelCopyPastePlugin.d.ts +6 -1
- package/lib-mjs/corePlugin/ContentModelCopyPastePlugin.js +38 -8
- package/lib-mjs/corePlugin/ContentModelCopyPastePlugin.js.map +1 -1
- package/lib-mjs/corePlugin/ContentModelFormatPlugin.js.map +1 -1
- package/lib-mjs/corePlugin/DOMEventPlugin.js +9 -38
- package/lib-mjs/corePlugin/DOMEventPlugin.js.map +1 -1
- package/lib-mjs/corePlugin/EntityPlugin.js +1 -1
- package/lib-mjs/corePlugin/EntityPlugin.js.map +1 -1
- package/lib-mjs/corePlugin/LifecyclePlugin.js.map +1 -1
- package/lib-mjs/corePlugin/SelectionPlugin.js +9 -8
- package/lib-mjs/corePlugin/SelectionPlugin.js.map +1 -1
- package/lib-mjs/corePlugin/UndoPlugin.js.map +1 -1
- package/lib-mjs/corePlugin/utils/applyDefaultFormat.d.ts +1 -2
- package/lib-mjs/corePlugin/utils/applyDefaultFormat.js +1 -1
- package/lib-mjs/corePlugin/utils/applyDefaultFormat.js.map +1 -1
- package/lib-mjs/editor/DarkColorHandlerImpl.d.ts +9 -0
- package/lib-mjs/editor/DarkColorHandlerImpl.js +41 -7
- package/lib-mjs/editor/DarkColorHandlerImpl.js.map +1 -1
- package/lib-mjs/editor/StandaloneEditor.d.ts +164 -0
- package/lib-mjs/editor/StandaloneEditor.js +278 -0
- package/lib-mjs/editor/StandaloneEditor.js.map +1 -0
- package/lib-mjs/editor/createStandaloneEditorCore.d.ts +8 -3
- package/lib-mjs/editor/createStandaloneEditorCore.js +19 -13
- package/lib-mjs/editor/createStandaloneEditorCore.js.map +1 -1
- package/lib-mjs/editor/createStandaloneEditorDefaultSettings.d.ts +9 -3
- package/lib-mjs/editor/createStandaloneEditorDefaultSettings.js +30 -21
- package/lib-mjs/editor/createStandaloneEditorDefaultSettings.js.map +1 -1
- package/lib-mjs/editor/standaloneCoreApiMap.d.ts +2 -2
- package/lib-mjs/editor/standaloneCoreApiMap.js +2 -0
- package/lib-mjs/editor/standaloneCoreApiMap.js.map +1 -1
- package/lib-mjs/index.d.ts +1 -2
- package/lib-mjs/index.js +1 -2
- package/lib-mjs/index.js.map +1 -1
- package/lib-mjs/override/containerWidthFormatParser.d.ts +5 -0
- package/lib-mjs/override/containerWidthFormatParser.js +10 -0
- package/lib-mjs/override/containerWidthFormatParser.js.map +1 -0
- package/lib-mjs/override/pasteDisplayFormatParser.d.ts +5 -0
- package/lib-mjs/override/pasteDisplayFormatParser.js +10 -0
- package/lib-mjs/override/pasteDisplayFormatParser.js.map +1 -0
- package/lib-mjs/override/pasteEntityProcessor.d.ts +5 -0
- package/lib-mjs/override/pasteEntityProcessor.js +20 -0
- package/lib-mjs/override/pasteEntityProcessor.js.map +1 -0
- package/lib-mjs/override/pasteGeneralProcessor.d.ts +9 -0
- package/lib-mjs/override/pasteGeneralProcessor.js +36 -0
- package/lib-mjs/override/pasteGeneralProcessor.js.map +1 -0
- package/lib-mjs/override/pasteTextProcessor.d.ts +5 -0
- package/lib-mjs/override/pasteTextProcessor.js +13 -0
- package/lib-mjs/override/pasteTextProcessor.js.map +1 -0
- package/lib-mjs/publicApi/selection/deleteSegment.js +1 -1
- package/lib-mjs/publicApi/selection/deleteSegment.js.map +1 -1
- package/lib-mjs/utils/paste/convertInlineCss.d.ts +5 -0
- package/lib-mjs/utils/paste/convertInlineCss.js +37 -0
- package/lib-mjs/utils/paste/convertInlineCss.js.map +1 -0
- package/lib-mjs/utils/paste/createPasteFragment.d.ts +5 -0
- package/lib-mjs/utils/paste/createPasteFragment.js +72 -0
- package/lib-mjs/utils/paste/createPasteFragment.js.map +1 -0
- package/lib-mjs/utils/paste/generatePasteOptionFromPlugins.d.ts +6 -0
- package/lib-mjs/utils/paste/generatePasteOptionFromPlugins.js +52 -0
- package/lib-mjs/utils/paste/generatePasteOptionFromPlugins.js.map +1 -0
- package/lib-mjs/utils/paste/mergePasteContent.d.ts +5 -0
- package/lib-mjs/utils/paste/mergePasteContent.js +68 -0
- package/lib-mjs/utils/paste/mergePasteContent.js.map +1 -0
- package/lib-mjs/utils/paste/retrieveHtmlInfo.d.ts +21 -0
- package/lib-mjs/utils/paste/retrieveHtmlInfo.js +83 -0
- package/lib-mjs/utils/paste/retrieveHtmlInfo.js.map +1 -0
- package/lib-mjs/utils/sanitizeElement.d.ts +17 -0
- package/lib-mjs/utils/sanitizeElement.js +347 -0
- package/lib-mjs/utils/sanitizeElement.js.map +1 -0
- package/package.json +3 -4
- package/lib/publicApi/model/paste.d.ts +0 -14
- package/lib/publicApi/model/paste.js +0 -152
- package/lib/publicApi/model/paste.js.map +0 -1
- package/lib-amd/publicApi/model/paste.d.ts +0 -14
- package/lib-amd/publicApi/model/paste.js +0 -148
- package/lib-amd/publicApi/model/paste.js.map +0 -1
- package/lib-mjs/publicApi/model/paste.d.ts +0 -14
- package/lib-mjs/publicApi/model/paste.js +0 -147
- package/lib-mjs/publicApi/model/paste.js.map +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createContentModel = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
4
|
var cloneModel_1 = require("../publicApi/model/cloneModel");
|
|
6
5
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
7
6
|
/**
|
|
@@ -34,7 +33,8 @@ exports.createContentModel = createContentModel;
|
|
|
34
33
|
function internalCreateContentModel(core, selection, option) {
|
|
35
34
|
var editorContext = core.api.createEditorContext(core);
|
|
36
35
|
var domToModelContext = option
|
|
37
|
-
?
|
|
36
|
+
? (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, core.domToModelSettings.builtIn, core.domToModelSettings.customized, option)
|
|
37
|
+
: (0, roosterjs_content_model_dom_1.createDomToModelContextWithConfig)(core.domToModelSettings.calculated, editorContext);
|
|
38
38
|
return (0, roosterjs_content_model_dom_1.domToContentModel)(core.contentDiv, domToModelContext, selection);
|
|
39
39
|
}
|
|
40
40
|
//# sourceMappingURL=createContentModel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createContentModel.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/createContentModel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createContentModel.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/createContentModel.ts"],"names":[],"mappings":";;;AAAA,4DAA2D;AAC3D,2EAIqC;AAQrC;;;;;;GAMG;AACI,IAAM,kBAAkB,GAAuB,UAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB;IAClF,IAAI,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;IAEpE,IAAI,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QAClD,6EAA6E;QAC7E,WAAW,GAAG,IAAA,uBAAU,EAAC,WAAW,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC;KACzE;IAED,IAAI,WAAW,EAAE;QACb,OAAO,WAAW,CAAC;KACtB;SAAM;QACH,IAAM,SAAS,GAAG,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QACnF,IAAM,KAAK,GAAG,0BAA0B,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAElE,IAAI,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE;YAC/B,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC;SAC1C;QAED,OAAO,KAAK,CAAC;KAChB;AACL,CAAC,CAAC;AArBW,QAAA,kBAAkB,sBAqB7B;AAEF,SAAS,0BAA0B,CAC/B,IAA0B,EAC1B,SAAwB,EACxB,MAAyB;IAEzB,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACzD,IAAM,iBAAiB,GAAG,MAAM;QAC5B,CAAC,CAAC,IAAA,qDAAuB,EACnB,aAAa,EACb,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAC/B,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAClC,MAAM,CACT;QACH,CAAC,CAAC,IAAA,+DAAiC,EAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAE3F,OAAO,IAAA,+CAAiB,EAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC","sourcesContent":["import { cloneModel } from '../publicApi/model/cloneModel';\nimport {\n createDomToModelContext,\n createDomToModelContextWithConfig,\n domToContentModel,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n DomToModelOption,\n CreateContentModel,\n StandaloneEditorCore,\n} 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 let cachedModel = selectionOverride ? null : core.cache.cachedModel;\n\n if (cachedModel && core.lifecycle.shadowEditFragment) {\n // When in shadow edit, use a cloned model so we won't pollute the cached one\n cachedModel = cloneModel(cachedModel, { includeCachedElement: true });\n }\n\n if (cachedModel) {\n return cachedModel;\n } else {\n const selection = selectionOverride || core.api.getDOMSelection(core) || undefined;\n const model = internalCreateContentModel(core, selection, option);\n\n if (!option && !selectionOverride) {\n core.cache.cachedModel = model;\n core.cache.cachedSelection = selection;\n }\n\n return model;\n }\n};\n\nfunction internalCreateContentModel(\n core: StandaloneEditorCore,\n selection?: DOMSelection,\n option?: DomToModelOption\n) {\n const editorContext = core.api.createEditorContext(core);\n const domToModelContext = option\n ? createDomToModelContext(\n editorContext,\n core.domToModelSettings.builtIn,\n core.domToModelSettings.customized,\n option\n )\n : createDomToModelContextWithConfig(core.domToModelSettings.calculated, editorContext);\n\n return domToContentModel(core.contentDiv, domToModelContext, selection);\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Paste } from 'roosterjs-content-model-types';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Paste into editor using a clipboardData object
|
|
5
|
+
* @param core The StandaloneEditorCore object.
|
|
6
|
+
* @param clipboardData Clipboard data retrieved from clipboard
|
|
7
|
+
* @param pasteType Type of content to paste. @default normal
|
|
8
|
+
*/
|
|
9
|
+
export declare const paste: Paste;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.paste = void 0;
|
|
4
|
+
var ChangeSource_1 = require("../constants/ChangeSource");
|
|
5
|
+
var cloneModel_1 = require("../publicApi/model/cloneModel");
|
|
6
|
+
var convertInlineCss_1 = require("../utils/paste/convertInlineCss");
|
|
7
|
+
var createPasteFragment_1 = require("../utils/paste/createPasteFragment");
|
|
8
|
+
var generatePasteOptionFromPlugins_1 = require("../utils/paste/generatePasteOptionFromPlugins");
|
|
9
|
+
var mergePasteContent_1 = require("../utils/paste/mergePasteContent");
|
|
10
|
+
var retrieveHtmlInfo_1 = require("../utils/paste/retrieveHtmlInfo");
|
|
11
|
+
var CloneOption = {
|
|
12
|
+
includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* @internal
|
|
16
|
+
* Paste into editor using a clipboardData object
|
|
17
|
+
* @param core The StandaloneEditorCore object.
|
|
18
|
+
* @param clipboardData Clipboard data retrieved from clipboard
|
|
19
|
+
* @param pasteType Type of content to paste. @default normal
|
|
20
|
+
*/
|
|
21
|
+
var paste = function (core, clipboardData, pasteType) {
|
|
22
|
+
if (pasteType === void 0) { pasteType = 'normal'; }
|
|
23
|
+
core.api.focus(core);
|
|
24
|
+
if (clipboardData.modelBeforePaste) {
|
|
25
|
+
core.api.setContentModel(core, (0, cloneModel_1.cloneModel)(clipboardData.modelBeforePaste, CloneOption));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
clipboardData.modelBeforePaste = (0, cloneModel_1.cloneModel)(core.api.createContentModel(core), CloneOption);
|
|
29
|
+
}
|
|
30
|
+
core.api.formatContentModel(core, function (model, context) {
|
|
31
|
+
var _a;
|
|
32
|
+
// 1. Prepare variables
|
|
33
|
+
var doc = createDOMFromHtml(clipboardData.rawHtml, core.trustedHTMLHandler);
|
|
34
|
+
// 2. Handle HTML from clipboard
|
|
35
|
+
var htmlFromClipboard = (0, retrieveHtmlInfo_1.retrieveHtmlInfo)(doc, clipboardData);
|
|
36
|
+
// 3. Create target fragment
|
|
37
|
+
var sourceFragment = (0, createPasteFragment_1.createPasteFragment)(core.contentDiv.ownerDocument, clipboardData, pasteType, (_a = (clipboardData.rawHtml == clipboardData.html
|
|
38
|
+
? doc
|
|
39
|
+
: createDOMFromHtml(clipboardData.html, core.trustedHTMLHandler))) === null || _a === void 0 ? void 0 : _a.body);
|
|
40
|
+
// 4. Trigger BeforePaste event to allow plugins modify the fragment
|
|
41
|
+
var eventResult = (0, generatePasteOptionFromPlugins_1.generatePasteOptionFromPlugins)(core, clipboardData, sourceFragment, htmlFromClipboard, pasteType);
|
|
42
|
+
// 5. Convert global CSS to inline CSS
|
|
43
|
+
(0, convertInlineCss_1.convertInlineCss)(eventResult.fragment, htmlFromClipboard.globalCssRules);
|
|
44
|
+
// 6. Merge pasted content into main Content Model
|
|
45
|
+
(0, mergePasteContent_1.mergePasteContent)(model, context, eventResult, core.domToModelSettings.customized);
|
|
46
|
+
return true;
|
|
47
|
+
}, {
|
|
48
|
+
changeSource: ChangeSource_1.ChangeSource.Paste,
|
|
49
|
+
getChangeData: function () { return clipboardData; },
|
|
50
|
+
apiName: 'paste',
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
exports.paste = paste;
|
|
54
|
+
function createDOMFromHtml(html, trustedHTMLHandler) {
|
|
55
|
+
return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=paste.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/paste.ts"],"names":[],"mappings":";;;AAAA,0DAAyD;AACzD,4DAA2D;AAC3D,oEAAmE;AACnE,0EAAyE;AACzE,gGAA+F;AAC/F,sEAAqE;AACrE,oEAAmE;AAUnE,IAAM,WAAW,GAAsB;IACnC,oBAAoB,EAAE,UAAC,IAAI,EAAE,IAAI,IAAK,OAAA,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAApC,CAAoC;CAC7E,CAAC;AAEF;;;;;;GAMG;AACI,IAAM,KAAK,GAAU,UACxB,IAA0B,EAC1B,aAA4B,EAC5B,SAA+B;IAA/B,0BAAA,EAAA,oBAA+B;IAE/B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAErB,IAAI,aAAa,CAAC,gBAAgB,EAAE;QAChC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,IAAA,uBAAU,EAAC,aAAa,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC;KAC3F;SAAM;QACH,aAAa,CAAC,gBAAgB,GAAG,IAAA,uBAAU,EAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;KAC/F;IAED,IAAI,CAAC,GAAG,CAAC,kBAAkB,CACvB,IAAI,EACJ,UAAC,KAAK,EAAE,OAAO;;QACX,uBAAuB;QACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAE9E,gCAAgC;QAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAE/D,4BAA4B;QAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,IAAI,CAAC,UAAU,CAAC,aAAa,EAC7B,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;YACxC,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAAC,CACnE,0CAAE,IAAI,CACV,CAAC;QAEF,oEAAoE;QACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,IAAI,EACJ,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;QAEF,sCAAsC;QACtC,IAAA,mCAAgB,EAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAEzE,kDAAkD;QAClD,IAAA,qCAAiB,EAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAEnF,OAAO,IAAI,CAAC;IAChB,CAAC,EACD;QACI,YAAY,EAAE,2BAAY,CAAC,KAAK;QAChC,aAAa,EAAE,cAAM,OAAA,aAAa,EAAb,CAAa;QAClC,OAAO,EAAE,OAAO;KACnB,CACJ,CAAC;AACN,CAAC,CAAC;AAxDW,QAAA,KAAK,SAwDhB;AAEF,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;IAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChG,CAAC","sourcesContent":["import { ChangeSource } from '../constants/ChangeSource';\nimport { cloneModel } from '../publicApi/model/cloneModel';\nimport { convertInlineCss } from '../utils/paste/convertInlineCss';\nimport { createPasteFragment } from '../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../utils/paste/generatePasteOptionFromPlugins';\nimport { mergePasteContent } from '../utils/paste/mergePasteContent';\nimport { retrieveHtmlInfo } from '../utils/paste/retrieveHtmlInfo';\nimport type { CloneModelOptions } from '../publicApi/model/cloneModel';\nimport type {\n PasteType,\n ClipboardData,\n Paste,\n StandaloneEditorCore,\n} from 'roosterjs-content-model-types';\nimport type { TrustedHTMLHandler } from 'roosterjs-editor-types';\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n * Paste into editor using a clipboardData object\n * @param core The StandaloneEditorCore object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport const paste: Paste = (\n core: StandaloneEditorCore,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) => {\n core.api.focus(core);\n\n if (clipboardData.modelBeforePaste) {\n core.api.setContentModel(core, cloneModel(clipboardData.modelBeforePaste, CloneOption));\n } else {\n clipboardData.modelBeforePaste = cloneModel(core.api.createContentModel(core), CloneOption);\n }\n\n core.api.formatContentModel(\n core,\n (model, context) => {\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, core.trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n core.contentDiv.ownerDocument,\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, core.trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n core,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(model, context, eventResult, core.domToModelSettings.customized);\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n};\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setContentModel = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
4
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
6
5
|
/**
|
|
7
6
|
* @internal
|
|
@@ -13,7 +12,8 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
|
13
12
|
var setContentModel = function (core, model, option, onNodeCreated) {
|
|
14
13
|
var editorContext = core.api.createEditorContext(core);
|
|
15
14
|
var modelToDomContext = option
|
|
16
|
-
?
|
|
15
|
+
? (0, roosterjs_content_model_dom_1.createModelToDomContext)(editorContext, core.modelToDomSettings.builtIn, core.modelToDomSettings.customized, option)
|
|
16
|
+
: (0, roosterjs_content_model_dom_1.createModelToDomContextWithConfig)(core.modelToDomSettings.calculated, editorContext);
|
|
17
17
|
var selection = (0, roosterjs_content_model_dom_1.contentModelToDom)(core.contentDiv.ownerDocument, core.contentDiv, model, modelToDomContext, onNodeCreated);
|
|
18
18
|
if (!core.lifecycle.shadowEditFragment) {
|
|
19
19
|
core.cache.cachedSelection = selection || undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setContentModel.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/setContentModel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setContentModel.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/setContentModel.ts"],"names":[],"mappings":";;;AAAA,2EAIqC;AAGrC;;;;;;GAMG;AACI,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa;IAC/E,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACzD,IAAM,iBAAiB,GAAG,MAAM;QAC5B,CAAC,CAAC,IAAA,qDAAuB,EACnB,aAAa,EACb,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAC/B,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAClC,MAAM,CACT;QACH,CAAC,CAAC,IAAA,+DAAiC,EAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAE3F,IAAM,SAAS,GAAG,IAAA,+CAAiB,EAC/B,IAAI,CAAC,UAAU,CAAC,aAAa,EAC7B,IAAI,CAAC,UAAU,EACf,KAAK,EACL,iBAAiB,EACjB,aAAa,CAChB,CAAC;IAEF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QACpC,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,IAAI,SAAS,CAAC;QAEpD,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,eAAe,CAAA,IAAI,SAAS,EAAE;YACvC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;SAC7C;aAAM,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;YACjD,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC;SACxC;QAED,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;KAClC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC,CAAC;AAhCW,QAAA,eAAe,mBAgC1B","sourcesContent":["import {\n contentModelToDom,\n createModelToDomContext,\n createModelToDomContextWithConfig,\n} from 'roosterjs-content-model-dom';\nimport type { SetContentModel } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Set content with content model\n * @param core The editor core object\n * @param model The content model to set\n * @param option Additional options to customize the behavior of Content Model to DOM conversion\n */\nexport const setContentModel: SetContentModel = (core, model, option, onNodeCreated) => {\n const editorContext = core.api.createEditorContext(core);\n const modelToDomContext = option\n ? createModelToDomContext(\n editorContext,\n core.modelToDomSettings.builtIn,\n core.modelToDomSettings.customized,\n option\n )\n : createModelToDomContextWithConfig(core.modelToDomSettings.calculated, editorContext);\n\n const selection = contentModelToDom(\n core.contentDiv.ownerDocument,\n core.contentDiv,\n model,\n modelToDomContext,\n onNodeCreated\n );\n\n if (!core.lifecycle.shadowEditFragment) {\n core.cache.cachedSelection = selection || undefined;\n\n if (!option?.ignoreSelection && selection) {\n core.api.setDOMSelection(core, selection);\n } else if (!selection || selection.type !== 'range') {\n core.selection.selection = selection;\n }\n\n core.cache.cachedModel = model;\n }\n\n return selection;\n};\n"]}
|
|
@@ -8,7 +8,8 @@ var IMAGE_ID = 'image';
|
|
|
8
8
|
var TABLE_ID = 'table';
|
|
9
9
|
var CONTENT_DIV_ID = 'contentDiv';
|
|
10
10
|
var DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';
|
|
11
|
-
var TABLE_CSS_RULE = '{background-color: rgb(198,198,198) !important;
|
|
11
|
+
var TABLE_CSS_RULE = '{background-color: rgb(198,198,198) !important;}';
|
|
12
|
+
var CARET_CSS_RULE = '{caret-color: transparent}';
|
|
12
13
|
var MAX_RULE_SELECTOR_LENGTH = 9000;
|
|
13
14
|
/**
|
|
14
15
|
* @internal
|
|
@@ -27,13 +28,13 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
27
28
|
switch (selection === null || selection === void 0 ? void 0 : selection.type) {
|
|
28
29
|
case 'image':
|
|
29
30
|
var image = selection.image;
|
|
30
|
-
selectionRules = buildImageCSS(rootSelector
|
|
31
|
+
selectionRules = buildImageCSS(rootSelector, addUniqueId(image, IMAGE_ID), core.selection.imageSelectionBorderColor);
|
|
31
32
|
core.selection.selection = selection;
|
|
32
33
|
setRangeSelection(doc, image);
|
|
33
34
|
break;
|
|
34
35
|
case 'table':
|
|
35
36
|
var table = selection.table, firstColumn = selection.firstColumn, firstRow = selection.firstRow;
|
|
36
|
-
selectionRules = buildTableCss(rootSelector
|
|
37
|
+
selectionRules = buildTableCss(rootSelector, addUniqueId(table, TABLE_ID), selection);
|
|
37
38
|
core.selection.selection = selection;
|
|
38
39
|
setRangeSelection(doc, (_b = table.rows[firstRow]) === null || _b === void 0 ? void 0 : _b.cells[firstColumn]);
|
|
39
40
|
break;
|
|
@@ -69,13 +70,14 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
69
70
|
}
|
|
70
71
|
};
|
|
71
72
|
exports.setDOMSelection = setDOMSelection;
|
|
72
|
-
function buildImageCSS(
|
|
73
|
+
function buildImageCSS(editorSelector, imageId, borderColor) {
|
|
73
74
|
var color = borderColor || DEFAULT_SELECTION_BORDER_COLOR;
|
|
74
75
|
return [
|
|
75
|
-
|
|
76
|
+
editorSelector + " #" + imageId + " {outline-style:auto!important;outline-color:" + color + "!important;}",
|
|
77
|
+
editorSelector + " " + CARET_CSS_RULE,
|
|
76
78
|
];
|
|
77
79
|
}
|
|
78
|
-
function buildTableCss(
|
|
80
|
+
function buildTableCss(editorSelector, tableId, selection) {
|
|
79
81
|
var _a, _b, _c;
|
|
80
82
|
var firstColumn = selection.firstColumn, firstRow = selection.firstRow, lastColumn = selection.lastColumn, lastRow = selection.lastRow;
|
|
81
83
|
var cells = (0, tableCellUtils_1.parseTableCells)(selection.table);
|
|
@@ -83,10 +85,11 @@ function buildTableCss(rootSelector, selection) {
|
|
|
83
85
|
firstColumn == 0 &&
|
|
84
86
|
lastRow == cells.length - 1 &&
|
|
85
87
|
lastColumn == ((_b = (_a = cells[lastRow]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1;
|
|
88
|
+
var rootSelector = editorSelector + ' #' + tableId;
|
|
86
89
|
var selectors = isAllTableSelected
|
|
87
90
|
? [rootSelector, rootSelector + " *"]
|
|
88
91
|
: handleTableSelected(rootSelector, selection, cells);
|
|
89
|
-
var cssRules = [];
|
|
92
|
+
var cssRules = [editorSelector + " " + CARET_CSS_RULE];
|
|
90
93
|
var currentRules = '';
|
|
91
94
|
for (var i = 0; i < selectors.length; i++) {
|
|
92
95
|
currentRules += (currentRules.length > 0 ? ',' : '') + selectors[i] || '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from '../corePlugin/utils/addRangeToSelection';\nimport { isNodeOfType, toArray } from 'roosterjs-content-model-dom';\nimport { parseTableCells } from '../publicApi/domUtils/tableCellUtils';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport type {\n ContentModelSelectionChangedEvent,\n SetDOMSelection,\n TableSelection,\n} from 'roosterjs-content-model-types';\n\nconst IMAGE_ID = 'image';\nconst TABLE_ID = 'table';\nconst CONTENT_DIV_ID = 'contentDiv';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\nconst TABLE_CSS_RULE = '{background-color: rgb(198,198,198) !important; caret-color: transparent}';\nconst MAX_RULE_SELECTOR_LENGTH = 9000;\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\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.contentDiv.ownerDocument;\n const sheet = core.selection.selectionStyleNode?.sheet;\n\n core.selection.skipReselectOnFocus = true;\n\n try {\n let selectionRules: string[] | undefined;\n const rootSelector = '#' + addUniqueId(core.contentDiv, CONTENT_DIV_ID);\n\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n selectionRules = buildImageCSS(\n rootSelector + ' #' + addUniqueId(image, IMAGE_ID),\n core.selection.imageSelectionBorderColor\n );\n core.selection.selection = selection;\n\n setRangeSelection(doc, image);\n break;\n case 'table':\n const { table, firstColumn, firstRow } = selection;\n\n selectionRules = buildTableCss(\n rootSelector + ' #' + addUniqueId(table, TABLE_ID),\n selection\n );\n core.selection.selection = selection;\n\n setRangeSelection(doc, table.rows[firstRow]?.cells[firstColumn]);\n break;\n case 'range':\n addRangeToSelection(doc, selection.range);\n\n core.selection.selection = core.api.hasFocus(core) ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n sheet.deleteRule(i);\n }\n\n if (selectionRules) {\n for (let i = 0; i < selectionRules.length; i++) {\n sheet.insertRule(selectionRules[i]);\n }\n }\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: ContentModelSelectionChangedEvent = {\n eventType: PluginEventType.SelectionChanged,\n newSelection: selection,\n selectionRangeEx: null,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction buildImageCSS(rootSelector: string, borderColor?: string): string[] {\n const color = borderColor || DEFAULT_SELECTION_BORDER_COLOR;\n\n return [\n `${rootSelector} {outline-style:auto!important;outline-color:${color}!important;caret-color:transparent;}`,\n ];\n}\n\nfunction buildTableCss(rootSelector: string, selection: TableSelection): string[] {\n const { firstColumn, firstRow, lastColumn, lastRow } = selection;\n const cells = parseTableCells(selection.table);\n const isAllTableSelected =\n firstRow == 0 &&\n firstColumn == 0 &&\n lastRow == cells.length - 1 &&\n lastColumn == (cells[lastRow]?.length ?? 0) - 1;\n const selectors = isAllTableSelected\n ? [rootSelector, `${rootSelector} *`]\n : handleTableSelected(rootSelector, selection, cells);\n\n const cssRules: string[] = [];\n let currentRules: string = '';\n\n for (let i = 0; i < selectors.length; i++) {\n currentRules += (currentRules.length > 0 ? ',' : '') + selectors[i] || '';\n\n if (\n currentRules.length + (selectors[0]?.length || 0) > MAX_RULE_SELECTOR_LENGTH ||\n i == selectors.length - 1\n ) {\n cssRules.push(currentRules + ' ' + TABLE_CSS_RULE);\n currentRules = '';\n }\n }\n\n return cssRules;\n}\n\nfunction handleTableSelected(\n rootSelector: string,\n selection: TableSelection,\n cells: (HTMLTableCellElement | null)[][]\n) {\n const { firstRow, firstColumn, lastRow, lastColumn, table } = selection;\n const selectors: string[] = [];\n\n // Get whether table has thead, tbody or tfoot, then Set the start and end of each of the table children,\n // so we can build the selector according the element between the table and the row.\n let cont = 0;\n const indexes = toArray(table.childNodes)\n .filter(\n (node): node is HTMLTableSectionElement =>\n ['THEAD', 'TBODY', 'TFOOT'].indexOf(\n isNodeOfType(node, 'ELEMENT_NODE') ? node.tagName : ''\n ) > -1\n )\n .map(node => {\n const result = {\n el: node.tagName,\n start: cont,\n end: node.childNodes.length + cont,\n };\n\n cont = result.end;\n return result;\n });\n\n cells.forEach((row, rowIndex) => {\n let tdCount = 0;\n\n //Get current TBODY/THEAD/TFOOT\n const midElement = indexes.filter(ind => ind.start <= rowIndex && ind.end > rowIndex)[0];\n const middleElSelector = midElement ? '>' + midElement.el + '>' : '>';\n const currentRow =\n midElement && rowIndex + 1 >= midElement.start\n ? rowIndex + 1 - midElement.start\n : rowIndex + 1;\n\n for (let cellIndex = 0; cellIndex < row.length; cellIndex++) {\n const cell = row[cellIndex];\n\n if (cell) {\n tdCount++;\n\n if (\n rowIndex >= firstRow &&\n rowIndex <= lastRow &&\n cellIndex >= firstColumn &&\n cellIndex <= lastColumn\n ) {\n const selector = `${rootSelector}${middleElSelector} tr:nth-child(${currentRow})>${cell.tagName}:nth-child(${tdCount})`;\n\n selectors.push(selector, selector + ' *');\n }\n }\n }\n });\n\n return selectors;\n}\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined) {\n if (element) {\n const range = doc.createRange();\n\n range.selectNode(element);\n range.collapse();\n\n addRangeToSelection(doc, range);\n }\n}\n\nfunction addUniqueId(element: HTMLElement, idPrefix: string): string {\n idPrefix = element.id || idPrefix;\n\n const doc = element.ownerDocument;\n let i = 0;\n\n while (!element.id || doc.querySelectorAll('#' + element.id).length > 1) {\n element.id = idPrefix + '_' + i++;\n }\n\n return element.id;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/coreApi/setDOMSelection.ts"],"names":[],"mappings":";;;AAAA,+EAA8E;AAC9E,2EAAoE;AACpE,uEAAuE;AAQvE,IAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,IAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,IAAM,cAAc,GAAG,YAAY,CAAC;AACpC,IAAM,8BAA8B,GAAG,SAAS,CAAC;AACjD,IAAM,cAAc,GAAG,kDAAkD,CAAC;AAC1E,IAAM,cAAc,GAAG,4BAA4B,CAAC;AACpD,IAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC;;GAEG;AACI,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,SAAS,EAAE,yBAAyB;;IACvF,iGAAiG;IACjG,gDAAgD;IAChD,IAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC;IAE/D,IAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;IAC1C,IAAM,KAAK,GAAG,MAAA,IAAI,CAAC,SAAS,CAAC,kBAAkB,0CAAE,KAAK,CAAC;IAEvD,IAAI,CAAC,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAE1C,IAAI;QACA,IAAI,cAAc,SAAsB,CAAC;QACzC,IAAM,YAAY,GAAG,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAExE,QAAQ,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,EAAE;YACrB,KAAK,OAAO;gBACR,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;gBAE9B,cAAc,GAAG,aAAa,CAC1B,YAAY,EACZ,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,EAC5B,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAC3C,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC;gBAErC,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC9B,MAAM;YACV,KAAK,OAAO;gBACA,IAAA,KAAK,GAA4B,SAAS,MAArC,EAAE,WAAW,GAAe,SAAS,YAAxB,EAAE,QAAQ,GAAK,SAAS,SAAd,CAAe;gBAEnD,cAAc,GAAG,aAAa,CAC1B,YAAY,EACZ,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,EAC5B,SAAS,CACZ,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC;gBAErC,iBAAiB,CAAC,GAAG,EAAE,MAAA,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,0CAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;gBACjE,MAAM;YACV,KAAK,OAAO;gBACR,IAAA,yCAAmB,EAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;gBAE1C,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;gBACtE,MAAM;YAEV;gBACI,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;gBAChC,MAAM;SACb;QAED,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,cAAc,EAAE;gBAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC5C,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;iBACvC;aACJ;SACJ;KACJ;YAAS;QACN,IAAI,CAAC,SAAS,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;KAC5D;IAED,IAAI,CAAC,yBAAyB,EAAE;QAC5B,IAAM,SAAS,GAAsC;YACjD,SAAS,2BAAkC;YAC3C,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE,IAAI;SACzB,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;KAC9D;AACL,CAAC,CAAC;AA1EW,QAAA,eAAe,mBA0E1B;AAEF,SAAS,aAAa,CAAC,cAAsB,EAAE,OAAe,EAAE,WAAoB;IAChF,IAAM,KAAK,GAAG,WAAW,IAAI,8BAA8B,CAAC;IAE5D,OAAO;QACA,cAAc,UAAK,OAAO,qDAAgD,KAAK,iBAAc;QAC7F,cAAc,SAAI,cAAgB;KACxC,CAAC;AACN,CAAC;AAED,SAAS,aAAa,CAClB,cAAsB,EACtB,OAAe,EACf,SAAyB;;IAEjB,IAAA,WAAW,GAAoC,SAAS,YAA7C,EAAE,QAAQ,GAA0B,SAAS,SAAnC,EAAE,UAAU,GAAc,SAAS,WAAvB,EAAE,OAAO,GAAK,SAAS,QAAd,CAAe;IACjE,IAAM,KAAK,GAAG,IAAA,gCAAe,EAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAM,kBAAkB,GACpB,QAAQ,IAAI,CAAC;QACb,WAAW,IAAI,CAAC;QAChB,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAC3B,UAAU,IAAI,CAAC,MAAA,MAAA,KAAK,CAAC,OAAO,CAAC,0CAAE,MAAM,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpD,IAAM,YAAY,GAAG,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC;IACrD,IAAM,SAAS,GAAG,kBAAkB;QAChC,CAAC,CAAC,CAAC,YAAY,EAAK,YAAY,OAAI,CAAC;QACrC,CAAC,CAAC,mBAAmB,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAE1D,IAAM,QAAQ,GAAa,CAAI,cAAc,SAAI,cAAgB,CAAC,CAAC;IACnE,IAAI,YAAY,GAAW,EAAE,CAAC;IAE9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,YAAY,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1E,IACI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAA,MAAA,SAAS,CAAC,CAAC,CAAC,0CAAE,MAAM,KAAI,CAAC,CAAC,GAAG,wBAAwB;YAC5E,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAC3B;YACE,QAAQ,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,GAAG,cAAc,CAAC,CAAC;YACnD,YAAY,GAAG,EAAE,CAAC;SACrB;KACJ;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,mBAAmB,CACxB,YAAoB,EACpB,SAAyB,EACzB,KAAwC;IAEhC,IAAA,QAAQ,GAA8C,SAAS,SAAvD,EAAE,WAAW,GAAiC,SAAS,YAA1C,EAAE,OAAO,GAAwB,SAAS,QAAjC,EAAE,UAAU,GAAY,SAAS,WAArB,EAAE,KAAK,GAAK,SAAS,MAAd,CAAe;IACxE,IAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,yGAAyG;IACzG,oFAAoF;IACpF,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAM,OAAO,GAAG,IAAA,qCAAO,EAAC,KAAK,CAAC,UAAU,CAAC;SACpC,MAAM,CACH,UAAC,IAAI;QACD,OAAA,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,CAC/B,IAAA,0CAAY,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CACzD,GAAG,CAAC,CAAC;IAFN,CAEM,CACb;SACA,GAAG,CAAC,UAAA,IAAI;QACL,IAAM,MAAM,GAAG;YACX,EAAE,EAAE,IAAI,CAAC,OAAO;YAChB,KAAK,EAAE,IAAI;YACX,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI;SACrC,CAAC;QAEF,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;QAClB,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC,CAAC;IAEP,KAAK,CAAC,OAAO,CAAC,UAAC,GAAG,EAAE,QAAQ;QACxB,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,+BAA+B;QAC/B,IAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,KAAK,IAAI,QAAQ,IAAI,GAAG,CAAC,GAAG,GAAG,QAAQ,EAA3C,CAA2C,CAAC,CAAC,CAAC,CAAC,CAAC;QACzF,IAAM,gBAAgB,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACtE,IAAM,UAAU,GACZ,UAAU,IAAI,QAAQ,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK;YAC1C,CAAC,CAAC,QAAQ,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK;YACjC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;QAEvB,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;YACzD,IAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;YAE5B,IAAI,IAAI,EAAE;gBACN,OAAO,EAAE,CAAC;gBAEV,IACI,QAAQ,IAAI,QAAQ;oBACpB,QAAQ,IAAI,OAAO;oBACnB,SAAS,IAAI,WAAW;oBACxB,SAAS,IAAI,UAAU,EACzB;oBACE,IAAM,QAAQ,GAAG,KAAG,YAAY,GAAG,gBAAgB,sBAAiB,UAAU,UAAK,IAAI,CAAC,OAAO,mBAAc,OAAO,MAAG,CAAC;oBAExH,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC;iBAC7C;aACJ;SACJ;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAa,EAAE,OAAgC;IACtE,IAAI,OAAO,EAAE;QACT,IAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAEhC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC1B,KAAK,CAAC,QAAQ,EAAE,CAAC;QAEjB,IAAA,yCAAmB,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KACnC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,OAAoB,EAAE,QAAgB;IACvD,QAAQ,GAAG,OAAO,CAAC,EAAE,IAAI,QAAQ,CAAC;IAElC,IAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;QACrE,OAAO,CAAC,EAAE,GAAG,QAAQ,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;KACrC;IAED,OAAO,OAAO,CAAC,EAAE,CAAC;AACtB,CAAC","sourcesContent":["import { addRangeToSelection } from '../corePlugin/utils/addRangeToSelection';\nimport { isNodeOfType, toArray } from 'roosterjs-content-model-dom';\nimport { parseTableCells } from '../publicApi/domUtils/tableCellUtils';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport type {\n ContentModelSelectionChangedEvent,\n SetDOMSelection,\n TableSelection,\n} from 'roosterjs-content-model-types';\n\nconst IMAGE_ID = 'image';\nconst TABLE_ID = 'table';\nconst CONTENT_DIV_ID = 'contentDiv';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\nconst TABLE_CSS_RULE = '{background-color: rgb(198,198,198) !important;}';\nconst CARET_CSS_RULE = '{caret-color: transparent}';\nconst MAX_RULE_SELECTOR_LENGTH = 9000;\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\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.contentDiv.ownerDocument;\n const sheet = core.selection.selectionStyleNode?.sheet;\n\n core.selection.skipReselectOnFocus = true;\n\n try {\n let selectionRules: string[] | undefined;\n const rootSelector = '#' + addUniqueId(core.contentDiv, CONTENT_DIV_ID);\n\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n selectionRules = buildImageCSS(\n rootSelector,\n addUniqueId(image, IMAGE_ID),\n core.selection.imageSelectionBorderColor\n );\n core.selection.selection = selection;\n\n setRangeSelection(doc, image);\n break;\n case 'table':\n const { table, firstColumn, firstRow } = selection;\n\n selectionRules = buildTableCss(\n rootSelector,\n addUniqueId(table, TABLE_ID),\n selection\n );\n core.selection.selection = selection;\n\n setRangeSelection(doc, table.rows[firstRow]?.cells[firstColumn]);\n break;\n case 'range':\n addRangeToSelection(doc, selection.range);\n\n core.selection.selection = core.api.hasFocus(core) ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n\n if (sheet) {\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n sheet.deleteRule(i);\n }\n\n if (selectionRules) {\n for (let i = 0; i < selectionRules.length; i++) {\n sheet.insertRule(selectionRules[i]);\n }\n }\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: ContentModelSelectionChangedEvent = {\n eventType: PluginEventType.SelectionChanged,\n newSelection: selection,\n selectionRangeEx: null,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction buildImageCSS(editorSelector: string, imageId: string, borderColor?: string): string[] {\n const color = borderColor || DEFAULT_SELECTION_BORDER_COLOR;\n\n return [\n `${editorSelector} #${imageId} {outline-style:auto!important;outline-color:${color}!important;}`,\n `${editorSelector} ${CARET_CSS_RULE}`,\n ];\n}\n\nfunction buildTableCss(\n editorSelector: string,\n tableId: string,\n selection: TableSelection\n): string[] {\n const { firstColumn, firstRow, lastColumn, lastRow } = selection;\n const cells = parseTableCells(selection.table);\n const isAllTableSelected =\n firstRow == 0 &&\n firstColumn == 0 &&\n lastRow == cells.length - 1 &&\n lastColumn == (cells[lastRow]?.length ?? 0) - 1;\n const rootSelector = editorSelector + ' #' + tableId;\n const selectors = isAllTableSelected\n ? [rootSelector, `${rootSelector} *`]\n : handleTableSelected(rootSelector, selection, cells);\n\n const cssRules: string[] = [`${editorSelector} ${CARET_CSS_RULE}`];\n let currentRules: string = '';\n\n for (let i = 0; i < selectors.length; i++) {\n currentRules += (currentRules.length > 0 ? ',' : '') + selectors[i] || '';\n\n if (\n currentRules.length + (selectors[0]?.length || 0) > MAX_RULE_SELECTOR_LENGTH ||\n i == selectors.length - 1\n ) {\n cssRules.push(currentRules + ' ' + TABLE_CSS_RULE);\n currentRules = '';\n }\n }\n\n return cssRules;\n}\n\nfunction handleTableSelected(\n rootSelector: string,\n selection: TableSelection,\n cells: (HTMLTableCellElement | null)[][]\n) {\n const { firstRow, firstColumn, lastRow, lastColumn, table } = selection;\n const selectors: string[] = [];\n\n // Get whether table has thead, tbody or tfoot, then Set the start and end of each of the table children,\n // so we can build the selector according the element between the table and the row.\n let cont = 0;\n const indexes = toArray(table.childNodes)\n .filter(\n (node): node is HTMLTableSectionElement =>\n ['THEAD', 'TBODY', 'TFOOT'].indexOf(\n isNodeOfType(node, 'ELEMENT_NODE') ? node.tagName : ''\n ) > -1\n )\n .map(node => {\n const result = {\n el: node.tagName,\n start: cont,\n end: node.childNodes.length + cont,\n };\n\n cont = result.end;\n return result;\n });\n\n cells.forEach((row, rowIndex) => {\n let tdCount = 0;\n\n //Get current TBODY/THEAD/TFOOT\n const midElement = indexes.filter(ind => ind.start <= rowIndex && ind.end > rowIndex)[0];\n const middleElSelector = midElement ? '>' + midElement.el + '>' : '>';\n const currentRow =\n midElement && rowIndex + 1 >= midElement.start\n ? rowIndex + 1 - midElement.start\n : rowIndex + 1;\n\n for (let cellIndex = 0; cellIndex < row.length; cellIndex++) {\n const cell = row[cellIndex];\n\n if (cell) {\n tdCount++;\n\n if (\n rowIndex >= firstRow &&\n rowIndex <= lastRow &&\n cellIndex >= firstColumn &&\n cellIndex <= lastColumn\n ) {\n const selector = `${rootSelector}${middleElSelector} tr:nth-child(${currentRow})>${cell.tagName}:nth-child(${tdCount})`;\n\n selectors.push(selector, selector + ' *');\n }\n }\n }\n });\n\n return selectors;\n}\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined) {\n if (element) {\n const range = doc.createRange();\n\n range.selectNode(element);\n range.collapse();\n\n addRangeToSelection(doc, range);\n }\n}\n\nfunction addUniqueId(element: HTMLElement, idPrefix: string): string {\n idPrefix = element.id || idPrefix;\n\n const doc = element.ownerDocument;\n let i = 0;\n\n while (!element.id || doc.querySelectorAll('#' + element.id).length > 1) {\n element.id = idPrefix + '_' + i++;\n }\n\n return element.id;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentModelCachePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/corePlugin/ContentModelCachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelection } from './utils/areSameSelection';\nimport { contentModelDomIndexer } from './utils/contentModelDomIndexer';\nimport { isCharacterValue } from '../publicApi/domUtils/eventUtils';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport type {\n ContentModelCachePluginState,\n ContentModelContentChangedEvent,\n IStandaloneEditor,\n StandaloneEditorOptions,\n} from 'roosterjs-content-model-types';\nimport type {\n IEditor,\n PluginEvent,\n PluginKeyDownEvent,\n PluginWithState,\n} from 'roosterjs-editor-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass ContentModelCachePlugin implements PluginWithState<ContentModelCachePluginState> {\n private editor: (IEditor & IStandaloneEditor) | null = null;\n private state: ContentModelCachePluginState;\n\n /**\n * Construct a new instance of ContentModelEditPlugin class\n * @param option The editor option\n */\n constructor(option: StandaloneEditorOptions) {\n this.state = {\n domIndexer: option.cacheModel ? contentModelDomIndexer : undefined,\n };\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ContentModelCache';\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 // TODO: Later we may need a different interface for Content Model editor plugin\n this.editor = editor as IEditor & IStandaloneEditor;\n this.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\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 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(): ContentModelCachePluginState {\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 PluginEventType.KeyDown:\n if (this.shouldClearCache(event)) {\n this.invalidateCache();\n }\n break;\n\n case PluginEventType.Input:\n {\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n }\n break;\n\n case PluginEventType.SelectionChanged:\n this.updateCachedModel(this.editor);\n break;\n\n case PluginEventType.ContentChanged:\n {\n const { contentModel, selection } = event as ContentModelContentChangedEvent;\n\n if (contentModel && this.state.domIndexer) {\n this.state.cachedModel = contentModel;\n this.state.cachedSelection = selection;\n } else {\n this.invalidateCache();\n }\n }\n\n break;\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 this.state.cachedModel = undefined;\n this.state.cachedSelection = undefined;\n }\n }\n\n private updateCachedModel(editor: IStandaloneEditor, forceUpdate?: boolean) {\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 !areSameSelection(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 this.state.cachedSelection = newRangeEx;\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n\n private shouldClearCache(event: PluginKeyDownEvent) {\n const { rawEvent, handledByEditFeature } = event;\n\n // In these cases we can't update the model, so clear cache:\n // 1. It is already handled by Content Edit Features\n if (handledByEditFeature) {\n return true;\n }\n\n // 2. Default behavior is prevented, which means other plugins has handled the event\n if (rawEvent.defaultPrevented) {\n return true;\n }\n\n // 3. ENTER key is pressed. ENTER key will create new paragraph, so need to update cache to reflect this change\n // TODO: Handle ENTER key to better reuse content model\n\n if (rawEvent.key == 'Enter') {\n return true;\n }\n\n // 4. Current selection is image or table or expanded range selection, and is inputting some text\n if (\n (this.state.cachedSelection?.type != 'range' ||\n !this.state.cachedSelection.range.collapsed) &&\n isCharacterValue(rawEvent)\n ) {\n return true;\n }\n\n return false;\n }\n}\n\n/**\n * @internal\n * Create a new instance of ContentModelCachePlugin class.\n * @param option The editor option\n */\nexport function createContentModelCachePlugin(\n option: StandaloneEditorOptions\n): PluginWithState<ContentModelCachePluginState> {\n return new ContentModelCachePlugin(option);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ContentModelCachePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/corePlugin/ContentModelCachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelection } from './utils/areSameSelection';\nimport { contentModelDomIndexer } from './utils/contentModelDomIndexer';\nimport { isCharacterValue } from '../publicApi/domUtils/eventUtils';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport type {\n ContentModelCachePluginState,\n ContentModelContentChangedEvent,\n IStandaloneEditor,\n StandaloneEditorOptions,\n} from 'roosterjs-content-model-types';\nimport type {\n IEditor,\n PluginEvent,\n PluginKeyDownEvent,\n PluginWithState,\n} from 'roosterjs-editor-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass ContentModelCachePlugin implements PluginWithState<ContentModelCachePluginState> {\n private editor: IStandaloneEditor | null = null;\n private state: ContentModelCachePluginState;\n\n /**\n * Construct a new instance of ContentModelEditPlugin class\n * @param option The editor option\n */\n constructor(option: StandaloneEditorOptions) {\n this.state = {\n domIndexer: option.cacheModel ? contentModelDomIndexer : undefined,\n };\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ContentModelCache';\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 // TODO: Later we may need a different interface for Content Model editor plugin\n this.editor = editor as IEditor & IStandaloneEditor;\n this.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\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 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(): ContentModelCachePluginState {\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 PluginEventType.KeyDown:\n if (this.shouldClearCache(event)) {\n this.invalidateCache();\n }\n break;\n\n case PluginEventType.Input:\n {\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n }\n break;\n\n case PluginEventType.SelectionChanged:\n this.updateCachedModel(this.editor);\n break;\n\n case PluginEventType.ContentChanged:\n {\n const { contentModel, selection } = event as ContentModelContentChangedEvent;\n\n if (contentModel && this.state.domIndexer) {\n this.state.cachedModel = contentModel;\n this.state.cachedSelection = selection;\n } else {\n this.invalidateCache();\n }\n }\n\n break;\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 this.state.cachedModel = undefined;\n this.state.cachedSelection = undefined;\n }\n }\n\n private updateCachedModel(editor: IStandaloneEditor, forceUpdate?: boolean) {\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 !areSameSelection(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 this.state.cachedSelection = newRangeEx;\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n\n private shouldClearCache(event: PluginKeyDownEvent) {\n const { rawEvent, handledByEditFeature } = event;\n\n // In these cases we can't update the model, so clear cache:\n // 1. It is already handled by Content Edit Features\n if (handledByEditFeature) {\n return true;\n }\n\n // 2. Default behavior is prevented, which means other plugins has handled the event\n if (rawEvent.defaultPrevented) {\n return true;\n }\n\n // 3. ENTER key is pressed. ENTER key will create new paragraph, so need to update cache to reflect this change\n // TODO: Handle ENTER key to better reuse content model\n\n if (rawEvent.key == 'Enter') {\n return true;\n }\n\n // 4. Current selection is image or table or expanded range selection, and is inputting some text\n if (\n (this.state.cachedSelection?.type != 'range' ||\n !this.state.cachedSelection.range.collapsed) &&\n isCharacterValue(rawEvent)\n ) {\n return true;\n }\n\n return false;\n }\n}\n\n/**\n * @internal\n * Create a new instance of ContentModelCachePlugin class.\n * @param option The editor option\n */\nexport function createContentModelCachePlugin(\n option: StandaloneEditorOptions\n): PluginWithState<ContentModelCachePluginState> {\n return new ContentModelCachePlugin(option);\n}\n"]}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import type { CopyPastePluginState, ContentModelTable, OnNodeCreated, StandaloneEditorOptions } from 'roosterjs-content-model-types';
|
|
1
|
+
import type { CopyPastePluginState, ContentModelTable, OnNodeCreated, StandaloneEditorOptions, ContentModelDocument } from 'roosterjs-content-model-types';
|
|
2
2
|
import type { PluginWithState } from 'roosterjs-editor-types';
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
* Exported only for unit testing
|
|
6
|
+
*/
|
|
7
|
+
export declare function adjustSelectionForCopyCut(pasteModel: ContentModelDocument): void;
|
|
3
8
|
/**
|
|
4
9
|
* @internal
|
|
5
10
|
* Exported only for unit testing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createContentModelCopyPastePlugin = exports.preprocessTable = exports.onNodeCreated = void 0;
|
|
3
|
+
exports.createContentModelCopyPastePlugin = exports.preprocessTable = exports.onNodeCreated = exports.adjustSelectionForCopyCut = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var addRangeToSelection_1 = require("./utils/addRangeToSelection");
|
|
6
6
|
var ChangeSource_1 = require("../constants/ChangeSource");
|
|
@@ -10,7 +10,6 @@ var deleteSelection_1 = require("../publicApi/selection/deleteSelection");
|
|
|
10
10
|
var extractClipboardItems_1 = require("../utils/extractClipboardItems");
|
|
11
11
|
var getSelectedCells_1 = require("../publicApi/table/getSelectedCells");
|
|
12
12
|
var iterateSelections_1 = require("../publicApi/selection/iterateSelections");
|
|
13
|
-
var paste_1 = require("../publicApi/model/paste");
|
|
14
13
|
var transformColor_1 = require("../publicApi/color/transformColor");
|
|
15
14
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
16
15
|
/**
|
|
@@ -33,7 +32,7 @@ var ContentModelCopyPastePlugin = /** @class */ (function () {
|
|
|
33
32
|
event.preventDefault();
|
|
34
33
|
(0, extractClipboardItems_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType).then(function (clipboardData) {
|
|
35
34
|
if (!editor_1.isDisposed()) {
|
|
36
|
-
|
|
35
|
+
editor_1.pasteFromClipboard(clipboardData);
|
|
37
36
|
}
|
|
38
37
|
});
|
|
39
38
|
}
|
|
@@ -102,13 +101,15 @@ var ContentModelCopyPastePlugin = /** @class */ (function () {
|
|
|
102
101
|
return this.state;
|
|
103
102
|
};
|
|
104
103
|
ContentModelCopyPastePlugin.prototype.onCutCopy = function (event, isCut) {
|
|
104
|
+
var _this = this;
|
|
105
|
+
var _a;
|
|
105
106
|
if (!this.editor) {
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
109
|
var doc = this.editor.getDocument();
|
|
109
110
|
var selection = this.editor.getDOMSelection();
|
|
110
111
|
if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
|
|
111
|
-
var model = this.editor.createContentModel();
|
|
112
|
+
var model = this.editor.createContentModel(undefined /* option */, selection);
|
|
112
113
|
var cacheProcessor = this.editor.isDarkMode() ? this.processEntityColor : false;
|
|
113
114
|
var pasteModel = (0, cloneModel_1.cloneModel)(model, {
|
|
114
115
|
includeCachedElement: cacheProcessor,
|
|
@@ -122,6 +123,9 @@ var ContentModelCopyPastePlugin = /** @class */ (function () {
|
|
|
122
123
|
return false;
|
|
123
124
|
});
|
|
124
125
|
}
|
|
126
|
+
else if (selection.type === 'range') {
|
|
127
|
+
adjustSelectionForCopyCut(pasteModel);
|
|
128
|
+
}
|
|
125
129
|
var tempDiv_1 = this.getTempDiv(this.editor.getDocument());
|
|
126
130
|
var selectionForCopy = (0, roosterjs_content_model_dom_1.contentModelToDom)(tempDiv_1.ownerDocument, tempDiv_1, pasteModel, (0, roosterjs_content_model_dom_1.createModelToDomContext)(), exports.onNodeCreated);
|
|
127
131
|
var newRange = selectionForCopy
|
|
@@ -137,13 +141,15 @@ var ContentModelCopyPastePlugin = /** @class */ (function () {
|
|
|
137
141
|
if (newRange) {
|
|
138
142
|
(0, addRangeToSelection_1.addRangeToSelection)(doc, newRange);
|
|
139
143
|
}
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
(_a = doc.defaultView) === null || _a === void 0 ? void 0 : _a.requestAnimationFrame(function () {
|
|
145
|
+
if (!_this.editor) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
142
148
|
cleanUpAndRestoreSelection(tempDiv_1);
|
|
143
|
-
editor.focus();
|
|
144
|
-
editor.setDOMSelection(selection);
|
|
149
|
+
_this.editor.focus();
|
|
150
|
+
_this.editor.setDOMSelection(selection);
|
|
145
151
|
if (isCut) {
|
|
146
|
-
editor.formatContentModel(function (model, context) {
|
|
152
|
+
_this.editor.formatContentModel(function (model, context) {
|
|
147
153
|
if ((0, deleteSelection_1.deleteSelection)(model, [deleteEmptyList_1.deleteEmptyList], context)
|
|
148
154
|
.deleteResult == 'range') {
|
|
149
155
|
(0, roosterjs_content_model_dom_1.normalizeContentModel)(model);
|
|
@@ -185,6 +191,31 @@ var ContentModelCopyPastePlugin = /** @class */ (function () {
|
|
|
185
191
|
};
|
|
186
192
|
return ContentModelCopyPastePlugin;
|
|
187
193
|
}());
|
|
194
|
+
/**
|
|
195
|
+
* @internal
|
|
196
|
+
* Exported only for unit testing
|
|
197
|
+
*/
|
|
198
|
+
function adjustSelectionForCopyCut(pasteModel) {
|
|
199
|
+
var selectionMarker;
|
|
200
|
+
var firstBlock;
|
|
201
|
+
var tableContext;
|
|
202
|
+
(0, iterateSelections_1.iterateSelections)(pasteModel, function (_, tableCtxt, block, segments) {
|
|
203
|
+
if (selectionMarker) {
|
|
204
|
+
if (tableCtxt != tableContext && (firstBlock === null || firstBlock === void 0 ? void 0 : firstBlock.segments.includes(selectionMarker))) {
|
|
205
|
+
firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);
|
|
206
|
+
}
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
var marker = segments === null || segments === void 0 ? void 0 : segments.find(function (segment) { return segment.segmentType == 'SelectionMarker'; });
|
|
210
|
+
if (!selectionMarker && marker) {
|
|
211
|
+
tableContext = tableCtxt;
|
|
212
|
+
firstBlock = (block === null || block === void 0 ? void 0 : block.blockType) == 'Paragraph' ? block : undefined;
|
|
213
|
+
selectionMarker = marker;
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
exports.adjustSelectionForCopyCut = adjustSelectionForCopyCut;
|
|
188
219
|
function cleanUpAndRestoreSelection(tempDiv) {
|
|
189
220
|
tempDiv.style.backgroundColor = '';
|
|
190
221
|
tempDiv.style.color = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentModelCopyPastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/corePlugin/ContentModelCopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './utils/addRangeToSelection';\nimport { ChangeSource } from '../constants/ChangeSource';\nimport { cloneModel } from '../publicApi/model/cloneModel';\nimport { deleteEmptyList } from './utils/deleteEmptyList';\nimport { deleteSelection } from '../publicApi/selection/deleteSelection';\nimport { extractClipboardItems } from '../utils/extractClipboardItems';\nimport { getSelectedCells } from '../publicApi/table/getSelectedCells';\nimport { iterateSelections } from '../publicApi/selection/iterateSelections';\nimport { paste } from '../publicApi/model/paste';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport { transformColor } from '../publicApi/color/transformColor';\nimport {\n contentModelToDom,\n createModelToDomContext,\n isElementOfType,\n isNodeOfType,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IStandaloneEditor,\n OnNodeCreated,\n StandaloneEditorOptions,\n} from 'roosterjs-content-model-types';\nimport type { IEditor, PluginWithState } from 'roosterjs-editor-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass ContentModelCopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: (IStandaloneEditor & IEditor) | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: StandaloneEditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'ContentModelCopyPaste';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor as IStandaloneEditor & IEditor;\n this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const model = this.editor.createContentModel();\n const cacheProcessor = this.editor.isDarkMode() ? this.processEntityColor : false;\n\n const pasteModel = cloneModel(model, {\n includeCachedElement: cacheProcessor,\n });\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n }\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n createModelToDomContext(),\n onNodeCreated\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerPluginEvent(PluginEventType.BeforeCutCopy, {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n this.editor.runAsync(e => {\n const editor = e as IStandaloneEditor & IEditor;\n\n cleanUpAndRestoreSelection(tempDiv);\n editor.focus();\n editor.setDOMSelection(selection);\n\n if (isCut) {\n editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n\n private processEntityColor = (\n node: HTMLElement,\n type: 'general' | 'entity' | 'cache'\n ): HTMLElement | undefined => {\n if (type == 'cache' || !this.editor) {\n return undefined;\n }\n\n const result = node.cloneNode(true /*deep*/) as HTMLElement;\n const colorHandler = this.editor.getDarkColorHandler();\n\n transformColor(result, true /*includeSelf*/, 'darkToLight', colorHandler);\n\n result.style.color = result.style.color || 'inherit';\n result.style.backgroundColor = result.style.backgroundColor || 'inherit';\n\n return result;\n };\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\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\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (_, 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};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of ContentModelCopyPastePlugin\n * @param option The editor option\n */\nexport function createContentModelCopyPastePlugin(\n option: StandaloneEditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new ContentModelCopyPastePlugin(option);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ContentModelCopyPastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/corePlugin/ContentModelCopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './utils/addRangeToSelection';\nimport { ChangeSource } from '../constants/ChangeSource';\nimport { cloneModel } from '../publicApi/model/cloneModel';\nimport { deleteEmptyList } from './utils/deleteEmptyList';\nimport { deleteSelection } from '../publicApi/selection/deleteSelection';\nimport { extractClipboardItems } from '../utils/extractClipboardItems';\nimport { getSelectedCells } from '../publicApi/table/getSelectedCells';\nimport { iterateSelections } from '../publicApi/selection/iterateSelections';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport { transformColor } from '../publicApi/color/transformColor';\nimport {\n contentModelToDom,\n createModelToDomContext,\n isElementOfType,\n isNodeOfType,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IStandaloneEditor,\n OnNodeCreated,\n StandaloneEditorOptions,\n ContentModelDocument,\n ContentModelParagraph,\n TableSelectionContext,\n ContentModelSegment,\n} from 'roosterjs-content-model-types';\nimport type { IEditor, PluginWithState } from 'roosterjs-editor-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass ContentModelCopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IStandaloneEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: StandaloneEditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'ContentModelCopyPaste';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor as IStandaloneEditor & IEditor;\n this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const model = this.editor.createContentModel(undefined /* option */, selection);\n const cacheProcessor = this.editor.isDarkMode() ? this.processEntityColor : false;\n\n const pasteModel = cloneModel(model, {\n includeCachedElement: cacheProcessor,\n });\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n createModelToDomContext(),\n onNodeCreated\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerPluginEvent(PluginEventType.BeforeCutCopy, {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.focus();\n this.editor.setDOMSelection(selection);\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n editor.pasteFromClipboard(clipboardData);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n\n private processEntityColor = (\n node: HTMLElement,\n type: 'general' | 'entity' | 'cache'\n ): HTMLElement | undefined => {\n if (type == 'cache' || !this.editor) {\n return undefined;\n }\n\n const result = node.cloneNode(true /*deep*/) as HTMLElement;\n const colorHandler = this.editor.getDarkColorHandler();\n\n transformColor(result, true /*includeSelf*/, 'darkToLight', colorHandler);\n\n result.style.color = result.style.color || 'inherit';\n result.style.backgroundColor = result.style.backgroundColor || 'inherit';\n\n return result;\n };\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: TableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\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\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (_, 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};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of ContentModelCopyPastePlugin\n * @param option The editor option\n */\nexport function createContentModelCopyPastePlugin(\n option: StandaloneEditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new ContentModelCopyPastePlugin(option);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentModelFormatPlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/corePlugin/ContentModelFormatPlugin.ts"],"names":[],"mappings":";;;;AAAA,iEAAgE;AAChE,iEAAgE;AAChE,2EAA4D;AAC5D,+DAAuF;AASvF,6DAA6D;AAC7D,IAAM,UAAU,GAAG,SAAS,CAAC;AAE7B;;;;GAIG;AACH;IAKI;;;OAGG;IACH,kCAAY,MAA+B;QARnC,WAAM,
|
|
1
|
+
{"version":3,"file":"ContentModelFormatPlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-core/lib/corePlugin/ContentModelFormatPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyDefaultFormat } from './utils/applyDefaultFormat';\nimport { applyPendingFormat } from './utils/applyPendingFormat';\nimport { getObjectKeys } from 'roosterjs-content-model-dom';\nimport { isCharacterValue, isCursorMovingKey } from '../publicApi/domUtils/eventUtils';\nimport { PluginEventType } from 'roosterjs-editor-types';\nimport type { IEditor, PluginEvent, PluginWithState } from 'roosterjs-editor-types';\nimport type {\n ContentModelFormatPluginState,\n IStandaloneEditor,\n StandaloneEditorOptions,\n} from 'roosterjs-content-model-types';\n\n// During IME input, KeyDown event will have \"Process\" as key\nconst ProcessKey = 'Process';\n\n/**\n * ContentModelFormat 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 ContentModelFormatPlugin implements PluginWithState<ContentModelFormatPluginState> {\n private editor: IStandaloneEditor | null = null;\n private hasDefaultFormat = false;\n private state: ContentModelFormatPluginState;\n\n /**\n * Construct a new instance of ContentModelEditPlugin class\n * @param option The editor option\n */\n constructor(option: StandaloneEditorOptions) {\n this.state = {\n defaultFormat: { ...option.defaultSegmentFormat },\n pendingFormat: null,\n };\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ContentModelFormat';\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 // TODO: Later we may need a different interface for Content Model editor plugin\n this.editor = editor as IStandaloneEditor & IEditor;\n this.hasDefaultFormat =\n getObjectKeys(this.state.defaultFormat).filter(\n x => typeof this.state.defaultFormat[x] !== 'undefined'\n ).length > 0;\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(): ContentModelFormatPluginState {\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 PluginEventType.Input:\n const env = this.editor.getEnvironment();\n\n // In Safari, isComposing will be undefined but isInIME() works\n // For Android, we can skip checking isComposing since this property is not always reliable in all IME,\n // and we have tested without this check it can still work correctly\n if (env.isAndroid || (!event.rawEvent.isComposing && !this.editor.isInIME())) {\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n }\n\n break;\n\n case PluginEventType.CompositionEnd:\n this.checkAndApplyPendingFormat(event.rawEvent.data);\n break;\n\n case PluginEventType.KeyDown:\n if (isCursorMovingKey(event.rawEvent)) {\n this.clearPendingFormat();\n } else if (\n this.hasDefaultFormat &&\n (isCharacterValue(event.rawEvent) || event.rawEvent.key == ProcessKey)\n ) {\n applyDefaultFormat(this.editor, this.state.defaultFormat);\n }\n\n break;\n\n case PluginEventType.MouseUp:\n case PluginEventType.ContentChanged:\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 { posContainer, posOffset } = this.state.pendingFormat;\n\n if (range && range.startContainer == posContainer && range.startOffset == posOffset) {\n result = true;\n }\n }\n\n return result;\n }\n}\n\n/**\n * @internal\n * Create a new instance of ContentModelFormatPlugin.\n * @param option The editor option\n */\nexport function createContentModelFormatPlugin(\n option: StandaloneEditorOptions\n): PluginWithState<ContentModelFormatPluginState> {\n return new ContentModelFormatPlugin(option);\n}\n"]}
|