roosterjs-content-model-core 9.53.0 → 9.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/command/paste/mergePasteContent.d.ts +1 -5
- package/lib/command/paste/mergePasteContent.js +2 -12
- package/lib/command/paste/mergePasteContent.js.map +1 -1
- package/lib/command/paste/paste.js +3 -2
- package/lib/command/paste/paste.js.map +1 -1
- package/lib/coreApi/createContentModel/createContentModel.js +3 -0
- package/lib/coreApi/createContentModel/createContentModel.js.map +1 -1
- package/lib/corePlugin/cache/CachePlugin.js +5 -0
- package/lib/corePlugin/cache/CachePlugin.js.map +1 -1
- package/lib/corePlugin/cache/MutationType.d.ts +12 -1
- package/lib/corePlugin/cache/MutationType.js.map +1 -1
- package/lib/corePlugin/cache/domIndexerImpl.d.ts +1 -0
- package/lib/corePlugin/cache/domIndexerImpl.js +27 -0
- package/lib/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib/corePlugin/cache/textMutationObserver.js +10 -0
- package/lib/corePlugin/cache/textMutationObserver.js.map +1 -1
- package/lib/corePlugin/copyPaste/CopyPastePlugin.js +1 -1
- package/lib/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
- package/lib-amd/command/paste/mergePasteContent.d.ts +1 -5
- package/lib-amd/command/paste/mergePasteContent.js +2 -12
- package/lib-amd/command/paste/mergePasteContent.js.map +1 -1
- package/lib-amd/command/paste/paste.js +2 -2
- package/lib-amd/command/paste/paste.js.map +1 -1
- package/lib-amd/coreApi/createContentModel/createContentModel.js +3 -0
- package/lib-amd/coreApi/createContentModel/createContentModel.js.map +1 -1
- package/lib-amd/corePlugin/cache/CachePlugin.js +5 -0
- package/lib-amd/corePlugin/cache/CachePlugin.js.map +1 -1
- package/lib-amd/corePlugin/cache/MutationType.d.ts +12 -1
- package/lib-amd/corePlugin/cache/MutationType.js.map +1 -1
- package/lib-amd/corePlugin/cache/domIndexerImpl.d.ts +1 -0
- package/lib-amd/corePlugin/cache/domIndexerImpl.js +27 -0
- package/lib-amd/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib-amd/corePlugin/cache/textMutationObserver.js +10 -0
- package/lib-amd/corePlugin/cache/textMutationObserver.js.map +1 -1
- package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js +1 -1
- package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
- package/lib-mjs/command/paste/mergePasteContent.d.ts +1 -5
- package/lib-mjs/command/paste/mergePasteContent.js +1 -10
- package/lib-mjs/command/paste/mergePasteContent.js.map +1 -1
- package/lib-mjs/command/paste/paste.js +2 -1
- package/lib-mjs/command/paste/paste.js.map +1 -1
- package/lib-mjs/coreApi/createContentModel/createContentModel.js +3 -0
- package/lib-mjs/coreApi/createContentModel/createContentModel.js.map +1 -1
- package/lib-mjs/corePlugin/cache/CachePlugin.js +5 -0
- package/lib-mjs/corePlugin/cache/CachePlugin.js.map +1 -1
- package/lib-mjs/corePlugin/cache/MutationType.d.ts +12 -1
- package/lib-mjs/corePlugin/cache/MutationType.js.map +1 -1
- package/lib-mjs/corePlugin/cache/domIndexerImpl.d.ts +1 -0
- package/lib-mjs/corePlugin/cache/domIndexerImpl.js +27 -0
- package/lib-mjs/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib-mjs/corePlugin/cache/textMutationObserver.js +10 -0
- package/lib-mjs/corePlugin/cache/textMutationObserver.js.map +1 -1
- package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js +1 -1
- package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textMutationObserver.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/textMutationObserver.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"textMutationObserver.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/textMutationObserver.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDOMHelper } from '../../editor/core/DOMHelperImpl';\nimport {\n findClosestBlockEntityContainer,\n findClosestEntityWrapper,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type { DOMHelper, TextMutationObserver } from 'roosterjs-content-model-types';\nimport type { Mutation } from './MutationType';\n\nclass TextMutationObserverImpl implements TextMutationObserver {\n private observer: MutationObserver;\n private domHelper: DOMHelper;\n\n constructor(\n private contentDiv: HTMLDivElement,\n private onMutation: (mutation: Mutation) => void\n ) {\n this.observer = new MutationObserver(this.onMutationInternal);\n this.domHelper = createDOMHelper(contentDiv);\n }\n\n startObserving() {\n this.observer.observe(this.contentDiv, {\n subtree: true,\n childList: true,\n attributes: true,\n characterData: true,\n });\n }\n\n stopObserving() {\n this.observer.disconnect();\n }\n\n flushMutations(ignoreMutations?: boolean) {\n const mutations = this.observer.takeRecords();\n\n if (!ignoreMutations) {\n this.onMutationInternal(mutations);\n }\n }\n\n private onMutationInternal = (mutations: MutationRecord[]) => {\n let canHandle = true;\n let firstTarget: Node | null = null;\n let lastTextChangeNode: Node | null = null;\n let addedNodes: Node[] = [];\n let removedNodes: Node[] = [];\n let reconcileText = false;\n\n const ignoredNodes = new Set<Node>();\n const includedNodes = new Set<Node>();\n\n for (let i = 0; i < mutations.length && canHandle; i++) {\n const mutation = mutations[i];\n const target = mutation.target;\n\n if (ignoredNodes.has(target)) {\n continue;\n } else if (!includedNodes.has(target)) {\n if (\n !this.domHelper.isNodeInEditor(target) ||\n findClosestEntityWrapper(target, this.domHelper) ||\n findClosestBlockEntityContainer(target, this.domHelper)\n ) {\n ignoredNodes.add(target);\n\n continue;\n } else {\n includedNodes.add(target);\n }\n }\n\n switch (mutation.type) {\n case 'attributes':\n if (this.domHelper.isNodeInEditor(target, true /*excludingSelf*/)) {\n if (\n mutation.attributeName == 'id' &&\n isNodeOfType(target, 'ELEMENT_NODE')\n ) {\n this.onMutation({ type: 'elementId', element: target });\n } else if (\n mutation.attributeName &&\n isNodeOfType(target, 'ELEMENT_NODE') &&\n (mutation.attributeName == 'src' ||\n mutation.attributeName.indexOf('data-') == 0)\n ) {\n this.onMutation({\n type: 'attribute',\n element: target,\n attributeName: mutation.attributeName,\n });\n } else {\n // We cannot handle attributes changes on editor content for now\n canHandle = false;\n }\n }\n break;\n\n case 'characterData':\n if (lastTextChangeNode && lastTextChangeNode != mutation.target) {\n // Multiple text nodes got changed, we don't know how to handle it\n canHandle = false;\n } else {\n lastTextChangeNode = mutation.target;\n reconcileText = true;\n }\n break;\n\n case 'childList':\n if (!firstTarget) {\n firstTarget = mutation.target;\n } else if (firstTarget != mutation.target) {\n canHandle = false;\n }\n\n if (canHandle) {\n addedNodes = addedNodes.concat(Array.from(mutation.addedNodes));\n removedNodes = removedNodes.concat(Array.from(mutation.removedNodes));\n }\n\n break;\n }\n }\n\n if (canHandle) {\n if (addedNodes.length > 0 || removedNodes.length > 0) {\n this.onMutation({\n type: 'childList',\n addedNodes,\n removedNodes,\n });\n }\n\n if (reconcileText) {\n this.onMutation({ type: 'text' });\n }\n } else {\n this.onMutation({ type: 'unknown' });\n }\n };\n}\n\n/**\n * @internal\n */\nexport function createTextMutationObserver(\n contentDiv: HTMLDivElement,\n onMutation: (mutation: Mutation) => void\n): TextMutationObserver {\n return new TextMutationObserverImpl(contentDiv, onMutation);\n}\n"]}
|
|
@@ -23,7 +23,7 @@ var CopyPastePlugin = /** @class */ (function () {
|
|
|
23
23
|
var dataTransfer = event.clipboardData;
|
|
24
24
|
if (shouldPreventDefaultPaste(dataTransfer, editor_1)) {
|
|
25
25
|
event.preventDefault();
|
|
26
|
-
(0, roosterjs_content_model_dom_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType).then(function (clipboardData) {
|
|
26
|
+
(0, roosterjs_content_model_dom_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType, true /* isPasteNative */).then(function (clipboardData) {
|
|
27
27
|
if (!editor_1.isDisposed()) {
|
|
28
28
|
(0, paste_1.paste)(editor_1, clipboardData, _this.state.defaultPasteType);
|
|
29
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";;;AAAA,2DAA0D;AAC1D,6EAA4E;AAC5E,mDAAkD;AAClD,2EAMqC;AASrC;;GAEG;AACH;IAKI;;;OAGG;IACH,yBAAY,MAAqB;QAAjC,iBAMC;QAdO,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAkGrC,YAAO,GAAG,UAAC,KAAY;YAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;gBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;gBAEzC,IAAI,yBAAyB,CAAC,YAAY,EAAE,QAAM,CAAC,EAAE;oBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,IAAA,mDAAqB,EACjB,IAAA,qCAAO,EAAC,YAAa,CAAC,KAAK,CAAC,EAC5B,KAAI,CAAC,KAAK,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteEmptyList } from './utils/deleteEmptyList';\nimport { getContentForCopy } from '../../command/cutCopy/getContentForCopy';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n deleteSelection,\n extractClipboardItems,\n normalizeContentModel,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n IEditor,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: 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: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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;\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 || !isClipboardEvent(event)) {\n return;\n }\n\n const textAndHtmlContent = getContentForCopy(this.editor, isCut, event);\n\n if (textAndHtmlContent) {\n const { htmlContent, textContent } = textAndHtmlContent;\n event.preventDefault();\n event.clipboardData?.setData('text/html', htmlContent.innerHTML);\n event.clipboardData?.setData('text/plain', textContent);\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context).deleteResult ==\n 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\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 (shouldPreventDefaultPaste(dataTransfer, editor)) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer!.items),\n this.state.allowedCustomPasteType,\n true /* isPasteNative */\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function shouldPreventDefaultPaste(\n dataTransfer: DataTransfer | null,\n editor: IEditor\n): boolean {\n if (!dataTransfer?.items) {\n return false;\n }\n\n if (!editor.getEnvironment().isAndroid) {\n return true;\n }\n\n // On Android, the clipboard data from Office apps is a file, which can't be loaded\n // so we have to allow the default browser behavior\n return toArray(dataTransfer.items).some(item => {\n const { type } = item;\n const isNormalFile = item.kind === 'file' && type !== '';\n const isText = type.indexOf('text/') === 0;\n return isNormalFile || isText;\n });\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type { BeforePasteEvent,
|
|
2
|
-
/**
|
|
3
|
-
* @internal
|
|
4
|
-
*/
|
|
5
|
-
export declare function cloneModelForPaste(model: ReadonlyContentModelDocument): ContentModelDocument;
|
|
1
|
+
import type { BeforePasteEvent, IEditor } from 'roosterjs-content-model-types';
|
|
6
2
|
/**
|
|
7
3
|
* @internal
|
|
8
4
|
*/
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
define(["require", "exports", "tslib", "../createModelFromHtml/createDomToModelContextForSanitizing", "roosterjs-content-model-dom"], function (require, exports, tslib_1, createDomToModelContextForSanitizing_1, roosterjs_content_model_dom_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.mergePasteContent =
|
|
4
|
+
exports.mergePasteContent = void 0;
|
|
5
5
|
var BlackColor = 'rgb(0,0,0)';
|
|
6
|
-
var CloneOption = {
|
|
7
|
-
includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
function cloneModelForPaste(model) {
|
|
13
|
-
return (0, roosterjs_content_model_dom_1.cloneModel)(model, CloneOption);
|
|
14
|
-
}
|
|
15
|
-
exports.cloneModelForPaste = cloneModelForPaste;
|
|
16
6
|
/**
|
|
17
7
|
* @internal
|
|
18
8
|
*/
|
|
@@ -20,7 +10,7 @@ define(["require", "exports", "tslib", "../createModelFromHtml/createDomToModelC
|
|
|
20
10
|
var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType, clipboardData = eventResult.clipboardData, containsBlockElements = eventResult.containsBlockElements;
|
|
21
11
|
editor.formatContentModel(function (model, context) {
|
|
22
12
|
if (!isFirstPaste && clipboardData.modelBeforePaste) {
|
|
23
|
-
var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
|
|
13
|
+
var clonedModel = (0, roosterjs_content_model_dom_1.cloneModelForPaste)(clipboardData.modelBeforePaste);
|
|
24
14
|
model.blocks = clonedModel.blocks;
|
|
25
15
|
}
|
|
26
16
|
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption, editor.getDOMHelper());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing';\nimport {\n ChangeSource,\n EmptySegmentFormat,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n cloneModelForPaste,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n isFirstPaste: boolean\n) {\n const {\n fragment,\n domToModelOption,\n customizedMerge,\n pasteType,\n clipboardData,\n containsBlockElements,\n } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (!isFirstPaste && clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption,\n editor.getDOMHelper()\n );\n\n domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n addParagraphAfterMergedContent: containsBlockElements,\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...(pasteType == 'normal' && !containsBlockElements\n ? getLastSegmentFormat(pasteModel)\n : insertPoint.marker.format),\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n scrollCaretIntoView: true,\n apiName: 'paste',\n }\n );\n}\n\nfunction getSegmentFormatForPaste(\n model: ShallowMutableContentModelDocument,\n pasteType: PasteType\n): ContentModelSegmentFormat {\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n\n if (selectedSegment) {\n const result = getSegmentTextFormat(selectedSegment);\n if (pasteType == 'normal') {\n // When using normal paste (Keep source formatting) set the default text color to black when creating the\n // Model from the clipboard content, so the elements that do not contain any text color in their style\n // Are set to black. Otherwise, These segments would get the selected segments format or the default text set in the content.\n result.textColor = BlackColor;\n }\n\n return result;\n }\n\n return {};\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n\nfunction getLastSegmentFormat(pasteModel: ContentModelDocument): ContentModelSegmentFormat {\n if (pasteModel.blocks.length == 1) {\n const [firstBlock] = pasteModel.blocks;\n\n if (firstBlock.blockType == 'Paragraph') {\n const segment = firstBlock.segments[firstBlock.segments.length - 1];\n\n return {\n ...segment.format,\n };\n }\n }\n\n return {};\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
define(["require", "exports", "./cleanHtmlComments", "
|
|
1
|
+
define(["require", "exports", "./cleanHtmlComments", "roosterjs-content-model-dom", "../createModelFromHtml/convertInlineCss", "./createPasteFragment", "./generatePasteOptionFromPlugins", "./mergePasteContent", "./retrieveHtmlInfo"], function (require, exports, cleanHtmlComments_1, roosterjs_content_model_dom_1, convertInlineCss_1, createPasteFragment_1, generatePasteOptionFromPlugins_1, mergePasteContent_1, retrieveHtmlInfo_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.paste = void 0;
|
|
@@ -16,7 +16,7 @@ define(["require", "exports", "./cleanHtmlComments", "./mergePasteContent", "../
|
|
|
16
16
|
if (!clipboardData.modelBeforePaste) {
|
|
17
17
|
isFirstPaste = true;
|
|
18
18
|
editor.formatContentModel(function (model) {
|
|
19
|
-
clipboardData.modelBeforePaste = (0,
|
|
19
|
+
clipboardData.modelBeforePaste = (0, roosterjs_content_model_dom_1.cloneModelForPaste)(model);
|
|
20
20
|
return false;
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;;IAcA;;;;;OAKG;IACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,iBAA+C;;QAA/C,kCAAA,EAAA,4BAA+C;QAE/C,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;YACjC,YAAY,GAAG,IAAI,CAAC;YAEpB,MAAM,CAAC,kBAAkB,CAAC,UAAA,KAAK;gBAC3B,aAAa,CAAC,gBAAgB,GAAG,IAAA,gDAAkB,EAAC,KAAK,CAAC,CAAC;gBAE3D,OAAO,KAAK,CAAC;YACjB,CAAC,CAAC,CAAC;SACN;QAED,uBAAuB;QACvB,IAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,EAAE;YACjD,aAAa,CAAC,OAAO,GAAG,IAAA,qCAAiB,EAAC,aAAa,CAAC,OAAO,CAAC,CAAC;SACpE;QACD,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACjE,IAAM,SAAS,GACX,OAAO,iBAAiB,IAAI,UAAU;YAClC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,aAAa,CAAC;YACvC,CAAC,CAAC,iBAAiB,CAAC;QAE5B,gCAAgC;QAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAE/D,4BAA4B;QAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,MAAM,CAAC,WAAW,EAAE,EACpB,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,UAAU,CAAC,CACtD,0CAAE,IAAI,CACV,CAAC;QAEF,oEAAoE;QACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,MAAM,EACN,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,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IACzD,CAAC;IAzDD,sBAyDC;IAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,UAAsB;QAEtB,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,CAAC","sourcesContent":["import { cleanHtmlComments } from './cleanHtmlComments';\nimport { cloneModelForPaste } from 'roosterjs-content-model-dom';\nimport { convertInlineCss } from '../createModelFromHtml/convertInlineCss';\nimport { createPasteFragment } from './createPasteFragment';\nimport { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';\nimport { mergePasteContent } from './mergePasteContent';\nimport { retrieveHtmlInfo } from './retrieveHtmlInfo';\nimport type {\n PasteTypeOrGetter,\n ClipboardData,\n IEditor,\n DOMCreator,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteTypeOrGetter Type of content to paste or function that returns the Paste Type to use based on the document and the clipboard Data. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteTypeOrGetter: PasteTypeOrGetter = 'normal'\n) {\n editor.focus();\n let isFirstPaste = false;\n\n if (!clipboardData.modelBeforePaste) {\n isFirstPaste = true;\n\n editor.formatContentModel(model => {\n clipboardData.modelBeforePaste = cloneModelForPaste(model);\n\n return false;\n });\n }\n\n // 1. Prepare variables\n const domCreator = editor.getDOMCreator();\n if (!domCreator.isBypassed && clipboardData.rawHtml) {\n clipboardData.rawHtml = cleanHtmlComments(clipboardData.rawHtml);\n }\n const doc = createDOMFromHtml(clipboardData.rawHtml, domCreator);\n const pasteType =\n typeof pasteTypeOrGetter == 'function'\n ? pasteTypeOrGetter(doc, clipboardData)\n : pasteTypeOrGetter;\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, domCreator)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\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(editor, eventResult, isFirstPaste);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n domCreator: DOMCreator\n): Document | null {\n return html ? domCreator.htmlToDOM(html) : null;\n}\n"]}
|
|
@@ -33,6 +33,9 @@ define(["require", "exports", "../../corePlugin/cache/updateCache", "roosterjs-c
|
|
|
33
33
|
var domToModelContext = option
|
|
34
34
|
? (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, settings.builtIn, settings.customized, option)
|
|
35
35
|
: (0, roosterjs_content_model_dom_1.createDomToModelContextWithConfig)(settings.calculated, editorContext);
|
|
36
|
+
if (option === null || option === void 0 ? void 0 : option.skipFormatContainerFallbackCheck) {
|
|
37
|
+
domToModelContext.skipFormatContainerFallbackCheck = true;
|
|
38
|
+
}
|
|
36
39
|
if (selection) {
|
|
37
40
|
domToModelContext.selection = selection;
|
|
38
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createContentModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/createContentModel/createContentModel.ts"],"names":[],"mappings":";;;;IASA;;;;;;OAMG;IACI,IAAM,kBAAkB,GAAuB,UAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB;;QAClF,6EAA6E;QAC7E,MAAA,IAAI,CAAC,KAAK,CAAC,oBAAoB,0CAAE,cAAc,EAAE,CAAC;QAClD,IAAM,eAAe,GACjB,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,OAAO,MAAM,CAAC,oBAAoB,KAAK,WAAW,CAAC,CAAC;QAE9F,IAAI,CAAC,iBAAiB,IAAI,eAAe,EAAE;YACvC,IAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAE3C,IAAI,WAAW,EAAE;gBACb,6EAA6E;gBAC7E,OAAO,IAAI,CAAC,SAAS,CAAC,kBAAkB;oBACpC,CAAC,CAAC,IAAA,wCAAU,EAAC,WAAW,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;oBACzD,CAAC,CAAC,WAAW,CAAC;aACrB;SACJ;QAED,IAAM,SAAS,GACX,iBAAiB,IAAI,MAAM;YACvB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3E,IAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEpE,aAAa,CAAC,oBAAoB,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAAC;QAElE,IAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;QACrD,IAAM,iBAAiB,GAAG,MAAM;YAC5B,CAAC,CAAC,IAAA,qDAAuB,EAAC,aAAa,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YACvF,CAAC,CAAC,IAAA,+DAAiC,EAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAE5E,IAAI,SAAS,EAAE;YACX,iBAAiB,CAAC,SAAS,GAAG,SAAS,CAAC;SAC3C;QAED,IAAM,KAAK,GAAG,IAAA,+CAAiB,EAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAErE,IAAI,SAAS,EAAE;YACX,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SAC7C;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"createContentModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/createContentModel/createContentModel.ts"],"names":[],"mappings":";;;;IASA;;;;;;OAMG;IACI,IAAM,kBAAkB,GAAuB,UAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB;;QAClF,6EAA6E;QAC7E,MAAA,IAAI,CAAC,KAAK,CAAC,oBAAoB,0CAAE,cAAc,EAAE,CAAC;QAClD,IAAM,eAAe,GACjB,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,OAAO,MAAM,CAAC,oBAAoB,KAAK,WAAW,CAAC,CAAC;QAE9F,IAAI,CAAC,iBAAiB,IAAI,eAAe,EAAE;YACvC,IAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAE3C,IAAI,WAAW,EAAE;gBACb,6EAA6E;gBAC7E,OAAO,IAAI,CAAC,SAAS,CAAC,kBAAkB;oBACpC,CAAC,CAAC,IAAA,wCAAU,EAAC,WAAW,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;oBACzD,CAAC,CAAC,WAAW,CAAC;aACrB;SACJ;QAED,IAAM,SAAS,GACX,iBAAiB,IAAI,MAAM;YACvB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3E,IAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEpE,aAAa,CAAC,oBAAoB,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAAC;QAElE,IAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;QACrD,IAAM,iBAAiB,GAAG,MAAM;YAC5B,CAAC,CAAC,IAAA,qDAAuB,EAAC,aAAa,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YACvF,CAAC,CAAC,IAAA,+DAAiC,EAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAE5E,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gCAAgC,EAAE;YAC1C,iBAAiB,CAAC,gCAAgC,GAAG,IAAI,CAAC;SAC7D;QAED,IAAI,SAAS,EAAE;YACX,iBAAiB,CAAC,SAAS,GAAG,SAAS,CAAC;SAC3C;QAED,IAAM,KAAK,GAAG,IAAA,+CAAiB,EAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAErE,IAAI,SAAS,EAAE;YACX,IAAA,yBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SAC7C;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;IA9CW,QAAA,kBAAkB,sBA8C7B","sourcesContent":["import { updateCache } from '../../corePlugin/cache/updateCache';\nimport {\n cloneModel,\n createDomToModelContext,\n createDomToModelContextWithConfig,\n domToContentModel,\n} from 'roosterjs-content-model-dom';\nimport type { CreateContentModel } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Create Content Model from DOM tree in this editor\n * @param core The editor core object\n * @param option The option to customize the behavior of DOM to Content Model conversion\n * @param selectionOverride When passed, use this selection range instead of current selection in editor\n */\nexport const createContentModel: CreateContentModel = (core, option, selectionOverride) => {\n // Flush all mutations if any, so that we can get an up-to-date Content Model\n core.cache.textMutationObserver?.flushMutations();\n const tryGetFromCache =\n !option || (option.tryGetFromCache && typeof option.recalculateTableSize === 'undefined');\n\n if (!selectionOverride && tryGetFromCache) {\n const cachedModel = core.cache.cachedModel;\n\n if (cachedModel) {\n // When in shadow edit, use a cloned model so we won't pollute the cached one\n return core.lifecycle.shadowEditFragment\n ? cloneModel(cachedModel, { includeCachedElement: true })\n : cachedModel;\n }\n }\n\n const selection =\n selectionOverride == 'none'\n ? undefined\n : selectionOverride || core.api.getDOMSelection(core) || undefined;\n const saveIndex = !option && !selectionOverride;\n const editorContext = core.api.createEditorContext(core, saveIndex);\n\n editorContext.recalculateTableSize = option?.recalculateTableSize;\n\n const settings = core.environment.domToModelSettings;\n const domToModelContext = option\n ? createDomToModelContext(editorContext, settings.builtIn, settings.customized, option)\n : createDomToModelContextWithConfig(settings.calculated, editorContext);\n\n if (option?.skipFormatContainerFallbackCheck) {\n domToModelContext.skipFormatContainerFallbackCheck = true;\n }\n\n if (selection) {\n domToModelContext.selection = selection;\n }\n\n const model = domToContentModel(core.logicalRoot, domToModelContext);\n\n if (saveIndex) {\n updateCache(core.cache, model, selection);\n }\n\n return model;\n};\n"]}
|
|
@@ -31,6 +31,11 @@ define(["require", "exports", "./areSameSelections", "./ParagraphMapImpl", "./te
|
|
|
31
31
|
_this.invalidateCache();
|
|
32
32
|
}
|
|
33
33
|
break;
|
|
34
|
+
case 'attribute':
|
|
35
|
+
if (!_this.state.domIndexer.reconcileImageAttribute(mutation.element, mutation.attributeName)) {
|
|
36
|
+
_this.invalidateCache();
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
34
39
|
case 'unknown':
|
|
35
40
|
_this.invalidateCache();
|
|
36
41
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CachePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/CachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelections } from './areSameSelections';\nimport { createParagraphMap } from './ParagraphMapImpl';\nimport { createTextMutationObserver } from './textMutationObserver';\nimport { DomIndexerImpl } from './domIndexerImpl';\nimport { updateCache } from './updateCache';\nimport type { Mutation } from './MutationType';\nimport type {\n CachePluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass CachePlugin implements PluginWithState<CachePluginState> {\n private editor: IEditor | null = null;\n private state: CachePluginState;\n\n /**\n * Construct a new instance of CachePlugin class\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\n constructor(option: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n domIndexer: new DomIndexerImpl(\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf(\n 'KeepSelectionMarkerWhenEnteringTextNode'\n ) >= 0\n ),\n textMutationObserver: createTextMutationObserver(contentDiv, this.onMutation),\n };\n\n if (option.enableParagraphMap) {\n this.state.paragraphMap = createParagraphMap();\n }\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Cache';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\n\n this.state.textMutationObserver.startObserving();\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.state.textMutationObserver.stopObserving();\n\n if (this.editor) {\n this.editor\n .getDocument()\n .removeEventListener('selectionchange', this.onNativeSelectionChange);\n this.editor = null;\n }\n }\n\n /**\n * Get plugin state object\n */\n getState(): CachePluginState {\n return this.state;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'logicalRootChanged':\n this.invalidateCache();\n\n this.state.textMutationObserver.stopObserving();\n this.state.textMutationObserver = createTextMutationObserver(\n event.logicalRoot,\n this.onMutation\n );\n this.state.textMutationObserver.startObserving();\n break;\n\n case 'selectionChanged':\n this.updateCachedModel(this.editor);\n break;\n\n case 'contentChanged':\n const { contentModel, selection } = event;\n\n if (contentModel) {\n updateCache(this.state, contentModel, selection);\n }\n\n break;\n }\n }\n\n private onMutation = (mutation: Mutation) => {\n if (this.editor) {\n switch (mutation.type) {\n case 'childList':\n if (\n !this.state.domIndexer.reconcileChildList(\n mutation.addedNodes,\n mutation.removedNodes\n )\n ) {\n this.invalidateCache();\n }\n break;\n\n case 'text':\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n break;\n\n case 'elementId':\n const element = mutation.element;\n\n if (!this.state.domIndexer.reconcileElementId(element)) {\n this.invalidateCache();\n }\n\n break;\n\n case 'unknown':\n this.invalidateCache();\n break;\n }\n }\n };\n\n private onNativeSelectionChange = () => {\n if (this.editor?.hasFocus()) {\n this.updateCachedModel(this.editor);\n }\n };\n\n private invalidateCache() {\n if (!this.editor?.isInShadowEdit()) {\n if (this.state.cachedModel) {\n this.state.cachedModel = undefined;\n }\n\n if (this.state.cachedSelection) {\n this.state.cachedSelection = undefined;\n }\n\n // Clear paragraph indexer to prevent stale references to old paragraphs\n // It will be rebuild next time when we create a new Content Model\n this.state.paragraphMap?.clear();\n }\n }\n\n private updateCachedModel(editor: IEditor, forceUpdate?: boolean) {\n if (editor.isInShadowEdit()) {\n return;\n }\n\n const cachedSelection = this.state.cachedSelection;\n this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range\n\n const newRangeEx = editor.getDOMSelection() || undefined;\n const model = this.state.cachedModel;\n const isSelectionChanged =\n forceUpdate ||\n !cachedSelection ||\n !newRangeEx ||\n !areSameSelections(newRangeEx, cachedSelection);\n\n if (isSelectionChanged) {\n if (\n !model ||\n !newRangeEx ||\n !this.state.domIndexer.reconcileSelection(model, newRangeEx, cachedSelection)\n ) {\n this.invalidateCache();\n } else {\n updateCache(this.state, model, newRangeEx);\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of CachePlugin class.\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\nexport function createCachePlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<CachePluginState> {\n return new CachePlugin(option, contentDiv);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"CachePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/CachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelections } from './areSameSelections';\nimport { createParagraphMap } from './ParagraphMapImpl';\nimport { createTextMutationObserver } from './textMutationObserver';\nimport { DomIndexerImpl } from './domIndexerImpl';\nimport { updateCache } from './updateCache';\nimport type { Mutation } from './MutationType';\nimport type {\n CachePluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass CachePlugin implements PluginWithState<CachePluginState> {\n private editor: IEditor | null = null;\n private state: CachePluginState;\n\n /**\n * Construct a new instance of CachePlugin class\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\n constructor(option: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n domIndexer: new DomIndexerImpl(\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf(\n 'KeepSelectionMarkerWhenEnteringTextNode'\n ) >= 0\n ),\n textMutationObserver: createTextMutationObserver(contentDiv, this.onMutation),\n };\n\n if (option.enableParagraphMap) {\n this.state.paragraphMap = createParagraphMap();\n }\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Cache';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\n\n this.state.textMutationObserver.startObserving();\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.state.textMutationObserver.stopObserving();\n\n if (this.editor) {\n this.editor\n .getDocument()\n .removeEventListener('selectionchange', this.onNativeSelectionChange);\n this.editor = null;\n }\n }\n\n /**\n * Get plugin state object\n */\n getState(): CachePluginState {\n return this.state;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'logicalRootChanged':\n this.invalidateCache();\n\n this.state.textMutationObserver.stopObserving();\n this.state.textMutationObserver = createTextMutationObserver(\n event.logicalRoot,\n this.onMutation\n );\n this.state.textMutationObserver.startObserving();\n break;\n\n case 'selectionChanged':\n this.updateCachedModel(this.editor);\n break;\n\n case 'contentChanged':\n const { contentModel, selection } = event;\n\n if (contentModel) {\n updateCache(this.state, contentModel, selection);\n }\n\n break;\n }\n }\n\n private onMutation = (mutation: Mutation) => {\n if (this.editor) {\n switch (mutation.type) {\n case 'childList':\n if (\n !this.state.domIndexer.reconcileChildList(\n mutation.addedNodes,\n mutation.removedNodes\n )\n ) {\n this.invalidateCache();\n }\n break;\n\n case 'text':\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n break;\n\n case 'elementId':\n const element = mutation.element;\n\n if (!this.state.domIndexer.reconcileElementId(element)) {\n this.invalidateCache();\n }\n\n break;\n\n case 'attribute':\n if (\n !this.state.domIndexer.reconcileImageAttribute(\n mutation.element,\n mutation.attributeName\n )\n ) {\n this.invalidateCache();\n }\n\n break;\n\n case 'unknown':\n this.invalidateCache();\n break;\n }\n }\n };\n\n private onNativeSelectionChange = () => {\n if (this.editor?.hasFocus()) {\n this.updateCachedModel(this.editor);\n }\n };\n\n private invalidateCache() {\n if (!this.editor?.isInShadowEdit()) {\n if (this.state.cachedModel) {\n this.state.cachedModel = undefined;\n }\n\n if (this.state.cachedSelection) {\n this.state.cachedSelection = undefined;\n }\n\n // Clear paragraph indexer to prevent stale references to old paragraphs\n // It will be rebuild next time when we create a new Content Model\n this.state.paragraphMap?.clear();\n }\n }\n\n private updateCachedModel(editor: IEditor, forceUpdate?: boolean) {\n if (editor.isInShadowEdit()) {\n return;\n }\n\n const cachedSelection = this.state.cachedSelection;\n this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range\n\n const newRangeEx = editor.getDOMSelection() || undefined;\n const model = this.state.cachedModel;\n const isSelectionChanged =\n forceUpdate ||\n !cachedSelection ||\n !newRangeEx ||\n !areSameSelections(newRangeEx, cachedSelection);\n\n if (isSelectionChanged) {\n if (\n !model ||\n !newRangeEx ||\n !this.state.domIndexer.reconcileSelection(model, newRangeEx, cachedSelection)\n ) {\n this.invalidateCache();\n } else {\n updateCache(this.state, model, newRangeEx);\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of CachePlugin class.\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\nexport function createCachePlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<CachePluginState> {\n return new CachePlugin(option, contentDiv);\n}\n"]}
|
|
@@ -10,6 +10,10 @@ export declare type MutationType =
|
|
|
10
10
|
* Element id is changed
|
|
11
11
|
*/
|
|
12
12
|
| 'elementId'
|
|
13
|
+
/**
|
|
14
|
+
* An attribute (such as src or data-*) is changed on an element
|
|
15
|
+
*/
|
|
16
|
+
| 'attribute'
|
|
13
17
|
/**
|
|
14
18
|
* Only text is changed
|
|
15
19
|
*/
|
|
@@ -35,6 +39,13 @@ export interface UnknownMutation extends MutationBase<'unknown'> {
|
|
|
35
39
|
export interface ElementIdMutation extends MutationBase<'elementId'> {
|
|
36
40
|
element: HTMLElement;
|
|
37
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export interface AttributeMutation extends MutationBase<'attribute'> {
|
|
46
|
+
element: HTMLElement;
|
|
47
|
+
attributeName: string;
|
|
48
|
+
}
|
|
38
49
|
/**
|
|
39
50
|
* @internal
|
|
40
51
|
*/
|
|
@@ -50,4 +61,4 @@ export interface ChildListMutation extends MutationBase<'childList'> {
|
|
|
50
61
|
/**
|
|
51
62
|
* @internal
|
|
52
63
|
*/
|
|
53
|
-
export declare type Mutation = UnknownMutation | ElementIdMutation | TextMutation | ChildListMutation;
|
|
64
|
+
export declare type Mutation = UnknownMutation | ElementIdMutation | AttributeMutation | TextMutation | ChildListMutation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MutationType.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/MutationType.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @internal Type of mutations\n */\nexport type MutationType =\n /**\n * We found some change happened but we cannot handle it, so set mutation type as \"unknown\"\n */\n | 'unknown'\n /**\n * Element id is changed\n */\n | 'elementId'\n /**\n * Only text is changed\n */\n | 'text'\n /**\n * Child list is changed\n */\n | 'childList';\n\n/**\n * @internal\n */\nexport interface MutationBase<T extends MutationType> {\n type: T;\n}\n\n/**\n * @internal\n */\nexport interface UnknownMutation extends MutationBase<'unknown'> {}\n\n/**\n * @internal\n */\nexport interface ElementIdMutation extends MutationBase<'elementId'> {\n element: HTMLElement;\n}\n\n/**\n * @internal\n */\nexport interface TextMutation extends MutationBase<'text'> {}\n\n/**\n * @internal\n */\nexport interface ChildListMutation extends MutationBase<'childList'> {\n addedNodes: Node[];\n removedNodes: Node[];\n}\n\n/**\n * @internal\n */\nexport type Mutation
|
|
1
|
+
{"version":3,"file":"MutationType.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/MutationType.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @internal Type of mutations\n */\nexport type MutationType =\n /**\n * We found some change happened but we cannot handle it, so set mutation type as \"unknown\"\n */\n | 'unknown'\n /**\n * Element id is changed\n */\n | 'elementId'\n /**\n * An attribute (such as src or data-*) is changed on an element\n */\n | 'attribute'\n /**\n * Only text is changed\n */\n | 'text'\n /**\n * Child list is changed\n */\n | 'childList';\n\n/**\n * @internal\n */\nexport interface MutationBase<T extends MutationType> {\n type: T;\n}\n\n/**\n * @internal\n */\nexport interface UnknownMutation extends MutationBase<'unknown'> {}\n\n/**\n * @internal\n */\nexport interface ElementIdMutation extends MutationBase<'elementId'> {\n element: HTMLElement;\n}\n\n/**\n * @internal\n */\nexport interface AttributeMutation extends MutationBase<'attribute'> {\n element: HTMLElement;\n attributeName: string;\n}\n\n/**\n * @internal\n */\nexport interface TextMutation extends MutationBase<'text'> {}\n\n/**\n * @internal\n */\nexport interface ChildListMutation extends MutationBase<'childList'> {\n addedNodes: Node[];\n removedNodes: Node[];\n}\n\n/**\n * @internal\n */\nexport type Mutation =\n | UnknownMutation\n | ElementIdMutation\n | AttributeMutation\n | TextMutation\n | ChildListMutation;\n"]}
|
|
@@ -53,6 +53,7 @@ export declare class DomIndexerImpl implements DomIndexer {
|
|
|
53
53
|
reconcileSelection(model: ContentModelDocument, newSelection: DOMSelection, oldSelection?: CacheSelection): boolean;
|
|
54
54
|
reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean;
|
|
55
55
|
reconcileElementId(element: HTMLElement): boolean;
|
|
56
|
+
reconcileImageAttribute(element: HTMLElement, attributeName: string): boolean;
|
|
56
57
|
private onBlockEntityDelimiter;
|
|
57
58
|
private isCollapsed;
|
|
58
59
|
private reconcileNodeSelection;
|
|
@@ -232,6 +232,33 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
|
|
|
232
232
|
return false;
|
|
233
233
|
}
|
|
234
234
|
};
|
|
235
|
+
DomIndexerImpl.prototype.reconcileImageAttribute = function (element, attributeName) {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
if ((0, roosterjs_content_model_dom_1.isElementOfType)(element, 'img')) {
|
|
238
|
+
var image = (_a = getIndexedSegmentItem(element)) === null || _a === void 0 ? void 0 : _a.segments[0];
|
|
239
|
+
if ((image === null || image === void 0 ? void 0 : image.segmentType) == 'Image') {
|
|
240
|
+
if (attributeName == 'src') {
|
|
241
|
+
// Use getAttribute('src') instead of retrieving src directly, in case the src
|
|
242
|
+
// has port and may be stripped by browser. This matches imageProcessor.
|
|
243
|
+
image.src = (_b = element.getAttribute('src')) !== null && _b !== void 0 ? _b : '';
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
else if (attributeName.indexOf('data-') == 0) {
|
|
247
|
+
// A data-* attribute may be added, modified or removed. Rebuild the whole
|
|
248
|
+
// dataset from DOM to keep it in sync, the same way imageProcessor builds it.
|
|
249
|
+
var dataset_1 = image.dataset;
|
|
250
|
+
(0, roosterjs_content_model_dom_1.getObjectKeys)(dataset_1).forEach(function (key) {
|
|
251
|
+
delete dataset_1[key];
|
|
252
|
+
});
|
|
253
|
+
(0, roosterjs_content_model_dom_1.getObjectKeys)(element.dataset).forEach(function (key) {
|
|
254
|
+
dataset_1[key] = element.dataset[key] || '';
|
|
255
|
+
});
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return false;
|
|
261
|
+
};
|
|
235
262
|
DomIndexerImpl.prototype.onBlockEntityDelimiter = function (node, entity, parent) {
|
|
236
263
|
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(node) && node.firstChild) {
|
|
237
264
|
var indexedDelimiter = node.firstChild;
|